Commits

Guilherme Gondim committed 85ff720

first commit

  • Participants
  • Tags 0.1

Comments (0)

Files changed (18)

+syntax: glob
+*.pyc
+*.bak
+*.swp
+*~
+._*
+.\#*
+*\#
+dist/
+build/
+*.egg-info/
+[main]
+host = https://www.transifex.net
+
+[django-tube.master]
+type = PO
+file_filter = tube/locale/<lang>/LC_MESSAGES/django.po
+source_file = tube/locale/en/LC_MESSAGES/django.po
+source_lang = en
+Django Tube was created in 2008 by Guilherme (semente). Following is a
+(probably incomplete) list of its contributors:
+
+  * Guilherme Gondim <semente+django-tube@taurinus.org>
+  * Sam Powers <sampowers at gmail.com>
+  * Your Name Here  ;-)
+		   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions. 
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version. 
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+include AUTHORS
+include COPYING.LESSER
+include README.rst
+recursive-include docs *
+recursive-include tube/locale *
+recursive-include tube/static *
+recursive-include tube/templates *
+===========
+Django Tube
+===========
+
+**Django Tube** is a pluggable YouTube video management application for
+`Django Web Framework`_.
+
+Project page
+    https://bitbucket.org/semente/django-tube
+Translations
+    https://www.transifex.net/projects/p/django-tube/
+
+.. _`Django Web Framework`: http://www.djangoproject.com
+
+
+Installing & Setup
+==================
+
+TODO
+
+
+License
+=======
+
+Copyright (c) 2012 Guilherme Gondim and individual contributors
+
+Django Tube is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation; either version 3 of the License, or (at your option) any
+later version.
+
+Django Tube 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 Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program; see the file COPYING.LESSER. If not, see
+<http://www.gnu.org/licenses/>.
+#/usr/bin/env python
+
+import codecs
+import os
+import sys
+
+from setuptools import setup, find_packages
+
+
+if 'publish' in sys.argv:
+    os.system('python setup.py sdist upload')
+    sys.exit()
+
+read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read()
+
+
+# Dynamically calculate the version based on tube.VERSION.
+version = __import__('tube').get_version()
+
+setup(
+    name='django-tube',
+    version=version,
+    description='YouTube video management application for Django projects',
+    long_description=read(os.path.join(os.path.dirname(__file__), 'README.rst')),
+    keywords = 'django app youtube video',
+    author='Guilherme Gondim',
+    author_email='semente+django-tube@taurinus.org',
+    maintainer='Guilherme Gondim',
+    maintainer_email='semente+django-tube@taurinus.org',
+    license='GNU Lesser General Public License (LGPL), Version 3',
+    url='https://bitbucket.org/semente/django-tube/',
+    download_url='https://bitbucket.org/semente/django-tube/downloads',
+    packages=find_packages(),
+    zip_safe=False,
+    include_package_data=True,
+    classifiers=[
+        'Development Status :: 5 - Production/Stable',
+        'Environment :: Web Environment',
+        'Framework :: Django',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
+        'Operating System :: OS Independent',
+        'Programming Language :: Python',
+        'Topic :: Software Development :: Libraries :: Python Modules',
+    ],
+    #install_requires=[],
+)
+VERSION = (0, 1)
+
+
+def get_version():
+    """Returns the version as a human-format string.
+    """
+    return '.'.join([str(i) for i in VERSION])
+
+
+__author__ = 'See the file AUTHORS'
+__license__ = 'GNU Lesser General Public License (GPL), Version 3'
+__url__ = 'https://bitbucket.org/semente/django-tube'
+__version__ = get_version()
+# -*- coding: utf-8 -*-
+
+from django.contrib import admin
+from django.utils.translation import ugettext_lazy as _
+
+from tube.models import Video
+
+
+class VideoAdmin(admin.ModelAdmin):
+    date_hierarchy = 'date_added'
+    fieldsets = (
+        (None, {
+            'fields': ('title', 'slug', 'youtube_url', 'description', 'visible')
+        }),
+        (_('Video detail'), {
+            'fields': ('date_recorded', 'time_recorded', 'place', 'cameraman')
+        }),
+    )
+    list_display = ('title', 'visible', 'date_added')
+    list_filter = ('date_added', 'visible')
+    prepopulated_fields = {'slug': ('title',)}
+    search_fields = ('slug', 'place', 'title', 'description', 'cameraman',
+                     'youtube_url')
+
+admin.site.register(Video, VideoAdmin)

