Permalink
Browse files

Got all the feeds working.

  • Loading branch information...
0 parents commit 45a946ddf67f8b9dd8ee7d42998616645fc90029 @mikeal committed Oct 11, 2009
Showing with 254 additions and 0 deletions.
  1. +83 −0 couchcast/__init__.py
  2. +15 −0 couchcast/design/podcastDocs/map.js
  3. +46 −0 couchcast/templates/itunes.mko
  4. +23 −0 couchcast/templates/rss.mko
  5. +17 −0 feeds_mikealcast.py
  6. +70 −0 setup.py
@@ -0,0 +1,83 @@
+import os, sys
+from datetime import datetime
+
+from couchquery import Database
+from webenv import HtmlResponse
+from webenv.rest import RestApplication
+from mako.lookup import TemplateLookup
+
+try:
+ import json
+except:
+ import simplejson as json
+
+
+this_directory = os.path.abspath(os.path.dirname(__file__))
+design_doc = os.path.join(this_directory, 'design')
+template_dir = os.path.join(this_directory, 'templates')
+
+lookup = TemplateLookup(directories=[template_dir], encoding_errors='ignore', input_encoding='utf-8', output_encoding='utf-8')
+
+class MakoResponse(HtmlResponse):
+ def __init__(self, name, **kwargs):
+ template = lookup.get_template(name+'.mko')
+ kwargs['json'] = json
+ self.body = template.render_unicode(**kwargs).encode('utf-8', 'replace')
+ self.headers = []
+
+class FeedResponse(MakoResponse):
+ content_type = 'application/rss+xml'
+
+class PodcastApplication(RestApplication):
+ def __init__(self, db, title, description, default_entry_title, default_entry_description,
+ site_link, author, author_email, explicit, tags):
+ super(PodcastApplication, self).__init__()
+ self.db = db
+ self.db.sync_design_doc('couchcast', design_doc)
+ self.title = title
+ self.description = description
+ self.default_entry_title = default_entry_title
+ self.default_entry_description = default_entry_description
+ self.site_link = site_link
+ self.author = author
+ self.author_email = author_email
+ self.explicit = explicit
+ self.tags = tags
+
+ def GET(self, request, collection):
+ nulltimes = self.db.views.couchcast.podcastDocs(key=None)
+ if len(nulltimes) is not 0:
+ nulltimes.couchcast_pubdatetime = datetime.now().isoformat()
+ for doc in nulltimes:
+ if 'title' not in doc:
+ doc.title = self.default_entry_title
+ if 'description' not in doc:
+ doc.description = self.default_entry_description
+ self.db.save(nulltimes)
+ items = self.db.views.couchcast.podcastDocs(descending=True)
+ for item in items:
+ item.attachment, item.attachment['filename'] = [
+ (item._attachments[i], i,) for i in item._attachments.keys() if
+ item._attachments[i].get('content_type') == 'audio/mpeg'][0]
+ item.attachment['uri'] = self.db.uri+item['_id']+'/'+item.attachment['filename']
+ podcast = {'title':self.title, 'description':self.description, 'site_link':self.site_link,
+ 'author':self.author, 'author_email':self.author_email, 'explicit':self.explicit,
+ 'tags':self.tags, 'items':items,
+ }
+
+ return FeedResponse(collection, podcast=podcast)
+
+class Podcasts(RestApplication):
+ def add_podcast(self, name, dburi, title, description, default_entry_title, default_entry_description, site_link, author, author_email, explicit=True, tags=['Technology']):
+ db = Database(dburi)
+ application = PodcastApplication(db, title, description, default_entry_title, default_entry_description, site_link, author, author_email, explicit, tags)
+ self.add_resource(name, application)
+
+
+def cli():
+ from wsgiref.simple_server import make_server
+ import imp
+ appmodule = imp.load_source('appmodule', os.path.abspath(sys.argv[-1]))
+ httpd = make_server('', 8888, appmodule.application)
+ print "Serving on http://localhost:8888/"
+ httpd.serve_forever()
@@ -0,0 +1,15 @@
+function (doc) {
+ if (doc._attachments) {
+ for (i in doc._attachments) {
+ var attachment = doc._attachments[i];
+ if (attachment.content_type == 'audio/mpeg') {
+ if (doc.couchcast_pubdatetime) {
+ var pubdatetime = doc.couchcast_pubdatetime.replace(' ','T');
+ } else {
+ var pubdatetime = null;
+ }
+ emit(pubdatetime, doc);
+ }
+ }
+ }
+}
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
+ <channel>
+ <title>${podcast['title']}</title>
+ <link>${podcast['site_link']}</link>
+ <description>${podcast['description']}</description>
+ <language>en</language>
+ <pubDate>Sun, 11 Oct 2009 11:22:45 -0700</pubDate>
+ <lastBuildDate>Sun, 11 Oct 2009 11:22:45 -0700</lastBuildDate>
+ <itunes:author>${podcast['author']}</itunes:author>
+% if podcast['explicit']:
+ <itunes:explicit>yes</itunes:explicit>
+% else:
+ <itunes:explicit>no</itunes:explicit>
+% endif
+ <itunes:owner>
+ <itunes:name>${podcast['author']}</itunes:name>
+ <itunes:email>${podcast['author_email']}</itunes:email>
+ </itunes:owner>
+ <itunes:block>no</itunes:block>
+% for tag in podcast['tags']:
+ <itunes:category text="${tag}"/>
+% endfor
+
+% for item in podcast['items']:
+ <item>
+ <title>${item['title']}</title>
+% if 'article_link' in item:
+ <link>${item['article_link']}</link>
+% endif
+ <description><![CDATA[${item['description']}]]></description>
+ <pubDate>Sun, 11 Oct 2009 11:22:12 -0700</pubDate>
+ <enclosure url="${item['attachment']['uri']}" length="${item['attachment']['length']}" type="${item['attachment']['content_type']}"/>
+ <guid isPermaLink="false">${item['title']}</guid>
+ <itunes:author>${podcast['author']}</itunes:author>
+ <itunes:subtitle>${item['title']}</itunes:subtitle>
+ <itunes:summary>${item['description']}</itunes:summary>
+% if podcast['explicit']:
+ <itunes:explicit>yes</itunes:explicit>
+% else:
+ <itunes:explicit>no</itunes:explicit>
+% endif
+ </item>
+% endfor
+ </channel>
+</rss>
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
+ <channel>
+ <title>${podcast['title']}</title>
+ <link>${podcast['site_link']}</link>
+ <description>${podcast['description']}</description>
+ <language>en</language>
+ <pubDate>Sun, 11 Oct 2009 11:46:12 -0700</pubDate>
+ <lastBuildDate>Sun, 11 Oct 2009 11:46:12 -0700</lastBuildDate>
+% for item in podcast['items']:
+ <item>
+ <title>${item['title']}</title>
+% if 'article_link' in item:
+ <link>${item['article_link']}</link>
+% endif
+ <description><![CDATA[${item['description']}]]></description>
+ <pubDate>Sun, 11 Oct 2009 11:22:12 -0700</pubDate>
+ <enclosure url="${item['attachment']['uri']}" length="${item['attachment']['length']}" type="${item['attachment']['content_type']}"/>
+ <guid isPermaLink="false">${item['title']}</guid>
+ </item>
+% endfor
+ </channel>
+</rss>
@@ -0,0 +1,17 @@
+from couchcast import Podcasts
+
+couchdb = {'name':'couchdb', 'title':'CouchDB Podcast',
+ 'dburi':'http://localhost:5984/couchcast',
+ 'description':'CouchDB pushing pure relaxification in your ears',
+ 'default_entry_title':'CouchDB Podcast',
+ 'default_entry_description':'CouchDB Podcast with Chris Anderson and Jan Lehnardt',
+ 'site_link':'http://jchrisa.net',
+ 'author':'Chris Anderson and Jan Lehnardt',
+ 'author_email':'couchdb-podcast@couch.io'
+ }
+
+application = Podcasts()
+application.add_podcast(**couchdb)
+
+
+
@@ -0,0 +1,70 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla Corporation Code.
+#
+# The Initial Developer of the Original Code is
+# Mikeal Rogers.
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mikeal Rogers <mikeal.rogers@gmail.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+from setuptools import setup, find_packages
+
+desc = """Create podcast feeds for CouchDB Databases."""
+summ = """Creates podcast feeds for CouchDB Databases."""
+
+PACKAGE_NAME = "couchcast"
+PACKAGE_VERSION = "0.1"
+
+setup(name=PACKAGE_NAME,
+ version=PACKAGE_VERSION,
+ description=desc,
+ long_description=summ,
+ author='Mikeal Rogers, Mozilla',
+ author_email='mikeal.rogers@gmail.com',
+ #url='http://',
+ license='http://www.mozilla.org/MPL/',
+ packages=find_packages(exclude=['test']),
+ include_package_data=True,
+ package_data = {'': ['*.js', '*.css', '*.html', '*.txt', '*.xpi', '*.rdf', '*.xul', '*.jsm', '*.xml'],},
+ entry_points="""
+ [console_scripts]
+ couchcast = couchcast:cli
+ """,
+ platforms =['Any'],
+ install_requires = ['webenv','couchquery','mako', 'iso8601'],
+ classifiers=['Development Status :: 4 - Beta',
+ 'Environment :: Console',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Apache Software License',
+ 'Operating System :: OS Independent',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ ]
+ )

0 comments on commit 45a946d

Please sign in to comment.