Skip to content
This repository has been archived by the owner on Jun 12, 2021. It is now read-only.

Commit

Permalink
Merge branch 'feature/bug674526-accounts-dashtags-l10nstats-webby' in…
Browse files Browse the repository at this point in the history
…to develop
  • Loading branch information
peterbe committed Aug 8, 2011
2 parents 89032d5 + dd8f240 commit 54f0318
Show file tree
Hide file tree
Showing 18 changed files with 134 additions and 100 deletions.
1 change: 1 addition & 0 deletions apps/accounts/context_processors.py
Expand Up @@ -37,6 +37,7 @@

from forms import AuthenticationForm


def accounts(request):
login_form = AuthenticationForm()
return {'login_form': login_form}
1 change: 1 addition & 0 deletions apps/accounts/forms.py
Expand Up @@ -38,6 +38,7 @@
from django import forms
import django.contrib.auth.forms


class AuthenticationForm(django.contrib.auth.forms.AuthenticationForm):
"""override the authentication form because we use the email address as the
key to authentication."""
Expand Down
4 changes: 2 additions & 2 deletions apps/accounts/tests.py
Expand Up @@ -40,10 +40,10 @@
from django.test import TestCase
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.conf import settings
from django.utils import simplejson as json
from nose.tools import eq_, ok_


class AccountsTestCase(TestCase):

def test_login_long_username(self):
Expand Down Expand Up @@ -127,7 +127,7 @@ def test_logout(self):
assert self.client.login(username=user.username,
password='secret')

response = self.client.get(url) # note: it's GET
response = self.client.get(url) # note: it's GET
eq_(response.status_code, 302)
path = urlparse(response['Location']).path
eq_(path, '/')
Expand Down
2 changes: 1 addition & 1 deletion apps/accounts/urls.py
Expand Up @@ -36,7 +36,7 @@

'Url mappings for accounts app'

from django.conf.urls.defaults import *
from django.conf.urls.defaults import patterns

