diff --git a/apps/devhub/models.py b/apps/devhub/models.py
index 388df5534b3..33545158d39 100644
--- a/apps/devhub/models.py
+++ b/apps/devhub/models.py
@@ -34,6 +34,15 @@ class Meta:
db_table = 'hubrsskeys'
+class BlogPost(amo.models.ModelBase):
+ title = models.CharField(max_length=255)
+ date_posted = models.DateField(default=datetime.now)
+ permalink = models.CharField(max_length=255)
+
+ class Meta:
+ db_table = 'blogposts'
+
+
class HubPromo(amo.models.ModelBase):
VISIBILITY_CHOICES = (
(0, 'Nobody'),
diff --git a/apps/devhub/templates/devhub/addons/dashboard.html b/apps/devhub/templates/devhub/addons/dashboard.html
index bc4de352d9d..f80f9406475 100644
--- a/apps/devhub/templates/devhub/addons/dashboard.html
+++ b/apps/devhub/templates/devhub/addons/dashboard.html
@@ -81,6 +81,8 @@
+
+
+ {% for post in blog_posts %}
+ -
+
+ {{ post.title }}
+
+
+ {{ post.date_posted|timesince }}
+
+
+ {% endfor %}
+
+
+ {{ _('View the blog ►') }}
+
diff --git a/apps/devhub/tests/test_models.py b/apps/devhub/tests/test_models.py
index c3fd85d56ff..f8f87e2bd51 100644
--- a/apps/devhub/tests/test_models.py
+++ b/apps/devhub/tests/test_models.py
@@ -9,7 +9,7 @@
import amo
from addons.models import Addon, AddonUser
from bandwagon.models import Collection
-from devhub.models import ActivityLog, AddonLog
+from devhub.models import ActivityLog, AddonLog, BlogPost
from tags.models import Tag
from files.models import File
from reviews.models import Review
@@ -281,3 +281,13 @@ def test_total_last_month(self):
eq_(len(result), 1)
eq_(result[0]['approval_count'], 1)
eq_(result[0]['user'], self.user.pk)
+
+
+class TestBlogPosts(test_utils.TestCase):
+
+ def test_blog_posts(self):
+ BlogPost.objects.create(title='hi')
+ bp = BlogPost.objects.all()
+ eq_(bp.count(), 1)
+ eq_(bp[0].title, "hi")
+
diff --git a/apps/devhub/tests/test_views.py b/apps/devhub/tests/test_views.py
index 9b492cff952..f9cd55bc380 100644
--- a/apps/devhub/tests/test_views.py
+++ b/apps/devhub/tests/test_views.py
@@ -32,7 +32,7 @@
from addons.utils import ReverseNameLookup
from applications.models import Application, AppVersion
from devhub.forms import ContribForm
-from devhub.models import ActivityLog, SubmitStep
+from devhub.models import ActivityLog, BlogPost, SubmitStep
from files.models import File, FileUpload, Platform
from files.tests.test_models import UploadTest as BaseUploadTest
from reviews.models import Review
@@ -207,6 +207,20 @@ def test_incomplete_addon_item(self):
assert not doc('.item[data-addonid=%s] h4 a' % a_pk)
assert doc('.item[data-addonid=%s] > p' % a_pk)
+ def test_dev_news(self):
+ self.clone_addon(1) # We need one to see this module
+ for i in xrange(7):
+ bp = BlogPost(title='hi %s' % i,
+ date_posted=datetime.now() - timedelta(days=i))
+ bp.save()
+ r = self.client.get(self.url)
+ doc = pq(r.content)
+
+ eq_(doc('.blog-posts').length, 1)
+ eq_(doc('.blog-posts li').length, 5)
+ eq_(doc('.blog-posts li a').eq(0).text(), "hi 0")
+ eq_(doc('.blog-posts li a').eq(4).text(), "hi 4")
+
class TestUpdateCompatibility(test_utils.TestCase):
fixtures = ['base/apps', 'base/users', 'base/addon_4594_a9',
diff --git a/apps/devhub/views.py b/apps/devhub/views.py
index 6dc145c14da..20433a46c11 100644
--- a/apps/devhub/views.py
+++ b/apps/devhub/views.py
@@ -38,7 +38,7 @@
from addons.decorators import addon_view
from addons.models import Addon, AddonUser
from addons.views import BaseFilter
-from devhub.models import ActivityLog, RssKey, SubmitStep
+from devhub.models import ActivityLog, BlogPost, RssKey, SubmitStep
from files.models import File, FileUpload
from files.utils import parse_addon
from translations.models import delete_translation
@@ -118,10 +118,11 @@ def index(request):
def dashboard(request):
addons, filter = addon_listing(request, addon_type=amo.ADDON_ANY)
addons = amo.utils.paginate(request, addons, per_page=10)
+ blog_posts = BlogPost.objects.order_by('-date_posted')[0:5]
data = dict(addons=addons, sorting=filter.field,
items=_get_items(None, request.amo_user.addons.all())[:4],
sort_opts=filter.opts, rss=_get_rss_feed(request),
- timestamp=int(time.time()))
+ blog_posts=blog_posts, timestamp=int(time.time()))
return jingo.render(request, 'devhub/addons/dashboard.html', data)
diff --git a/media/css/zamboni/developers.css b/media/css/zamboni/developers.css
index 7bccce2f393..5c467188510 100644
--- a/media/css/zamboni/developers.css
+++ b/media/css/zamboni/developers.css
@@ -805,11 +805,13 @@ a.more-actions:after:hover {
margin-bottom: 3em;
}
-.secondary .recent-activity>ul>li {
+.secondary .recent-activity>ul>li,
+.secondary .blog-posts>ul>li {
color: #555;
line-height: 1.2em;
margin-bottom: 0.75em;
}
+.secondary .blog-posts>ul>li a,
.secondary .recent-activity>ul>li a {
color: #333;
}
diff --git a/migrations/201-add-pk-to-blogpost.sql b/migrations/201-add-pk-to-blogpost.sql
new file mode 100644
index 00000000000..ffe84b7150e
--- /dev/null
+++ b/migrations/201-add-pk-to-blogpost.sql
@@ -0,0 +1,7 @@
+ALTER TABLE blogposts
+ ADD COLUMN id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY FIRST,
+ ADD COLUMN `modified` datetime NOT NULL default '0000-00-00 00:00:00',
+ ADD COLUMN `created` datetime NOT NULL default '0000-00-00 00:00:00';
+
+UPDATE blogposts SET modified=date_posted, created=date_posted;
+