2008-10-18 Christopher Blizzard <blizzard@0xdeadbeef.com>
authorblizzard <blizzard@ae879524-a8bd-4c4c-a5ea-74d2e5fc5a2c>
Sun, 19 Oct 2008 00:48:23 +0000 (00:48 +0000)
committerblizzard <blizzard@ae879524-a8bd-4c4c-a5ea-74d2e5fc5a2c>
Sun, 19 Oct 2008 00:48:23 +0000 (00:48 +0000)
        * whoisi/templates/vimeo-widget.mak: Widget to render vimeo
        content in person and follow pages.

        * whoisi/templates/follow.mak: Add vimeo to the types we know how
        to render

        * whoisi/templates/unseen.mak: Add vimeo to the types we know how
        to render.

        * whoisi/templates/person-widget.mak: Add vimeo to the types we
        know how to render.

        * whoisi/utils/sites.py (site_value): Put vimeo before youtube in
        the order in which we render sites.

        * whoisi/controllers.py (Root.getDisplayDepth): Add vimeo display
        depth so we render the right number of items in various contexts.
        (Root.rendersite): If the site type if vimeo, use the vimeo
        template for rendering.

        * whoisi/static/images/sites/vimeo-favicon.png: Icon for vimeo
        items.

        * tests/nose/test_newsite.py (TestNewSite.test_vimeo): Code to
        test the vimeo url detection code.

        * services/command/vimeo.py (Vimeo): Class for vimeo url detection
        and selecting a preferred feed.

        * services/command/newsite.py (NewSiteTryURL.getPreferredFeed): If
        the url is a vimeo url, pick the perferred feed from the list of
        feeds left over from scraping the HTML.
        (NewSiteTryURL.getFeedType): If the url is a vimeo url set the
        site type to "vimeo."

git-svn-id: svn://trac.whoisi.com/whoisi/trunk@9 ae879524-a8bd-4c4c-a5ea-74d2e5fc5a2c

ChangeLog
services/command/newsite.py
services/command/vimeo.py [new file with mode: 0644]
tests/nose/test_newsite.py
whoisi/controllers.py
whoisi/static/images/sites/vimeo-favicon.png [new file with mode: 0644]
whoisi/templates/follow.mak
whoisi/templates/person-widget.mak
whoisi/templates/unseen.mak
whoisi/templates/vimeo-widget.mak [new file with mode: 0644]
whoisi/utils/sites.py

index d5664cf..9fffc5e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,42 @@
 2008-10-18  Christopher Blizzard  <blizzard@0xdeadbeef.com>
 
+       * whoisi/templates/vimeo-widget.mak: Widget to render vimeo
+       content in person and follow pages.
+
+       * whoisi/templates/follow.mak: Add vimeo to the types we know how
+       to render
+
+       * whoisi/templates/unseen.mak: Add vimeo to the types we know how
+       to render.
+
+       * whoisi/templates/person-widget.mak: Add vimeo to the types we
+       know how to render.
+
+       * whoisi/utils/sites.py (site_value): Put vimeo before youtube in
+       the order in which we render sites.
+
+       * whoisi/controllers.py (Root.getDisplayDepth): Add vimeo display
+       depth so we render the right number of items in various contexts.
+       (Root.rendersite): If the site type if vimeo, use the vimeo
+       template for rendering.
+
+       * whoisi/static/images/sites/vimeo-favicon.png: Icon for vimeo
+       items.
+
+       * tests/nose/test_newsite.py (TestNewSite.test_vimeo): Code to
+       test the vimeo url detection code.
+
+       * services/command/vimeo.py (Vimeo): Class for vimeo url detection
+       and selecting a preferred feed.
+
+       * services/command/newsite.py (NewSiteTryURL.getPreferredFeed): If
+       the url is a vimeo url, pick the perferred feed from the list of
+       feeds left over from scraping the HTML.
+       (NewSiteTryURL.getFeedType): If the url is a vimeo url set the
+       site type to "vimeo."
+
+2008-10-18  Christopher Blizzard  <blizzard@0xdeadbeef.com>
+
        * whoisi/templates/youtube-widget.mak: Show 3 videos on one line.
 
        * services/command/youtube.py: Add license header.
