Initial data/grid table for pending editor queue (bug 622172)

This commit is contained in:
Kumar McMillan 2011-01-14 17:41:22 -06:00
Родитель 27dd0de185
Коммит 17593c09da
16 изменённых файлов: 1060 добавлений и 8 удалений

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

@ -133,16 +133,65 @@
"model": "users.userprofile",
"pk": 4043307
},
{
"pk": 5497308,
"model": "auth.user",
"fields": {
"username": "editor@mozilla.com",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": "2010-12-29 08:47:36",
"groups": [],
"user_permissions": [],
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600",
"email": "editor@mozilla.com",
"date_joined": "2010-10-19 13:02:25"
}
},
{
"pk": 5497308,
"model": "users.userprofile",
"fields": {
"sandboxshown": false,
"display_collections_fav": false,
"display_collections": false,
"email": "editor@mozilla.com",
"notifycompat": false,
"username": "editor",
"failed_login_attempts": 0,
"deleted": false,
"emailhidden": false,
"last_login_attempt_ip": "127.0.0.1",
"last_login_attempt": "2010-11-16 10:51:34",
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600",
"nickname": "editor",
"resetcode_expires": "2010-10-19 13:02:25",
"created": "2010-10-19 13:02:25",
"modified": "2010-11-16 10:51:34",
"last_login_ip": "127.0.0.1",
"notifyevents": false,
"user": 5497308
}
},
{
"pk": 1,
"model": "access.group",
"fields": {
"rules": "*:*",
"modified": null,
"name": "Admins",
"created": "2007-03-05 16:06:55"
}
},
{
"pk": 2,
"model": "access.group",
"fields": {
"rules": "Editors:*",
"name": "Editors",
"created": "2007-03-05 16:06:55"
}
},
{
"pk": 10,
"model": "access.groupuser",
@ -150,5 +199,13 @@
"group": 1,
"user": 4043307
}
},
{
"pk": 258,
"model": "access.groupuser",
"fields": {
"group": 2,
"user": 5497308
}
}
]

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

