JWPlatform Integration Application

JWPlatform integration

Settings

Default settings values for the mediaplatform_jwp application.

mediaplatform_jwp.defaultsettings.JWPLATFORM_API_BASE_URL = 'https://cdn.jwplayer.com/'

Base URL for the JWPlatform API. This can usually be left at its default value.

mediaplatform_jwp.defaultsettings.JWPLATFORM_API_KEY = None

The jwplatform API key. Defaults to the empty string but a custom system check ensures that this setting has a non-empty value.

mediaplatform_jwp.defaultsettings.JWPLATFORM_API_SECRET = None

The jwplatform API secret. Defaults to the empty string but a custom system check ensures that this setting has a non-empty value.

mediaplatform_jwp.defaultsettings.JWPLATFORM_CONTENT_BASE_URL = 'https://content.jwplatform.com'

Base URL for the JWPlatform Content. This can usually be left at its default value.

mediaplatform_jwp.defaultsettings.JWPLATFORM_EMBED_PLAYER_KEY = None

Player key for the embedded player used by the embed view.

mediaplatform_jwp.defaultsettings.JWPLATFORM_SIGNATURE_TIMEOUT = 3600

Lifetime of signed URL in seconds.

mediaplatform_jwp.defaultsettings.JWP_FORCE_HTTPS_UPLOAD = True

Should we force http upload links to be https?

mediaplatform_jwp.defaultsettings.JWP_SYNC_ITEMS = True

Should matching JWP videos should be creatred/updated when MediaItem objects change.

mediaplatform_jwp.defaultsettings.LOOKUP_PEOPLE_CACHE_LIFETIME = 1800

Responses to the people endpoint of lookupproxy are cached to increase performance. We assume that lookup details on people change rarely. This setting specifies the lifetime of a single cached lookup resource for a person in seconds.

mediaplatform_jwp.defaultsettings.LOOKUP_PEOPLE_ID_SCHEME = 'mock'

The ID scheme to use when querying people in LOOKUP. This is almost always ‘crsid’ unless you are using test raven, in which case it is ‘mock’.

mediaplatform_jwp.defaultsettings.LOOKUP_ROOT = None

URL of the lookup proxy’s API root.

mediaplatform_jwp.defaultsettings.OAUTH2_CLIENT_ID = None

OAuth2 client id which the API server uses to identify itself to the OAuth2 token introspection endpoint.

mediaplatform_jwp.defaultsettings.OAUTH2_CLIENT_SECRET = None

OAuth2 client secret which the API server uses to identify itself to the OAuth2 token introspection endpoint.

mediaplatform_jwp.defaultsettings.OAUTH2_LOOKUP_SCOPES = ['lookup:anonymous']

List of OAuth2 scopes the API server will request for the token it will use with lookup.

mediaplatform_jwp.defaultsettings.OAUTH2_MAX_RETRIES = 5

Maximum number of retries when fetching URLs from the OAuth2 endpoint or OAuth2 authenticated URLs. This applies only to failed DNS lookups, socket connections and connection timeouts, never to requests where data has made it to the server.

mediaplatform_jwp.defaultsettings.OAUTH2_TOKEN_URL = None

URL of the OAuth2 token endpoint the API server uses to request an authorisation token to perform OAuth2 token introspection.

Models

class mediaplatform_jwp.models.CachedResource(*args, **kwargs)

A cache of a JWPlatform resource.

This model should be queried by way of the various type-specific helpers. For example, to filter videos by title:

CachedResource.videos.filter(data__title='some title')