index 4a97a0f..8d73cc3 100644 (file)
@@ -32,6 +32,7 @@ from services.command.flickr import Flickr
 from services.command.identica import Identica
 from services.command.delicious import Delicious
 from services.command.youtube import Youtube
+from services.command.vimeo import Vimeo
 from services.command.exceptions import PageNotFoundError, FeedNotFoundError, InvalidFeedError, \
     NeedsFeedPickError
 from services.command.utils import resolve_relative_url
@@ -298,6 +299,11 @@ class NewSiteTryURL(BaseCommand):
         if d.isDelicious(url):
             return d.getPreferredFeed(feeds)
 
+        # see if it's a vimeo feed
+        v = Vimeo()
+        if v.isVimeo(url):
+            return v.getPreferredFeed(feeds)
+
         return None
 
 ####
@@ -405,6 +411,11 @@ class NewSiteTryURL(BaseCommand):
         if t.isYoutube(url):
             return "youtube"
 
+        # Check to see if it's a vimeo url
+        t = Vimeo()
+        if t.isVimeo(url):
+            return "vimeo"
+
         return "feed"
 
 
diff --git a/services/command/vimeo.py b/services/command/vimeo.py
new file mode 100644 (file)
index 0000000..afcdc17
--- /dev/null
@@ -0,0 +1,59 @@
+# Copyright (c) 2008 Christopher Blizzard <blizzard@0xdeadbeef.com>
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+
+import urlparse
+import re
+
+class Vimeo:
+    def isVimeo(self, url):
+        u = urlparse.urlparse(url)
+        urlparse.clear_cache()
+        host = u[1]
+        path = u[2]
+
+        # forms
+        # http://vimeo.com/abc123/videos/uploaded
+        # http://vimeo.com/abc123
+        try:
+            if host != 'vimeo.com' and host != 'www.vimeo.com':
+                return False
+
+            match = re.match('^/[a-zA-Z0-9]+$', path)
+            if match:
+                print("  This is a vimeo account.")
+                return True
+
+            match = re.match('^/[a-zA-Z0-9]+/videos.*$', path)
+            if match:
+                print("  This is a vimeo account.")
+                return True
+
+        except:
+            pass
+
+        return False
+
+    def getPreferredFeed(self, feeds):
+        for i in range(0, len(feeds)):
+            if re.match('.*videos/rss$', feeds[i][0]):
+                return feeds[i]
+
+        return None
index c7a7f38..2cb56ff 100644 (file)
@@ -6,6 +6,7 @@ from services.command.newsite import NewSiteTryURL
 from services.command.identica import Identica
 from services.command.delicious import Delicious
 from services.command.youtube import Youtube
+from services.command.vimeo import Vimeo
 
 class TestNewSite(unittest.TestCase):
     def setUp(self):
@@ -204,3 +205,27 @@ class TestNewSite(unittest.TestCase):
             x = Youtube()
             print("trying not %s" % i)
             assert(x.isYoutube(i) == False)
+
+    def test_vimeo(self):
+        """
+        Test that we can detect vimeo urls.
+        """
+        good_urls = ['http://vimeo.com/oldtropes/videos/uploaded',
+                     'http://vimeo.com/user672164/videos/uploaded',
+                     'http://www.vimeo.com/user672164',
+                     'http://vimeo.com/user672164',
+                     'http://vimeo.com/factoryjoe/videos/uploaded']
+
+        bad_urls = ['http://vimeo.com/claysmith/likes',
+                    'http://vimeo.com/claysmith/albums',
+                    'http://something.else/']
+
+        for i in good_urls:
+            x = Vimeo()
+            print("trying %s" % i)
+            assert(x.isVimeo(i))
+
+        for i in bad_urls:
+            x = Vimeo()
+            print("trying not %s" % i)
+            assert(not x.isVimeo(i))
index e6a2feb..21fba9b 100644 (file)
@@ -504,10 +504,10 @@ class Root(controllers.RootController):
         return dict(content=unicode(self.rendersite(s, sh, "full"), "utf-8"))
 
     def getDisplayDepth(self, site_type, render_type):