urlpatterns = patterns('accounts.views',
(r'^login', 'login'),
Expand Down
5 changes: 1 addition & 4 deletions apps/accounts/views.py
Expand Up @@ -39,15 +39,11 @@


from django.contrib.auth.views import REDIRECT_FIELD_NAME
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.template import RequestContext
from django.views.decorators import cache
from django.core.context_processors import csrf
from django.utils import simplejson as json
from django.views.decorators.csrf import csrf_protect
from django.contrib.auth.views import login as django_login

from forms import AuthenticationForm


Expand All @@ -65,6 +61,7 @@ def login(request):

return response


@cache.cache_control(private=True)
def user_json(request):
result = {}
Expand Down
10 changes: 7 additions & 3 deletions apps/dashtags/templatetags/recurse.py
Expand Up @@ -38,15 +38,13 @@
'''

from django import template
from django.utils.safestring import mark_safe
from django.utils.html import conditional_escape
from django.core.urlresolvers import reverse


register = template.Library()

templates_stack = []


@register.tag(name="recurse_children")
def do_recurse(parser, token):
nodelist = parser.create_nodelist()
Expand All @@ -57,23 +55,29 @@ def do_recurse(parser, token):
parser.delete_first_token()
return node


class RecurseNode(template.Node):
def __init__(self, nodelist):
self._nodelist = nodelist

def render(self, context):
output = self._nodelist.render(context)
return output


@register.tag(name="recurse")
def do_depth(parser, token):
tag_name, nodes, _as, varname = token.split_contents()
return DepthNode(nodes, varname)


class DepthNode(template.Node):

def __init__(self, nodes, varname):
self.vals = template.Variable(nodes)
self.varname = varname
self._nodelist = templates_stack[-1]

def render(self, context):
nodes = self.vals.resolve(context)
d = context.push()
Expand Down
19 changes: 11 additions & 8 deletions apps/dashtags/templatetags/simile.py
Expand Up @@ -2,30 +2,30 @@
'''

from django import template
from django.utils.safestring import mark_safe
from django.core.urlresolvers import reverse


register = template.Library()


def simile(parser, token, apps, forceBundle=False):
"""Generic function for simile api inclusions
"""

args = token.split_contents()[1:]
simileurl = reverse('static', kwargs={'path':'simile/'})
opts = {'bundle':'true', 'autoCreate': 'true'}
simileurl = reverse('static', kwargs={'path': 'simile/'})
opts = {'bundle': 'true', 'autoCreate': 'true'}
for arg in args:
try:
k, v = arg.split('=', 1)
if k in opts:
opts[k] = v
except ValueError:
pass
bundle = opts['bundle']=='false' and 'bundle=false' or None
bundle = opts['bundle'] == 'false' and 'bundle=false' or None
if bundle is None and forceBundle:
bundle = 'bundle=true'
autoCreate = opts['autoCreate']=='false' and 'autoCreate=false' or None
autoCreate = opts['autoCreate'] == 'false' and 'autoCreate=false' or None
ajax_params = '&'.join(filter(None, [bundle]))
if ajax_params:
ajax_params = '?' + ajax_params
Expand All @@ -38,7 +38,8 @@ def simile(parser, token, apps, forceBundle=False):
script_tail = '''
})();
</script>
<script type="text/javascript" src="%(base)sajax/simile-ajax-api.js%(params)s"></script>
<script type="text/javascript" '''\
'''src="%(base)sajax/simile-ajax-api.js%(params)s"></script>
''' % {'base': simileurl, 'params': ajax_params}
loaders = []
next = None
Expand All @@ -48,7 +49,9 @@ def simile(parser, token, apps, forceBundle=False):
if next is not None:
loaders += [' window.SimileAjax_onLoad = load_%s;' % next]
loaders += [
' SimileAjax.includeJavascriptFile(document, "%(base)s%(app)s/%(app)s-api.js%(params)s");' % {'base': simileurl, 'app': app, 'params': params},
' SimileAjax.includeJavascriptFile(document, "%(base)s%(app)s/'\
'%(app)s-api.js%(params)s");' % \
{'base': simileurl, 'app': app, 'params': params},
'};']
next = app
params = ajax_params
Expand All @@ -70,4 +73,4 @@ def timeplot(parser, token):
Includes timeline.
"""
return simile(parser, token, ('timeline','timeplot'), forceBundle=True)
return simile(parser, token, ('timeline', 'timeplot'), forceBundle=True)
18 changes: 10 additions & 8 deletions apps/dashtags/tests.py
Expand Up @@ -2,12 +2,16 @@
import unittest
from django import template


class Recurse(TestCase):
"""Test the three tags for recursive templates, recurse, recurse_children, endrecurse."""
"""Test the three tags for recursive templates, recurse, recurse_children,
endrecurse."""
# no fixtures = []
def test_recurse(self):
t = template.Template("""{% load recurse %}{% recurse_children %}{% for item in items %}{{ item.value }}
{% if item.children %}{% recurse item.children as items %}{% endif %}{% endfor %}{% endrecurse %}""")
t = template.Template("""{% load recurse %}{% recurse_children %}
{% for item in items %}{{ item.value }}
{% if item.children %}{% recurse item.children as items %}{% endif %}
{% endfor %}{% endrecurse %}""")
d = {"items":
[{
"value": "root",
Expand All @@ -26,11 +30,9 @@ def test_recurse(self):
]}
c = template.Context(d)
out = t.render(c)
self.assertEqual(out, """root
leaf1
leafleaf1
leaf2
""")
self.assertEqual(out,
u'\nroot\n\n leaf1\n\n leafleaf1\n\n\n leaf2\n\n\n')


class Simile(unittest.TestCase):
"""Test the simile tags to include script tags for exhibit and timeplot."""
Expand Down
29 changes: 19 additions & 10 deletions apps/l10nstats/models.py
Expand Up @@ -41,13 +41,15 @@
from life.models import Locale, Tree, Changeset
from mbdb.models import Build


class ModuleCount(models.Model):
"""Abstraction of untranslated strings per module.
Module is usually something like 'browser' or 'security/manager'
"""
name = models.CharField(max_length=50)
count = models.IntegerField()

def __unicode__(self):
return self.name + '(%d)' % self.count

Expand All @@ -60,6 +62,7 @@ class Meta:
unique_together = (('repository', 'ident'),)
'''


class Run(models.Model):
"""Abstraction for a inspect-locales run.
"""
Expand All @@ -79,21 +82,23 @@ class Run(models.Model):
unchanged = models.IntegerField(default=0)
keys = models.IntegerField(default=0)
errors = models.IntegerField(default=0)
report = models.IntegerField(default=0)
warnings = models.IntegerField(default=0)
report = models.IntegerField(default=0)
warnings = models.IntegerField(default=0)
completion = models.SmallIntegerField(default=0)

@property
def allmissing(self):
"""property adding missing and missingInFiles to be used in templates etc.
"""property adding missing and missingInFiles to be used in templates
etc.
We keep track of missing strings in existing files and in new files
separetely, add the two for the most stats here.
"""
return self.missing + self.missingInFiles

def activate(self):
previous = Active.objects.filter(run__tree = self.tree, run__locale = self.locale)
previous = Active.objects.filter(run__tree=self.tree,
run__locale=self.locale)
previousl = list(previous)
if len(previousl) == 1:
previousl[0].run = self
Expand All @@ -103,23 +108,26 @@ def activate(self):
previous.delete()
Active.objects.create(run=self)
if self.cleanupUnchanged:
UnchangedInFile.objects.filter(run__active__isnull=True).distinct().delete()
(UnchangedInFile.objects.filter(run__active__isnull=True)
.distinct().delete())

# fields and class method to convert a query over runs to a brief text
dfields = ['errors', 'missing', 'missingInFiles',
'obsolete',
'completion']

@classmethod
def to_class_string(cls, iterable, prefix = ''):
'''Convert an iterable list of dictionaries to brief output, and result.
def to_class_string(cls, iterable, prefix=''):
"""Convert an iterable list of dictionaries to brief output, and
result.
The input can be a values() query ending up on Run objects, and needs
all the fields in dfields. The given prefix can be used if the
Runs are not the primary manager.
Yields triples of the input dictionary, the short text, and a
classification, any of "error", "warnings", or "success".
'''
"""
for d in iterable:
cmp_segs = []
cls = None
Expand Down Expand Up @@ -149,8 +157,9 @@ class Run_Revisions(models.Model):
"""
run = models.ForeignKey(Run)
changeset = models.ForeignKey(Changeset)

class Meta:
unique_together = (('run','changeset'),)
unique_together = (('run', 'changeset'),)
managed = False


Expand Down
21 changes: 10 additions & 11 deletions apps/l10nstats/templatetags/run_filters.py
Expand Up @@ -40,29 +40,30 @@

from django import template
from django.utils.safestring import mark_safe
from django.utils.html import conditional_escape
from django.core.urlresolvers import reverse

from l10nstats.models import Run

register = template.Library()


@register.filter
def showrun(run, autoescape=None):
"""Display a l10nstats.models.Run object in a template in a consistent manner.
def showrun(run):
"""Display a l10nstats.models.Run object in a template in a consistent
manner.
Since we're not accepting input strings we don't have to worry about
autoescaping.
"""
if autoescape:
esc = conditional_escape
else:
esc = lambda x: x
if not isinstance(run, Run):
return mark_safe("&nbsp;")
fmt = '<a %%s href="%s?run=%%d">%%s</a>' % reverse('l10nstats.views.compare')
fmt = ('<a %%s href="%s?run=%%d">%%s</a>' %
reverse('l10nstats.views.compare'))
missing = run.missing + run.missingInFiles
data = {'missing': missing}
for k in ('errors', 'total'):
data[k] = getattr(run, k)
datastr = ' '.join('data-%s="%d"' % (k,v) for k,v in data.iteritems())
datastr = ' '.join('data-%s="%d"' % (k, v) for k, v in data.iteritems())
cmp_segs = []
if run.errors:
cmp_segs.append('%d error(s)' % run.errors)
Expand All @@ -76,5 +77,3 @@ def showrun(run, autoescape=None):
compare = ', '.join(cmp_segs)

return mark_safe(fmt % (datastr, run.id, compare))

showrun.needs_autoescape = True
14 changes: 6 additions & 8 deletions apps/l10nstats/tests.py
Expand Up @@ -115,7 +115,7 @@ def test_index_with_wrong_args(self):
"""index() view takes arguments 'locale' and 'tree' and if these
aren't correct that view should raise a 404"""
url = reverse('l10nstats.views.index')
response = self.client.get(url, {'locale':'xxx'})
response = self.client.get(url, {'locale': 'xxx'})
eq_(response.status_code, 404)

locale, __ = Locale.objects.get_or_create(
Expand All @@ -128,24 +128,22 @@ def test_index_with_wrong_args(self):
name='Japanese',
)

response = self.client.get(url, {'locale':['en-US','xxx']})
response = self.client.get(url, {'locale': ['en-US', 'xxx']})
eq_(response.status_code, 404)

response = self.client.get(url, {'locale':['en-US','jp']})
response = self.client.get(url, {'locale': ['en-US', 'jp']})
eq_(response.status_code, 200)

# test the tree argument now


response = self.client.get(url, {'tree':'xxx'})
response = self.client.get(url, {'tree': 'xxx'})
eq_(response.status_code, 404)

self._create_appver_milestone()
assert Tree.objects.all().exists()
tree, = Tree.objects.all()

response = self.client.get(url, {'tree':['xxx', tree.code]})
response = self.client.get(url, {'tree': ['xxx', tree.code]})
eq_(response.status_code, 404)

response = self.client.get(url, {'tree':[tree.code]})
response = self.client.get(url, {'tree': [tree.code]})
eq_(response.status_code, 200)

0 comments on commit 54f0318

Please sign in to comment.