@ -0,0 +1,574 @@
[
{
"pk": 758965,
"model": "translations.translation",
"fields": {
"localized_string_clean": "Some new features, several bug fixes.",
"created": "2009-12-04 19:02:24",
"locale": "en-US",
"id": 707988,
"localized_string": "Some new features, several bug fixes."
}
},
{
"pk": 1382212,
"model": "translations.translation",
"fields": {
"localized_string_clean": "[removed]",
"created": "2010-09-07 21:14:44",
"locale": "en-US",
"id": 1308444,
"localized_string": "[removed]"
}
},
{
"pk": 415971,
"model": "translations.translation",
"fields": {
"created": "2009-05-07 12:18:33",
"locale": "en-US",
"id": 377576,
"localized_string": "http://creativecommons.org/licenses/by-nd/3.0/"
}
},
{
"pk": 86573,
"model": "versions.version",
"fields": {
"license": 77,
"created": "2009-12-04 19:01:24",
"releasenotes": 707988,
"modified": "2009-12-04 19:02:31",
"version": "0.9.3",
"addon": 2286
}
},
{
"pk": 698131,
"model": "translations.translation",
"fields": {
"created": "2009-10-21 18:08:57",
"locale": "en-US",
"modified": "2009-11-27 18:58:18",
"id": 650750,
"localized_string": "[removed]"
}
},
{
"pk": 698130,
"model": "translations.translation",
"fields": {
"created": "2009-10-21 18:08:56",
"locale": "en-US",
"modified": "2009-12-15 07:00:03",
"id": 650749,
"localized_string": "[removed]"
}
},
{
"pk": 108574,
"model": "translations.translation",
"fields": {
"created": "2007-10-15 13:17:11",
"locale": "en-US",
"modified": "2009-04-06 08:21:04",
"id": 75558,
"localized_string": "[removed]"
}
},
{
"pk": 19335,
"model": "translations.translation",
"fields": {
"localized_string_clean": "[removed]",
"created": "2007-03-05 13:10:33",
"locale": "en-US",
"modified": "2010-09-28 15:30:51",
"id": 9748,
"localized_string": "[removed]"
}
},
{
"pk": 19338,
"model": "translations.translation",
"fields": {
"localized_string_clean": "[removed]",
"created": "2007-03-05 13:10:33",
"locale": "en-US",
"modified": "2009-05-14 01:46:07",
"id": 9749,
"localized_string": "[removed]"
}
},
{
"pk": 19327,
"model": "translations.translation",
"fields": {
"localized_string_clean": "[removed]",
"created": "2007-03-05 13:10:33",
"locale": "en-US",
"modified": "2010-09-28 15:30:51",
"id": 9747,
"localized_string": "[removed]"
}
},
{
"pk": 241547,
"model": "translations.translation",
"fields": {
"created": "2008-08-02 18:00:50",
"locale": "en-US",
"modified": "2010-09-28 13:44:03",
"id": 204517,
"localized_string": "http://www.the-converter.co/feedback.php?src=a"
}
},
{
"pk": 241546,
"model": "translations.translation",
"fields": {
"created": "2008-08-02 18:00:50",
"locale": "en-US",
"modified": "2009-04-06 08:19:43",
"id": 204516,
"localized_string": "none@nowhere"
}
},
{
"pk": 19317,
"model": "translations.translation",
"fields": {
"created": "2007-03-05 13:10:33",
"locale": "en-US",
"modified": "2010-09-28 13:44:03",
"id": 9746,
"localized_string": "http://www.the-converter.co/"
}
},
{
"pk": 19307,
"model": "translations.translation",
"fields": {
"created": "2007-03-05 13:10:33",
"locale": "en-US",
"modified": "2009-04-06 08:21:04",
"id": 9745,
"localized_string": "Converter"
}
},
{
"pk": 117129,
"model": "versions.version",
"fields": {
"license": 5,
"created": "2010-09-07 21:13:56",
"releasenotes": 1308444,
"approvalnotes": "[removed]",
"modified": "2010-09-07 21:14:45",
"version": "3.800",
"addon": 52369
}
},
{
"pk": 881229,
"model": "translations.translation",
"fields": {
"created": "2010-02-09 10:45:02",
"locale": "en-US",
"modified": null,
"id": 823673,
"localized_string": "[removed]"
}
},
{
"pk": 881228,
"model": "translations.translation",
"fields": {
"created": "2010-02-09 10:45:00",
"locale": "en-US",
"id": 823672,
"localized_string": "[removed]"
}
},
{
"pk": 1242341,
"model": "translations.translation",
"fields": {
"localized_string_clean": "[removed]",
"created": "2010-07-02 05:42:18",
"locale": "en-US",
"id": 1172842,
"localized_string": "[removed]"
}
},
{
"pk": 753533,
"model": "translations.translation",
"fields": {
"localized_string_clean": "[removed]",
"created": "2009-11-30 10:08:41",
"locale": "en-US",
"modified": "2010-07-02 05:42:17",
"id": 702814,
"localized_string": "[removed]"
}
},
{
"pk": 753537,
"model": "translations.translation",
"fields": {
"localized_string_clean": "[removed]",
"created": "2009-11-30 10:15:03",
"locale": "en-US",
"modified": "2010-07-02 05:42:18",
"id": 702818,
"localized_string": "[removed]"
}
},
{
"pk": 1242343,
"model": "translations.translation",
"fields": {
"created": "2010-07-02 05:44:04",
"locale": "en-US",
"modified": null,
"id": 1172844,
"localized_string": "http://Facebook.com/betterfb"
}
},
{
"pk": 1242342,
"model": "translations.translation",
"fields": {
"created": "2010-07-02 05:44:04",
"locale": "en-US",
"id": 1172843,
"localized_string": "none@nowhere"
}
},
{
"pk": 753531,
"model": "translations.translation",
"fields": {
"created": "2009-11-30 10:08:41",
"locale": "en-US",
"modified": "2010-07-02 05:44:03",
"id": 702812,
"localized_string": "http://BetterFacebook.net"
}
},
{
"pk": 753532,
"model": "translations.translation",
"fields": {
"created": "2009-11-30 10:08:41",
"locale": "en-US",
"id": 702813,
"localized_string": "Better Facebook!"
}
},
{
"pk": 1442595,
"model": "translations.translation",
"fields": {
"localized_string_clean": "[removed]",
"created": "2010-09-26 08:07:00",
"locale": "en-US",
"id": 1366941,
"localized_string": "[removed]"
}
},
{
"pk": 77,
"model": "versions.license",
"fields": {
"created": "2009-05-07 12:18:33",
"text": 377576,
"modified": "2009-05-07 12:18:33",
"some_rights": false,
"builtin": 0,
"on_form": false
}
},
{
"pk": 5,
"model": "versions.license",
"fields": {
"created": "2009-04-30 22:29:53",
"modified": "2009-04-30 22:29:53",
"some_rights": false,
"builtin": 1,
"on_form": false
}
},
{
"pk": 347,
"model": "applications.appversion",
"fields": {
"version_int": 4000000106100,
"application": 1,
"version": "4.0b6"
}
},
{
"pk": 97,
"model": "applications.appversion",
"fields": {
"version_int": 2000000200100,
"application": 1,
"version": "2.0",
"created": "2007-03-05 13:09:26"
}
},
{
"pk": 2286,
"model": "addons.addon",
"fields": {
"dev_agreement": true,
"eula": 75558,
"last_updated": "2009-12-08 22:07:46",
"view_source": false,
"enable_thankyou": false,
"total_downloads": 297990,
"developer_comments": 9748,
"_current_version": 86573,
"average_daily_downloads": 249,
"admin_review_type": 1,
"the_future": 650750,
"trusted": false,
"total_contributions": "0.00",
"binary": false,
"guid": "{8B72860F-C5F8-4286-865E-D2C2DB98A9E6}",
"weekly_downloads": 2690,
"support_url": 204517,
"disabled_by_user": false,
"paypal_id": "none@nowhere.com",
"average_rating": 4.7045000000000003,
"wants_contributions": false,
"average_daily_users": 19788,
"bayesian_rating": 4.6212799999999996,
"share_count": 3,
"homepage": 9746,
"support_email": 204516,
"public_stats": false,
"status": 4,
"description": 9747,
"default_locale": "en-US",
"get_satisfaction_product": "",
"prerelease": false,
"admin_review": true,
"slug": "",
"external_software": false,
"highest_status": 4,
"get_satisfaction_company": "",
"name": 9745,
"created": "2006-03-26 05:55:23",
"type": 1,
"icon_type": "image/png",
"annoying": 1,
"modified": "2011-01-18 15:05:59",
"summary": 9749,
"site_specific": false,
"total_reviews": 44,
"the_reason": 650749,
"nomination_date": "2009-04-06 08:21:09"
}
},
{
"pk": 350,
"model": "applications.appversion",
"fields": {
"version_int": 4000000108000,
"application": 1,
"version": "4.0b8pre"
}
},
{
"pk": 233,
"model": "applications.appversion",
"fields": {
"version_int": 3000000200100,
"application": 1,
"version": "3.0"
}
},
{
"pk": 1,
"model": "applications.application",
"fields": {
"guid": "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}",
"modified": "2008-11-03 15:34:59",
"created": "2007-03-05 13:09:26"
}
},
{
"pk": 52369,
"model": "addons.addon",
"fields": {
"dev_agreement": true,
"last_updated": "2010-09-08 09:38:22",
"view_source": true,
"enable_thankyou": false,
"total_downloads": 47160,
"developer_comments": 1172842,
"_current_version": 117129,
"average_daily_downloads": 152,
"admin_review_type": 1,
"the_future": 823673,
"trusted": false,
"total_contributions": "64.00",
"binary": false,
"guid": "none@nowhere.com",
"weekly_downloads": 1099,
"support_url": 1172844,
"disabled_by_user": false,
"paypal_id": "none@nowhere.com",
"average_rating": 3.1818,
"wants_contributions": true,
"average_daily_users": 4436,
"bayesian_rating": 3.10846,
"share_count": 0,
"homepage": 702812,
"support_email": 1172843,
"public_stats": true,
"status": 4,
"description": 702818,
"default_locale": "en-US",
"get_satisfaction_product": "",
"prerelease": false,
"admin_review": false,
"slug": "better-facebook",
"external_software": false,
"highest_status": 4,
"get_satisfaction_company": "",
"name": 702813,
"created": "2009-11-30 10:08:41",
"type": 1,
"icon_type": "image/png",
"annoying": 2,
"modified": "2011-01-18 15:05:10",
"summary": 702814,
"suggested_amount": "5.00",
"site_specific": true,
"total_reviews": 33,
"the_reason": 823672,
"nomination_date": "2010-01-19 07:18:11"
}
},
{
"pk": 1,
"model": "files.platform",
"fields": {
"icontype": "",
"modified": "2008-04-07 08:16:55",
"created": "2007-03-05 13:09:27"
}
},
{
"pk": 118409,
"model": "versions.version",
"fields": {
"license": 77,
"created": "2010-09-26 08:05:40",
"releasenotes": 1366941,
"approvalnotes": "[removed]",
"modified": "2010-10-05 06:59:49",
"version": "1.0.0",
"addon": 2286
}
},
{
"pk": 118467,
"model": "versions.version",
"fields": {
"license": 5,
"created": "2010-09-27 08:44:01",
"approvalnotes": "",
"modified": "2010-09-27 08:44:53",
"version": "4.105",
"addon": 52369
}
},
{
"pk": 91808,
"model": "versions.applicationsversions",
"fields": {
"application": 1,
"max": 347,
"version": 118409,
"min": 97
}
},
{
"pk": 77311474,
"model": "versions.versionsummary",
"fields": {
"min": 97,
"max": 291,
"created": "2010-09-26 08:05:40",
"modified": "2010-10-01 20:13:21",
"application": 1,
"version": 118409,
"addon": 2286
}
},
{
"pk": 100455,
"model": "files.file",
"fields": {
"status": 1,
"codereview": false,
"no_restart": false,
"hash": "sha256:88425938728b0f6e68205c86121d5e9c83c98d4982690d9fdd3f2025e93a0451",
"created": "2010-10-05 06:59:17",
"jetpack": false,
"modified": "2010-10-05 06:59:49",
"filename": "converter-1.0.0-fx.xpi",
"platform": 1,
"version": 118409,
"datestatuschanged": "2010-10-05 06:59:07",
"size": 79
}
},
{
"pk": 91884,
"model": "versions.applicationsversions",
"fields": {
"application": 1,
"max": 350,
"version": 118467,
"min": 233
}
},
{
"pk": 77322711,
"model": "versions.versionsummary",
"fields": {
"min": 233,
"max": 350,
"created": "2010-09-27 08:44:01",
"modified": "2010-09-27 08:44:53",
"application": 1,
"version": 118467,
"addon": 52369
}
},
{
"pk": 99984,
"model": "files.file",
"fields": {
"status": 1,
"codereview": false,
"no_restart": false,
"hash": "sha256:6f26b5f65fc0f89b997cf9c84a6d8627d1b8e89f0041c4010223db8b1c0e93e3",
"created": "2010-09-27 08:44:01",
"jetpack": false,
"modified": "2010-09-27 08:44:52",
"filename": "better_facebook!-4.105-fx.xpi",
"platform": 1,
"version": 118467,
"datestatuschanged": "2010-09-27 08:43:55",
"size": 72
}
}
]

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