Do not insert values directly, instead use the set_videos`() method to update the cached resources atomically:

set_resources((video['key'], video) for video in fetch_videos())

N.B. Since we use Postgres-specific field types (JSONB), this model requires that Postgres be the database.

CHANNEL = 'channel'

channel resource type

exception DoesNotExist
exception MultipleObjectsReturned
VIDEO = 'video'

video resource type

channels = <mediaplatform_jwp.models.CachedResourceTypeManager object>

Convenience manager instance whose base queryset is all the non-deleted channels

objects = <django.db.models.manager.Manager object>

Since we add an object manager, we need to explicitly add back the default one

videos = <mediaplatform_jwp.models.CachedResourceTypeManager object>

Convenience manager instance whose base queryset is all the non-deleted videos

class mediaplatform_jwp.models.CachedResourceTypeManager(type)

A models.Manager subclass which restricts the base query set to the non-deleted cached resources of a particular type.

get_queryset()

Return a new QuerySet object. Subclasses can override this method to customize the behavior of the Manager.

class mediaplatform_jwp.models.Channel(*args, **kwargs)

A JWPlatform channel resource.

exception DoesNotExist
exception MultipleObjectsReturned
channel

Corresponding mediaplatform.Channel. Accessible from the mediaplatform.Channel model via the jwp field. This can be NULL if there is no corresponding media item hosted by the Media Platform.

key

JWPlatform channel key

resource

Cached resource instance associated with this channel.

updated

The updated timestamp from JWPlatform. Used to determine which items need updating. This is an integer field rather than a datetime field because JWP uses timestamps and we should store the same value to make sure we compare apples to apples.

class mediaplatform_jwp.models.Video(*args, **kwargs)

A JWPlatform video resource.

exception DoesNotExist
exception MultipleObjectsReturned
embed_url(format='html')

Return a URL with an embed view of a mediaplatform.MediaItem. Returns None if there is no JWP video associated with the item.

get_sources()

Uses the JWP fetch API to retrieve a list of mediaplatform.MediaItem.Source instances for each source associated with the media item. Ignores the downloadable attribute of the item.

item

Corresponding mediaplatform.MediaItem. Accessible from the mediaplatform.MediaItem model via the jwp field. This can be NULL if there is no corresponding media item hosted by the Media Platform.

key

JWPlatform video key

resource

Cached resource instance associated with this video.

sources

A property which calls get_sources and caches the result.

updated

The updated timestamp from JWPlatform. Used to determine which items need updating. This is an integer field rather than a datetime field because JWP uses timestamps and we should store the same value to make sure we compare apples to apples.

mediaplatform_jwp.models.set_resources(resources, resource_type)

Helper function which updates the cached resources and marks resources as deleted if no longer present.

Parameters:
  • resources (iterable) – iterable of dicts representing the JWPlatform resources
  • resource_type (str) – type of JWPlatform resource (e.g. “video”)

Iterates over all of the dicts in resources adding or updating corresponding CachedResource models as it goes. After all resources have been added, any resources of the specified type which have not been created or updated are deleted from the cache.

This is all run inside an atomic block. Note that these blocks can be nested so calls to this function can themselves be within an atomic block.

[1] https://docs.djangoproject.com/en/2.0/topics/db/transactions/#django.db.transaction.atomic

Celery tasks

Celery tasks.

mediaplatform_jwp.tasks.fetch_channels(client)

Returns an iterable of dicts representing all channel resources in the JWPlatform database.

mediaplatform_jwp.tasks.fetch_videos(client)

Returns an iterable of dicts representing all video resources in the JWPlatform database.

Management commands

jwpfetch

The jwpfetch management command fetches metadata on videos from JWPlayer via the JWPlatform management API and caches it in the database as a series of CachedResource objects.

It is designed to be called periodically without arguments to keep the local cache of the JWPlatform state in sync with reality.

Note that resources which disappear from JWPlayer are not deleted from the database. Rather, their deleted_at attribute is set to a non-NULL date and time. The specialised object managers on :py:class`~mediaplatform_jwp.models.CachedResource` understand this and filter out deleted objects for you.

The --sync-all flag may be given to bypass the freshness check for updating database objects from the associated JWP metadata. If given, all py:class`mediaplatform.models.MediaItem` objects associated with a JWP video will have their metadata re-synchronised. This is a useful thing to do from time to time to make sure that all videos are in sync.

The --skip-fetch flag may be given to skip updating the cached resources from JWP and to only perform the database metadata synchronisation. This can be useful in combination with the --sync-all flag to make sure the database is consistent with all cached resources. Skipping only video or channel resources is controlled via the --skip-video-fetch and --skip-channel-fetch flags.

JWPlatform API

ACLs

Module providing functionality for handling ACL’s stored in the JWPlayer custom property - sms_acl.

class mediaplatform_jwp.acl.AceCam

This class encapsulates an ACE of the form CAM

static has_permission(user)

Any authenticated user can see the media

static parse(ace)

Parses an ACE and constructs/return an AceCam if it matches or None if it doesn’t

class mediaplatform_jwp.acl.AceGroup(groupid)

This class encapsulates an ACE of the form GROUP_{groupid}

has_permission(user)

Only a user belonging to the ‘groupid’ lookup group can see the media

static parse(ace)

Parses an ACE and constructs/return an AceGroup if it matches or None if it doesn’t

class mediaplatform_jwp.acl.AceInst(instid)

This class encapsulates an ACE of the form INST_{instid}

has_permission(user)

Only a user belonging to the ‘instid’ lookup institution can see the media

static parse(ace)

Parses an ACE and constructs/return an AceInst if it matches or None if it doesn’t

class mediaplatform_jwp.acl.AceUser(crsid)

This class encapsulates an ACE of the form USER_{crsid}

has_permission(user)

Only a user with this CRSID can see the media

static parse(ace)

Parses an ACE and constructs/return an AceUser if it matches or None if it doesn’t

class mediaplatform_jwp.acl.AceWorld

This class encapsulates an ACE of the form WORLD

static has_permission(user)

Anyone can see the media

static parse(ace)

Parses an ACE and constructs/return an AceWorld if it matches or None if it doesn’t

mediaplatform_jwp.acl.build_acl(acl)

Iterates over the acl and encapsulates each ACE with the corresponding Ace* Class.

TODO there are performance enhancements that can be made (Eg only returning AceWorld, if it exists) but I have kept thing simple for now.

Parameters:acl – access control list
Returns:list of Ace* objects

Application configuration

class mediaplatform_jwp.apps.Config(app_name, app_module)

Configuration for JWPlatform integration application.

name = 'mediaplatform_jwp'

The short name for this application.

ready()

Perform application initialisation once the Django platform has been initialised.

verbose_name = 'JWPlatform Integration with Media Platform'

The human-readable verbose name for this application.

System checks

Custom system checks for the mediaplatform_jwp application.

mediaplatform_jwp.systemchecks.required_settings_check(app_configs, **kwargs)

A system check ensuring that all required settings are specified.