-        depth_matrix = dict(full=dict(flickr=10, picasa=12, twitter=3, identica=3, delicious=3, feed=3, youtube=3),
-                            edit=dict(flickr=5, picasa=6, twitter=1, identica=1, delicious=1, feed=1, youtube=3),
-                            search=dict(flickr=5, picasa=6, twitter=1, identica=1, delicious=1, feed=1, youtube=3),
-                            preview=dict(flickr=5, picasa=6, twitter=3, identica=3, delicious=3, feed=3, youtube=3))
+        depth_matrix = dict(full=dict(flickr=10, picasa=12, twitter=3, identica=3, delicious=3, feed=3, youtube=3, vimeo=3),
+                            edit=dict(flickr=5, picasa=6, twitter=1, identica=1, delicious=1, feed=1, youtube=3, vimeo=3),
+                            search=dict(flickr=5, picasa=6, twitter=1, identica=1, delicious=1, feed=1, youtube=3, vimeo=3),
+                            preview=dict(flickr=5, picasa=6, twitter=3, identica=3, delicious=3, feed=3, youtube=3, vimeo=3))
         return depth_matrix[render_type][site_type]
 
     def rendersite(self, site, site_history, display):
@@ -530,6 +530,8 @@ class Root(controllers.RootController):
             template = "whoisi.templates.delicious-widget"
         elif site.type == "youtube":
             template = "whoisi.templates.youtube-widget"
+        elif site.type == "vimeo":
+            template = "whoisi.templates.vimeo-widget"
         else:
             return "<div>Oh, crap.  Wtf?</div>\n"
 
diff --git a/whoisi/static/images/sites/vimeo-favicon.png b/whoisi/static/images/sites/vimeo-favicon.png
new file mode 100644 (file)
index 0000000..cd8fe73
Binary files /dev/null and b/whoisi/static/images/sites/vimeo-favicon.png differ
index 153af96..61fd727 100644 (file)
@@ -35,6 +35,7 @@
 <%namespace file="picasa-widget.mak" import="picasa_widget"/>
 <%namespace file="delicious-widget.mak" import="delicious_widget"/>
 <%namespace file="youtube-widget.mak" import="youtube_widget"/>
+<%namespace file="vimeo-widget.mak" import="vimeo_widget"/>
 
 <%inherit file="master.mak"/>
 
@@ -65,6 +66,8 @@ ${picasa_widget(site=site, site_history=cluster, display="time")}
 ${delicious_widget(site=site, site_history=cluster, display="time")}
 %elif site.type == "youtube":
 ${youtube_widget(site=site, site_history=cluster, display="time")}
+%elif site.type == "vimeo":
+${vimeo_widget(site=site, site_history=cluster, display="time")}
 %endif
 
 %endfor
index 42450bc..4fcb461 100644 (file)
@@ -30,6 +30,7 @@
 <%namespace file="linkedin-widget.mak" import="linkedin_widget"/>
 <%namespace file="delicious-widget.mak" import="delicious_widget"/>
 <%namespace file="youtube-widget.mak" import="youtube_widget"/>
+<%namespace file="vimeo-widget.mak" import="vimeo_widget"/>
 <%namespace file="aliases-widget.mak" import="aliases_widget"/>
 <%namespace file="site-add-status-widget.mak" import="site_add_status_widget"/>
 <%namespace file="site-add-pick-widget.mak" import="site_add_pick_widget"/>
@@ -98,6 +99,8 @@ ${aliases_widget(person=person, other_names=other_names, display=display)}
     ${picasa_widget(site=site, site_history=site_history[site.id], display=display)}
   %elif site.type == "youtube":
     ${youtube_widget(site=site, site_history=site_history[site.id], display=display)}
+  %elif site.type == "vimeo":
+    ${vimeo_widget(site=site, site_history=site_history[site.id], display=display)}
   %endif
 %endfor
 
index 031af2d..a6cb586 100644 (file)
@@ -35,6 +35,7 @@
 <%namespace file="picasa-widget.mak" import="picasa_widget"/>
 <%namespace file="delicious-widget.mak" import="delicious_widget"/>
 <%namespace file="youtube-widget.mak" import="youtube_widget"/>