@ -1,8 +1,15 @@
import os
from django.conf import settings
import django_tables as tables
import jinja2
from jingo import register
from tower import ugettext as _
from tower import ugettext_lazy as _, ungettext as ngettext
import amo
from editors.models import ViewEditorQueue
from amo.helpers import page_title
from amo.urlresolvers import reverse
@register.function
@ -15,3 +22,70 @@ def editor_page_title(context, title=None, addon=None):
devhub = _('Editor Tools')
title = '%s :: %s' % (title, devhub) if title else devhub
return page_title(context, title)
class ViewEditorQueueTable(tables.ModelTable):
addon_name = tables.Column(verbose_name=_(u'Addon'))
addon_type_id = tables.Column(verbose_name=_(u'Type'))
days_since_created = tables.Column(verbose_name=_(u'Waiting Time'))
flags = tables.Column()
applications = tables.Column()
additional_info = tables.Column(verbose_name=_(u'Additional Information'))
class Meta:
model = ViewEditorQueue
sortable = True
exclude = ['id', 'version_id', 'admin_review',
'hours_since_created',
'days_since_nominated', 'hours_since_nominated',
'platform_id', 'is_site_specific',
'version_max', 'version_min', 'version_apps']
def render_addon_name(self, row):
return u'<a href="%s">%s</a>' % (reverse('editors.review',
args=[row.version_id]),
jinja2.escape(row.addon_name))
def render_addon_type_id(self, row):
return amo.ADDON_TYPE[row.addon_type_id]
def render_additional_info(self, row):
if row.is_site_specific:
r = _(u'Site Specific')
elif row.platform_id != amo.PLATFORM_ALL.id:
# L10n: first argument is the platform such as Linux, Mac OS X
r = _(u'{0} only').format(amo.PLATFORMS[row.platform_id].name)
else:
r = ''
return jinja2.escape(r)
def render_applications(self, row):
app_ids = self._explode_concat(row.applications)
# _apps = self._explode_concat(row.version_apps)
# version_min = dict(zip(_apps, self._explode_concat(row.version_min)))
# version_max = dict(zip(_apps, self._explode_concat(row.version_max)))
icon = u'<div class="app-icon ed-sprite-%s"></div>'
return u' '.join(icon % amo.APPS_ALL[i].short for i in app_ids)
def render_days_since_created(self, row):
if row.days_since_created == 1:
# L10n: first argument is number of hours
r = ngettext(u'{0} hour', u'{0} hours',
row.hours_since_created).format(
row.hours_since_created)
else:
# L10n: first argument is number of days
r = _(u'%d days') % row.days_since_created
return jinja2.escape(r)
def render_flags(self, row):
if row.admin_review:
# TODO(Kumar) display Admin Review on hover
return u'<div class="app-icon ed-sprite-admin-review"></div>'
else:
return ''
def _explode_concat(self, value):
"""Returns list of IDs in a MySQL GROUP_CONCAT(field) result."""
return [int(i) for i in value.split(',')]

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

