<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Food for thought from TheHuey &#187; gallery2</title>
	<atom:link href="http://www.thehuey.com/blog/tag/gallery2/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thehuey.com/blog</link>
	<description>News and other posts for friends and family</description>
	<lastBuildDate>Wed, 14 Apr 2010 02:05:20 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Gallery2 Media Rss Patch for CoolIris Embed Wall</title>
		<link>http://www.thehuey.com/blog/2009/03/08/gallery2-media-rss-patch-for-cooliris-embed-wall/</link>
		<comments>http://www.thehuey.com/blog/2009/03/08/gallery2-media-rss-patch-for-cooliris-embed-wall/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 21:23:14 +0000</pubDate>
		<dc:creator>huey</dc:creator>
				<category><![CDATA[Technical Musings]]></category>
		<category><![CDATA[cooliris]]></category>
		<category><![CDATA[gallery2]]></category>
		<category><![CDATA[media rss]]></category>
		<category><![CDATA[php programming]]></category>

		<guid isPermaLink="false">http://www.thehuey.com/blog/?p=52</guid>
		<description><![CDATA[Use Cooliris to show your photos using Gallery2.  The quickest and coolest way to showcase your photos.  Follow the patches and you can too!]]></description>
			<content:encoded><![CDATA[<p>I was recently looking at different opportunities and saw a quite a few great companies doing wonderful things.  Among them is Cooliris, previously known as PicLens.  Their flagship product is a browser plugin which allows a very enticing scrolling view of media files.  Images, videos, and music scroll by on the screen in an endless wall.  Clicking on an image will zoom in to a higher resolution photo and a video file will zoom in and start playing.  Needless to say this is a pretty cool little tool, but it&#8217;s a plugin which means the download stops a lot of potential users.  But wait, they have a flash embed file which allows any website to embed the same experience on any web page!  Let&#8217;s see how we can use this to <a href="http://www.thehuey.com/cooliris/index.html">show off our photos</a>. <span id="more-52"></span></p>
<p>Wanting to use it for my own photos, I couldn&#8217;t wait to get started.  Since I already have a bunch of my own photos hosted using Gallery2, I decided to see if I could hook up an RSS feed and get it running quickly.  Unfortunately the default installation of the RSS plugin with Gallery2 didn&#8217;t support media rss.  My plugin version was a bit outdated so first I had to upgrade it.</p>
<p>Being new to Gallery2 development, I had to take a little bit and familiarize myself with the code.  The code structure is very well done and was pretty easy to start seeing what needed to be done.  I wanted to stick with the existing convention and not break anything unintentionally, so I made copies where needed and was careful about what I changed in shared files.</p>
<p>The code is located mostly under the /modules directory.  The /core sub-directory contains the Gallery core files.  What we&#8217;re interested in lies in /rss.  Makes sense right?  First thing I did was to make a examine the existing usage.  When viewing an album via a browser, the RSS feed link shows that the resource is accessed via g2_view=rss.SimpleRender.  So I made a copy of /rss/SimpleRender.inc to /rss/MediaRss.inc. My original version of the RSS plugin did not have any support for the media rss format, but the latest update does.  That helps make my task a LOT easier, but there is still more to do.  </p>
<ol>
<li>Add the &#8216;useMedia&#8217; parameter and the page variable to the params array.<br />
<code><br />
      $params['useCloud'] = false;<br />
      $params['useMedia'] = true;</p>
<p>      $params['page'] = GalleryUtilities::getRequestVariables('page');<br />
      $ret = $this->continueRender($params);<br />
</code>
</li>
</ol>
<p>Next, we need to examine the other classes that are used to support the feed generation.  Looking under the /classes directory (/modules/rss/classes), we see two that catch the eye immediately.  RssHelper.class and RssGenerator.class.</p>
<p>RssHelper.class generates the SQL which is used to find items to show in the feed.  One of the main things missing here is the ability to paginate results.  So let&#8217;s add it!  In the getFeed function, find the function call for fetchAlbumTree and make the following change:<br />
<strong>From</strong><br />
<code>RssHelper::fetchAlbumTree(<br />
   $entity->getId(),<br />
   $param['count'],<br />
   $newOnly,<br />
   $param['feedType'] != 'album',<br />
   $param['feedType'] == 'photosRecursive' ? $param['photosRecursiveLimit'] : 0,<br />
   $param['feedType'] == 'photosRandomRecursive');<br />
</code><br />
<strong>To</strong><br />
<code>RssHelper::fetchAlbumTree(<br />
   $entity->getId(),<br />
   array('count' => $param['count'], 'offset' => $param['offset']),<br />
   $newOnly,<br />
   $param['feedType'] != 'album',<br />
   $param['feedType'] == 'photosRecursive' ? $param['photosRecursiveLimit'] : 0,<br />
   $param['feedType'] == 'photosRandomRecursive');<br />
</code></p>
<p>We&#8217;ll put in the calculations for the offset in a bit.  First we worry about how to make sure it&#8217;s used.  In the &#8216;fetchAlbumTree&#8217; function, we need to check the $limit parameter and use it to set the offset.<br />
<code><br />
if (isset($limit)) {<br />
  $params['limit'] = array('count' => $limit);<br />
}<br />
</code><br />
<strong>Becomes</strong><br />
<code><br />
if (isset($limit)) {<br />
  if (is_array($limit)) $params['limit'] = $limit;<br />
  else $params['limit'] = array('count' => $limit);<br />
  }<br />
}<br />
</code><br />
The offset parameter is now used in the $gallery->search call.  Now, I thought I was all done, but when reviewing the response, I noticed the media:thumbnail url was set the same as the description.  This resulted in Cooliris not being able to pull in the thumbnails for the wall.  The bug is in the RssHelper.class code, function addPhotoOrAlbum.  Here is the change:<br />
<code><br />
          $itemSettings['thumbnail']['url'] = $url;<br />
SHOULD BE<br />
          $itemSettings['thumbnail']['url'] = $imageUrl;<br />
</code></p>
<p>RssGenerator.class does just that.  Depending on the version of RSS and whether you are &#8216;useMedia&#8217;, it generates the correct response XML document for feed readers.  There are a few changes here.</p>
<ol>
<li>Add a &#8216;default&#8217; statement to function generate() so we use 2.0 by default<br />
<code><br />
  case '2.0':<br />
  default:<br />
    return $this->generate200();<br />
    break;<br />
</code>
</li>
<li>Because we want pagination of our results, for the infinite wall experience in cooliris, we need to determine the next and previous feed URLs.  We will use an Apache rewrite rule for a pretty URL, so here&#8217;s the code to generate the links based on the current URL.<br />
<code>
<pre>
     $platform =&#038; $gallery->getPlatform();
      $lf = $platform->getLineEnding();

      if (isset($this->_properties['useMedia']) &#038;&#038; $this->_properties['useMedia'] == 1) {
        $generator = $gallery->getUrlGenerator();
        //GalleryUtilities::putRequestVariable('page', 4);
        $current = $generator->getCurrentRequestUri();
        $matches = array();
        if (preg_match("#media(\d*).rss$#", $current, $matches)) {
          $curPage = $matches[1];
          if (intval($curPage) < 1) {
            $curPage = 1;
          }
          $nextPage = $generator->makeUrl($current);
          $nextPage = preg_replace("#media\d*.rss#", "media" . ($curPage + 1) . ".rss", $nextPage);
          if ($curPage > 1) {
            $prevPage = $generator->makeUrl($current);
            $prevPage = preg_replace("#media\d*.rss#", "media" . ($curPage - 1) . ".rss", $prevPage);
          }
        }

        $multiPage = &lt;&lt;&lt;MULTIPAGE
    &lt;atom:link rel="previous" href="$prevPage" /&gt;
    &lt;atom:link rel="next" href="$nextPage" /&gt;
MULTIPAGE;
      }</pre>
<p></code>
</li>
<li>Since we&#8217;re using ATOM, we need to tell setup the XML namespace in our response.<br />
<code><br />
  if (isset($this->_properties['useMedia']) &#038;&#038; $this->_properties['useMedia'] == 1) {<br />
    $data = '<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom">';<br />
  }<br />
</code>
</li>
<li>Finally, we add the links into the response right after the link tag.<br />
<code><br />
         '
<link>' . $this->_properties['link'] . '</link>' . $lf .<br />
          $multiPage . $lf .<br />
          '<description>' .<br />
</code></p>
<li>All this, but we&#8217;re not handling the pages correctly during the request.  What we&#8217;re missing is the ability to control where the slice happens.  Open up Render.inc in the /modules/rss/ directory and find where <code>$generator->sliceItems($count);</code> is being called.  We have already changed RssHelper::getFeed to handle the SQL offset, all we need is to set the &#8216;offset&#8217; variable.<br />
<code>
<pre>
    if (isset($params['page']) &#038;&#038; $params['page'] > 1) {
        $start = ($params['page'] - 1) * $count;
    } else {
        $start = 0;
    }
    $params['count'] = $count;
    $params['offset'] = $start;

    $generator = new RssGenerator();
</pre>
<p></code>
</li>
</ol>
<h2>Pretty SEO URLs</h2>
<p>We want to present easy to understand URLs to any spider.  Instead of /main.php?g2_view=rss.MediaRss&#038;g2_itemId=xxxx&#8230;.., let&#8217;s do something like the /v/album1/subAlbum/ style URL.  Of course, the Cooliris embed wall only seems to like urls that end in .rss which means we MUST do this step.</p>
<p>If we take a look at the existing rewrite rule for Paths, we can just modify their scheme to fit our needs.<br />
<code><br />
        RewriteCond %{THE_REQUEST} /gallery/v/([^?]+)(\?.|\ .)<br />
        RewriteCond %{REQUEST_URI} !/gallery/main\.php$<br />
        RewriteRule .   /gallery/main.php?g2_path=%1   [QSA,L]<br />
</code><br />
Now it look simply like everything after /gallery/v/ and before query parameters is dumped into a g2_path variable.  We need the same thing except we must also check the page that we are on.  I settled on a URL like:<br />
<code>/gallery/m/album_path_info/media2.rss</code><br />
Here, we use the same path method that View does and we have additional page information after media.  Our rewrite rule would look something like:<br />
<code><br />
        RewriteCond %{REQUEST_URI} /gallery/m/([^?]+)/media(\d*).rss<br />
        RewriteRule .   /gallery/main.php?g2_view=rss.MediaRss&#038;g2_path=%1&#038;g2_page=%2   [QSA,L]<br />
</code></p>
<p>That&#8217;s pretty much it.  We can now access any of our albums with a media.rss feed that allows pagination and viewing in Cooliris&#8217;s Embed Wall.</p>
<p>For future enhancements, it should be possible to hook up the album navigation thru Javascript and have a seamless interface suitable for a Gallery2 Theme.</p>
<p>Maybe I&#8217;ll do that for fun next weekend.<br />
-Huey</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thehuey.com/blog/2009/03/08/gallery2-media-rss-patch-for-cooliris-embed-wall/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
