[damned-lies] [vertimus] Use proxy models for State classes
- From: Claude Paroz <claudep src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [damned-lies] [vertimus] Use proxy models for State classes
- Date: Fri, 20 May 2011 21:03:08 +0000 (UTC)
commit 79f1f5edfb7906570281ae6abaa22ea3cf1f028e
Author: Claude Paroz <claude 2xlibre net>
Date: Fri May 20 22:56:54 2011 +0200
[vertimus] Use proxy models for State classes
Next step is to do the same for Action classes...
people/views.py | 4 +-
stats/models.py | 9 +-
teams/tests.py | 2 +-
vertimus/admin.py | 6 +-
vertimus/models.py | 268 +++++++++++++++++++-------------------------
vertimus/tests/__init__.py | 192 +++++++++++++------------------
vertimus/views.py | 14 +--
7 files changed, 213 insertions(+), 282 deletions(-)
---
diff --git a/people/views.py b/people/views.py
index fdfbd26..428204a 100644
--- a/people/views.py
+++ b/people/views.py
@@ -36,7 +36,7 @@ from django.views.generic import ListView, DetailView, UpdateView
from people.models import Person
from teams.models import Team, Role
from people.forms import TeamJoinForm, DetailForm
-from vertimus.models import StateDb
+from vertimus.models import State
class PeopleListView(ListView):
@@ -54,7 +54,7 @@ class PersonDetailView(DetailView):
def get_context_data(self, **kwargs):
context = super(PersonDetailView, self).get_context_data(**kwargs)
- states = StateDb.objects.filter(actiondb__person=self.object).distinct()
+ states = State.objects.filter(actiondb__person=self.object).distinct()
all_languages = [(lg[0], LANG_INFO.get(lg[0], {'name_local': lg[1]})['name_local']) for lg in settings.LANGUAGES]
all_languages.sort(key=itemgetter(1))
context.update({
diff --git a/stats/models.py b/stats/models.py
index 7e4696e..6171473 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -1496,7 +1496,8 @@ class Statistics(models.Model):
'all_errors':[]
}
"""
- from vertimus.models import StateDb, ActionDb # import here to prevent a circular dependency
+ # Import here to prevent a circular dependency
+ from vertimus.models import State, ActionDb
if dtype.endswith('-part'):
dtype = dtype[:-5]
@@ -1523,15 +1524,15 @@ class Statistics(models.Model):
infos_dict = Information.get_info_dict(lang)
- # Prepare StateDb objects in a dict (with "branch_id-domain_id" as key), to save database queries later
- vt_states = StateDb.objects.select_related('branch','domain')
+ # Prepare State objects in a dict (with "branch_id-domain_id" as key), to save database queries later
+ vt_states = State.objects.select_related('branch','domain')
if release:
vt_states = vt_states.filter(language=lang, branch__releases=release, domain__dtype=dtype)
else:
vt_states = vt_states.filter(language=lang, domain__dtype=dtype)
vt_states_dict = dict([("%d-%d" % (vt.branch.id, vt.domain.id),vt) for vt in vt_states])
- # Get comments from last action of StateDb objects
+ # Get comments from last action of State objects
actions = ActionDb.objects.filter(state_db__in=vt_states, comment__isnull=False).order_by('created')
actions_dict = dict([(act.state_db_id, act) for act in actions])
for vt_state in vt_states_dict.values():
diff --git a/teams/tests.py b/teams/tests.py
index b705aca..4a379c8 100644
--- a/teams/tests.py
+++ b/teams/tests.py
@@ -37,7 +37,7 @@ class TeamsAndRolesTests(TestCase):
self.pcoo.set_password('password')
self.pcoo.save()
- self.t = Team(name='fr', description='French')
+ self.t = Team(name='fr', description='French', mailing_list='nowhere example org')
self.t.save()
self.t2 = Team(name='pt', description='Portuguese')
diff --git a/vertimus/admin.py b/vertimus/admin.py
index ea4e0fa..a24473f 100644
--- a/vertimus/admin.py
+++ b/vertimus/admin.py
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
-from vertimus.models import StateDb, ActionDb
+from vertimus.models import State, ActionDb
-class StateDbAdmin(admin.ModelAdmin):
+class StateAdmin(admin.ModelAdmin):
raw_id_fields = ('branch', 'domain', 'person',)
class ActionDbAdmin(admin.ModelAdmin):
list_display = ('__unicode__', 'state_db')
-admin.site.register(StateDb, StateDbAdmin)
+admin.site.register(State, StateAdmin)
admin.site.register(ActionDb, ActionDbAdmin)
diff --git a/vertimus/models.py b/vertimus/models.py
index 89a9bbe..bc2f97e 100644
--- a/vertimus/models.py
+++ b/vertimus/models.py
@@ -42,11 +42,8 @@ from teams.models import Role
# States
#
-# Sadly, the Django ORM isn't as powerful than SQLAlchemy :-(
-# So we need to use composition with StateDB and State to obtain
-# the desired behaviour.
-class StateDb(models.Model):
- """Database storage of a State"""
+class State(models.Model):
+ """State of a module translation"""
branch = models.ForeignKey(Branch)
domain = models.ForeignKey(Domain)
language = models.ForeignKey(Language)
@@ -60,10 +57,21 @@ class StateDb(models.Model):
verbose_name = 'state'
unique_together = ('branch', 'domain', 'language')
- def get_state(self):
- state = eval('State'+self.name)()
- state._state_db = self
- return state
+ def __init__(self, *args, **kwargs):
+ super(State, self).__init__(*args, **kwargs)
+ if self.name == 'None' and getattr(self.__class__, 'name', 'None') != 'None':
+ self.name = self.__class__.name
+ self.__class__ = {
+ 'None' : StateNone,
+ 'Translating' : StateTranslating,
+ 'Translated' : StateTranslated,
+ 'Proofreading': StateProofreading,
+ 'Proofread' : StateProofread,
+ 'ToReview' : StateToReview,
+ 'ToCommit' : StateToCommit,
+ 'Committing' : StateCommitting,
+ 'Committed' : StateCommitted,
+ }.get(self.name, State)
def __unicode__(self):
return "%s: %s %s (%s - %s)" % (self.name, self.branch.module.name,
@@ -73,37 +81,10 @@ class StateDb(models.Model):
def get_absolute_url(self):
return ('vertimus_by_ids', [self.branch.id, self.domain.id, self.language.id])
-class StateAbstract(object):
- """Abstract class"""
-
- @property
- def branch(self):
- return self._state_db.branch
-
- @property
- def domain(self):
- return self._state_db.domain
-
- @property
- def language(self):
- return self._state_db.language
-
- def get_person(self):
- return self._state_db.person
-
- def set_person(self, person):
- self._state_db.person = person
- person = property(get_person, set_person)
-
- @property
- def updated(self):
- return self._state_db.updated
-
- def get_state_db(self):
- return self._state_db
-
- def __unicode__(self):
- return unicode(self.description)
+ def change_state(self, state_class):
+ self.name = state_class.name
+ self.__class__ = state_class
+ self.save()
def _get_available_actions(self, person, action_names):
action_names.append('WC')
@@ -116,24 +97,14 @@ class StateAbstract(object):
def apply_action(self, action, person, comment=None, file=None):
# Check the permission to use this action
if action.name in (a.name for a in self.get_available_actions(person)):
- new_state = action.apply(self, person, comment, file)
- if new_state != None:
- # Reuse the current state_db
- new_state._state_db = self._state_db
- # Only the name and the person change
- new_state._state_db.name = new_state.name
- new_state._state_db.person = person
-
- if isinstance(new_state, StateCommitted):
- # Committed is the last state of the workflow
- new_state.save()
-
- # Archive actions
- return new_state.apply_action(ActionAA(), person)
-
- return new_state
- else:
- return self
+ action.apply(self, person, comment, file)
+ if not isinstance(self, StateNone):
+ self.person = person
+ self.save()
+
+ if isinstance(self, StateCommitted):
+ # Committed is the last state of the workflow, archive actions
+ self.apply_action(ActionAA(), person)
else:
raise Exception('Not allowed')
@@ -142,20 +113,20 @@ class StateAbstract(object):
The first level is 1."""
assert level > 0, "Level must be greater than 0"
- query = ActionDbArchived.objects.filter(state_db=self._state_db).values('sequence').distinct().order_by('-sequence')[level-1:level]
+ query = self.actiondbarchived_set.all().values('sequence').distinct().order_by('-sequence')[level-1:level]
sequence = None
if len(query) > 0:
sequence = query[0]['sequence']
return sequence
- def save(self):
- self._state_db.save()
-
-class StateNone(StateAbstract):
+class StateNone(State):
name = 'None'
description = _('Inactive')
+ class Meta:
+ proxy = True
+
def get_available_actions(self, person):
action_names = []
@@ -165,10 +136,13 @@ class StateNone(StateAbstract):
return self._get_available_actions(person, action_names)
-class StateTranslating(StateAbstract):
+class StateTranslating(State):
name = 'Translating'
description = _('Translating')
+ class Meta:
+ proxy = True
+
def get_available_actions(self, person):
action_names = []
@@ -178,10 +152,13 @@ class StateTranslating(StateAbstract):
return self._get_available_actions(person, action_names)
-class StateTranslated(StateAbstract):
+class StateTranslated(State):
name = 'Translated'
description = _('Translated')
+ class Meta:
+ proxy = True
+
def get_available_actions(self, person):
action_names = []
@@ -198,10 +175,13 @@ class StateTranslated(StateAbstract):
return self._get_available_actions(person, action_names)
-class StateProofreading(StateAbstract):
+class StateProofreading(State):
name = 'Proofreading'
description = _('Proofreading')
+ class Meta:
+ proxy = True
+
def get_available_actions(self, person):
action_names = []
@@ -212,11 +192,14 @@ class StateProofreading(StateAbstract):
return self._get_available_actions(person, action_names)
-class StateProofread(StateAbstract):
+class StateProofread(State):
name = 'Proofread'
# Translators: This is a status, not a verb
description = _('Proofread')
+ class Meta:
+ proxy = True
+
def get_available_actions(self, person):
if person.is_reviewer(self.language.team):
action_names = ['TC', 'RP', 'TR']
@@ -228,10 +211,13 @@ class StateProofread(StateAbstract):
return self._get_available_actions(person, action_names)
-class StateToReview(StateAbstract):
+class StateToReview(State):
name = 'ToReview'
description = _('To Review')
+ class Meta:
+ proxy = True
+
def get_available_actions(self, person):
action_names = []
if person.is_translator(self.language.team):
@@ -240,10 +226,13 @@ class StateToReview(StateAbstract):
return self._get_available_actions(person, action_names)
-class StateToCommit(StateAbstract):
+class StateToCommit(State):
name = 'ToCommit'
description = _('To Commit')
+ class Meta:
+ proxy = True
+
def get_available_actions(self, person):
if person.is_committer(self.language.team):
action_names = ['RC', 'TR']
@@ -255,10 +244,13 @@ class StateToCommit(StateAbstract):
return self._get_available_actions(person, action_names)
-class StateCommitting(StateAbstract):
+class StateCommitting(State):
name = 'Committing'
description = _('Committing')
+ class Meta:
+ proxy = True
+
def get_available_actions(self, person):
action_names = []
@@ -269,10 +261,13 @@ class StateCommitting(StateAbstract):
return self._get_available_actions(person, action_names)
-class StateCommitted(StateAbstract):
+class StateCommitted(State):
name = 'Committed'
description = _('Committed')
+ class Meta:
+ proxy = True
+
def get_available_actions(self, person):
if person.is_committer(self.language.team):
action_names = ['AA']
@@ -281,6 +276,7 @@ class StateCommitted(StateAbstract):
return self._get_available_actions(person, action_names)
+
#
# Actions
#
@@ -335,7 +331,7 @@ def action_db_get_action_history(cls, state_db=None, sequence=None):
return history
class ActionDb(models.Model):
- state_db = models.ForeignKey(StateDb)
+ state_db = models.ForeignKey(State)
person = models.ForeignKey(Person)
name = models.SlugField(max_length=8)
@@ -395,7 +391,7 @@ def generate_archive_filename(instance, original_filename):
return "%s/%s" % (settings.UPLOAD_ARCHIVED_DIR, os.path.basename(original_filename))
class ActionDbArchived(models.Model):
- state_db = models.ForeignKey(StateDb)
+ state_db = models.ForeignKey(State)
person = models.ForeignKey(Person)
name = models.SlugField(max_length=8)
@@ -488,8 +484,8 @@ class ActionAbstract(object):
def save_action_db(self, state, person, comment=None, file=None):
"""Used by apply"""
- self._action_db = ActionDb(state_db=state._state_db,
- person=person, name=self.name, comment=comment, file=file)
+ self._action_db = ActionDb(state_db=state, person=person,
+ name=self.name, comment=comment, file=file)
if file:
self._action_db.file.save(file.name, file, save=False)
self._action_db.save()
@@ -529,33 +525,33 @@ class ActionAbstract(object):
except:
return False
- def send_mail_new_state(self, old_state, new_state, recipient_list):
+ def send_mail_new_state(self, state, recipient_list):
# Remove None and empty string items from the list
recipient_list = filter(lambda x: x and x is not None, recipient_list)
if recipient_list:
current_lang = get_language()
- activate(old_state.language.locale)
+ activate(state.language.locale)
current_site = Site.objects.get_current()
url = "http://%s%s" % (current_site.domain, urlresolvers.reverse(
'vertimus_by_names',
args = (
- old_state.branch.module.name,
- old_state.branch.name,
- old_state.domain.name,
- old_state.language.locale)))
- subject = old_state.branch.module.name + u' - ' + old_state.branch.name
+ state.branch.module.name,
+ state.branch.name,
+ state.domain.name,
+ state.language.locale)))
+ subject = state.branch.module.name + u' - ' + state.branch.name
message = _(u"""Hello,
The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is now '%(new_state)s'.
%(url)s
""") % {
- 'module': old_state.branch.module.name,
- 'branch': old_state.branch.name,
- 'domain': old_state.domain.name,
- 'language': old_state.language.get_name(),
- 'new_state': new_state,
+ 'module': state.branch.module.name,
+ 'branch': state.branch.name,
+ 'domain': state.domain.name,
+ 'language': state.language.get_name(),
+ 'new_state': state,
'url': url
}
message += self.comment or ugettext("Without comment")
@@ -570,15 +566,12 @@ class ActionWC(ActionAbstract):
description = _('Write a comment')
comment_is_required = True
- def _new_state(self):
- return None
-
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
# Send an email to all translators of the page
translator_emails = set()
- for d in Person.objects.filter(actiondb__state_db=state.get_state_db()).values('email'):
+ for d in Person.objects.filter(actiondb__state_db=state).values('email'):
translator_emails.add(d['email'])
# Remove None items from the list
@@ -614,158 +607,129 @@ A new comment has been left on %(module)s - %(branch)s - %(domain)s (%(language)
mail.send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, translator_emails)
activate(current_lang)
- return self._new_state()
-
class ActionRT(ActionAbstract):
name = 'RT'
description = _('Reserve for translation')
+ target_state = StateTranslating
file_is_prohibited = True
- def _new_state(self):
- return StateTranslating()
-
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
- return self._new_state()
+ state.change_state(self.target_state)
class ActionUT(ActionAbstract):
name = 'UT'
description = _('Upload the new translation')
+ target_state = StateTranslated
file_is_required = True
- def _new_state(self):
- return StateTranslated()
-
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
- new_state = self._new_state()
- self.send_mail_new_state(state, new_state, (state.language.team.mailing_list,))
- return new_state
+ state.change_state(self.target_state)
+ self.send_mail_new_state(state, (state.language.team.mailing_list,))
class ActionRP(ActionAbstract):
name = 'RP'
description = _('Reserve for proofreading')
+ target_state = StateProofreading
file_is_prohibited = True
- def _new_state(self):
- return StateProofreading()
-
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
- return self._new_state()
+ state.change_state(self.target_state)
class ActionUP(ActionAbstract):
name = 'UP'
description = _('Upload the proofread translation')
+ target_state = StateProofread
file_is_required = True
- def _new_state(self):
- return StateProofread()
-
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
- new_state = self._new_state()
- self.send_mail_new_state(state, new_state, (state.language.team.mailing_list,))
- return new_state
+ state.change_state(self.target_state)
+ self.send_mail_new_state(state, (state.language.team.mailing_list,))
class ActionTC(ActionAbstract):
name = 'TC'
# Translators: this means the file is ready to be committed in repository
description = _('Ready for submission')
-
- def _new_state(self):
- return StateToCommit()
+ target_state = StateToCommit
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
- new_state = self._new_state()
+ state.change_state(self.target_state)
# Send an email to all committers of the team
committers = [c.email for c in state.language.team.get_committers()]
- self.send_mail_new_state(state, new_state, committers)
- return new_state
+ self.send_mail_new_state(state, committers)
class ActionCI(ActionAbstract):
name = 'CI'
description = _('Submit to repository')
+ target_state = StateCommitted
file_is_prohibited = True
- def _new_state(self):
- return StateCommitted()
-
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
action_with_po = self.get_previous_action_with_po()
try:
state.branch.commit_po(action_with_po.file.path, state.domain, state.language, person)
- new_state = self._new_state()
+ state.change_state(self.target_state)
except:
# Commit failed, state unchanged
self._action_db.delete()
# FIXME: somewhere the error should be catched and handled properly
- #new_state = state
raise Exception(_("The commit failed. The error was: '%s'") % sys.exc_info()[1])
- if state != new_state:
- self.send_mail_new_state(state, new_state, (state.language.team.mailing_list,))
- return new_state
+
+ self.send_mail_new_state(state, (state.language.team.mailing_list,))
class ActionRC(ActionAbstract):
name = 'RC'
# Translators: this indicates a committer is going to commit the file in the repository
description = _('Reserve to submit')
+ target_state = StateCommitting
file_is_prohibited = True
- def _new_state(self):
- return StateCommitting()
-
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
- return self._new_state()
+ state.change_state(self.target_state)
class ActionIC(ActionAbstract):
name = 'IC'
# Translators: this is used to indicate the file has been committed in the repository
description = _('Inform of submission')
-
- def _new_state(self):
- return StateCommitted()
+ target_state = StateCommitted
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
- new_state = self._new_state()
- self.send_mail_new_state(state, new_state, (state.language.team.mailing_list,))
- return new_state
+ state.change_state(self.target_state)
+ self.send_mail_new_state(state, (state.language.team.mailing_list,))
class ActionTR(ActionAbstract):
name = 'TR'
# Translators: regardless of the translation completion, this file need to be reviewed
description = _('Review required')
+ target_state = StateToReview
arg_is_required = True
- def _new_state(self):
- return StateToReview()
-
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
- new_state = self._new_state()
- self.send_mail_new_state(state, new_state, (state.language.team.mailing_list,))
- return new_state
+ state.change_state(self.target_state)
+ self.send_mail_new_state(state, (state.language.team.mailing_list,))
class ActionAA(ActionAbstract):
name = 'AA'
description = _('Archive the actions')
-
- def _new_state(self):
- return StateNone()
+ target_state = StateNone
def apply(self, state, person, comment=None, file=None):
self.save_action_db(state, person, comment, file)
- actions_db = ActionDb.objects.filter(state_db=state._state_db).order_by('id').all()
+ actions_db = ActionDb.objects.filter(state_db=state).order_by('id').all()
sequence = None
for action_db in actions_db:
@@ -791,8 +755,7 @@ class ActionAA(ActionAbstract):
action_db_archived.save()
action_db.delete() # The file is also automatically deleted, if it is not referenced elsewhere
-
- return self._new_state()
+ state.change_state(self.target_state)
class ActionUNDO(ActionAbstract):
name = 'UNDO'
@@ -802,7 +765,7 @@ class ActionUNDO(ActionAbstract):
self.save_action_db(state, person, comment, file)
# Exclude WC because this action is a noop on State
- actions_db = ActionDb.objects.filter(state_db__id=state._state_db.id).exclude(name='WC').order_by('-id')
+ actions_db = ActionDb.objects.filter(state_db__id=state.id).exclude(name='WC').order_by('-id')
i = 0
while (i < len(actions_db)):
if actions_db[i].name == 'UNDO':
@@ -811,8 +774,9 @@ class ActionUNDO(ActionAbstract):
else:
# Found
action = actions_db[i].get_action()
- return action._new_state()
- return StateNone()
+ state.change_state(action.target_state)
+ return
+ state.change_state(StateNone)
class ActionSeparator(object):
""" Fake action to add a separator in action menu """
diff --git a/vertimus/tests/__init__.py b/vertimus/tests/__init__.py
index f02298c..3c0a62a 100644
--- a/vertimus/tests/__init__.py
+++ b/vertimus/tests/__init__.py
@@ -20,14 +20,16 @@
import os
+from django.conf import settings
from django.core.files.base import File, ContentFile
from django.core.files.uploadedfile import SimpleUploadedFile
+from django.core import mail
+from django.core.urlresolvers import reverse
from django.http import QueryDict
from django.utils.datastructures import MultiValueDict
-from django.conf import settings
from teams.tests import TeamsAndRolesTests
-from stats.models import Module, Branch, Release, Category, Domain
+from stats.models import Module, Branch, Release, Category, Domain, Statistics
from vertimus.models import *
from vertimus.forms import ActionForm
@@ -62,10 +64,7 @@ class VertimusTest(TeamsAndRolesTests):
self.d.save()
def test_state_none(self):
- sdb = StateDb(branch=self.b, domain=self.d, language=self.l)
- sdb.name = 'None'
- state = sdb.get_state()
- self.assert_(isinstance(state, StateNone))
+ state = StateNone(branch=self.b, domain=self.d, language=self.l)
action_names = [a.name for a in state.get_available_actions(self.pn)]
self.assertEqual(action_names, ['WC'])
@@ -79,10 +78,7 @@ class VertimusTest(TeamsAndRolesTests):
self.assertEqual(action_names, ['RT', 'WC', None, 'IC'])
def test_state_translating(self):
- sdb = StateDb(branch=self.b, domain=self.d, language=self.l, person=self.pt)
- sdb.name = 'Translating'
- state = sdb.get_state()
- self.assert_(isinstance(state, StateTranslating))
+ state = StateTranslating(branch=self.b, domain=self.d, language=self.l, person=self.pt)
for p in (self.pn, self.pr):
action_names = [a.name for a in state.get_available_actions(p)]
@@ -97,10 +93,7 @@ class VertimusTest(TeamsAndRolesTests):
self.assertEqual(action_names, ['UT', 'UNDO', 'WC'])
def test_state_translated(self):
- sdb = StateDb(branch=self.b, domain=self.d, language=self.l, person=self.pt)
- sdb.name = 'Translated'
- state = sdb.get_state()
- self.assert_(isinstance(state, StateTranslated))
+ state = StateTranslated(branch=self.b, domain=self.d, language=self.l, person=self.pt)
action_names = [a.name for a in state.get_available_actions(self.pn)]
self.assertEqual(action_names, ['WC'])
@@ -116,10 +109,7 @@ class VertimusTest(TeamsAndRolesTests):
self.assertEqual(action_names, ['RP', 'RT', 'TR', 'TC', 'WC', None, 'IC', 'AA'])
def test_state_proofreading(self):
- sdb = StateDb(branch=self.b, domain=self.d, language=self.l, person=self.pr)
- sdb.name = 'Proofreading'
- state = sdb.get_state()
- self.assert_(isinstance(state, StateProofreading))
+ state = StateProofreading(branch=self.b, domain=self.d, language=self.l, person=self.pr)
for p in (self.pn, self.pt):
action_names = [a.name for a in state.get_available_actions(p)]
@@ -134,10 +124,7 @@ class VertimusTest(TeamsAndRolesTests):
self.assertEqual(action_names, ['UP', 'TR', 'TC', 'UNDO', 'WC'])
def test_state_proofread(self):
- sdb = StateDb(branch=self.b, domain=self.d, language=self.l, person=self.pr)
- sdb.name = 'Proofread'
- state = sdb.get_state()
- self.assert_(isinstance(state, StateProofread))
+ state = StateProofread(branch=self.b, domain=self.d, language=self.l, person=self.pr)
for p in (self.pn, self.pt):
action_names = [a.name for a in state.get_available_actions(p)]
@@ -151,10 +138,7 @@ class VertimusTest(TeamsAndRolesTests):
self.assertEqual(action_names, ['TC', 'RP', 'TR', 'WC', None, 'IC', 'AA'])
def test_state_to_review(self):
- sdb = StateDb(branch=self.b, domain=self.d, language=self.l, person=self.pt)
- sdb.name = 'ToReview'
- state = sdb.get_state()
- self.assert_(isinstance(state, StateToReview))
+ state = StateToReview(branch=self.b, domain=self.d, language=self.l, person=self.pt)
action_names = [a.name for a in state.get_available_actions(self.pn)]
self.assertEqual(action_names, ['WC'])
@@ -168,10 +152,7 @@ class VertimusTest(TeamsAndRolesTests):
self.assertEqual(action_names, ['RT', 'WC', None, 'IC', 'AA'])
def test_state_to_commit(self):
- sdb = StateDb(branch=self.b, domain=self.d, language=self.l, person=self.pr)
- sdb.name = 'ToCommit'
- state = sdb.get_state()
- self.assert_(isinstance(state, StateToCommit))
+ state = StateToCommit(branch=self.b, domain=self.d, language=self.l, person=self.pr)
for p in (self.pn, self.pt, self.pr):
action_names = [a.name for a in state.get_available_actions(p)]
@@ -182,10 +163,7 @@ class VertimusTest(TeamsAndRolesTests):
self.assertEqual(action_names, ['RC', 'TR', 'WC', None, 'IC', 'AA'])
def test_state_committing(self):
- sdb = StateDb(branch=self.b, domain=self.d, language=self.l, person=self.pc)
- sdb.name = 'Committing'
- state = sdb.get_state()
- self.assert_(isinstance(state, StateCommitting))
+ state = StateCommitting(branch=self.b, domain=self.d, language=self.l, person=self.pc)
for p in (self.pn, self.pt, self.pr):
action_names = [a.name for a in state.get_available_actions(p)]
@@ -198,10 +176,7 @@ class VertimusTest(TeamsAndRolesTests):
self.assertEqual(action_names, ['IC', 'TR', 'UNDO', 'WC'])
def test_state_committed(self):
- sdb = StateDb(branch=self.b, domain=self.d, language=self.l, person=self.pc)
- sdb.name = 'Committed'
- state = sdb.get_state()
- self.assert_(isinstance(state, StateCommitted))
+ state = StateCommitted(branch=self.b, domain=self.d, language=self.l, person=self.pc)
for p in (self.pn, self.pt, self.pr):
action_names = [a.name for a in state.get_available_actions(p)]
@@ -212,23 +187,22 @@ class VertimusTest(TeamsAndRolesTests):
self.assertEqual(action_names, ['AA', 'WC', None, 'IC'])
def test_action_wc(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='None').get_state()
+ state = StateNone(branch=self.b, domain=self.d, language=self.l)
state.save()
action = ActionAbstract.new_by_name('WC')
- new_state = state.apply_action(action, self.pt, "Hi!", None)
- new_state.save()
+ state.apply_action(action, self.pt, "Hi!", None)
# Test that submitting a comment without text generates a validation error
form = ActionForm([('WC', u'Write a comment')], QueryDict('action=WC&comment='))
self.assertTrue("A comment is needed" in str(form.errors))
def test_action_rt(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='None').get_state()
+ state = StateNone(branch=self.b, domain=self.d, language=self.l)
state.save()
action = ActionAbstract.new_by_name('RT')
- new_state = state.apply_action(action, self.pt, "Reserved!", None)
- new_state.save()
+ state.apply_action(action, self.pt, "Reserved!", None)
+ self.assertTrue(isinstance(state, StateTranslating))
def test_action_ut(self):
# Disabling the role
@@ -236,57 +210,61 @@ class VertimusTest(TeamsAndRolesTests):
role.is_active = False
role.save()
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='Translating', person=self.pt).get_state()
+ state = StateTranslating(branch=self.b, domain=self.d, language=self.l, person=self.pt)
state.save()
test_file = ContentFile('test content')
test_file.name = 'mytestfile.po'
action = ActionAbstract.new_by_name('UT')
- new_state = state.apply_action(action, self.pt, "Done by translator.", test_file)
- new_state.save()
+ state.apply_action(action, self.pt, "Done by translator.", test_file)
+ self.assertTrue(isinstance(state, StateTranslated))
+ # Mail sent to mailing list
+ self.assertEquals(len(mail.outbox), 1)
+ self.assertEquals(mail.outbox[0].recipients(), [self.l.team.mailing_list])
+ self.assertEquals(mail.outbox[0].subject, u"gedit - gnome-2-24")
# Testing if the role was activated
role = Role.objects.get(person=self.pt, team=self.l.team)
self.assertTrue(role.is_active)
def test_action_rp(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='Translated').get_state()
+ state = StateTranslated(branch=self.b, domain=self.d, language=self.l)
state.save()
action = ActionAbstract.new_by_name('RP')
- new_state = state.apply_action(action, self.pr, "Reserved by a reviewer!")
- new_state.save()
+ state.apply_action(action, self.pr, "Reserved by a reviewer!")
+ self.assertTrue(isinstance(state, StateProofreading))
def test_action_up(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='Proofreading', person=self.pr).get_state()
+ state = StateProofreading(branch=self.b, domain=self.d, language=self.l, person=self.pr)
state.save()
test_file = ContentFile('test content')
test_file.name = 'mytestfile.po'
action = ActionAbstract.new_by_name('UP')
- new_state = state.apply_action(action, self.pr, "Done.", test_file)
- new_state.save()
+ state.apply_action(action, self.pr, "Done.", test_file)
+ self.assertTrue(isinstance(state, StateProofread))
def test_action_tc(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='Proofread').get_state()
+ state = StateProofread(branch=self.b, domain=self.d, language=self.l)
state.save()
action = ActionAbstract.new_by_name('TC')
- new_state = state.apply_action(action, self.pr, "Ready!")
- new_state.save()
+ state.apply_action(action, self.pr, "Ready!")
+ self.assertTrue(isinstance(state, StateToCommit))
def test_action_rc(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='ToCommit').get_state()
+ state = StateToCommit(branch=self.b, domain=self.d, language=self.l)
state.save()
action = ActionAbstract.new_by_name('RC')
- new_state = state.apply_action(action, self.pc, "This work is mine!")
- new_state.save()
+ state.apply_action(action, self.pc, "This work is mine!")
+ self.assertTrue(isinstance(state, StateCommitting))
def test_action_ic(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='Proofreading', person=self.pr).get_state()
+ state = StateProofreading(branch=self.b, domain=self.d, language=self.l, person=self.pr)
state.save()
# Create a new file
@@ -294,23 +272,19 @@ class VertimusTest(TeamsAndRolesTests):
test_file.name = 'mytestfile.po'
action = ActionAbstract.new_by_name('UP')
- state = state.apply_action(action, self.pr, "Done.", test_file)
- state.save()
+ state.apply_action(action, self.pr, "Done.", test_file)
file_path = os.path.join(settings.MEDIA_ROOT, action.file.name)
self.assertTrue(os.access(file_path, os.W_OK))
action = ActionAbstract.new_by_name('TC')
- state = state.apply_action(action, self.pc, "To commit.")
- state.save()
+ state.apply_action(action, self.pc, "To commit.")
action = ActionAbstract.new_by_name('RC')
- state = state.apply_action(action, self.pc, "Reserved commit.")
- state.save()
+ state.apply_action(action, self.pc, "Reserved commit.")
action = ActionAbstract.new_by_name('IC')
- state = state.apply_action(action, self.pc, "Committed.")
- state.save()
+ state.apply_action(action, self.pc, "Committed.")
self.assertTrue(not os.access(file_path, os.F_OK), "%s not deleted" % file_path)
@@ -321,75 +295,75 @@ class VertimusTest(TeamsAndRolesTests):
self.assertTrue(not os.access(filename_archived, os.F_OK), "%s not deleted" % filename_archived)
def test_action_tr(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='Translated').get_state()
+ state = StateTranslated(branch=self.b, domain=self.d, language=self.l)
state.save()
action = ActionAbstract.new_by_name('TR')
- state = state.apply_action(action, self.pc, "Bad work :-/")
- state.save()
+ state.apply_action(action, self.pc, "Bad work :-/")
+ self.assertTrue(isinstance(state, StateToReview))
def test_action_ba(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='Committed', person=self.pr).get_state()
+ state = StateCommitted(branch=self.b, domain=self.d, language=self.l, person=self.pr)
state.save()
action = ActionAbstract.new_by_name('AA')
- state = state.apply_action(action, self.pc, comment="I don't want to disappear :)")
- state.save()
+ state.apply_action(action, self.pc, comment="I don't want to disappear :)")
- sdb = StateDb.objects.get(branch=self.b, domain=self.d, language=self.l)
- state = sdb.get_state()
- self.assert_(isinstance(state, StateNone))
+ state = State.objects.get(branch=self.b, domain=self.d, language=self.l)
+ self.assertTrue(isinstance(state, StateNone))
def test_action_undo(self):
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='None').get_state()
+ state = StateNone(branch=self.b, domain=self.d, language=self.l)
state.save()
action = ActionAbstract.new_by_name('RT')
- state = state.apply_action(action, self.pt, "Reserved!")
- state.save()
+ state.apply_action(action, self.pt, "Reserved!")
action = ActionAbstract.new_by_name('UNDO')
- state = state.apply_action(action, self.pt, "Ooops! I don't want to do that. Sorry.")
- state.save()
+ state.apply_action(action, self.pt, "Ooops! I don't want to do that. Sorry.")
self.assertEqual(state.name, 'None')
action = ActionAbstract.new_by_name('RT')
- state = state.apply_action(action, self.pt, "Translating")
- state.save()
+ state.apply_action(action, self.pt, "Translating")
action = ActionAbstract.new_by_name('UT')
- state = state.apply_action(action, self.pt, "Translated")
- state.save()
+ state.apply_action(action, self.pt, "Translated")
action = ActionAbstract.new_by_name('RT')
- state = state.apply_action(action, self.pt, "Reserved!")
- state.save()
+ state.apply_action(action, self.pt, "Reserved!")
action = ActionAbstract.new_by_name('UNDO')
- state = state.apply_action(action, self.pt, "Ooops! I don't want to do that. Sorry.")
- state.save()
+ state.apply_action(action, self.pt, "Ooops! I don't want to do that. Sorry.")
self.assertEqual(state.name, 'Translated')
action = ActionAbstract.new_by_name('RT')
- state = state.apply_action(action, self.pt, "Translating 1")
- state.save()
+ state.apply_action(action, self.pt, "Translating 1")
action = ActionAbstract.new_by_name('UNDO')
- state = state.apply_action(action, self.pt, "Undo 1")
- state.save()
+ state.apply_action(action, self.pt, "Undo 1")
action = ActionAbstract.new_by_name('RT')
- state = state.apply_action(action, self.pt, "Translating 2")
- state.save()
+ state.apply_action(action, self.pt, "Translating 2")
action = ActionAbstract.new_by_name('UNDO')
- state = state.apply_action(action, self.pt, "Undo 2")
- state.save()
+ state.apply_action(action, self.pt, "Undo 2")
self.assertEqual(state.name, 'Translated')
+ def test_vertimus_view(self):
+ pot_stat = Statistics(language=None, branch=self.b, domain=self.d)
+ pot_stat.save()
+
+ url = reverse('vertimus_by_ids', args=[self.b.id, self.d.id, self.l.id])
+ response = self.client.get(url)
+ self.assertNotContains(response, '<option value="WC">')
+
+ self.client.login(username=self.pn.username, password='password')
+ response = self.client.get(url)
+ self.assertContains(response, '<option value="WC">')
+
def test_uploaded_file_validation(self):
# Test a non valid po file
post_content = QueryDict('action=WC&comment=Test1')
@@ -411,34 +385,28 @@ class VertimusTest(TeamsAndRolesTests):
def test_mysql(self):
# Copied from test_action_undo() with minor changes
- state = StateDb(branch=self.b, domain=self.d, language=self.l, name='None').get_state()
+ state = StateNone(branch=self.b, domain=self.d, language=self.l)
state.save()
action = ActionAbstract.new_by_name('RT')
- state = state.apply_action(action, self.pr, "Reserved!")
- state.save()
+ state.apply_action(action, self.pr, "Reserved!")
action = ActionAbstract.new_by_name('UNDO')
- state = state.apply_action(action, self.pr, "Ooops! I don't want to do that. Sorry.")
- state.save()
+ state.apply_action(action, self.pr, "Ooops! I don't want to do that. Sorry.")
action = ActionAbstract.new_by_name('RT')
- state = state.apply_action(action, self.pr, "Translating")
- state.save()
+ state.apply_action(action, self.pr, "Translating")
action = ActionAbstract.new_by_name('UT')
- state = state.apply_action(action, self.pr, "Translated")
- state.save()
+ state.apply_action(action, self.pr, "Translated")
action = ActionAbstract.new_by_name('RP')
- state = state.apply_action(action, self.pr, "Proofreading")
- state.save()
+ state.apply_action(action, self.pr, "Proofreading")
action = ActionAbstract.new_by_name('UNDO')
- state = state.apply_action(action, self.pr, "Ooops! I don't want to do that. Sorry.")
- state.save()
+ state.apply_action(action, self.pr, "Ooops! I don't want to do that. Sorry.")
- actions_db = ActionDb.objects.filter(state_db__id=state._state_db.id).exclude(name='WC').order_by('-id')
+ actions_db = ActionDb.objects.filter(state_db__id=state.id).exclude(name='WC').order_by('-id')
# So the last action is UNDO
self.assert_(isinstance(actions_db[0].get_action(), ActionUNDO))
diff --git a/vertimus/views.py b/vertimus/views.py
index b21c2bc..a04e038 100644
--- a/vertimus/views.py
+++ b/vertimus/views.py
@@ -27,7 +27,7 @@ from django.utils.translation import ugettext as _
from stats.models import Statistics, Module, Branch, Domain, Language
from stats.utils import is_po_reduced
-from vertimus.models import StateDb, ActionDb, ActionDbArchived, ActionAbstract
+from vertimus.models import State, ActionDb, ActionDbArchived, ActionAbstract
from vertimus.forms import ActionForm
def vertimus_by_stats_id(request, stats_id, lang_id):
@@ -71,17 +71,16 @@ def vertimus(request, branch, domain, language, stats=None, level="0"):
po_url = stats.po_url()
# Get the state of the translation
- (state_db, created) = StateDb.objects.get_or_create(
+ (state, created) = State.objects.get_or_create(
branch=branch,
domain=domain,
language=language)
- other_branch_states = StateDb.objects.filter(
+ other_branch_states = State.objects.filter(
domain=domain, language=language).exclude(branch=branch.pk).exclude(name='None')
- state = state_db.get_state()
if level == 0:
# Current actions
- action_history = ActionDb.get_action_history(state_db)
+ action_history = ActionDb.get_action_history(state)
else:
sequence = state.get_action_sequence_from_level(level)
action_history = ActionDbArchived.get_action_history(sequence)
@@ -107,9 +106,8 @@ def vertimus(request, branch, domain, language, stats=None, level="0"):
comment = action_form.cleaned_data['comment']
action = ActionAbstract.new_by_name(action)
- new_state = state.apply_action(action, person, comment,
- request.FILES.get('file', None))
- new_state.save()
+ state.apply_action(action, person, comment,
+ request.FILES.get('file', None))
return HttpResponseRedirect(
urlresolvers.reverse('vertimus_by_names',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]