@ -1,3 +1,10 @@
import os
from django.conf import settings
from django.db import connection, models
from django.db.models.signals import post_syncdb
from tower import ugettext_lazy as _
import amo.models
from translations.fields import TranslatedField
@ -12,3 +19,36 @@ class CannedResponse(amo.models.ModelBase):
def __unicode__(self):
return unicode(self.name)
class ViewEditorQueue(models.Model):
# id is Addon ID.
version_id = models.PositiveIntegerField()
addon_name = models.CharField(max_length=255)
addon_type_id = models.PositiveIntegerField()
admin_review = models.BooleanField()
is_site_specific = models.BooleanField()
platform_id = models.PositiveIntegerField()
days_since_created = models.PositiveIntegerField()
hours_since_created = models.PositiveIntegerField()
days_since_nominated = models.PositiveIntegerField(null=True)
hours_since_nominated = models.PositiveIntegerField(null=True)
applications = models.CharField(max_length=255)
# version_apps = models.CharField(max_length=255)
# version_min = models.CharField(max_length=255)
# version_max = models.CharField(max_length=255)
class Meta:
db_table = 'view_editor_queue'
managed = False
def create_view(sender, **kw):
cursor = connection.cursor()
ddl = os.path.join(settings.ROOT, 'migrations',
'129-view-editor-queue.sql')
with open(ddl, 'r') as f:
cursor.execute(f.read())
post_syncdb.connect(create_view)

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

