diff options
author | Evan Prodromou <evan@controlyourself.ca> | 2009-05-26 23:24:01 -0400 |
---|---|---|
committer | Evan Prodromou <evan@controlyourself.ca> | 2009-05-26 23:24:01 -0400 |
commit | 648d967226f3b47aa6237d2be9d1a82df4f78402 (patch) | |
tree | 2592f56f0073ee21ce320a158233fdb1bd2710c4 /lib | |
parent | 6335c9cf59b384da24506c4a3f799315fbbc4b09 (diff) | |
parent | 0b53a820c2b4224b66b2a24f67302b4c5ca1deed (diff) |
Merge branch '0.8.x' into userdesign
Conflicts:
lib/attachmentlist.php
lib/noticelist.php
Diffstat (limited to 'lib')
-rw-r--r-- | lib/attachmentlist.php | 31 | ||||
-rw-r--r-- | lib/attachmentsection.php | 80 | ||||
-rw-r--r-- | lib/common.php | 4 | ||||
-rw-r--r-- | lib/facebookaction.php | 8 | ||||
-rw-r--r-- | lib/frequentattachmentsection.php | 66 | ||||
-rw-r--r-- | lib/noticelist.php | 52 | ||||
-rw-r--r-- | lib/router.php | 17 | ||||
-rw-r--r-- | lib/snapshot.php | 227 | ||||
-rw-r--r-- | lib/util.php | 21 |
9 files changed, 289 insertions, 217 deletions
diff --git a/lib/attachmentlist.php b/lib/attachmentlist.php index 8d6d19f2a..dcf59b1bc 100644 --- a/lib/attachmentlist.php +++ b/lib/attachmentlist.php @@ -79,9 +79,9 @@ class AttachmentList extends Widget function show() { -// $this->out->elementStart('div', array('id' =>'attachments_primary')); - $this->out->elementStart('div', array('id' =>'content')); - $this->out->element('h2', null, _('Attachments')); + $this->out->elementStart('dl', array('id' =>'attachment')); + $this->out->element('dt', null, _('Attachments')); + $this->out->elementStart('dd'); $this->out->elementStart('ul', array('class' => 'attachments')); $atts = new File; @@ -91,8 +91,9 @@ class AttachmentList extends Widget $item->show(); } + $this->out->elementEnd('dd'); $this->out->elementEnd('ul'); - $this->out->elementEnd('div'); + $this->out->elementEnd('dl'); return count($att); } @@ -170,7 +171,7 @@ class AttachmentListItem extends Widget } function linkTitle() { - return 'Our page for ' . $this->title(); + return $this->title(); } /** @@ -190,33 +191,25 @@ class AttachmentListItem extends Widget } function linkAttr() { - return array('class' => 'attachment', 'href' => common_local_url('attachment', array('attachment' => $this->attachment->id))); + return array('class' => 'attachment', 'href' => $this->attachment->url, 'id' => 'attachment-' . $this->attachment->id); } function showLink() { - $attr = $this->linkAttr(); - $text = $this->linkTitle(); - $this->out->elementStart('h4'); - $this->out->element('a', $attr, $text); - - if ($this->attachment->url !== $this->title()) - $this->out->element('span', null, " ({$this->attachment->url})"); - - $this->out->elementEnd('h4'); + $this->out->elementStart('a', $this->linkAttr()); + $this->out->element('span', null, $this->linkTitle()); + $this->showRepresentation(); + $this->out->elementEnd('a'); } function showNoticeAttachment() { $this->showLink(); - $this->showRepresentation(); } function showRepresentation() { $thumbnail = File_thumbnail::staticGet('file_id', $this->attachment->id); if (!empty($thumbnail)) { - $this->out->elementStart('a', $this->linkAttr()/*'href' => $this->linkTo()*/); $this->out->element('img', array('alt' => 'nothing to say', 'src' => $thumbnail->url, 'width' => $thumbnail->width, 'height' => $thumbnail->height)); - $this->out->elementEnd('a'); } } @@ -258,7 +251,7 @@ class Attachment extends AttachmentListItem } function linkTitle() { - return 'Direct link to ' . $this->title(); + return $this->attachment->url; } function showRepresentation() { diff --git a/lib/attachmentsection.php b/lib/attachmentsection.php deleted file mode 100644 index 20e620b9b..000000000 --- a/lib/attachmentsection.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php -/** - * Laconica, the distributed open-source microblogging tool - * - * Base class for sections showing lists of attachments - * - * PHP version 5 - * - * LICENCE: This program 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 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY 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 this program. If not, see <http://www.gnu.org/licenses/>. - * - * @category Widget - * @package Laconica - * @author Evan Prodromou <evan@controlyourself.ca> - * @copyright 2009 Control Yourself, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://laconi.ca/ - */ - -if (!defined('LACONICA')) { - exit(1); -} - -define('ATTACHMENTS_PER_SECTION', 6); - -/** - * Base class for sections showing lists of attachments - * - * These are the widgets that show interesting data about a person - * group, or site. - * - * @category Widget - * @package Laconica - * @author Evan Prodromou <evan@controlyourself.ca> - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://laconi.ca/ - */ - -class AttachmentSection extends Section -{ - function showContent() - { - $attachments = $this->getAttachments(); - - $cnt = 0; - - $this->out->elementStart('ul', 'attachments'); - - while ($attachments->fetch() && ++$cnt <= ATTACHMENTS_PER_SECTION) { - $this->showAttachment($attachments); - } - - $this->out->elementEnd('ul'); - - return ($cnt > ATTACHMENTS_PER_SECTION); - } - - function getAttachments() - { - return null; - } - - function showAttachment($attachment) - { - $this->out->elementStart('li'); - $this->out->element('a', array('class' => 'attachment', 'href' => common_local_url('attachment', array('attachment' => $attachment->file_id))), "Attachment tagged {$attachment->c} times"); - $this->out->elementEnd('li'); - } -} - diff --git a/lib/common.php b/lib/common.php index 3feba1d8b..0ce46442d 100644 --- a/lib/common.php +++ b/lib/common.php @@ -159,6 +159,10 @@ $config = 'newuser' => array('subscribe' => null, 'welcome' => null), + 'snapshot' => + array('run' => 'web', + 'frequency' => 10000, + 'reporturl' => 'http://laconi.ca/stats/report'), ); $config['db'] = &PEAR::getStaticProperty('DB_DataObject','options'); diff --git a/lib/facebookaction.php b/lib/facebookaction.php index 043a078cd..637a6284d 100644 --- a/lib/facebookaction.php +++ b/lib/facebookaction.php @@ -97,11 +97,11 @@ class FacebookAction extends Action { // Add a timestamp to the file so Facebook cache wont ignore our changes $ts = filemtime(INSTALLDIR.'/theme/base/css/display.css'); + + $this->element('link', array('rel' => 'stylesheet', + 'type' => 'text/css', + 'href' => theme_path('css/display.css', 'base') . '?ts=' . $ts)); - $this->element('link', array('rel' => 'stylesheet', - 'type' => 'text/css', - 'href' => theme_path('css/display.css', 'base') . '?ts=' . $ts)); - $theme = common_config('site', 'theme'); $ts = filemtime(INSTALLDIR. '/theme/' . $theme .'/css/display.css'); diff --git a/lib/frequentattachmentsection.php b/lib/frequentattachmentsection.php deleted file mode 100644 index 0ce0d1871..000000000 --- a/lib/frequentattachmentsection.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php -/** - * Laconica, the distributed open-source microblogging tool - * - * FIXME - * - * PHP version 5 - * - * LICENCE: This program 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 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY 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 this program. If not, see <http://www.gnu.org/licenses/>. - * - * @category Widget - * @package Laconica - * @author Evan Prodromou <evan@controlyourself.ca> - * @copyright 2009 Control Yourself, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://laconi.ca/ - */ - -if (!defined('LACONICA')) { - exit(1); -} - -/** - * FIXME - * - * These are the widgets that show interesting data about a person - * group, or site. - * - * @category Widget - * @package Laconica - * @author Evan Prodromou <evan@controlyourself.ca> - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://laconi.ca/ - */ - -class FrequentAttachmentSection extends AttachmentSection -{ - function getAttachments() { - $notice_tag = new Notice_tag; - $query = 'select file_id, count(file_id) as c from notice_tag join file_to_post on post_id = notice_id where tag="' . $notice_tag->escape($this->out->tag) . '" group by file_id order by c desc'; - $notice_tag->query($query); - return $notice_tag; - } - - function title() - { - return sprintf(_('Attachments frequently tagged with %s'), $this->out->tag); - } - - function divId() - { - return 'frequent_attachments'; - } -} - diff --git a/lib/noticelist.php b/lib/noticelist.php index ba3526509..8aab83433 100644 --- a/lib/noticelist.php +++ b/lib/noticelist.php @@ -34,6 +34,7 @@ if (!defined('LACONICA')) { require_once INSTALLDIR.'/lib/favorform.php'; require_once INSTALLDIR.'/lib/disfavorform.php'; +require_once INSTALLDIR.'/lib/attachmentlist.php'; /** * widget for displaying a list of notices @@ -192,45 +193,24 @@ class NoticeListItem extends Widget $this->out->elementEnd('div'); } - function showNoticeAttachments() - { - $f2p = new File_to_post; - $f2p->post_id = $this->notice->id; - $file = new File; - $file->joinAdd($f2p); - $file->selectAdd(); - $file->selectAdd('file.id as id'); - $count = $file->find(true); - if (!$count) return; - if (1 === $count) { - $href = common_local_url('attachment', array('attachment' => $file->id)); - $att_class = 'attachment'; - } else { - $href = common_local_url('attachments', array('notice' => $this->notice->id)); - $att_class = 'attachments'; + function showNoticeAttachments() { + if ($this->isUsedInList()) { + return; } + $al = new AttachmentList($this->notice, $this->out); + $al->show(); + } - $clip = theme_path('images/icons/clip', 'base'); - if ('shownotice' === $this->out->args['action']) { - $height = '96px'; - $width = '83%'; - $width_att = '15%'; - $clip .= '-big.png'; - $top = '70px'; - } else { - $height = '48px'; - $width = '90%'; - $width_att = '8%'; - $clip .= '.png'; - $top = '20px'; - } -if(0) - $this->out->elementStart('div', 'entry-attachments'); -else - $this->out->elementStart('p', array('class' => 'entry-attachments', 'style' => "float: right; width: $width_att; background: url($clip) no-repeat; text-align: right; height: $height;")); - $this->out->element('a', array('class' => $att_class, 'style' => "text-decoration: none; padding-top: $top; display: block; height: $height;", 'href' => $href, 'title' => "# of attachments: $count"), $count === 1 ? '' : $count); + function isUsedInList() { + return 'shownotice' !== $this->out->args['action']; + } - $this->out->elementEnd('p'); + function attachmentCount($discriminant = true) { + $file_oembed = new File_oembed; + $query = "select count(*) as c from file_oembed join file_to_post on file_oembed.file_id = file_to_post.file_id where post_id=" . $this->notice->id; + $file_oembed->query($query); + $file_oembed->fetch(); + return intval($file_oembed->c); } function showNoticeInfo() diff --git a/lib/router.php b/lib/router.php index 70ee0f3fb..fc119821b 100644 --- a/lib/router.php +++ b/lib/router.php @@ -153,24 +153,17 @@ class Router $m->connect('attachment/:attachment/ajax', array('action' => 'attachment_ajax'), - array('notice' => '[0-9]+')); - - $m->connect('attachment/:attachment', - array('action' => 'attachment'), - array('notice' => '[0-9]+')); + array('attachment' => '[0-9]+')); - // notice + $m->connect('attachment/:attachment/thumbnail', + array('action' => 'attachment_thumbnail'), + array('attachment' => '[0-9]+')); $m->connect('notice/new', array('action' => 'newnotice')); $m->connect('notice/new?replyto=:replyto', array('action' => 'newnotice'), array('replyto' => '[A-Za-z0-9_-]+')); - $m->connect('notice/:notice/attachments/ajax', - array('action' => 'attachments_ajax'), - array('notice' => '[0-9]+')); - $m->connect('notice/:notice/attachments', - array('action' => 'attachments'), - array('notice' => '[0-9]+')); + $m->connect('notice/:notice', array('action' => 'shownotice'), array('notice' => '[0-9]+')); diff --git a/lib/snapshot.php b/lib/snapshot.php new file mode 100644 index 000000000..4b05b502d --- /dev/null +++ b/lib/snapshot.php @@ -0,0 +1,227 @@ +<?php +/** + * Laconica, the distributed open-source microblogging tool + * + * A snapshot of site stats that can report itself to headquarters + * + * PHP version 5 + * + * LICENCE: This program 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY 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 this program. If not, see <http://www.gnu.org/licenses/>. + * + * @category Stats + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +/** + * A snapshot of site stats that can report itself to headquarters + * + * This class will collect statistics on the site and report them to + * a statistics server of the admin's choice. (Default is the big one + * at laconi.ca.) + * + * It can either be called from a cron job, or run occasionally by the + * Web site. + * + * @category Stats + * @package Laconica + * @author Evan Prodromou <evan@controlyourself.ca> + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + */ + +class Snapshot +{ + var $stats = null; + + /** + * Constructor for a snapshot + */ + + function __construct() + { + } + + /** + * Static function for reporting statistics + * + * This function checks whether it should report statistics, based on + * the current configuation settings. If it should, it creates a new + * Snapshot object, takes a snapshot, and reports it to headquarters. + * + * @return void + */ + + static function check() + { + switch (common_config('snapshot', 'run')) { + case 'web': + // skip if we're not running on the Web. + if (!isset($_SERVER) || !array_key_exists('REQUEST_METHOD', $_SERVER)) { + break; + } + // Run once every frequency hits + // XXX: do frequency by time (once a week, etc.) rather than + // hits + if (rand() % common_config('snapshot', 'frequency') == 0) { + $snapshot = new Snapshot(); + $snapshot->take(); + $snapshot->report(); + } + break; + case 'cron': + // skip if we're running on the Web + if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) { + break; + } + common_log(LOG_INFO, 'Running snapshot from cron job'); + // We're running from the command line; assume + + $snapshot = new Snapshot(); + $snapshot->take(); + common_log(LOG_INFO, count($snapshot->stats) . " statistics being uploaded."); + $snapshot->report(); + + break; + case 'never': + break; + default: + common_log(LOG_WARNING, "Unrecognized value for snapshot run config."); + } + } + + /** + * Take a snapshot of the server + * + * Builds an array of statistical and configuration data based + * on the local database and config files. We avoid grabbing any + * information that could be personal or private. + * + * @return void + */ + + function take() + { + $this->stats = array(); + + // Some basic identification stuff + + $this->stats['version'] = LACONICA_VERSION; + $this->stats['phpversion'] = phpversion(); + $this->stats['name'] = common_config('site', 'name'); + $this->stats['root'] = common_root_url(); + + // non-identifying stats on various tables. Primary + // interest is size and rate of activity of service. + + $tables = array('user', + 'notice', + 'subscription', + 'remote_profile', + 'user_group'); + + foreach ($tables as $table) { + $this->tableStats($table); + } + + // stats on some important config options + + $this->stats['theme'] = common_config('site', 'theme'); + $this->stats['dbtype'] = common_config('db', 'type'); + $this->stats['xmpp'] = common_config('xmpp', 'enabled'); + $this->stats['inboxes'] = common_config('inboxes', 'enabled'); + $this->stats['queue'] = common_config('queue', 'enabled'); + $this->stats['license'] = common_config('license', 'url'); + $this->stats['fancy'] = common_config('site', 'fancy'); + $this->stats['private'] = common_config('site', 'private'); + $this->stats['closed'] = common_config('site', 'closed'); + $this->stats['memcached'] = common_config('memcached', 'enabled'); + $this->stats['language'] = common_config('site', 'language'); + $this->stats['timezone'] = common_config('site', 'timezone'); + + } + + /** + * Reports statistics to headquarters + * + * Posts statistics to a reporting server. + * + * @return void + */ + + function report() + { + // XXX: Use OICU2 and OAuth to make authorized requests + + $postdata = http_build_query($this->stats); + + $opts = + array('http' => + array( + 'method' => 'POST', + 'header' => 'Content-type: '. + 'application/x-www-form-urlencoded', + 'content' => $postdata, + 'user_agent' => 'Laconica/'.LACONICA_VERSION + ) + ); + + $context = stream_context_create($opts); + + $reporturl = common_config('snapshot', 'reporturl'); + + $result = @file_get_contents($reporturl, false, $context); + + return $result; + } + + /** + * Updates statistics for a single table + * + * Determines the size of a table and its oldest and newest rows. + * Goal here is to see how active a site is. Note that it + * fills up the instance stats variable. + * + * @param string $table name of table to check + * + * @return void + */ + + function tableStats($table) + { + $inst = DB_DataObject::factory($table); + + $inst->selectAdd(); + $inst->selectAdd('count(*) as cnt, '. + 'min(created) as first, '. + 'max(created) as last'); + + if ($inst->find(true)) { + $this->stats[$table.'count'] = $inst->cnt; + $this->stats[$table.'first'] = $inst->first; + $this->stats[$table.'last'] = $inst->last; + } + + $inst->free(); + unset($inst); + } +} diff --git a/lib/util.php b/lib/util.php index fbef8764a..d56f44f7b 100644 --- a/lib/util.php +++ b/lib/util.php @@ -496,6 +496,27 @@ function common_linkify($url) { } $attrs = array('href' => $longurl, 'rel' => 'external'); + +// if this URL is an attachment, then we set class='attachment' and id='attahcment-ID' +// where ID is the id of the attachment for the given URL. + $query = "select file_oembed.file_id as file_id from file join file_oembed on file.id = file_oembed.file_id where file.url='$longurl'"; + $file = new File; + $file->query($query); + $file->fetch(); + + if (!empty($file->file_id)) { + $query = "select file_thumbnail.file_id as file_id from file join file_thumbnail on file.id = file_thumbnail.file_id where file.url='$longurl'"; + $file2 = new File; + $file2->query($query); + $file2->fetch(); + + if (empty($file2->file_id)) { + $attrs['class'] = 'attachment'; + } else { + $attrs['class'] = 'attachment thumbnail'; + } + $attrs['id'] = "attachment-{$file->file_id}"; + } return XMLStringer::estring('a', $attrs, $display); } |