tube/locale/en/LC_MESSAGES/django.mo

Binary file added.

tube/locale/en/LC_MESSAGES/django.po

+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-06-27 17:32-0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: admin.py:15
+msgid "Video detail"
+msgstr ""
+
+#: models.py:26
+msgid "title"
+msgstr ""
+
+#: models.py:28
+msgid "slug"
+msgstr ""
+
+#: models.py:29
+msgid ""
+"Automatically built from the title. A slug is a short label generally used "
+"in URLs."
+msgstr ""
+
+#: models.py:33
+msgid "YouTube URL"
+msgstr ""
+
+#: models.py:34
+msgid ""
+"Enter the YouTube video URL, e.g.: http://www.youtube.com/watch?v=wuzgCwKElm4"
+msgstr ""
+
+#: models.py:37
+msgid "description"
+msgstr ""
+
+#: models.py:38
+msgid "visible"
+msgstr ""
+
+#: models.py:39
+msgid "date added"
+msgstr ""
+
+#: models.py:40
+msgid "date modified"
+msgstr ""
+
+#: models.py:41
+msgid "date recorded"
+msgstr ""
+
+#: models.py:42
+msgid "time recorded"
+msgstr ""
+
+#: models.py:43
+msgid "place"
+msgstr ""
+
+#: models.py:45
+msgid "cameraman"
+msgstr ""
+
+#: models.py:55
+msgid "video"
+msgstr ""
+
+#: models.py:56
+msgid "videos"
+msgstr ""

tube/locale/pt_BR/LC_MESSAGES/django.mo

Binary file added.

tube/locale/pt_BR/LC_MESSAGES/django.po

+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# 
+# Translators:
+# Guilherme Gondim <semente@taurinus.org>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: Django Tube\n"
+"Report-Msgid-Bugs-To: https://bitbucket.org/semente/django-tube/issues?status=new&status=open\n"
+"POT-Creation-Date: 2012-06-27 17:32-0300\n"
+"PO-Revision-Date: 2012-06-27 21:27+0000\n"
+"Last-Translator: Guilherme Gondim <semente@taurinus.org>\n"
+"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/django-tube/language/pt_BR/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: pt_BR\n"
+"Plural-Forms: nplurals=2; plural=(n > 1)\n"
+
+#: admin.py:15
+msgid "Video detail"
+msgstr "Detalhes do vídeo"
+
+#: models.py:26
+msgid "title"
+msgstr "título"
+
+#: models.py:28
+msgid "slug"
+msgstr "slug"
+
+#: models.py:29
+msgid ""
+"Automatically built from the title. A slug is a short label generally used "
+"in URLs."
+msgstr "Construído automaticamente a partir do título. Um slug é uma pequena etiqueta geralmente utilizada em URLs."
+
+#: models.py:33
+msgid "YouTube URL"
+msgstr "URL do YouTube"
+
+#: models.py:34
+msgid ""
+"Enter the YouTube video URL, e.g.: "
+"http://www.youtube.com/watch?v=wuzgCwKElm4"
+msgstr "Insira a URL do vídeo do YouTube, por exemplo: http://www.youtube.com/watch?v=wuzgCwKElm4"
+
+#: models.py:37
+msgid "description"
+msgstr "descrição"
+
+#: models.py:38
+msgid "visible"
+msgstr "visível"
+
+#: models.py:39
+msgid "date added"
+msgstr "data de adição"
+
+#: models.py:40
+msgid "date modified"
+msgstr "data de modificação"
+
+#: models.py:41
+msgid "date recorded"
+msgstr "data da gravação"
+
+#: models.py:42
+msgid "time recorded"
+msgstr "horário da gravação"
+
+#: models.py:43
+msgid "place"
+msgstr "local"
+
+#: models.py:45
+msgid "cameraman"
+msgstr "cameraman"
+
+#: models.py:55
+msgid "video"
+msgstr "vídeo"
+
+#: models.py:56
+msgid "videos"
+msgstr "vídeos"

tube/migrations/0001_initial.py