@ -3,7 +3,7 @@
{% block title %}{{ editor_page_title() }}{% endblock %}
{% block extrahead %}
{{ css('zamboni/devhub') }}
{{ css('zamboni/editors') }}
{% endblock %}
{% block navbar %}

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

@ -0,0 +1,36 @@
{% extends "editors/base.html" %}
{% block content %}
{{ page|paginator }}
<table class="data-grid">
<thead>
<tr>
{% for column in table.columns %}
{% if column.is_ordered_reverse %}
{% set cls, sprite = 'ordered', 'desc' %}
{% elif column.is_ordered_straight %}
{% set cls, sprite = 'ordered', 'asc' %}
{% else %}
{% set cls, sprite = '', 'both' %}
{% endif %}
<th class="{{ cls }}"><a href="?sort={{ column.name_toggled }}">
{{ column }}
<div class="sort-icon ed-sprite-sort-{{ sprite }}"></div></a>
</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in page.object_list %}
<tr>
{% for value in row %}
<td>{{ value|xssafe }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{{ page|paginator }}
{% endblock %}

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

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

@ -0,0 +1,81 @@
# -*- coding: utf8 -*-
import os
from mock import Mock
from nose.tools import eq_
from pyquery import PyQuery as pq
import test_utils
import amo
from amo.urlresolvers import reverse
from editors.helpers import ViewEditorQueueTable
class TestViewEditorQueueTable(test_utils.TestCase):
def setUp(self):
super(TestViewEditorQueueTable, self).setUp()
qs = Mock()
self.table = ViewEditorQueueTable(qs)
def test_addon_name(self):
row = Mock()
row.addon_name = 'フォクすけといっしょ 0.12'.decode('utf8')
row.version_id = 1234
a = pq(self.table.render_addon_name(row))
eq_(a.attr('href'),
reverse('editors.review', args=[row.version_id]))
eq_(a.text(), row.addon_name)
def test_addon_type_id(self):
row = Mock()
row.addon_type_id = amo.ADDON_THEME
eq_(unicode(self.table.render_addon_type_id(row)), u'Theme')
def test_additional_info_site_specific(self):
row = Mock()
row.is_site_specific = True
eq_(self.table.render_additional_info(row), u'Site Specific')
def test_additional_info_for_platform(self):
row = Mock()
row.is_site_specific = False
row.platform_id = amo.PLATFORM_LINUX.id
eq_(self.table.render_additional_info(row), u'Linux only')
def test_additional_info_for_all_platforms(self):
row = Mock()
row.is_site_specific = False
row.platform_id = amo.PLATFORM_ALL.id
eq_(self.table.render_additional_info(row), u'')
def test_applications(self):
row = Mock()
row.applications = ','.join([str(amo.FIREFOX.id),
str(amo.THUNDERBIRD.id)])
doc = pq(self.table.render_applications(row))
eq_(sorted(a.attrib['class'] for a in doc('div div')),
['app-icon ed-sprite-firefox', 'app-icon ed-sprite-thunderbird'])
def test_waiting_time_in_days(self):
row = Mock()
row.days_since_created = 10
row.hours_since_created = 10 * 24
eq_(self.table.render_days_since_created(row), u'10 days')
def test_waiting_time_in_hours(self):
row = Mock()
row.days_since_created = 1
row.hours_since_created = 22
eq_(self.table.render_days_since_created(row), u'22 hours')
def test_flags_admin_review(self):
row = Mock()
row.admin_review = True
doc = pq(self.table.render_flags(row))
eq_(doc('div').attr('class'), 'app-icon ed-sprite-admin-review')
def test_no_flags(self):
row = Mock()
row.admin_review = False
eq_(self.table.render_flags(row), '')

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

@ -0,0 +1,46 @@
# -*- coding: utf8 -*-
import re
from nose.tools import eq_
from pyquery import PyQuery as pq
import test_utils
import amo
from amo.urlresolvers import reverse
class EditorTest(test_utils.TestCase):
def login_as_editor(self):
assert self.client.login(username='editor@mozilla.com',
password='password')
class TestPendingQueue(EditorTest):
fixtures = ['base/users', 'editors/pending-queue']
def setUp(self):
super(TestPendingQueue, self).setUp()
self.login_as_editor()
def test_only_viewable_by_editor(self):
self.client.logout()
assert self.client.login(username='regular@mozilla.com',
password='password')
r = self.client.get(reverse('editors.queue_pending'))
eq_(r.status_code, 403)
def test_grid(self):
r = self.client.get(reverse('editors.queue_pending'))
eq_(r.status_code, 200)
doc = pq(r.content)
eq_(doc('div.section table tr th:eq(0)').text(), u'Addon')
eq_(doc('div.section table tr th:eq(1)').text(), u'Type')
eq_(doc('div.section table tr th:eq(2)').text(), u'Waiting Time')
eq_(doc('div.section table tr th:eq(3)').text(), u'Applications')
eq_(doc('div.section table tr th:eq(4)').text(), u'Flags')
eq_(doc('div.section table tr th:eq(5)').text(),
u'Additional Information')
# Smoke test the grid. More tests in test_helpers.py
eq_(doc('div.section table tr td:eq(0)').text(), u'Converter 1.0.0')
eq_(doc('div.section table tr td a:eq(0)').attr('href'),
reverse('editors.review', args=['118409']))

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

@ -4,5 +4,9 @@ from . import views
# All URLs under /editors/
urlpatterns = patterns('',
url('^$', views.home, name='editors.home'),
url(r'^queue$', views.queue, name='editors.queue'),
url(r'^queue/pending$', views.queue_pending,
name='editors.queue_pending'),
url(r'^review/(?P<version_id>\d+)$', views.review, name='editors.review'),
url(r'^$', views.home, name='editors.home'),
)

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

@ -1,11 +1,50 @@
import functools
from django import http
from django.shortcuts import redirect
from django.core.paginator import Paginator
import jingo
from access import acl
from amo.decorators import login_required
from editors.models import ViewEditorQueue
from editors.helpers import ViewEditorQueueTable
from amo.utils import paginate
from amo.urlresolvers import reverse
@login_required
def editor_required(func):
"""Requires the user to be logged in as an editor or admin."""
@functools.wraps(func)
@login_required
def wrapper(request, *args, **kw):
if acl.action_allowed(request, 'Editors', '%'):
return func(request, *args, **kw)
else:
return http.HttpResponseForbidden()
return wrapper
@editor_required
def home(request):
# @TODO: This needs @editor_required!
return jingo.render(request, 'editors/home.html', {})
@editor_required
def queue(request):
return redirect(reverse('editors.queue_pending'))
@editor_required
def queue_pending(request):
qs = ViewEditorQueue.objects.all()
order_by = request.GET.get('sort', '-days_since_created')
table = ViewEditorQueueTable(qs, order_by=order_by)
page = paginate(request, table.rows, per_page=45)
return jingo.render(request, 'editors/queue/pending.html',
{'table': table, 'page': page})
@editor_required
def review(request, version_id):
raise NotImplementedError

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

@ -0,0 +1,56 @@
.app-icon {
float: left;
margin-right: 4px;
background: url(../../img/developers/editors-sprite.png) no-repeat top left;
width: 16px; height: 16px;
}
.ed-sprite-admin-review { background-position: 0 0; }
.ed-sprite-firefox { background-position: 0 -66px; }
.ed-sprite-mobile { background-position: 0 -132px; }
.ed-sprite-mz { background-position: 0 -198px; }
.ed-sprite-mozilla { background-position: 0 -198px; }
.ed-sprite-seamonkey { background-position: 0 -264px; }
.ed-sprite-sunbird { background-position: 0 -497px; }
.ed-sprite-thunderbird { background-position: 0 -563px; }
.sort-icon {
margin-top: 0.5em;
background: url(../../img/developers/editors-sprite.png) no-repeat top left;
float: right;
}
.ed-sprite-sort-asc {
background-position: 0 -330px;
width: 21px; height: 4px; }
.ed-sprite-sort-both {
background-position: 0 -384px;
width: 21px; height: 9px; }
.ed-sprite-sort-desc {
background-position: 0 -443px;
width: 21px; height: 4px; }
table.data-grid {
border: 1px solid #666666;
}
table.data-grid tr th a:active,
table.data-grid tr th a:hover,
table.data-grid tr th a:visited {
color: #3D6DB5;
}
table.data-grid tr th.ordered {
background-color: #D0E8F4;
}
table.data-grid tr th.ordered a:active,
table.data-grid tr th.ordered a:hover,
table.data-grid tr th.ordered a:visited {
color: #003595;
}
table.data-grid tr th, table.data-grid tr td {
padding: 0.5em;
}
table.data-grid tr td {
border-top: 1px solid #DDDDDD;
}
table.data-grid tbody tr:nth-child(odd) {
background-color: #F3F3F3;
}
table.data-grid tbody tr:nth-child(even) {
background-color: #FFFFFF;
}

Двоичные данные
media/img/developers/editors-sprite.png Normal file

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

После

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

Двоичные данные
media/img/developers/mozilla.png Normal file

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

После

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

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

@ -0,0 +1,42 @@
-- bug 622172
CREATE OR REPLACE VIEW view_editor_queue AS
SELECT
addons.id,
versions.id as version_id,
CONCAT_WS(' ', tr.localized_string,
versions.version) as addon_name,
addons.addontype_id as addon_type_id,
addons.adminreview as admin_review,
addons.sitespecific as is_site_specific,
files.platform_id,
versions.created as version_created,
addons.nominationdate as nomination_date,
TIMESTAMPDIFF(DAY, versions.created,
NOW()) as days_since_created,
TIMESTAMPDIFF(HOUR, versions.created,
NOW()) as hours_since_created,
TIMESTAMPDIFF(DAY, addons.nominationdate,
NOW()) as days_since_nominated,
TIMESTAMPDIFF(HOUR, addons.nominationdate,
NOW()) as hours_since_nominated,
GROUP_CONCAT(apps.application_id) as applications
-- ,
-- GROUP_CONCAT(vs.application_id) as version_apps,
-- GROUP_CONCAT(app_versions_min.version) as version_min,
-- GROUP_CONCAT(app_versions_max.version) as version_max
FROM files
JOIN versions ON (files.version_id = versions.id)
JOIN addons ON (versions.addon_id = addons.id)
JOIN applications_versions as apps on versions.id = apps.version_id
JOIN translations AS tr ON (tr.id = addons.name
AND tr.locale = addons.defaultlocale)
-- JOIN versions_summary as vs ON
-- (versions.id = vs.version_id
-- AND vs.application_id = apps.application_id)
-- JOIN versions as app_versions_min ON app_versions_min.id = vs.min
-- JOIN versions as app_versions_max ON app_versions_min.id = vs.max
-- STATUS_SANDBOX in remora, STATUS_UNREVIEWED in zamboni
WHERE files.status=1
-- STATUS_PUBLIC
AND addons.status=4
GROUP BY 1, 2;

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

@ -369,6 +369,9 @@ MINIFY_BUNDLES = {
'zamboni/devhub': (
'css/zamboni/developers.css',
),
'zamboni/editors': (
'css/zamboni/editors.css',
),
},
'js': {
# JS files common to the entire site.