<file_sep>(function ($) {
    var Brightcove = {
        init: function () {
            $('.brightcove_widget_refresh').on("click", function(e){
                var that = this;
                $(that).find('.fa').addClass('fa-spin');
                $('.brightcove_widget select').load($(this).attr('href'), function () {
                    $(that).find('.fa').removeClass('fa-spin');
                });
                e.preventDefault();
            });
        }
    };

    $(function () {
        Brightcove.init();
    });
})(window.jQuery || django.jQuery);
<file_sep>from django.db import models
from django.utils.translation import ugettext_lazy as _

from .models import BrightcoveItems
from .widgets import BrightcoveIntegerField


class BrightcoveField(models.ForeignKey):
    """
    Custom manager that inherits form the ForeignKey default django field, used to easily set a field up in order to
    relate a Model the the BrightCoveItems model and widget.

    i.e.::

        class MyModel(Model):
            my_field = BrightcoveField()
    """
    def __init__(self, null=True, blank=True, **kwargs):
        """Overwites default settings to setup the relationship with the BrightcoveItems model"""
        kwargs['verbose_name'] = kwargs.get('verbose_name', _("Brightcove"))
        kwargs['null'] = null
        kwargs['blank'] = blank
        # If null is set to True we can't use SET_NULL as default
        if null:
            default_on_delete =  models.PROTECT
        else:
            default_on_delete = models.SET_NULL
        kwargs['on_delete'] = kwargs.get('on_delete', default_on_delete)
        to_field = kwargs.pop('to_field', 'brightcove_id')
        rel_class = models.ManyToOneRel
        db_constraint = True
        to = kwargs.pop('to', BrightcoveItems)
        super(BrightcoveField, self).__init__(to, to_field, rel_class, db_constraint, **kwargs)

    def save_form_data(self, instance, data):
        #when data is u'' and form allow te be null, we need to make sure
        #it will not blow up the page
        if data:
            video = BrightcoveItems.objects.get(pk=data)
        else:
            video = None
        super(BrightcoveField, self).save_form_data(instance, video)

    def formfield(self, **kwargs):
        """Overwites default formfield to trigger the custom Brightcove choicefield widget"""
        defaults = {
            'form_class': BrightcoveIntegerField,
        }
        defaults.update(kwargs)
        return super(models.ForeignKey, self).formfield(**defaults)

    def south_field_triple(self):
        """Provide a suitable description of this field for South."""
        from south.modelsinspector import introspector
        args, kwargs = introspector(self)
        return 'django.db.models.fields.related.ForeignKey', args, kwargs
