diff options
author | Mike Cochrane <mikec@mikenz.geek.nz> | 2008-07-20 01:57:02 -0400 |
---|---|---|
committer | Mike Cochrane <mikec@mikenz.geek.nz> | 2008-07-20 01:57:02 -0400 |
commit | 5d84485001ace75c49cdc295b4ed3540db83e988 (patch) | |
tree | 4100b04f90ecfecf95082c5fc2472bd7707e28f3 | |
parent | e4f1d6f50444cf2ca6e9aaf7116d40eaa17b0f1c (diff) |
First cut at hastags support.
darcs-hash:20080720055702-533db-193ed842b0d0a952bef71a3c5287213ada0ef15c.gz
-rw-r--r-- | actions/newnotice.php | 3 | ||||
-rw-r--r-- | actions/postnotice.php | 3 | ||||
-rw-r--r-- | classes/Notice.php | 24 | ||||
-rw-r--r-- | classes/Notice_tag.php | 22 | ||||
-rw-r--r-- | db/laconica.sql | 11 | ||||
-rwxr-xr-x | fixup_hashtags.php | 46 | ||||
-rw-r--r-- | lib/common.php | 1 | ||||
-rw-r--r-- | lib/util.php | 23 | ||||
-rwxr-xr-x | xmppdaemon.php | 27 |
9 files changed, 139 insertions, 21 deletions
diff --git a/actions/newnotice.php b/actions/newnotice.php index 711b77e0a..5f6a22484 100644 --- a/actions/newnotice.php +++ b/actions/newnotice.php @@ -71,7 +71,8 @@ class NewnoticeAction extends Action { return; } - common_save_replies($notice); + common_save_replies($notice); + $notice->saveTags(); common_broadcast_notice($notice); $returnto = $this->trimmed('returnto'); diff --git a/actions/postnotice.php b/actions/postnotice.php index ab12277bb..b08f27ac4 100644 --- a/actions/postnotice.php +++ b/actions/postnotice.php @@ -89,7 +89,8 @@ class PostnoticeAction extends Action { common_server_error(_('Error inserting notice'), 500); return false; } - common_save_replies($notice); + common_save_replies($notice); + $notice->saveTags(); common_broadcast_notice($notice, true); } return true; diff --git a/classes/Notice.php b/classes/Notice.php index 1b9191ad6..02526bae2 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -51,4 +51,28 @@ class Notice extends DB_DataObject function getProfile() { return Profile::staticGet($this->profile_id); } + + function saveTags() { + /* extract all #hastags */ + $count = preg_match_all('/(?:^|\s)#([a-z0-9]{1,64})/', strtolower($this->content), $match); + if (!$count) { + return true; + } + + /* Add them to the database */ + foreach(array_unique($match[1]) as $hashtag) { + $tag = DB_DataObject::factory('Notice_tag'); + $tag->notice_id = $this->id; + $tag->tag = $hashtag; + $tag->created = $this->created; + $id = $tag->insert(); + if (!$id) { + $last_error = PEAR::getStaticProperty('DB_DataObject','lastError'); + common_log(LOG_ERROR, 'DB error inserting hashtag: ' . $last_error->message); + common_server_error(sprintf(_('DB error inserting hashtag: %s'), $last_error->message)); + return; + } + } + return true; + } } diff --git a/classes/Notice_tag.php b/classes/Notice_tag.php new file mode 100644 index 000000000..0dc862bf3 --- /dev/null +++ b/classes/Notice_tag.php @@ -0,0 +1,22 @@ +<?php +/** + * Table Definition for notice_tag + */ +require_once 'DB/DataObject.php'; + +class Notice_tag extends DB_DataObject +{ + ###START_AUTOCODE + /* the code below is auto generated do not remove the above tag */ + + public $__table = 'notice_tag'; // table name + public $tag; // varchar(64) primary_key not_null + public $notice_id; // int(4) primary_key not_null + public $created; // datetime() not_null + + /* Static get */ + function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Notice_tag',$k,$v); } + + /* the code above is auto generated do not remove the tag below */ + ###END_AUTOCODE +} diff --git a/db/laconica.sql b/db/laconica.sql index 4a09670a2..277b792e3 100644 --- a/db/laconica.sql +++ b/db/laconica.sql @@ -123,7 +123,7 @@ create table reply ( profile_id integer not null comment 'profile replied to' references profile (id), modified timestamp not null comment 'date this record was modified', replied_id integer comment 'notice replied to (not used, see notice.reply_to)', - + constraint primary key (notice_id, profile_id), index reply_notice_id_idx (notice_id), index reply_profile_id_idx (profile_id), @@ -226,3 +226,12 @@ create table queue_item ( ) ENGINE=MyISAM; +/* Hash tags */ +create table notice_tag ( + tag varchar( 64 ) not null comment 'hash tag associated with this notice', + notice_id integer not null comment 'notice tagged' references notice (id), + created datetime not null comment 'date this record was created', + + constraint primary key (tag, notice_id), + index notice_tag_created_idx (created) +) ENGINE=MyISAM; diff --git a/fixup_hashtags.php b/fixup_hashtags.php new file mode 100755 index 000000000..d5cf8ca85 --- /dev/null +++ b/fixup_hashtags.php @@ -0,0 +1,46 @@ +#!/usr/bin/env php +<?php +/* + * Laconica - a distributed open-source microblogging tool + * Copyright (C) 2008, Controlez-Vous, Inc. + * + * 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/>. + */ + +# Abort if called from a web server +if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) { + print "This script must be run from the command line\n"; + exit(); +} + +define('INSTALLDIR', dirname(__FILE__)); +define('LACONICA', true); + +require_once(INSTALLDIR . '/lib/common.php'); + +common_log(LOG_INFO, 'Starting to do old notices.'); + +$notice = new Notice(); +$cnt = $notice->find(); + +while ($notice->fetch()) { + common_log(LOG_INFO, 'Getting replies for notice #' . $notice->id); + $notice->saveTags(); + $original = clone($notice); + $notice->rendered = common_render_content($notice->content, $notice); + $result = $notice->update($original); + if (!$result) { + common_log_db_error($notice, 'UPDATE', __FILE__); + } +} diff --git a/lib/common.php b/lib/common.php index 69714be1d..518171249 100644 --- a/lib/common.php +++ b/lib/common.php @@ -115,6 +115,5 @@ require_once(INSTALLDIR.'/classes/Confirm_address.php'); require_once(INSTALLDIR.'/classes/Remember_me.php'); require_once(INSTALLDIR.'/classes/Queue_item.php'); require_once(INSTALLDIR.'/classes/Reply.php'); -require_once(INSTALLDIR.'/classes/Sms_carrier.php'); require_once('markdown.php'); diff --git a/lib/util.php b/lib/util.php index cc7a725fb..a049ea600 100644 --- a/lib/util.php +++ b/lib/util.php @@ -275,6 +275,7 @@ function common_nav_menu() { } common_menu_item(common_local_url('public'), _('Public')); common_menu_item(common_local_url('peoplesearch'), _('Search')); + common_menu_item(common_local_url('tags'), _('Tags')); common_menu_item(common_local_url('doc', array('title' => 'help')), _('Help')); if ($user) { @@ -603,11 +604,15 @@ function common_render_content($text, $notice) { $r = preg_replace('@https?://[^)\]>\s]+@', '<a href="\0" class="extlink">\0</a>', $r); $r = preg_replace('/(^|\s+)@([a-z0-9]{1,64})/e', "'\\1@'.common_at_link($id, '\\2')", $r); $r = preg_replace('/^T ([A-Z0-9]{1,64}) /e', "'T '.common_at_link($id, '\\1').' '", $r); - # XXX: # tags + $r = preg_replace('/(^|\s+)#([a-z0-9]{1,64})/e', "'\\1#'.common_tag_link('\\2')", $r); # XXX: machine tags return $r; } +function common_tag_link($tag) { + return '<a href="' . htmlspecialchars(common_path('tag/' . $tag)) . '" class="hashlink">' . $tag . '</a>'; +} + function common_at_link($sender_id, $nickname) { $sender = Profile::staticGet($sender_id); $recipient = common_relative_profile($sender, $nickname); @@ -790,6 +795,16 @@ function common_fancy_url($action, $args=NULL) { return common_path('search/notice/rss' . (($args) ? ('?' . http_build_query($args)) : '')); case 'avatarbynickname': return common_path($args['nickname'].'/avatar/'.$args['size']); + case 'tag': + if (isset($args['tag']) && $args['tag']) { + $path = 'tag/' . $args['tag']; + unset($args['tag']); + } else { + $path = 'tags'; + } + return common_path($path . (($args) ? ('?' . http_build_query($args)) : '')); + case 'tags': + return common_path('tags' . (($args) ? ('?' . http_build_query($args)) : '')); default: return common_simple_url($action, $args); } @@ -859,12 +874,12 @@ function common_date_w3dtf($dt) { function common_date_rfc2822($dt) { $t = strtotime($dt); - return date("r", $t); + return date("r", $t); } function common_date_iso8601($dt) { $t = strtotime($dt); - return date("c", $t); + return date("c", $t); } function common_redirect($url, $code=307) { @@ -1314,7 +1329,7 @@ function common_profile_uri($profile) { if ($user) { return $user->uri; } - + $remote = Remote_profile::staticGet($profile->id); if ($remote) { return $remote->uri; diff --git a/xmppdaemon.php b/xmppdaemon.php index d2e609b44..91ea833ce 100755 --- a/xmppdaemon.php +++ b/xmppdaemon.php @@ -27,20 +27,20 @@ function xmppdaemon_error_handler($errno, $errstr, $errfile, $errline, $errconte echo "Aborting...\n"; exit(1); break; - + case E_USER_WARNING: echo "WARNING [$errno] $errstr\n"; break; - + case E_USER_NOTICE: echo "My NOTICE [$errno] $errstr\n"; break; - + default: echo "Unknown error type: [$errno] $errstr\n"; break; } - + /* Don't execute PHP internal error handler */ return true; } @@ -93,7 +93,7 @@ class XMPPDaemon { if (!$this->conn) { return false; } - + return !$this->conn->isDisconnected(); } @@ -127,12 +127,12 @@ class XMPPDaemon { $this->confirmation_queue(); } } - + function handle_session($pl) { # XXX what to do here? return true; } - + function get_user($from) { $user = User::staticGet('jabber', jabber_normalize_jid($from)); return $user; @@ -184,7 +184,7 @@ class XMPPDaemon { return false; } } - + function from_site($address, $msg) { $text = '['.common_config('site', 'name') . '] ' . $msg; jabber_send_message($address, $text); @@ -251,7 +251,8 @@ class XMPPDaemon { return; } $notice->query('COMMIT'); - common_save_replies($notice); + common_save_replies($notice); + $notice->saveTags(); common_real_broadcast($notice); $this->log(LOG_INFO, 'Added notice ' . $notice->id . ' from user ' . $user->nickname); @@ -372,7 +373,7 @@ class XMPPDaemon { $user = User::staticGet($notice->profile_id); return !$user; } - + function confirmation_queue() { # $this->clear_old_confirm_claims(); $this->log(LOG_INFO, 'checking for queued confirmations'); @@ -407,7 +408,7 @@ class XMPPDaemon { } } while ($confirm); } - + function next_confirm() { $confirm = new Confirm_address(); $confirm->whereAdd('claimed IS NULL'); @@ -433,14 +434,14 @@ class XMPPDaemon { } return NULL; } - + function clear_old_confirm_claims() { $confirm = new Confirm(); $confirm->claimed = NULL; $confirm->whereAdd('now() - claimed > '.CLAIM_TIMEOUT); $confirm->update(DB_DATAOBJECT_WHEREADD_ONLY); } - + } $resource = ($argc > 1) ? $argv[1] : NULL; |