fixes bug 1141318 - Trending videos on Roku

This commit is contained in:
Peter Bengtsson 2015-03-09 15:50:34 -07:00
Родитель b91107f71e
Коммит cd43443a98
8 изменённых файлов: 121 добавлений и 35 удалений

Просмотреть файл

@ -24,8 +24,17 @@ def dev(request):
def sidebar(request):
# none of this is relevant if you're in certain URLs
if '/manage/' in request.path_info:
return {}
if '/roku/' in request.path_info:
# Special circumstance here.
# We have a static page with URL "/roku" (which django redirects
# to "/roku/"). On that page we want sidebar stuff.
# But on all XML related roku views we don't want sidebar stuff.
if not request.path_info.endswith('/roku/'):
return {}
data = {
# used for things like {% if event.attr == Event.ATTR1 %}
'Event': Event,
@ -113,8 +122,11 @@ def _get_upcoming_events(channels, anonymous, contributor):
return upcoming
def get_featured_events(channels, user,
length=settings.FEATURED_SIDEBAR_COUNT):
def get_featured_events(
channels,
user,
length=settings.FEATURED_SIDEBAR_COUNT
):
"""return a list of events that are sorted by their score"""
anonymous = True
contributor = False
@ -124,7 +136,8 @@ def get_featured_events(channels, user,
contributor = True
cache_key = 'featured_events_%s_%s' % (int(anonymous), int(contributor))
cache_key += ','.join(str(x.id) for x in channels)
if channels:
cache_key += ','.join(str(x.id) for x in channels)
event = most_recent_event()
if event:
cache_key += str(event.modified.microsecond)
@ -146,7 +159,7 @@ def _get_featured_events(channels, anonymous, contributor):
EventHitStats.objects
.exclude(event__archive_time__isnull=True)
.filter(event__archive_time__lt=yesterday)
.filter(event__channels__in=channels)
.exclude(event__channels__exclude_from_trending=True)
.extra(
select={
@ -159,6 +172,9 @@ def _get_featured_events(channels, anonymous, contributor):
.select_related('event')
.order_by('-score')
)
if channels:
featured = featured.filter(event__channels__in=channels)
if anonymous:
featured = featured.filter(event__privacy=Event.PRIVACY_PUBLIC)
elif contributor:

Двоичные данные
airmozilla/roku/static/roku/images/trending.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Просмотреть файл

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<categories>
<!-- banner_ad: optional element which displays an at the top level category screen -->
<banner_ad sd_img="{{ abs_static('roku/images/banner_sd.png') }}"
hd_img="{{ abs_static('roku/images/banner_hd.png') }}"/>
<!-- banner_ad: optional element which displays an at the top level category screen -->
<banner_ad sd_img="{{ abs_static('roku/images/banner_sd.png') }}"
hd_img="{{ abs_static('roku/images/banner_hd.png') }}"/>
<category title="Archived Events" description="Blasts from the past"
@ -23,26 +23,40 @@
</category>
<category title="Trending Events" description="Most popular events most recently"
sd_img="{{ abs_static('roku/images/trending.png') }}"
hd_img="{{ abs_static('roku/images/trending.png') }}">
<categoryLeaf title="Trending Events" description=""
feed="{{ abs_url('roku:trending_feed') }}">
</categoryLeaf>
</category>
{% for event in live_events %}
<!-- EVENT LIVE -->
<!-- LIVE EVENT -->
{% set media_info = get_media_info(event) %}
{% if media_info %}
{% if media_info.format == 'hls' %}
{% if event.picture %}
{% set thumb_hd = thumbnail(event.picture.file, '304x237', crop='center') %}
{% set thumb_sd = thumbnail(event.picture.file, '224x158', crop='center') %}
{% if media_info.format == 'hls' %}
{% if event.picture %}
{% set thumb_hd = thumbnail(event.picture.file, '304x237', crop='center') %}
{% set thumb_sd = thumbnail(event.picture.file, '224x158', crop='center') %}
{% else %}
{% set thumb_hd = thumbnail(event.placeholder_img, '304x237', crop='center') %}
{% set thumb_sd = thumbnail(event.placeholder_img, '224x158', crop='center') %}
{% endif %}
<specialCategory title="Live right now" description="{{ event.title }}"
sd_img="{{ make_absolute(thumb_sd.url) }}" hd_img="{{ make_absolute(thumb_hd.url) }}"
type="special_category">
<categoryLeaf title="{{ event.title }}" description="{{ event.title }}"
feed="{{ abs_url('roku:event_feed', event.id) }}">
</categoryLeaf>
</specialCategory>
{% else %}
{% set thumb_hd = thumbnail(event.placeholder_img, '304x237', crop='center') %}
{% set thumb_sd = thumbnail(event.placeholder_img, '224x158', crop='center') %}
<!-- not 'hls' {{ media_info.format }} -->
{% endif %}
<specialCategory title="Live right now" description="{{ event.title }}"
sd_img="{{ make_absolute(thumb_sd.url) }}" hd_img="{{ make_absolute(thumb_hd.url) }}"
type="special_category">
<categoryLeaf title="{{ event.title }}" description="{{ event.title }}"
feed="{{ abs_url('roku:event_feed', event.id) }}">
</categoryLeaf>
</specialCategory>
{% endif %}
{% else %}
<!-- lacking media_info -->
{% endif %}
{% endfor %}

Просмотреть файл

@ -7,7 +7,13 @@ from django.core.files import File
from funfactory.urlresolvers import reverse
from nose.tools import eq_, ok_
from airmozilla.main.models import Event, Channel, Template, Picture
from airmozilla.main.models import (
Event,
Channel,
Template,
Picture,
EventHitStats,
)
from airmozilla.base.tests.testbase import DjangoTestCase
@ -22,9 +28,11 @@ class TestRoku(DjangoTestCase):
url = reverse('roku:categories_feed')
main_channel = Channel.objects.get(slug=settings.DEFAULT_CHANNEL_SLUG)
main_url = reverse('roku:channel_feed', args=(main_channel.slug,))
trending_url = reverse('roku:trending_feed')
response = self.client.get(url)
eq_(response.status_code, 200)
ok_(main_url in response.content)
ok_(trending_url in response.content)
def test_categories_feed_live_events(self):
event = Event.objects.get(title='Test event')
@ -170,3 +178,34 @@ class TestRoku(DjangoTestCase):
response = self.client.get(url)
eq_(response.status_code, 200)
ok_('<runtime>12</runtime>' in response.content)
def test_trending_feed(self):
url = reverse('roku:trending_feed')
response = self.client.get(url)
eq_(response.status_code, 200)
event = Event.objects.get(title='Test event')
self._attach_file(event, self.main_image)
ok_(event.title not in response.content)
vidly = Template.objects.create(
name="Vid.ly Test",
content="test"
)
event.template = vidly
event.template_environment = {'tag': 'xyz123'}
event.save()
response = self.client.get(url)
eq_(response.status_code, 200)
# because it's not trending
ok_(event.title not in response.content)
EventHitStats.objects.create(
event=event,
total_hits=1000,
)
# This save will trigger to disrupt the cache used inside
# get_featured_events() since it'll change the modified time.
event.save()
response = self.client.get(url)
eq_(response.status_code, 200)
ok_(event.title in response.content)

Просмотреть файл

@ -11,6 +11,9 @@ urlpatterns = patterns(
url(r'event/(?P<id>\d+).xml$',
views.event_feed,
name='event_feed'),
url(r'channel/trending.xml$',
views.trending_feed,
name='trending_feed'),
url(r'channel/(?P<slug>[-\w]+).xml$',
views.channel_feed,
name='channel_feed'),

Просмотреть файл

@ -10,6 +10,7 @@ from airmozilla.main.views import is_contributor
from airmozilla.base.utils import (
paginate
)
from airmozilla.main.context_processors import get_featured_events
def categories_feed(request):
@ -117,14 +118,13 @@ def event_feed(request, id):
def channel_feed(request, slug):
context = {}
# this slug might be the slug of a parent
channels = Channel.objects.filter(
Q(slug=slug) |
Q(parent__slug=slug)
)
events = Event.objects.archived()
events = events.filter(channels__in=channels)
privacy_filter = {}
privacy_exclude = {}
if request.user.is_active:
@ -133,18 +133,28 @@ def channel_feed(request, slug):
else:
privacy_filter = {'privacy': Event.PRIVACY_PUBLIC}
archived_events = Event.objects.archived()
if privacy_filter:
archived_events = archived_events.filter(**privacy_filter)
events = events.filter(**privacy_filter)
elif privacy_exclude:
archived_events = archived_events.exclude(**privacy_exclude)
archived_events = archived_events.order_by('-start_time')
archived_events = archived_events.filter(channels__in=channels)
page = 1
archived_paged = paginate(archived_events, page, 100)
events = events.exclude(**privacy_exclude)
events = events.order_by('-start_time')
context['events'] = archived_paged
paged = paginate(events, 1, 100)
return render_channel_events(paged, request)
def trending_feed(request):
events = get_featured_events(
None, # across all channels
request.user,
length=settings.TRENDING_ROKU_COUNT,
)
return render_channel_events(events, request)
def render_channel_events(events, request):
context = {}
context['events'] = events
context['get_media_info'] = get_media_info
response = render(request, 'roku/channel.xml', context)

Просмотреть файл

@ -210,6 +210,9 @@ UPCOMING_SIDEBAR_COUNT = 5
# Number of featured/trending events to display in the sidebar
FEATURED_SIDEBAR_COUNT = 5
# Number of trending events to display in the Roku feed
TRENDING_ROKU_COUNT = 20
# Use memcached for session storage with fallback on the database
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

Просмотреть файл

@ -15,6 +15,7 @@ Function InitCategoryFeedConnection() As Object
' conn.UrlPrefix = "https://modern-rat.usefinch.us/roku"
'conn.UrlPrefix = "https://air-dev.allizom.org/roku"
conn.UrlPrefix = "https://air.mozilla.org/roku"
conn.UrlCategoryFeed = conn.UrlPrefix + "/categories.xml"
conn.Timer = CreateObject("roTimespan")
@ -38,7 +39,7 @@ Function get_category_names(categories As Object) As Dynamic
categoryNames = CreateObject("roArray", 100, true)
for each category in categories.kids
'print category.Title
' print category.Title
categoryNames.Push(category.Title)
next