+<%namespace file="vimeo-widget.mak" import="vimeo_widget"/>
 
 <%inherit file="master.mak"/>
 
@@ -70,6 +71,8 @@ ${picasa_widget(site=site, site_history=cluster, display="time")}
 ${delicious_widget(site=site, site_history=cluster, display="time")}
 %elif site.type == "youtube":
 ${youtube_widget(site=site, site_history=cluster, display="time")}
+%elif site.type == "vimeo":
+${vimeo_widget(site=site, site_history=cluster, display="time")}
 %endif
 
 %endfor
diff --git a/whoisi/templates/vimeo-widget.mak b/whoisi/templates/vimeo-widget.mak
new file mode 100644 (file)
index 0000000..58c918c
--- /dev/null
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+
+## Copyright (c) 2008 Christopher Blizzard <blizzard@0xdeadbeef.com>
+##
+## Permission is hereby granted, free of charge, to any person
+## obtaining a copy of this software and associated documentation files
+## (the "Software"), to deal in the Software without restriction,
+## including without limitation the rights to use, copy, modify, merge,
+## publish, distribute, sublicense, and/or sell copies of the Software,
+## and to permit persons to whom the Software is furnished to do so,
+## subject to the following conditions:
+##
+## The above copyright notice and this permission notice shall be
+## included in all copies or substantial portions of the Software.
+##
+## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+## BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+## ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+## CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+## SOFTWARE.
+
+<%!
+from whoisi.utils.follow import is_following_person
+from whoisi.utils.display import short_link_ref
+from whoisi.utils.youtube import youtube_get_user
+import simplejson
+%>
+
+<%def name="vimeo_widget(site, site_history, display)">
+<%
+
+entries_list = site_history
+count = len(site_history)
+needs_refresh = False
+%>
+
+<div class="link-collection-item" site-id="${site.id}" needs-refresh="${needs_refresh}">
+<img src="/static/images/sites/vimeo-favicon.png"/>
+%if display == "time" or display == "follow":
+<a href="/p/${site.personID}">${site.person.name | h}</a>:
+%endif
+<a href="${site.url}">${site.title | h}</a>
+
+<span class="link-action">
+%if display == "edit":
+&nbsp;&nbsp;<a site-id="${site.id}" class="site-remove" href="">Remove</a>
+%endif
+%if display == "time":
+  %if is_following_person(site.personID):
+  &nbsp;&nbsp;<a class="person-unfollow" person-id="${site.personID}" href="#">Stop Following</a>
+  %else:
+  &nbsp;&nbsp;<a class="person-follow" person-id="${site.personID}" href="#">Follow Person</a>
+  %endif
+%endif
+</span>
+
+<div class="link-collection">
+%for i in range(0, count):
+<%
+thumb = None
+title = None
+
+try:
+   title = entries_list[i].title
+except:
+   title = "Untitled"
+
+try:
+   thumb = simplejson.loads(entries_list[i].display_cache)["thumb"]
+except:
+   thumb = "/static/images/sites/flickr-blank-75x75.png"
+
+%>
+%if display != "preview":
+  <a target="_blank" href="${short_link_ref(entries_list[i].id)}">
+  <img width="80" height="60" src="${thumb}" title="${title| h}"/>
+  </a>
+%else:
+  <a target="_blank" href="${entries_list[i].link}">
+  <img width="80" height="60" src="${thumb}" title="${title | h}"/>
+  </a>
+%endif
+%if int(i+1) % 5 == 0:
+<br/>
+%endif
+%endfor
+</div>
+
+</div>
+</%def>
+
+${vimeo_widget(site=site, site_history=site_history, display=display)}
index d4d5fdd..35cd4fb 100644 (file)
@@ -23,7 +23,7 @@
 from whoisi.model import *
 
 def site_value(site):
-    types = [ "flickr", "picasa", "youtube", "linkedin", "twitter", "identica", "delicious", "feed" ]
+    types = [ "flickr", "picasa", "vimeo", "youtube", "linkedin", "twitter", "identica", "delicious", "feed" ]
     return types.index(site.type)
 
 def reorder_sort(x,y):