Commit bbf123b6 authored by hannes's avatar hannes

v3: major change

qvitter is now a plugin
parent 19ad3abd
<?php
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· ·
· Q V I T T E R ·
· ·
· http://github.com/hannesmannerheim/qvitter ·
· ·
· ·
· <o) ·
· /_//// ·
· (____/ ·
· (o< ·
· o> \\\\_\ ·
· \\) \____) ·
· ·
· ·
· ·
· Qvitter is free software: you can redistribute it and / or modify it ·
· under the terms of the GNU Affero General Public License as published by ·
· the Free Software Foundation, either version three of the License or (at ·
· your option) any later version. ·
· ·
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
· WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS ·
· FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for ·
· more details. ·
· ·
· You should have received a copy of the GNU Affero General Public License ·
· along with Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
· ·
· Contact h@nnesmannerhe.im if you have any questions. ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
class QvitterPlugin extends Plugin {
public function settings($setting)
{
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· S E T T I N G S ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
// ENABLED BY DEFAULT (true/false)
$settings['enabledbydefault'] = true;
// DEFAULT BACKGROUND COLOR
$settings['defaultbackgroundcolor'] = '#f4f4f4';
// DEFAULT LINK COLOR
$settings['defaultlinkcolor'] = '#0084B4';
// TIME BETWEEN POLLING
$settings['timebetweenpolling'] = 5000; // ms
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· (o> >o) ·
· \\\\_\ /_//// .
· \____) (____/ ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
return $settings[$setting];
}
public function onRouterInitialized($m)
{
$m->connect('api/qvitter.json', array('action' => 'qvitterapi'));
$m->connect('api/statuses/public_and_external_timeline.:format',
array('action' => 'ApiTimelinePublicAndExternal',
'format' => '(xml|json|rss|atom|as)'));
$m->connect('api/qvitter/update_link_color.json',
array('action' => 'apiqvitterupdatelinkcolor'));
$m->connect('api/qvitter/update_background_color.json',
array('action' => 'apiqvitterupdatebackgroundcolor'));
$m->connect('settings/qvitter',
array('action' => 'qvittersettings'));
$m->connect('main/qlogin',
array('action' => 'qvitterlogin'));
// check if we should reroute UI to qvitter
$logged_in_user = common_current_user();
$qvitter_enabled_by_user = false;
$qvitter_disabled_by_user = false;
if($logged_in_user) {
try {
$qvitter_enabled_by_user = Profile_prefs::getData($logged_in_user->getProfile(), 'qvitter', 'enable_qvitter');
} catch (NoResultException $e) {
$qvitter_enabled_by_user = false;
}
try {
$qvitter_disabled_by_user = Profile_prefs::getData($logged_in_user->getProfile(), 'qvitter', 'disable_qvitter');
} catch (NoResultException $e) {
$qvitter_disabled_by_user = false;
}
}
if((self::settings('enabledbydefault') && !$logged_in_user) ||
(self::settings('enabledbydefault') && !$qvitter_disabled_by_user) ||
(!self::settings('enabledbydefault') && $qvitter_enabled_by_user)) {
$m->connect('', array('action' => 'qvitter'));
$m->connect('main/all', array('action' => 'qvitter'));
$m->connect('search/notice', array('action' => 'qvitter'));
URLMapperOverwrite::overwrite_variable($m, ':nickname',
array('action' => 'showstream'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':nickname/',
array('action' => 'showstream'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':nickname/all',
array('action' => 'all'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':nickname/subscriptions',
array('action' => 'subscriptions'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':nickname/subscribers',
array('action' => 'subscribers'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':nickname/groups',
array('action' => 'usergroups'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':nickname/replies',
array('action' => 'replies'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, ':nickname/favorites',
array('action' => 'showfavorites'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, 'group/:nickname',
array('action' => 'showgroup'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
URLMapperOverwrite::overwrite_variable($m, 'group/:nickname/members',
array('action' => 'groupmembers'),
array('nickname' => Nickname::DISPLAY_FMT),
'qvitter');
$m->connect('group/:nickname/admins',
array('action' => 'qvitter'),
array('nickname' => Nickname::DISPLAY_FMT));
URLMapperOverwrite::overwrite_variable($m, 'tag/:tag',
array('action' => 'showstream'),
array('tag' => Router::REGEX_TAG),
'qvitter');
}
}
/**
* Menu item for Qvitter
*
* @param Action $action action being executed
*
* @return boolean hook return
*/
function onEndAccountSettingsNav($action)
{
$action_name = $action->trimmed('action');
$action->menuItem(common_local_url('qvittersettings'),
// TRANS: Poll plugin menu item on user settings page.
_m('MENU', 'Qvitter'),
// TRANS: Poll plugin tooltip for user settings menu item.
_m('Enable/Disable Qvitter UI'),
$action_name === 'qvittersettings');
return true;
}
}
/**
* Overwrites variables in URL-mapping
*
*/
class URLMapperOverwrite extends URLMapper
{
function overwrite_variable($m, $path, $args, $paramPatterns, $newaction)
{
$m->connect($path, array('action' => $newaction), $paramPatterns);
$regex = URLMapper::makeRegex($path, $paramPatterns);
foreach($m->variables as $n=>$v)
if($v[1] == $regex)
$m->variables[$n][0]['action'] = $newaction;
}
}
?>
......@@ -2,8 +2,8 @@ Qvitter
==========================================
* Author: Hannes Mannerheim (<h@nnesmannerhe.im>)
* Last mod.: November, 2013
* Version: 2
* Last mod.: May, 2014
* Version: 3
* GitHub: <https://github.com/hannesmannerheim/qvitter>
Qvitter is free software: you can redistribute it and / or modify it
......@@ -22,20 +22,21 @@ along with Qvitter. If not, see <http://www.gnu.org/licenses/>.
Setup
-----
1. You need a webserver with PHP support.
1. Install GNU Social
2. Edit settings.php.
2. Put all files in /plugins/Qvitter
3. You should really put some security-by-obscurity-stuff in the registration process. E-mail h@nnesmannerhe.im if you want to copy mine.
3. Add `addPlugin('Qvitter')` to your /config.php file;
Qvitter uses a slightly modified statusnet API. Some things will not work
if you connect to a site with standard API. Files are included if you want
to Qvitter-mod your Statusnet API.
4. There are a few settings in /plugins/Qvitter/QvitterPlugin.php. By default Qvitter is
opt-out for users. If you set `$settings['enabledbydefault'] = false;` Qvitter will
be opt-in instead.
5. Users can go to ://{instance}/settings/qvitter and enable or disable Qvitter.
NOTE: Qvitter is now a plugin for GNU Social. There will probably be bugs because of
this change.
Recently MMN-o has implemented these API-changes in GNU Social. The API changes should
only be needed if you are running Statusnet 1.1.1, not if you have a recent GNU Social
version.
TODO
----
......@@ -52,7 +53,7 @@ TODO
7. Settings (e.g. don't show replies to people I don't follow)
9. Image/file upload, drag-n-drop!
9. Image/file upload
10. Search users
......@@ -60,13 +61,15 @@ TODO
12. Filters (hide queets containing strings, e.g. mute users)
14. More languages
14. More languages, maybe make proper po/mo-files
15. Queet-page
15. Notice-page
16. Admin-interface
16. New api for serving _number_ of new items in several streams (to show number of new items in menu/history)
16. New api for serving _number_ of new items in several streams (to show number of new items in menu/history)
17. Notifications-page with likes and repeats
17. New "expand queet" api for getting conversation, retweets, favs and attachment in the same request
......
<?php
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· ·
· Q V I T T E R ·
· ·
· http://github.com/hannesmannerheim/qvitter ·
· ·
· ·
· <o) ·
· /_//// ·
· (____/ ·
· (o< ·
· o> \\\\_\ ·
· \\) \____) ·
· ·
· ·
· ·
· Qvitter is free software: you can redistribute it and / or modify it ·
· under the terms of the GNU Affero General Public License as published by ·
· the Free Software Foundation, either version three of the License or (at ·
· your option) any later version. ·
· ·
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
· WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS ·
· FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for ·
· more details. ·
· ·
· You should have received a copy of the GNU Affero General Public License ·
· along with Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
· ·
· Contact h@nnesmannerhe.im if you have any questions. ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
if (!defined('GNUSOCIAL')) { exit(1); }
class ApiQvitterUpdateBackgroundColorAction extends ApiAuthAction
{
var $backgroundcolor = null;
protected $needPost = true;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->backgroundcolor = $this->trimmed('backgroundcolor');
return true;
}
/**
* Handle the request
*
* Try to save the user's colors in her design. Create a new design
* if the user doesn't already have one.
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$validhex = preg_match('/^[a-f0-9]{6}$/i',$this->backgroundcolor);
if ($validhex === false || $validhex == 0) {
$this->clientError(_('Not a valid hex color.'), 400);
}
Profile_prefs::setData($this->scoped, 'theme', 'backgroundcolor', $this->backgroundcolor);
$twitter_user = $this->twitterUserArray($this->scoped, true);
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
}
<?php
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· ·
· Q V I T T E R ·
· ·
· http://github.com/hannesmannerheim/qvitter ·
· ·
· ·
· <o) ·
· /_//// ·
· (____/ ·
· (o< ·
· o> \\\\_\ ·
· \\) \____) ·
· ·
· ·
· ·
· Qvitter is free software: you can redistribute it and / or modify it ·
· under the terms of the GNU Affero General Public License as published by ·
· the Free Software Foundation, either version three of the License or (at ·
· your option) any later version. ·
· ·
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
· WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS ·
· FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for ·
· more details. ·
· ·
· You should have received a copy of the GNU Affero General Public License ·
· along with Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
· ·
· Contact h@nnesmannerhe.im if you have any questions. ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
if (!defined('GNUSOCIAL')) { exit(1); }
class ApiQvitterUpdateLinkColorAction extends ApiAuthAction
{
var $linkcolor = null;
protected $needPost = true;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
$this->linkcolor = $this->trimmed('linkcolor');
return true;
}
/**
* Handle the request
*
* Try to save the user's colors in her design. Create a new design
* if the user doesn't already have one.
*
* @param array $args $_REQUEST data (unused)
*
* @return void
*/
protected function handle()
{
parent::handle();
$validhex = preg_match('/^[a-f0-9]{6}$/i',$this->linkcolor);
if ($validhex === false || $validhex == 0) {
$this->clientError(_('Not a valid hex color.'), 400);
}
// save the new color
Profile_prefs::setData($this->scoped, 'theme', 'linkcolor', $this->linkcolor);
$twitter_user = $this->twitterUserArray($this->scoped, true);
$this->initDocument('json');
$this->showJsonObjects($twitter_user);
$this->endDocument('json');
}
}
......@@ -38,8 +38,6 @@ if (!defined('STATUSNET')) {
exit(1);
}
require_once INSTALLDIR . '/lib/apiprivateauth.php';
/**
* Returns the most recent notices (default 20) posted by everybody
*
......
This diff is collapsed.
......@@ -34,56 +34,65 @@
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
require_once('settings.php');
class QvitterApiAction extends ApiAction
{
header("Content-type: application/json; charset=utf-8");
protected $needPost = true;
// add slash if missing
if(substr($apiroot,-1) != '/') {
$apiroot .= '/';
}
protected function prepare(array $args=array())
{
parent::prepare($args);
// post requests
if(isset($_POST['postRequest'])) {
$query = http_build_query($_POST, '', '&');
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $apiroot.urldecode($_POST['postRequest']));
curl_setopt($ch, CURLOPT_USERPWD, $_POST['username'].":".$_POST['password']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
session_write_close(); // fix problem with curling to local
$reply=curl_exec($ch);
curl_close($ch);
return true;
}
// get requests
} elseif(isset($_POST['getRequest'])) {
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $apiroot.$_POST['getRequest']);
protected function handle()
{
parent::handle();
$apiroot = common_path('api/', true);
header("Content-type: application/json; charset=utf-8");
// post requests
if(isset($_POST['postRequest'])) {
$query = http_build_query($_POST, '', '&');
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $apiroot.urldecode($_POST['postRequest']));
curl_setopt($ch, CURLOPT_USERPWD, $_POST['username'].":".$_POST['password']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
session_write_close(); // fix problem with curling to local
$reply=curl_exec($ch);
curl_close($ch);
// get requests
} elseif(isset($_POST['getRequest'])) {
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $apiroot.$_POST['getRequest']);
if(isset($_POST['username'])) {
curl_setopt($ch, CURLOPT_USERPWD, $_POST['username'].":".$_POST['password']);
}
if(isset($_POST['username'])) {
curl_setopt($ch, CURLOPT_USERPWD, $_POST['username'].":".$_POST['password']);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
session_write_close();
$reply=curl_exec($ch);
curl_close($ch);
} else {
// 400 Bad request, since neither postRequest or getRequest were included
http_response_code(400);
exit;
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
session_write_close();
$reply=curl_exec($ch);
curl_close($ch);
} else {
// 400 Bad request, since neither postRequest or getRequest were included
http_response_code(400);
exit;
}
session_start();
session_start();
// force ssl on our domain
if($forcessl) {
$reply = str_replace('http://'.$siterootdomain,'https://'.$siterootdomain, $reply);
}
echo $reply;
echo $reply;
}
}
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
......
<?php
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· ·
· Q V I T T E R ·
· ·
· http://github.com/hannesmannerheim/qvitter ·
· ·
· ·
· <o) ·
· /_//// ·
· (____/ ·
· (o< ·
· o> \\\\_\ ·
· \\) \____) ·
· ·
· ·
· ·
· Qvitter is free software: you can redistribute it and / or modify it ·
· under the terms of the GNU Affero General Public License as published by ·
· the Free Software Foundation, either version three of the License or (at ·
· your option) any later version. ·
· ·
· Qvitter is distributed in hope that it will be useful but WITHOUT ANY ·
· WARRANTY; without even the implied warranty of MERCHANTABILTY or FITNESS ·
· FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for ·
· more details. ·
· ·
· You should have received a copy of the GNU Affero General Public License ·
· along with Qvitter. If not, see <http://www.gnu.org/licenses/>. ·
· ·
· Contact h@nnesmannerhe.im if you have any questions. ·
· ·
· · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · */
if (!defined('GNUSOCIAL')) { exit(1); }
class QvitterLoginAction extends FormAction
{
protected $needLogin = false;
/**
* Prepare page to run
*
*
* @param $args
* @return string title
*/
protected function prepare(array $args=array())
{
// @todo this check should really be in index.php for all sensitive actions
$ssl = common_config('site', 'ssl');
if (empty($_SERVER['HTTPS']) && ($ssl == 'always' || $ssl == 'sometimes')) {
common_redirect(common_local_url('login'));
}
return parent::prepare($args);
}
/**
* Handle input, produce output
*
* Switches on request method; either shows the form or handles its input.
*
* @return void
*/
protected function handle()
{
if (common_is_real_login()) {
common_redirect(common_local_url('all', array('nickname' => $this->scoped->nickname)), 307);
}
return parent::handle();
}
/**
* Check the login data
*
* Determines if the login data is valid. If so, logs the user
* in, and redirects to the 'with friends' page, or to the stored
* return-to URL.
*
* @return void
*/
protected function handlePost()
{
parent::handlePost();
// XXX: login throttle
$nickname = $this->trimmed('nickname');
$password = $this->arg('password');
$user = common_check_user($nickname, $password);
if (!$user instanceof User) {
// TRANS: Form validation error displayed when trying to log in with incorrect credentials.
throw new ServerException(_('Incorrect username or password.'));
}
// success!
if (!common_set_user($user)) {
// TRANS: Server error displayed when during login a server error occurs.
throw new ServerException(_('Error setting user. You are probably not authorized.'));
}
common_real_login(true);
$this->updateScopedProfile();
if ($this->boolean('rememberme')) {
common_rememberme($user);
}
$url = common_get_returnto();
if ($url) {
// We don't have to return to it again
common_set_returnto(null);
$url = common_inject_session($url);
} else {
$url = common_local_url('all',
array('nickname' => $this->scoped->nickname));
}
common_redirect($url, 303);
}
function showPage()
{
QvitterAction::showQvitter();
}
}
<?php
/* · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·
· ·
· ·
· Q V I T T E R ·
· ·