Skip to content
This repository has been archived by the owner on Feb 13, 2019. It is now read-only.

Commit

Permalink
Release branch for 0.8.x releases (#158)
Browse files Browse the repository at this point in the history
* cherry-pick contribution email.

* add amount paid back to email

* styled this

* style fix

* last style

* email

* last one

* last one part two

* fix deadline

* add bcc

* 0.8.15

* add bulbs/instant_articles

* add bulbs/ads

* just the stuff we like

* tests

* working business

* bump

* Merge pull request #173 from theonion/glance-json-feed

Glance json feed

* Merge pull request #174 from theonion/glance-feed-tweaks

Glance feed tweaks

* Wrapped footer in block so it can be overridden for individual properties

* Fixed issue with targeting not coming through in ads or analytics

* Default sort should be last modified, than published

* Bump version 0.8.17

* Bump version to 0.8.18

* Version bump

* fix some tests

* fix more tests

* changelog update
  • Loading branch information
kand committed May 12, 2016
1 parent 9dcf7f2 commit 330b5da
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 36 deletions.
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

## Development

## Version 2.0.0

- Merged in all 0.8.x changes.

## Version 1.1.1

- Update video grid styles and add bulbs-video-play-button

## Version 0.11.6

- Add video recirc widget and global SASS styles
- Add video recirc widget and global SASS styles

## Version 0.11.5

Expand All @@ -31,6 +35,16 @@
- TUNIC_REQUEST_TOKEN (ex: "12345")
- TUNIC_API_PATH (ex: "/api/v1/")

## Version 0.8.18

- Change default sort order of Instant Article feed to last modified time, than published date

## Version 0.8.17

- Add Glance JSON feed for content ingestion: `/feeds/glance.json`
- Instant article improvements
- Targeting + footer improvements

## Version 0.8.10

- Adds tag-based recirc fallback to `RecircViewSet` `GET` request
Expand Down
2 changes: 1 addition & 1 deletion bulbs/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.1.1"
__version__ = "2.0.0"
5 changes: 3 additions & 2 deletions bulbs/content/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from polymorphic import PolymorphicManager

from .filters import (
Authors, Evergreen, FeatureTypes, InstantArticle, Published, Status, Tags, VideohubChannel
Authors, Evergreen, FeatureTypes, InstantArticle, Published, Status, Tags,
VideohubChannel
)


Expand Down Expand Up @@ -42,7 +43,7 @@ def instant_articles(self, **kwargs):
Instant articles are configured via FeatureType. FeatureType.instant_article = True.
"""
eqs = self.search(**kwargs)
eqs = self.search(**kwargs).sort('-last_modified', '-published')
return eqs.filter(InstantArticle())

def sponsored(self, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% load betty %}

<!doctype HTML>
<html lang="en" prefix="op: http://media.facebook.com/op#">
<head>
Expand Down Expand Up @@ -49,11 +50,13 @@ <h3 class="op-kicker">
<iframe src="http://{{ absolute_uri }}{% url 'instant_article_analytics' pk=content.id %}?platform=ia&path={{ content.get_absolute_url }}"></iframe>
</figure>

<footer>
<small>
&copy; Copyright {% now "Y" %} Onion Inc. All rights reserved
</small>
</footer>
{% block article_footer %}
<footer>
<small>
&copy; Copyright {% now "Y" %} Onion Inc. All rights reserved
</small>
</footer>
{% endblock article_footer %}
</article>
</body>
</html>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
<language>en-us</language>
<lastBuildDate>{{ build_date|date:"D, d M Y H:i:s O" }}</lastBuildDate>
{% for content in page_obj.object_list %}<item>
<title>{{ content.feature_type }}: {{ content.title|striptags }}</title>
<title>{{ content.title|striptags }}</title>
<link>{{ content.feed_url }}</link>
<guid>{{ content.id }}</guid>
<pubDate>{{ content.published|date:"D, d M Y H:i:s O" }}</pubDate>
{% if content.authors.all %}<author>{% for author in content.authors.all %}{{ author.get_full_name }}{% if not forloop.last %}, {% endif %}{% endfor%}</author>{% endif %}
{% block authors %}{% if content.authors.all %}<author>{% for author in content.authors.all %}{{ author.get_full_name }}{% if not forloop.last %}, {% endif %}{% endfor%}</author>{% endif %}{% endblock authors %}
<description>
<![CDATA[
{{ content.description|safe }}
Expand Down
34 changes: 15 additions & 19 deletions bulbs/instant_articles/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from django.template import RequestContext, loader
from django.template.base import TemplateDoesNotExist
from django.views.decorators.cache import cache_control
from django.views.generic import TemplateView

from bulbs.content.models import Content
from bulbs.content.views import BaseContentDetailView
Expand Down Expand Up @@ -41,6 +40,7 @@ def get_context_data(self, *args, **kwargs):
content.instant_article_html = loader.render_to_string(
"instant_article/base_instant_article.html", content_ctx
)

return RequestContext(self.request, context)


Expand All @@ -58,33 +58,29 @@ def get_context_data(self, *args, **kwargs):
context = super(InstantArticleContentView, self).get_context_data(*args, **kwargs)
targeting = self.object.get_targeting()
context["targeting"] = targeting
context["targeting_params"] = "&".join(
["{}={}".format(key, value) for key, value in targeting.items()]
)
context["absolute_uri"] = self.request.META.get("HTTP_HOST", None)
return context


class InstantArticleAdView(TemplateView):
template_name = "instant_article/_instant_article_ad.html"
class InstantArticleAdView(InstantArticleContentView):
def get_template_names(self):
return [
"instant_article/_instant_article_ad.html",
]


class InstantArticleAnalyticsView(TemplateView):
template_name = "core/_analytics.html"
class InstantArticleAnalyticsView(InstantArticleContentView):
def get_template_names(self):
return [
"core/_analytics.html",
]

def get_context_data(self, *args, **kwargs):
context = {
"fire_pageview": True,
"platform": "Instant Articles"
}
context = super(InstantArticleAnalyticsView, self).get_context_data(*args, **kwargs)
context["fire_pageview"] = True
context["platform"] = "Instant Articles"
context["path"] = self.request.GET.get("path", "")
context["targeting"] = {
"dfp_site": self.request.GET.get("dfp_site", ""),
"dfp_feature": self.request.GET.get("dfp_feature", ""),
"dfp_contentid": self.request.GET.get("dfp_contentid", ""),
"dfp_pagetype": self.request.GET.get("dfp_pagetype", ""),
"dfp_slug": self.request.GET.get("dfp_slug", "")
}

return context


Expand Down
26 changes: 21 additions & 5 deletions tests/instant_articles/test_ia_ad.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
from django.contrib.auth import get_user_model
from django.core.urlresolvers import reverse
from django.template.defaultfilters import slugify
from django.test.client import Client
from django.test.utils import override_settings

from bulbs.content.models import FeatureType
from bulbs.utils.test import make_content, BaseIndexableTestCase

from example.testcontent.models import TestContentObj


DFP_SITE = "www.google.com"


class InstantArticleAdViewTests(BaseIndexableTestCase):
def setUp(self):
super(InstantArticleAdViewTests, self).setUp()
Expand All @@ -15,11 +21,21 @@ def setUp(self):
self.content = make_content(TestContentObj, feature_type=self.feature_type)
self.url = reverse("instant_article_ad", kwargs={"pk": self.content.pk})

User = get_user_model()
admin = self.admin = User.objects.create_user("admin", "[email protected]", "secret")
admin.is_staff = True
admin.save()

@override_settings(DFP_SITE=DFP_SITE)
def test_ad_unit(self):
self.client.login(username="admin", password="secret")

response = self.client.get(self.url)
targeting = response.context_data.get("targeting")

self.assertEqual(response.status_code, 200)
# TODO: bubble up ad formatting.
# self.assertInHTML(
# '<div class="dfp dfp-slot-instant-article-inread" data-ad-unit="instant-article-inread" >',
# str(response.content)
# )
self.assertEqual(DFP_SITE, targeting.get("dfp_site"))
self.assertEqual(slugify(self.feature_type), targeting.get("dfp_feature"))
self.assertEqual(self.content.id, targeting.get("dfp_contentid"))
self.assertEqual(self.content.__class__.__name__.lower(), targeting.get("dfp_pagetype"))
self.assertEqual(self.content.slug, targeting.get("dfp_slug"))
20 changes: 20 additions & 0 deletions tests/instant_articles/test_ia_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,26 @@ def test_pagination(self):
content_list = resp.context_data['content_list']
self.assertEqual(len(content_list), 100)

def test_sort_order(self):
content1 = TestContentObj.objects.create(
title='TestContentObj 1',
feature_type=self.news_in_brief,
published=timezone.now() - timezone.timedelta(days=1)
)
content2 = TestContentObj.objects.create(
title='TestContentObj 2',
feature_type=self.news_in_brief,
published=timezone.now() - timezone.timedelta(days=5)
)
TestContentObj.search_objects.refresh()
endpoint = reverse('instant_articles')
resp = self.client.get(endpoint)
self.assertEqual(resp.status_code, 200)
content_list = resp.context_data['content_list']
self.assertEqual(len(content_list), 2)
self.assertEqual(content_list[0].id, content2.id)
self.assertEqual(content_list[1].id, content1.id)

def test_project_not_base_template(self):
for i in range(100):
TestContentObj.objects.create(
Expand Down
20 changes: 20 additions & 0 deletions tests/instant_articles/test_instant_article_analytics.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
from django.contrib.auth import get_user_model
from django.core.urlresolvers import reverse
from django.template.defaultfilters import slugify
from django.test.client import Client
from django.test.utils import override_settings

from bulbs.content.models import FeatureType
from bulbs.utils.test import make_content, BaseIndexableTestCase

from example.testcontent.models import TestContentObj


DFP_SITE = "www.google.com"


class AnalyticsViewTests(BaseIndexableTestCase):

def setUp(self):
Expand All @@ -15,10 +21,24 @@ def setUp(self):
name="Ey go that way bruh", instant_article=True
)
self.content = make_content(TestContentObj, feature_type=self.feature_type)
User = get_user_model()
admin = self.admin = User.objects.create_user("admin", "[email protected]", "secret")
admin.is_staff = True
admin.save()

@override_settings(DFP_SITE=DFP_SITE)
def test_analytics(self):
self.client = Client()
self.client.login(username="admin", password="secret")
url = reverse("instant_article_analytics", kwargs={"pk": self.content.pk})

response = self.client.get(url)
targeting = response.context_data.get("targeting")

self.assertEqual(response.status_code, 200)
self.assertEqual("Instant Articles", response.context_data.get("platform"))
self.assertEqual(DFP_SITE, targeting.get("dfp_site"))
self.assertEqual(slugify(self.feature_type), targeting.get("dfp_feature"))
self.assertEqual(self.content.id, targeting.get("dfp_contentid"))
self.assertEqual(self.content.__class__.__name__.lower(), targeting.get("dfp_pagetype"))
self.assertEqual(self.content.slug, targeting.get("dfp_slug"))
41 changes: 41 additions & 0 deletions tests/instant_articles/test_instant_article_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from django.contrib.auth import get_user_model
from django.core.urlresolvers import reverse
from django.template.defaultfilters import slugify
from django.test.client import Client
from django.test.utils import override_settings

from bulbs.content.models import FeatureType
from bulbs.utils.test import make_content, BaseIndexableTestCase

from example.testcontent.models import TestContentObj


DFP_SITE = "www.google.com"


class InstantArticleAdViewTests(BaseIndexableTestCase):
def setUp(self):
super(InstantArticleAdViewTests, self).setUp()
self.client = Client()
self.feature_type = FeatureType.objects.create(name="AdBoys", instant_article=True)
self.content = make_content(TestContentObj, feature_type=self.feature_type)
self.url = reverse("instant_article", kwargs={"pk": self.content.pk})

User = get_user_model()
admin = self.admin = User.objects.create_user("admin", "[email protected]", "secret")
admin.is_staff = True
admin.save()

@override_settings(DFP_SITE=DFP_SITE)
def test_ad_unit(self):
self.client.login(username="admin", password="secret")

response = self.client.get(self.url)
targeting = response.context_data.get("targeting")

self.assertEqual(response.status_code, 200)
self.assertEqual(DFP_SITE, targeting.get("dfp_site"))
self.assertEqual(slugify(self.feature_type), targeting.get("dfp_feature"))
self.assertEqual(self.content.id, targeting.get("dfp_contentid"))
self.assertEqual(self.content.__class__.__name__.lower(), targeting.get("dfp_pagetype"))
self.assertEqual(self.content.slug, targeting.get("dfp_slug"))

0 comments on commit 330b5da

Please sign in to comment.