+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Video'
+        db.create_table('tube_video', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=60)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
+            ('youtube_url', self.gf('django.db.models.fields.URLField')(max_length=200)),
+            ('description', self.gf('django.db.models.fields.TextField')(blank=True)),
+            ('visible', self.gf('django.db.models.fields.BooleanField')(default=True)),
+            ('date_added', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
+            ('date_modified', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
+            ('date_recorded', self.gf('django.db.models.fields.DateField')(null=True, blank=True)),
+            ('time_recorded', self.gf('django.db.models.fields.TimeField')(null=True, blank=True)),
+            ('place', self.gf('django.db.models.fields.CharField')(max_length=70, blank=True)),
+            ('cameraman', self.gf('django.db.models.fields.CharField')(max_length=50, blank=True)),
+        ))
+        db.send_create_signal('tube', ['Video'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Video'
+        db.delete_table('tube_video')
+
+
+    models = {
+        'tube.video': {
+            'Meta': {'ordering': "('-date_added',)", 'object_name': 'Video'},
+            'cameraman': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
+            'date_added': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'date_modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'date_recorded': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'place': ('django.db.models.fields.CharField', [], {'max_length': '70', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
+            'time_recorded': ('django.db.models.fields.TimeField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '60'}),
+            'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'youtube_url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
+        }
+    }
+
+    complete_apps = ['tube']

tube/migrations/__init__.py

Empty file added.
+# -*- coding: utf-8 -*-
+
+import re
+
+from django.db import models
+from django.db.models import Manager, permalink
+from django.utils.translation import ugettext_lazy as _
+
+
+EMBED_HTML = """<iframe src="http://www.youtube.com/embed/%s?rel=0"
+        width="640" height="360" frameborder="0" allowfullscreen></iframe>
+"""
+
+URL_PATTERN = re.compile(r'^(http[s]?://www\.youtube\.com/watch\?v='
+                         r'|http[s]?://youtu\.be/)([-a-z0-9A-Z_]+)')
+
+
+class VideoManager(Manager):
+    use_for_related_fields = True
+
+    def visible(self, *args, **kwargs):
+        return super(VideoManager, self).filter(visible=True, *args, **kwargs)
+
+
+class Video(models.Model):
+    title = models.CharField(_('title'), max_length=60)
+    slug = models.SlugField(
+        _('slug'),
+        help_text=_('Automatically built from the title. A slug is a short '
+                    'label generally used in URLs.'),
+    )
+    youtube_url = models.URLField(
+        _('YouTube URL'),
+        help_text=_('Enter the YouTube video URL, e.g.: '
+                    'http://www.youtube.com/watch?v=wuzgCwKElm4')
+    )
+    description = models.TextField(_('description'), blank=True)
+    visible = models.BooleanField(_('visible'), default=True)
+    date_added = models.DateTimeField(_('date added'), auto_now_add=True)
+    date_modified = models.DateTimeField(_('date modified'), auto_now=True)
+    date_recorded = models.DateField(_('date recorded'), blank=True, null=True)
+    time_recorded = models.TimeField(_('time recorded'), blank=True, null=True)
+    place = models.CharField(_('place'), blank=True, max_length=70)
+    cameraman = models.CharField(
+        _('cameraman'),
+        blank=True,
+        max_length=50
+    )
+
+    objects   = VideoManager()
+
+    class Meta:
+        get_latest_by = 'date_added'
+        ordering      = ('-date_added',)
+        verbose_name  = _('video')
+        verbose_name_plural = _('videos')
+
+    def __unicode__(self):
+        return self.title
+
+    @permalink
+    def get_absolute_url(self):
+        return ('tube-video', None, {
+            'pk' : str(self.pk),
+            'slug' : str(self.slug),
+        })
+
+    @property
+    def youtube_id(self):
+        match = re.match(URL_PATTERN, self.youtube_url)
+        if match:
+            return match.groups()[1]
+        return None
+
+    @property
+    def thumbnail_url(self):
+        return 'http://i.ytimg.com/vi/%s/default.jpg' % self.youtube_id
+
+    @property
+    def embed_html(self):
+        return EMBED_HTML % self.youtube_id
+# -*- coding: utf-8 -*-
+
+from django.conf.urls import patterns, url
+
+from tube import views
+
+
+urlpatterns = patterns('',
+    url('^(?P<pk>[0-9]+)/(?P<slug>[-\w]+)/$', views.VideoDetail.as_view(), name='tube-video'),
+    url('^$', views.VideoList.as_view(), name='tube-video-list'),
+)
+# -*- coding: utf-8 -*-
+
+from django.views import generic
+
+from tube.models import Video
+
+
+class VideoList(generic.list.ListView):
+    model = Video
+    queryset = Video.objects.visible()
+    paginate_by = 20
+
+
+class VideoDetail(generic.detail.DetailView):
+    model = Video
+    queryset = Video.objects.visible()
+