diff options
-rw-r--r-- | README | 6 | ||||
-rw-r--r-- | classes/File.php | 47 | ||||
-rw-r--r-- | classes/File_oembed.php | 21 | ||||
-rw-r--r-- | classes/Notice.php | 9 | ||||
-rw-r--r-- | db/08to09.sql | 2 | ||||
-rw-r--r-- | db/statusnet.sql | 1 | ||||
-rw-r--r-- | db/statusnet_pg.sql | 1 | ||||
-rw-r--r-- | install.php | 253 | ||||
-rw-r--r-- | js/userdesign.go.js | 3 | ||||
-rw-r--r-- | lib/facebookaction.php | 1 | ||||
-rw-r--r-- | lib/facebookutil.php | 39 | ||||
-rw-r--r-- | lib/rssaction.php | 23 | ||||
-rw-r--r-- | lib/twitterapi.php | 9 | ||||
-rw-r--r-- | tests/HashTagDetectionTests.php (renamed from tests/HashTagDetectionTest.php) | 2 |
14 files changed, 367 insertions, 50 deletions
@@ -622,10 +622,10 @@ key and secret, e.g.: In Facebook's application editor, specify the following URLs for your app: -- Callback URL: http://example.net/mublog/facebook/ -- Post-Remove URL: http://example.net/mublog/facebook/remove +- Canvas Callback URL: http://example.net/mublog/facebook/ +- Post-Remove Callback URL: http://example.net/mublog/facebook/remove - Post-Add Redirect URL: http://apps.facebook.com/yourapp/ -- Canvas URL: http://apps.facebook.com/yourapp/ +- Canvas Page URL: http://apps.facebook.com/yourapp/ (Replace 'example.net' with your host's URL, 'mublog' with the path to your StatusNet installation, and 'yourapp' with the name of the diff --git a/classes/File.php b/classes/File.php index 0cebfc55e..dc668ab23 100644 --- a/classes/File.php +++ b/classes/File.php @@ -195,17 +195,44 @@ class File extends Memcached_DataObject return 'http://'.$server.$path.$filename; } - function isEnclosure(){ - if(isset($this->filename)){ - return true; - } - $notEnclosureMimeTypes = array('text/html','application/xhtml+xml'); - $mimetype = strtolower($this->mimetype); - $semicolon = strpos($mimetype,';'); - if($semicolon){ - $mimetype = substr($mimetype,0,$semicolon); + function getEnclosure(){ + $enclosure = (object) array(); + $enclosure->title=$this->title; + $enclosure->url=$this->url; + $enclosure->title=$this->title; + $enclosure->date=$this->date; + $enclosure->modified=$this->modified; + $enclosure->size=$this->size; + $enclosure->mimetype=$this->mimetype; + + if(! isset($this->filename)){ + $notEnclosureMimeTypes = array('text/html','application/xhtml+xml'); + $mimetype = strtolower($this->mimetype); + $semicolon = strpos($mimetype,';'); + if($semicolon){ + $mimetype = substr($mimetype,0,$semicolon); + } + if(in_array($mimetype,$notEnclosureMimeTypes)){ + $oembed = File_oembed::staticGet('file_id',$this->id); + if($oembed){ + $mimetype = strtolower($oembed->mimetype); + $semicolon = strpos($mimetype,';'); + if($semicolon){ + $mimetype = substr($mimetype,0,$semicolon); + } + if(in_array($mimetype,$notEnclosureMimeTypes)){ + return false; + }else{ + if($oembed->mimetype) $enclosure->mimetype=$oembed->mimetype; + if($oembed->url) $enclosure->url=$oembed->url; + if($oembed->title) $enclosure->title=$oembed->title; + if($oembed->modified) $enclosure->modified=$oembed->modified; + unset($oembed->size); + } + } + } } - return(! in_array($mimetype,$notEnclosureMimeTypes)); + return $enclosure; } } diff --git a/classes/File_oembed.php b/classes/File_oembed.php index 6be651815..e41ccfd09 100644 --- a/classes/File_oembed.php +++ b/classes/File_oembed.php @@ -20,6 +20,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; +require_once INSTALLDIR.'/classes/File_redirection.php'; /** * Table Definition for file_oembed @@ -34,6 +35,7 @@ class File_oembed extends Memcached_DataObject public $file_id; // int(4) primary_key not_null public $version; // varchar(20) public $type; // varchar(20) + public $mimetype; // varchar(50) public $provider; // varchar(50) public $provider_url; // varchar(255) public $width; // int(4) @@ -93,7 +95,24 @@ class File_oembed extends Memcached_DataObject if (!empty($data->title)) $file_oembed->title = $data->title; if (!empty($data->author_name)) $file_oembed->author_name = $data->author_name; if (!empty($data->author_url)) $file_oembed->author_url = $data->author_url; - if (!empty($data->url)) $file_oembed->url = $data->url; + if (!empty($data->url)){ + $file_oembed->url = $data->url; + $given_url = File_redirection::_canonUrl($file_oembed->url); + if (! empty($given_url)){ + $file = File::staticGet('url', $given_url); + if (empty($file)) { + $file_redir = File_redirection::staticGet('url', $given_url); + if (empty($file_redir)) { + $redir_data = File_redirection::where($given_url); + $file_oembed->mimetype = $redir_data['type']; + } else { + $file_id = $file_redir->file_id; + } + } else { + $file_oembed->mimetype=$file->mimetype; + } + } + } $file_oembed->insert(); if (!empty($data->thumbnail_url)) { File_thumbnail::saveNew($data, $file_id); diff --git a/classes/Notice.php b/classes/Notice.php index ed41acbae..e569d8305 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -1199,10 +1199,11 @@ class Notice extends Memcached_DataObject $attachments = $this->attachments(); if($attachments){ foreach($attachments as $attachment){ - if ($attachment->isEnclosure()) { - $attributes = array('rel'=>'enclosure','href'=>$attachment->url,'type'=>$attachment->mimetype,'length'=>$attachment->size); - if($attachment->title){ - $attributes['title']=$attachment->title; + $enclosure=$attachment->getEnclosure(); + if ($enclosure) { + $attributes = array('rel'=>'enclosure','href'=>$enclosure->url,'type'=>$enclosure->mimetype,'length'=>$enclosure->size); + if($enclosure->title){ + $attributes['title']=$enclosure->title; } $xs->element('link', $attributes, null); } diff --git a/db/08to09.sql b/db/08to09.sql index 4d1830611..223a99fa3 100644 --- a/db/08to09.sql +++ b/db/08to09.sql @@ -10,3 +10,5 @@ alter table profile alter table user_group modify column description text comment 'group description'; +alter table file_oembed + add column mimetype varchar(50) comment 'mime type of resource'; diff --git a/db/statusnet.sql b/db/statusnet.sql index deebe72c6..221d60ce3 100644 --- a/db/statusnet.sql +++ b/db/statusnet.sql @@ -450,6 +450,7 @@ create table file_oembed ( file_id integer primary key comment 'oEmbed for that URL/file' references file (id), version varchar(20) comment 'oEmbed spec. version', type varchar(20) comment 'oEmbed type: photo, video, link, rich', + mimetype varchar(50) comment 'mime type of resource', provider varchar(50) comment 'name of this oEmbed provider', provider_url varchar(255) comment 'URL of this oEmbed provider', width integer comment 'width of oEmbed resource when available', diff --git a/db/statusnet_pg.sql b/db/statusnet_pg.sql index b5626d3f4..5b4d0485a 100644 --- a/db/statusnet_pg.sql +++ b/db/statusnet_pg.sql @@ -465,6 +465,7 @@ create table file_oembed ( file_id bigint default nextval('file_oembed_seq') primary key /* comment 'unique identifier' */, version varchar(20), type varchar(20), + mimetype varchar(50), provider varchar(50), provider_url varchar(255), width integer, diff --git a/install.php b/install.php index dc42a5b3d..4c5bc38ae 100644 --- a/install.php +++ b/install.php @@ -19,18 +19,199 @@ define('INSTALLDIR', dirname(__FILE__)); +$external_libraries=array( + array( + 'name'=>'gettext', + 'url'=>'http://us.php.net/manual/en/book.gettext.php', + 'check_function'=>'gettext' + ), + array( + 'name'=>'PEAR', + 'url'=>'http://pear.php.net/', + 'deb'=>'php-pear', + 'include'=>'PEAR.php', + 'check_class'=>'PEAR' + ), + array( + 'name'=>'DB', + 'pear'=>'DB', + 'url'=>'http://pear.php.net/package/DB', + 'deb'=>'php-db', + 'include'=>'DB/common.php', + 'check_class'=>'DB_common' + ), + array( + 'name'=>'DB_DataObject', + 'pear'=>'DB_DataObject', + 'url'=>'http://pear.php.net/package/DB_DataObject', + 'include'=>'DB/DataObject.php', + 'check_class'=>'DB_DataObject' + ), + array( + 'name'=>'Console_Getopt', + 'pear'=>'Console_Getopt', + 'url'=>'http://pear.php.net/package/Console_Getopt', + 'include'=>'Console/Getopt.php', + 'check_class'=>'Console_Getopt' + ), + array( + 'name'=>'Facebook API', + 'url'=>'http://developers.facebook.com/', + 'include'=>'facebook/facebook.php', + 'check_class'=>'Facebook' + ), + array( + 'name'=>'htmLawed', + 'url'=>'http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed', + 'include'=>'htmLawed/htmLawed.php', + 'check_function'=>'htmLawed' + ), + array( + 'name'=>'HTTP_Request', + 'pear'=>'HTTP_Request', + 'url'=>'http://pear.php.net/package/HTTP_Request', + 'deb'=>'php-http-request', + 'include'=>'HTTP/Request.php', + 'check_class'=>'HTTP_Request' + ), + array( + 'name'=>'Mail', + 'pear'=>'Mail', + 'url'=>'http://pear.php.net/package/Mail', + 'deb'=>'php-mail', + 'include'=>'Mail.php', + 'check_class'=>'Mail' + ), + array( + 'name'=>'Mail_mimeDecode', + 'pear'=>'Mail_mimeDecode', + 'url'=>'http://pear.php.net/package/Mail_mimeDecode', + 'deb'=>'php-mail-mimedecode', + 'include'=>'Mail/mimeDecode.php', + 'check_class'=>'Mail_mimeDecode' + ), + array( + 'name'=>'Mime_Type', + 'pear'=>'Mime_Type', + 'url'=>'http://pear.php.net/package/Mime_Type', + 'include'=>'MIME/Type.php', + 'check_class'=>'Mime_Type' + ), + array( + 'name'=>'Net_URL_Mapper', + 'pear'=>'Net_URL_Mapper', + 'url'=>'http://pear.php.net/package/Net_URL_Mapper', + 'include'=>'Net/URL/Mapper.php', + 'check_class'=>'Net_URL_Mapper' + ), + array( + 'name'=>'Net_Socket', + 'pear'=>'Net_Socket', + 'url'=>'http://pear.php.net/package/Net_Socket', + 'deb'=>'php-net-socket', + 'include'=>'Net/Socket.php', + 'check_class'=>'Net_Socket' + ), + array( + 'name'=>'Net_SMTP', + 'pear'=>'Net_SMTP', + 'url'=>'http://pear.php.net/package/Net_SMTP', + 'deb'=>'php-net-smtp', + 'include'=>'Net/SMTP.php', + 'check_class'=>'Net_SMTP' + ), + array( + 'name'=>'Net_URL', + 'pear'=>'Net_URL', + 'url'=>'http://pear.php.net/package/Net_URL', + 'deb'=>'php-net-url', + 'include'=>'Net/URL.php', + 'check_class'=>'Net_URL' + ), + array( + 'name'=>'Net_URL2', + 'pear'=>'Net_URL2', + 'url'=>'http://pear.php.net/package/Net_URL2', + 'include'=>'Net/URL2.php', + 'check_class'=>'Net_URL2' + ), + array( + 'name'=>'Services_oEmbed', + 'pear'=>'Services_oEmbed', + 'url'=>'http://pear.php.net/package/Services_oEmbed', + 'include'=>'Services/oEmbed.php', + 'check_class'=>'Services_oEmbed' + ), + array( + 'name'=>'Stomp', + 'url'=>'http://stomp.codehaus.org/PHP', + 'include'=>'Stomp.php', + 'check_class'=>'Stomp' + ), + array( + 'name'=>'System_Command', + 'pear'=>'System_Command', + 'url'=>'http://pear.php.net/package/System_Command', + 'include'=>'System/Command.php', + 'check_class'=>'System_Command' + ), + array( + 'name'=>'XMPPHP', + 'url'=>'http://code.google.com/p/xmpphp', + 'include'=>'XMPPHP/XMPP.php', + 'check_class'=>'XMPPHP_XMPP' + ), + array( + 'name'=>'PHP Markdown', + 'url'=>'http://www.michelf.com/projects/php-markdown/', + 'include'=>'markdown.php', + 'check_class'=>'Markdown_Parser' + ), + array( + 'name'=>'OAuth', + 'url'=>'http://code.google.com/p/oauth-php', + 'include'=>'OAuth.php', + 'check_class'=>'OAuthRequest' + ), + array( + 'name'=>'Validate', + 'pear'=>'Validate', + 'url'=>'http://pear.php.net/package/Validate', + 'include'=>'Validate.php', + 'check_class'=>'Validate' + ) +); + function main() { if (!checkPrereqs()) { return; } + + if( $_GET['checklibs'] ){ + showLibs(); + }else{ + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + handlePost(); + } else { + showForm(); + } + } +} - if ($_SERVER['REQUEST_METHOD'] == 'POST') { - handlePost(); - } else { - showForm(); +function haveExternalLibrary($external_library) +{ + if(isset($external_library['include']) && ! include_once($external_library['include'])){ + return false; } + if(isset($external_library['check_function']) && ! function_exists($external_library['check_function'])){ + return false; + } + if(isset($external_library['check_class']) && ! class_exists($external_library['check_class'])){ + return false; + } + return true; } function checkPrereqs() @@ -94,6 +275,69 @@ function checkExtension($name) return true; } +function showLibs() +{ + global $external_libraries; + $present_libraries=array(); + $absent_libraries=array(); + foreach($external_libraries as $external_library){ + if(haveExternalLibrary($external_library)){ + $present_libraries[]=$external_library; + }else{ + $absent_libraries[]=$external_library; + } + } + echo<<<E_O_T + <div class="instructions"> + <p>Laconica comes bundled with a number of libraries required for the application to work. However, it is best that you use PEAR or you distribution to manage + libraries instead, as they tend to provide security updates faster, and may offer improved performance.</p> + <p>On Debian based distributions, such as Ubuntu, use a package manager (such as "aptitude", "apt-get", and "synaptic") to install the package listed.</p> + <p>On RPM based distributions, such as Red Hat, Fedora, CentOS, Scientific Linux, Yellow Dog Linux and Oracle Enterprise Linux, use a package manager (such as "yum", "apt-rpm", and "up2date") to install the package listed.</p> + <p>On servers without a package manager (such as Windows), or if the library is not packaged for your distribution, you can use PHP's PEAR to install the library. Simply run "pear install <name>".</p> + </div> + <h2>Absent Libraries</h2> + <ul id="absent_libraries"> +E_O_T; + foreach($absent_libraries as $library) + { + echo '<li>'; + if($library['url']){ + echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>'; + }else{ + echo htmlentities($library['name']); + } + echo '<ul>'; + if($library['deb']){ + echo '<li class="deb package">deb: <a href="apt:' . urlencode($library['deb']) . '">' . htmlentities($library['deb']) . '</a></li>'; + } + if($library['rpm']){ + echo '<li class="rpm package">rpm: ' . htmlentities($library['rpm']) . '</li>'; + } + if($library['pear']){ + echo '<li class="pear package">pear: ' . htmlentities($library['pear']) . '</li>'; + } + echo '</ul>'; + } + echo<<<E_O_T + </ul> + <h2>Installed Libraries</h2> + <ul id="present_libraries"> +E_O_T; + foreach($present_libraries as $library) + { + echo '<li>'; + if($library['url']){ + echo '<a href=">'.$library['url'].'">'.htmlentities($library['name']).'</a>'; + }else{ + echo htmlentities($library['name']); + } + echo '</li>'; + } + echo<<<E_O_T + </ul> +E_O_T; +} + function showForm() { echo<<<E_O_T @@ -105,6 +349,7 @@ function showForm() <dd> <div class="instructions"> <p>Enter your database connection information below to initialize the database.</p> + <p>Laconica bundles a number of libraries for ease of installation. <a href="?checklibs=true">You can see what bundled libraries you are using, versus what libraries are installed on your server.</a> </div> </dd> </dl> diff --git a/js/userdesign.go.js b/js/userdesign.go.js index 18f72f96a..eb4dece09 100644 --- a/js/userdesign.go.js +++ b/js/userdesign.go.js @@ -27,11 +27,12 @@ $(document).ready(function() { } } - /* rgb2hex written by R0bb13 <robertorebollo@gmail.com> */ function rgb2hex(rgb) { + if (rgb.slice(0,1) == '#') { return rgb; } rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); return '#' + dec2hex(rgb[1]) + dec2hex(rgb[2]) + dec2hex(rgb[3]); } + /* dec2hex written by R0bb13 <robertorebollo@gmail.com> */ function dec2hex(x) { hexDigits = new Array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); return isNaN(x) ? '00' : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16]; diff --git a/lib/facebookaction.php b/lib/facebookaction.php index b86276a0a..411f79594 100644 --- a/lib/facebookaction.php +++ b/lib/facebookaction.php @@ -95,6 +95,7 @@ class FacebookAction extends Action function showStylesheets() { $this->cssLink('css/display.css', 'base'); + $this->cssLink('css/display.css',null,'screen, projection, tv'); $this->cssLink('css/facebookapp.css', 'base'); } diff --git a/lib/facebookutil.php b/lib/facebookutil.php index 36b745279..f5121609d 100644 --- a/lib/facebookutil.php +++ b/lib/facebookutil.php @@ -109,7 +109,6 @@ function facebookBroadcastNotice($notice) $can_update = $facebook->api_client->users_hasAppPermission('status_update', $fbuid); - if (!empty($attachments) && $can_publish == 1) { $fbattachment = format_attachments($attachments); $facebook->api_client->stream_publish($status, $fbattachment, @@ -178,20 +177,42 @@ function format_attachments($attachments) $fbattachment = array(); $fbattachment['media'] = array(); - // Facebook only supports one attachment per item + foreach($attachments as $attachment) + { + if($enclosure = $attachment->getEnclosure()){ + $fbmedia = get_fbmedia_for_attachment($enclosure); + }else{ + $fbmedia = get_fbmedia_for_attachment($attachment); + } + if($fbmedia){ + $fbattachment['media'][]=$fbmedia; + }else{ + $fbattachment['name'] = ($attachment->title ? + $attachment->title : $attachment->url); + $fbattachment['href'] = $attachment->url; + } + } + if(count($fbattachment['media'])>0){ + unset($fbattachment['name']); + unset($fbattachment['href']); + } + return $fbattachment; +} - $attachment = $attachments[0]; +/** +* given an File objects, returns an associative array suitable for Facebook media +*/ +function get_fbmedia_for_attachment($attachment) +{ $fbmedia = array(); if (strncmp($attachment->mimetype, 'image/', strlen('image/')) == 0) { $fbmedia['type'] = 'image'; $fbmedia['src'] = $attachment->url; $fbmedia['href'] = $attachment->url; - $fbattachment['media'][] = $fbmedia; } else if ($attachment->mimetype == 'audio/mpeg') { $fbmedia['type'] = 'mp3'; $fbmedia['src'] = $attachment->url; - $fbattachment['media'][] = $fbmedia; }else if ($attachment->mimetype == 'application/x-shockwave-flash') { $fbmedia['type'] = 'flash'; @@ -200,14 +221,10 @@ function format_attachments($attachments) // $fbmedia['imgsrc']=''; $fbmedia['swfsrc'] = $attachment->url; - $fbattachment['media'][] = $fbmedia; }else{ - $fbattachment['name'] = ($attachment->title ? - $attachment->title : $attachment->url); - $fbattachment['href'] = $attachment->url; + return false; } - - return $fbattachment; + return $fbmedia; } function remove_facebook_app($flink) diff --git a/lib/rssaction.php b/lib/rssaction.php index 60611e48d..dd0f1005a 100644 --- a/lib/rssaction.php +++ b/lib/rssaction.php @@ -258,26 +258,27 @@ class Rss10Action extends Action $attachments = $notice->attachments(); if($attachments){ foreach($attachments as $attachment){ - if ($attachment->isEnclosure()) { + $enclosure=$attachment->getEnclosure(); + if ($enclosure) { // DO NOT move xmlns declaration to root element. Making it // the default namespace here improves compatibility with // real-world feed readers. $attribs = array( - 'rdf:resource' => $attachment->url, - 'url' => $attachment->url, + 'rdf:resource' => $enclosure->url, + 'url' => $enclosure->url, 'xmlns' => 'http://purl.oclc.org/net/rss_2.0/enc#' ); - if ($attachment->title) { - $attribs['dc:title'] = $attachment->title; + if ($enclosure->title) { + $attribs['dc:title'] = $enclosure->title; } - if ($attachment->modified) { - $attribs['dc:date'] = common_date_w3dtf($attachment->modified); + if ($enclosure->modified) { + $attribs['dc:date'] = common_date_w3dtf($enclosure->modified); } - if ($attachment->size) { - $attribs['length'] = $attachment->size; + if ($enclosure->size) { + $attribs['length'] = $enclosure->size; } - if ($attachment->mimetype) { - $attribs['type'] = $attachment->mimetype; + if ($enclosure->mimetype) { + $attribs['type'] = $enclosure->mimetype; } $this->element('enclosure', $attribs); } diff --git a/lib/twitterapi.php b/lib/twitterapi.php index c8099978f..9055d8b98 100644 --- a/lib/twitterapi.php +++ b/lib/twitterapi.php @@ -274,11 +274,12 @@ class TwitterapiAction extends Action $enclosures = array(); foreach ($attachments as $attachment) { - if ($attachment->isEnclosure()) { + $enclosure_o=$attachment->getEnclosure(); + if ($enclosure_o) { $enclosure = array(); - $enclosure['url'] = $attachment->url; - $enclosure['mimetype'] = $attachment->mimetype; - $enclosure['size'] = $attachment->size; + $enclosure['url'] = $enclosure_o->url; + $enclosure['mimetype'] = $enclosure_o->mimetype; + $enclosure['size'] = $enclosure_o->size; $enclosures[] = $enclosure; } } diff --git a/tests/HashTagDetectionTest.php b/tests/HashTagDetectionTests.php index 9afe34657..aeac4a5e3 100644 --- a/tests/HashTagDetectionTest.php +++ b/tests/HashTagDetectionTests.php @@ -10,7 +10,7 @@ define('STATUSNET', true); require_once INSTALLDIR . '/lib/common.php'; -class HashTagDetectionTest extends PHPUnit_Framework_TestCase +class HashTagDetectionTests extends PHPUnit_Framework_TestCase { /** * @dataProvider provider |