<file_sep># -*- coding: utf-8 -*-
from south.utils import datetime_utils as 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 'BrightcoveItems'
        db.create_table(u'django_brightcove_brightcoveitems', (
            ('brightcove_id', self.gf('django.db.models.fields.BigIntegerField')(primary_key=True)),
            ('name', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
            ('video_still_URL', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
            ('thumbnail_URL', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
            ('short_description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
            ('long_description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
            ('length', self.gf('django.db.models.fields.IntegerField')(null=True, blank=True)),
            ('link_URL', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
            ('plays_total', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)),
            ('creation_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
            ('published_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
        ))
        db.send_create_signal(u'django_brightcove', ['BrightcoveItems'])


    def backwards(self, orm):
        # Deleting model 'BrightcoveItems'
        db.delete_table(u'django_brightcove_brightcoveitems')


    models = {
        u'django_brightcove.brightcoveitems': {
            'Meta': {'object_name': 'BrightcoveItems'},
            'brightcove_id': ('django.db.models.fields.BigIntegerField', [], {'primary_key': 'True'}),
            'creation_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
            'length': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
            'link_URL': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
            'long_description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
            'plays_total': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
            'published_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
            'short_description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
            'thumbnail_URL': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
            'video_still_URL': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
        }
    }

    complete_apps = ['django_brightcove']<file_sep>from django.conf import settings

from brightcove.api import Brightcove

from .models import BrightcoveItems


class BrightcoveApi():
    """Class managing communication with the Brightcove API though the brightcove app."""
    token = ''
    connector = None

    def __init__(self, token=''):
        if token:
            self.token = token
        if not self.token:
            self.token = getattr(settings, 'BRIGHTCOVE_TOKEN', None)

        self.connector = Brightcove(self.token)

    def get_by_id(self, brightcove_id):
        video = self.connector.find_video_by_id(brightcove_id)
        if video:
            return self._save_item(video)
        return None

    def _get_list(self):
        return self.connector.find_all_videos()

    def synchronize_list(self):
        """Synchronizes the list of videos form a brightcove account with the BrightcoveItem model."""
        items = self._get_list()
        existing_ids = []
        for item in items.items:
            self._save_item(item)
            existing_ids.append(item.id)
        BrightcoveItems.objects.exclude(brightcove_id__in=existing_ids).delete()

    def _save_item(self, item):
        brightcove_item, created = BrightcoveItems.objects.get_or_create(brightcove_id=item.id)
        brightcove_item.name = item.name
        brightcove_item.video_still_URL = item.videoStillURL
        brightcove_item.thumbnail_URL = item.thumbnailURL
        brightcove_item.short_description = item.shortDescription
        brightcove_item.long_description = item.longDescription
        brightcove_item.length = item.length
        brightcove_item.link_URL = item.linkURL
        brightcove_item.plays_total = item.playsTotal
        brightcove_item.creation_date = item.creationDate
        brightcove_item.published_date = item.publishedDate
        brightcove_item.save()
        return brightcove_item
<file_sep># -*- coding: utf-8 -*-
"""
This package is for Django migrations. South migrations can be found in the `south_migrations`
package.
"""
from __future__ import unicode_literals

SOUTH_ERROR_MESSAGE = """\n
To enable South migrations for this app customize the `SOUTH_MIGRATION_MODULES` setting in your
settings file such as the following:

    SOUTH_MIGRATION_MODULES = {
        'django_brightcove': 'django_brightcove.south_migrations',
    }
"""

try:
    from django.db import models, migrations
except ImportError:
    from django.core.exceptions import ImproperlyConfigured
    raise ImproperlyConfigured(SOUTH_ERROR_MESSAGE)


class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='BrightcoveItems',
            fields=[
                ('brightcove_id', models.BigIntegerField(serialize=False, verbose_name='Brightcove id', primary_key=True)),
                ('name', models.CharField(max_length=255, null=True, verbose_name='Name', blank=True)),
                ('video_still_URL', models.CharField(max_length=255, null=True, verbose_name='Video still url', blank=True)),
                ('thumbnail_URL', models.CharField(max_length=255, null=True, verbose_name='Thumbnail url', blank=True)),
                ('short_description', models.TextField(null=True, verbose_name='Short description', blank=True)),
                ('long_description', models.TextField(null=True, verbose_name='Short description', blank=True)),
                ('length', models.IntegerField(null=True, verbose_name='Length', blank=True)),
                ('link_URL', models.CharField(max_length=255, null=True, verbose_name='Link url', blank=True)),
                ('plays_total', models.PositiveIntegerField(null=True, verbose_name='Number of plays', blank=True)),
                ('creation_date', models.DateTimeField(null=True, verbose_name='Creation date', blank=True)),
                ('published_date', models.DateTimeField(null=True, verbose_name='Published date', blank=True)),
            ],
            options={
            },
            bases=(models.Model,),
        ),
    ]
<file_sep>import datetime

from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _


@python_2_unicode_compatible
class BrightcoveItems(models.Model):
    """
    This class is storing the brightcove fields and managing the generic relationship
    """
    brightcove_id = models.BigIntegerField(verbose_name=_('Brightcove id'), primary_key=True)
    name = models.CharField(verbose_name=_('Name'), max_length=255, null=True, blank=True)
    video_still_URL = models.CharField(verbose_name=_('Video still url'), max_length=255, null=True, blank=True)
    thumbnail_URL = models.CharField(verbose_name=_('Thumbnail url'), max_length=255, null=True, blank=True)
    short_description = models.TextField(verbose_name=_('Short description'), null=True, blank=True)
    long_description = models.TextField(verbose_name=_('Short description'), null=True, blank=True)
    length = models.IntegerField(verbose_name=_('Length'), null=True, blank=True)
    link_URL = models.CharField(verbose_name=_('Link url'), max_length=255, null=True, blank=True)
    plays_total = models.PositiveIntegerField(verbose_name=_('Number of plays'), null=True, blank=True)
    creation_date = models.DateTimeField(verbose_name=_('Creation date'), null=True, blank=True)
    published_date = models.DateTimeField(verbose_name=_('Published date'), null=True, blank=True)

    def __str__(self):
        if self.name:
            return self.name
        return self.brightcove_id

    @property
    def length_seconds(self):
        length = datetime.timedelta(milliseconds=self.length)
        return ':'.join(str(length).split('.')[0:1])
<file_sep>from django.core import exceptions
from django.forms import IntegerField, NumberInput
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _

from .models import BrightcoveItems
from .utils import BrightcoveApi


class BrightcoveNumberInput(NumberInput):
    """
    Overwrites the default Select widget to add the brightcove specific magic.
    """
    choices = []

    def render(self, name, value, attrs=None):
        item = None
        if value:
            try:
                item = BrightcoveItems.objects.get(pk=value)
            except BrightcoveItems.DoesNotExist:
                pass

        context = {'select': self.render_input(name, value, attrs), 'pk': value, 'item': item}
        return render_to_string('select_widget.html', context)

    class Media:
        css = {
            'all': ('brightcove/css/brightcove.css',
                    '//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css',)
        }
        js = ('//admin.brightcove.com/js/APIModules_all.js', 'brightcove/js/brightcove.js',
              '//admin.brightcove.com/js/BrightcoveExperiences.js',)

    def render_input(self, name, value, attrs=None):
        return super(BrightcoveNumberInput, self).render(name, value, attrs)


class BrightcoveIntegerField(IntegerField):
    """
    Overwrites the default IntegerField widget to force the custom widget to be displayed.
    """
    widget = BrightcoveNumberInput

    def __init__(self, max_value=None, min_value=None, *args, **kwargs):
        kwargs.pop('limit_choices_to', None)
        super(BrightcoveIntegerField, self).__init__(max_value, min_value,
            *args, **kwargs)

    def clean(self, value):
        value = super(BrightcoveIntegerField, self).clean(value)
        if not self._has_changed(self.initial, value):
            return value
        api = BrightcoveApi()
        try:
            api.get_by_id(value)
        except:
            raise exceptions.ValidationError(_("The id you have passed doesn't seem to exist in the Brightcove \
                database."))
        return value
<file_sep>from django.conf.urls import patterns, url

from .views import refresh_item_list

urlpatterns = patterns(
    '',

    url(r'^brightcove-refresh-item-list/(?P<pk>[\w-]+)/$', refresh_item_list, name='brightcove-refresh-item-list'),
)
<file_sep>#################
Django Brightcove
#################

Manages the integration of brightcove videos in a django project. It extends the the Brightcove library developed by <NAME>: https://pypi.python.org/pypi/brightcove/0.2

It basically add a form field to easily integrate brightcove account video in the django admin or any form. And adds a template tag to fast integrate a brightcove video in a template.

*******
Install
*******

It is strongly recommanded to install this theme from GIT with PIP onto you project virtualenv.

From PyPi

.. code-block::  shell-session

    pip install django-brightcove

From Github

.. code-block::  shell-session

    https://github.com/RevSquare/django-brightcove#egg=django-brightcove


*****
Setup
*****

Before starting, you will need a Brightcove API token in order to connect to brightcove: http://docs.brightcove.com/en/video-cloud/media/guides/managing-media-api-tokens.html

The first step is to add the app in your installed apps list in settings.py

.. code-block::  python

    INSTALLED_APPS = (
        ...
        'django_brightcove'
        ...
    )

The you will need to declare the loaders you want to add in your settings.py file

.. code-block::  python

    BRIGHTCOVE_TOKEN = 'YOUR_TOKEN..'

Finally you will need to add the django-brightcove urls to your Root URLCONF

.. code-block::  python

    urlpatterns = patterns('',
        ...

        (r'^django_brightcove', include('django_brightcove.urls')),
        ...
    )



*********************************
Add a Brightcove video to a model
*********************************

Simply add the Brightcove field manager to it.

.. code-block::  python

    from django.db import models
    from django_brightcove.fields import BrightcoveField


    class MyModel(models.Model):
        brightcove = BrightcoveField()



*************
Template tags
*************

You can easily insert a video with a built in template tag.

The first step is to list your brightcove player id and key in your settings file.

.. code-block::  python

    BRIGHTCOVE_PLAYER = {
        'default': {
            'PLAYERID': 'a_default_player_id',
            'PLAYERKEY': 'a_default_player_key',
        },
        'single': {
            'PLAYERID': 'another_player_id',
            'PLAYERKEY': 'another_player_key',
        },
    }

Then within your template, simply call for the player tag and pass your video id and eventualy a specific brightcove player type. By default the tag with the key set as 'default' in settings.BRIGHTCOVE_PLAYER dictionary.

.. code-block::  html

    {% load brightcove %}

    <div class="player">{% brightcove_player object.brightcove_id player='single' %}</div>

You can also pass height and width to the template tag, ie:

.. code-block::  html

    {% load brightcove %}

    <div class="player">{% brightcove_player object.brightcove_id width=480 height=270 %}</div>

You will also need to add the Brightcove javascript library

.. code-block::  html

    <script type="text/javascript" src="http://admin.brightcove.com/js/BrightcoveExperiences.js"></script>


************
Contribution
************


Please feel free to contribute. Any help and advices are much appreciated.


*****
LINKS
*****

Development:
    https://github.com/RevSquare/django-brightcove

Package:
    https://pypi.python.org/pypi/django-brightcove
<file_sep>from django.http import HttpResponse, Http404


def refresh_item_list(request, pk):
    """Updates the select of brightcove items in a form"""
    if not request.is_ajax():
        raise Http404
    return HttpResponse(pk)
<file_sep>from django import template
from django.conf import settings


register = template.Library()


@register.inclusion_tag('tags/brightcove_player.html',
                        takes_context=True)
def brightcove_player(context, player_id, *args, **kwargs):
    """
    This tags generate the brightcove object code. It required the
    BRIGHTCOVE_PLAYER constant to be properly setup in
    the django settings.
    """
    if not settings.BRIGHTCOVE_PLAYER:
        raise Exception('BRIGHTCOVE_PLAYER constant is missing from your settings.')
    player = kwargs.get('player', 'default')

    try:
        player = settings.BRIGHTCOVE_PLAYER[player]
    except:
        raise KeyError('%s player type is missing from the BRIGHTCOVE_PLAYER constant' % player)

    try:
        context['playerID'] = player['PLAYERID']
        context['playerKey'] = player['PLAYERKEY']
    except:
        raise KeyError('%s player type from the BRIGHTCOVE_PLAYER constant is not properly configured' % player)

    context['width'] = kwargs.get('width', 480)
    context['height'] = kwargs.get('height', 270)
    context['bgcolor'] = kwargs.get('bgcolor', '#FFFFFF')
    context['isVid'] = kwargs.get('isVid', True)
    context['isUI'] = kwargs.get('isUI', True)
    context['dynamicStreaming'] = kwargs.get('dynamicStreaming', True)
    context['player_id'] = player_id
    return context
