зеркало из https://github.com/mozilla/airmozilla.git
fixes bug 1141318 - Trending videos on Roku
This commit is contained in:
Родитель
b91107f71e
Коммит
cd43443a98
|
@ -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:
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче