summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEvan Prodromou <evan@controlyourself.ca>2009-05-26 23:24:01 -0400
committerEvan Prodromou <evan@controlyourself.ca>2009-05-26 23:24:01 -0400
commit648d967226f3b47aa6237d2be9d1a82df4f78402 (patch)
tree2592f56f0073ee21ce320a158233fdb1bd2710c4 /lib
parent6335c9cf59b384da24506c4a3f799315fbbc4b09 (diff)
parent0b53a820c2b4224b66b2a24f67302b4c5ca1deed (diff)
Merge branch '0.8.x' into userdesign
Conflicts: lib/attachmentlist.php lib/noticelist.php
Diffstat (limited to 'lib')
-rw-r--r--lib/attachmentlist.php31
-rw-r--r--lib/attachmentsection.php80
-rw-r--r--lib/common.php4
-rw-r--r--lib/facebookaction.php8
-rw-r--r--lib/frequentattachmentsection.php66
-rw-r--r--lib/noticelist.php52
-rw-r--r--lib/router.php17
-rw-r--r--lib/snapshot.php227
-rw-r--r--lib/util.php21
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);
}