Refactoring with flake8

remotes/origin/enhancement/email-actions
Jesús Espino 2013-03-21 09:11:11 +01:00
parent a03fa3f3db
commit 4cb3df6ee9
31 changed files with 156 additions and 202 deletions

View File

@ -8,6 +8,7 @@ from django.contrib.auth.models import User
import json import json
class Login(View): class Login(View):
def post(self, request): def post(self, request):
username = request.POST.get('username', None) username = request.POST.get('username', None)
@ -30,6 +31,7 @@ class Login(View):
def dispatch(self, *args, **kwargs): def dispatch(self, *args, **kwargs):
return super(Login, self).dispatch(*args, **kwargs) return super(Login, self).dispatch(*args, **kwargs)
class Logout(View): class Logout(View):
def post(self, request): def post(self, request):
logout(request) logout(request)

View File

@ -14,6 +14,7 @@ import logging
logger = logging.getLogger("niwi") logger = logging.getLogger("niwi")
class DictField(models.Field): class DictField(models.Field):
""" Dictionary pickled field. """ """ Dictionary pickled field. """
__metaclass__ = models.SubfieldBase __metaclass__ = models.SubfieldBase
@ -64,7 +65,7 @@ class ListField(models.Field):
__pickleproto__ = -1 __pickleproto__ = -1
def to_python(self, value): def to_python(self, value):
if isinstance(value, (list,tuple)): if isinstance(value, (list, tuple)):
return value return value
if isinstance(value, (str, unicode)) and value.startswith(self.__prefix__): if isinstance(value, (str, unicode)) and value.startswith(self.__prefix__):
@ -75,7 +76,7 @@ class ListField(models.Field):
def get_db_prep_value(self, value, connection, prepared=False): def get_db_prep_value(self, value, connection, prepared=False):
if value is not None: if value is not None:
if isinstance(value, (list,tuple)): if isinstance(value, (list, tuple)):
value = self.__prefix__ + b64encode(pickle.dumps(value, protocol=self.__pickleproto__)) value = self.__prefix__ + b64encode(pickle.dumps(value, protocol=self.__pickleproto__))
else: else:
raise TypeError('This field can only store list or tuple objects') raise TypeError('This field can only store list or tuple objects')
@ -109,13 +110,15 @@ class CSVField(models.TextField):
super(CSVField, self).__init__(*args, **kwargs) super(CSVField, self).__init__(*args, **kwargs)
def to_python(self, value): def to_python(self, value):
if not value: return if not value:
return
if isinstance(value, list): if isinstance(value, list):
return value return value
return value.split(self.token) return value.split(self.token)
def get_db_prep_value(self, value): def get_db_prep_value(self, value):
if not value: return if not value:
return
assert(isinstance(value, list) or isinstance(value, tuple)) assert(isinstance(value, list) or isinstance(value, tuple))
return self.token.join([unicode(s) for s in value]) return self.token.join([unicode(s) for s in value])

View File

@ -1,14 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import logging
from celery import task from celery import task
from django.template import loader
from django.utils import translation
from django.core import mail from django.core import mail
from greenmine.base.utils.auth import set_token
@task(name='send-mail') @task(name='send-mail')
def send_mail(subject, body, to): def send_mail(subject, body, to):
@ -16,10 +11,11 @@ def send_mail(subject, body, to):
email_message.content_subtype = "html" email_message.content_subtype = "html"
email_message.send() email_message.send()
@task(name='send-bulk-mail') @task(name='send-bulk-mail')
def send_bulk_mail(emails): def send_bulk_mail(emails):
emessages = [mail.EmailMessage(body=body, subject=subject, to=to) emessages = [mail.EmailMessage(body=body, subject=subject, to=to)
for subject, body, to in emails] for subject, body, to in emails]
for msg in emessages: for msg in emessages:
msg.content_subtype = "html" msg.content_subtype = "html"

View File

@ -5,6 +5,7 @@ from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date from django.utils.http import cookie_date
from django.utils.importlib import import_module from django.utils.importlib import import_module
class GreenmineSessionMiddleware(object): class GreenmineSessionMiddleware(object):
def process_request(self, request): def process_request(self, request):
engine = import_module(settings.SESSION_ENGINE) engine = import_module(settings.SESSION_ENGINE)
@ -39,9 +40,11 @@ class GreenmineSessionMiddleware(object):
if response.status_code != 500: if response.status_code != 500:
request.session.save() request.session.save()
response.set_cookie(settings.SESSION_COOKIE_NAME, response.set_cookie(settings.SESSION_COOKIE_NAME,
request.session.session_key, max_age=max_age, request.session.session_key,
expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, max_age=max_age,
path=settings.SESSION_COOKIE_PATH, expires=expires,
secure=settings.SESSION_COOKIE_SECURE or None, domain=settings.SESSION_COOKIE_DOMAIN,
httponly=settings.SESSION_COOKIE_HTTPONLY or None) path=settings.SESSION_COOKIE_PATH,
secure=settings.SESSION_COOKIE_SECURE or None,
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
return response return response

View File

@ -7,6 +7,7 @@ from __future__ import absolute_import
from greenmine.profile.models import Role from greenmine.profile.models import Role
from greenmine.scrum.models import ProjectUserRole from greenmine.scrum.models import ProjectUserRole
def get_role(name): def get_role(name):
""" """
Helper method for a get role object Helper method for a get role object
@ -27,8 +28,7 @@ def has_perm(user, project, loc, perm, pur=None):
except ProjectUserRole.DoesNotExist: except ProjectUserRole.DoesNotExist:
return False return False
return getattr(pur.role, \ return getattr(pur.role, '%s_%s' % (loc.lower(), perm.lower()), False)
'%s_%s' % (loc.lower(), perm.lower()), False)
def has_perms(user, project, perms=[]): def has_perms(user, project, perms=[]):
@ -56,8 +56,8 @@ def has_perms(user, project, perms=[]):
if not isinstance(locperms, (list, tuple)): if not isinstance(locperms, (list, tuple)):
locperms = [locperms] locperms = [locperms]
valid = False not in [has_perm(user, project, loc, locperm, pur=pur)\ valid = False not in [has_perm(user, project, loc, locperm, pur=pur)
for locperm in locperms] for locperm in locperms]
if not valid: if not valid:
break break

View File

@ -1,16 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf import settings import json
from django.test import TestCase from django.test import TestCase
from django.core import mail from django.core import mail
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.contrib.auth.models import User from django.contrib.auth.models import User
from ..models import *
from django.utils import timezone
import datetime
import json
from greenqueue import send_task from greenqueue import send_task
@ -20,11 +16,11 @@ class LowLevelEmailTests(TestCase):
mail.outbox = [] mail.outbox = []
def test_send_one_mail(self): def test_send_one_mail(self):
send_task("send-mail", args = ["subject", "template", ["hola@niwi.be"]]) send_task("send-mail", args=["subject", "template", ["hola@niwi.be"]])
self.assertEqual(len(mail.outbox), 1) self.assertEqual(len(mail.outbox), 1)
def test_send_bulk_mail(self): def test_send_bulk_mail(self):
send_task("send-bulk-mail", args = [[ send_task("send-bulk-mail", args=[[
('s1', 't1', ['hola@niwi.be']), ('s1', 't1', ['hola@niwi.be']),
('s2', 't2', ['hola@niwi.be']), ('s2', 't2', ['hola@niwi.be']),
]]) ]])
@ -35,19 +31,19 @@ class LowLevelEmailTests(TestCase):
class UserMailTests(TestCase): class UserMailTests(TestCase):
def setUp(self): def setUp(self):
self.user1 = User.objects.create( self.user1 = User.objects.create(
username = 'test1', username='test1',
email = 'test1@test.com', email='test1@test.com',
is_active = True, is_active=True,
is_staff = True, is_staff=True,
is_superuser = True, is_superuser=True,
) )
self.user2 = User.objects.create( self.user2 = User.objects.create(
username = 'test2', username='test2',
email = 'test2@test.com', email='test2@test.com',
is_active = True, is_active=True,
is_staff = False, is_staff=False,
is_superuser = False, is_superuser=False,
) )
self.user1.set_password("test") self.user1.set_password("test")
@ -123,4 +119,3 @@ class UserMailTests(TestCase):
ok = self.client.login(username="test2", password="123123") ok = self.client.login(username="test2", password="123123")
self.assertTrue(ok) self.assertTrue(ok)

View File

@ -2,6 +2,7 @@
import unicodedata import unicodedata
class Singleton(type): class Singleton(type):
""" Singleton metaclass. """ """ Singleton metaclass. """
def __init__(cls, name, bases, dct): def __init__(cls, name, bases, dct):
@ -10,7 +11,7 @@ class Singleton(type):
def __call__(cls, *args, **kw): def __call__(cls, *args, **kw):
if cls.__instance is None: if cls.__instance is None:
cls.__instance = type.__call__(cls, *args,**kw) cls.__instance = type.__call__(cls, *args, **kw)
return cls.__instance return cls.__instance

View File

@ -2,6 +2,7 @@
import uuid import uuid
def set_token(user): def set_token(user):
""" """
Set new token for user profile. Set new token for user profile.
@ -14,4 +15,3 @@ def set_token(user):
user.save() user.save()
profile.save() profile.save()
return token return token

View File

@ -1,33 +0,0 @@
# -*- coding: utf-8 -*-
import sys
import codecs
from docutils import nodes
from docutils.parsers.rst import Directive, directives
def set_source_info(directive, node):
node.source, node.line = \
directive.state_machine.get_source_and_line(directive.lineno)
class CodeBlock(Directive):
"""
Directive for a code block with special highlighting or line numbering
settings.
"""
has_content = True
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = False
def run(self):
code = u'\n'.join(self.content)
literal = nodes.literal_block(code, code)
literal['classes'] = ['brush: java;']
set_source_info(self, literal)
return [literal]

View File

@ -5,6 +5,7 @@ from django.template.defaultfilters import slugify
import time import time
def slugify_uniquely(value, model, slugfield="slug"): def slugify_uniquely(value, model, slugfield="slug"):
""" """
Returns a slug on a name which is unique within a model's table Returns a slug on a name which is unique within a model's table

View File

@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
from tastypie.authentication import SessionAuthentication from tastypie.authentication import SessionAuthentication
from tastypie.authorization import DjangoAuthorization from tastypie.authorization import DjangoAuthorization
from greenmine.documents.models import * from greenmine.documents.models import Document
class DocumentResource(ModelResource): class DocumentResource(ModelResource):
class Meta: class Meta:

View File

@ -1,2 +0,0 @@
i# -*- coding: utf-8 -*-
from .documents import *

View File

@ -1,11 +0,0 @@
# -*- coding: utf-8 -*-
from django.test import TestCase
from django.core import mail
from django.core.urlresolvers import reverse
import json
from django.contrib.auth.models import User
from ..models import *

View File

@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
from tastypie.authentication import SessionAuthentication from tastypie.authentication import SessionAuthentication
from tastypie.authorization import DjangoAuthorization from tastypie.authorization import DjangoAuthorization
from greenmine.profile.models import * from greenmine.profile.models import Profile
class ProfileResource(ModelResource): class ProfileResource(ModelResource):
class Meta: class Meta:

View File

@ -1,34 +1,20 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf import settings
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from django.utils import timezone
from django.core.files.storage import FileSystemStorage
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User
from greenmine.base.fields import DictField, ListField
from greenmine.base.utils import iter_points
import datetime
import re
class Profile(models.Model): class Profile(models.Model):
user = models.OneToOneField("auth.User", related_name='profile') user = models.OneToOneField("auth.User", related_name='profile')
description = models.TextField(blank=True) description = models.TextField(blank=True)
photo = models.FileField(upload_to="files/msg", photo = models.FileField(upload_to="files/msg", max_length=500, null=True,
max_length=500, null=True, blank=True) blank=True)
default_language = models.CharField(max_length=20, default_language = models.CharField(max_length=20, null=True, blank=True,
null=True, blank=True, default=None) default=None)
default_timezone = models.CharField(max_length=20, default_timezone = models.CharField(max_length=20, null=True, blank=True,
null=True, blank=True, default=None) default=None)
token = models.CharField(max_length=200, unique=True, token = models.CharField(max_length=200, unique=True, null=True,
null=True, blank=True, default=None) blank=True, default=None)
colorize_tags = models.BooleanField(default=False) colorize_tags = models.BooleanField(default=False)

View File

@ -8,6 +8,7 @@ from django.contrib.auth.models import User
from .models import Profile from .models import Profile
@receiver(post_save, sender=User) @receiver(post_save, sender=User)
def user_post_save(sender, instance, created, **kwargs): def user_post_save(sender, instance, created, **kwargs):
""" """

View File

@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
from tastypie.authentication import SessionAuthentication from tastypie.authentication import SessionAuthentication
from tastypie.authorization import DjangoAuthorization from tastypie.authorization import DjangoAuthorization
from greenmine.questions.models import * from greenmine.questions.models import Question, QuestionResponse
class QuestionResource(ModelResource): class QuestionResource(ModelResource):
class Meta: class Meta:
@ -12,6 +13,7 @@ class QuestionResource(ModelResource):
authentication = SessionAuthentication() authentication = SessionAuthentication()
authorization = DjangoAuthorization() authorization = DjangoAuthorization()
class QuestionResponseResource(ModelResource): class QuestionResponseResource(ModelResource):
class Meta: class Meta:
queryset = QuestionResponse.objects.all() queryset = QuestionResponse.objects.all()

View File

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib import admin from django.contrib import admin
from greenmine.scrum.models import Project, ProjectExtras, ProjectUserRole, Milestone, UserStory, Change, ChangeAttachment, Task from greenmine.scrum.models import Project, ProjectExtras, ProjectUserRole, \
Milestone, UserStory, Change, ChangeAttachment, Task
class ProjectAdmin(admin.ModelAdmin): class ProjectAdmin(admin.ModelAdmin):

View File

@ -3,7 +3,9 @@ from tastypie.resources import ModelResource
from tastypie.authentication import SessionAuthentication from tastypie.authentication import SessionAuthentication
from tastypie.authorization import DjangoAuthorization from tastypie.authorization import DjangoAuthorization
from greenmine.scrum.models import * from greenmine.scrum.models import Project, ProjectUserRole, \
Milestone, UserStory, Change, ChangeAttachment, Task
class ProjectResource(ModelResource): class ProjectResource(ModelResource):
class Meta: class Meta:
@ -12,6 +14,7 @@ class ProjectResource(ModelResource):
authentication = SessionAuthentication() authentication = SessionAuthentication()
authorization = DjangoAuthorization() authorization = DjangoAuthorization()
class ProjectUserRoleResource(ModelResource): class ProjectUserRoleResource(ModelResource):
class Meta: class Meta:
queryset = ProjectUserRole.objects.all() queryset = ProjectUserRole.objects.all()
@ -19,6 +22,7 @@ class ProjectUserRoleResource(ModelResource):
authentication = SessionAuthentication() authentication = SessionAuthentication()
authorization = DjangoAuthorization() authorization = DjangoAuthorization()
class MilestoneResource(ModelResource): class MilestoneResource(ModelResource):
class Meta: class Meta:
queryset = Milestone.objects.all() queryset = Milestone.objects.all()
@ -26,6 +30,7 @@ class MilestoneResource(ModelResource):
authentication = SessionAuthentication() authentication = SessionAuthentication()
authorization = DjangoAuthorization() authorization = DjangoAuthorization()
class UserStoryResource(ModelResource): class UserStoryResource(ModelResource):
class Meta: class Meta:
queryset = UserStory.objects.all() queryset = UserStory.objects.all()
@ -33,6 +38,7 @@ class UserStoryResource(ModelResource):
authentication = SessionAuthentication() authentication = SessionAuthentication()
authorization = DjangoAuthorization() authorization = DjangoAuthorization()
class ChangeResource(ModelResource): class ChangeResource(ModelResource):
class Meta: class Meta:
queryset = Change.objects.all() queryset = Change.objects.all()
@ -40,6 +46,7 @@ class ChangeResource(ModelResource):
authentication = SessionAuthentication() authentication = SessionAuthentication()
authorization = DjangoAuthorization() authorization = DjangoAuthorization()
class ChangeAttachmentResource(ModelResource): class ChangeAttachmentResource(ModelResource):
class Meta: class Meta:
queryset = ChangeAttachment.objects.all() queryset = ChangeAttachment.objects.all()
@ -47,6 +54,7 @@ class ChangeAttachmentResource(ModelResource):
authentication = SessionAuthentication() authentication = SessionAuthentication()
authorization = DjangoAuthorization() authorization = DjangoAuthorization()
class TaskResource(ModelResource): class TaskResource(ModelResource):
class Meta: class Meta:
queryset = Task.objects.all() queryset = Task.objects.all()

View File

@ -1,16 +1,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand, CommandError import random
import datetime
from django.core.management.base import BaseCommand
from django.db import transaction from django.db import transaction
from django.db.utils import IntegrityError
from django.core import management
from django.contrib.webdesign import lorem_ipsum
from django.utils.timezone import now from django.utils.timezone import now
import random, sys, datetime from django.contrib.webdesign import lorem_ipsum
from django.contrib.auth.models import User
from greenmine.base.models import * from greenmine.scrum.models import Project, Milestone, UserStory, Task
from greenmine.scrum.models import *
subjects = [ subjects = [
"Fixing templates for Django 1.2.", "Fixing templates for Django 1.2.",
@ -27,6 +27,7 @@ subjects = [
"Support for bulk actions", "Support for bulk actions",
] ]
class Command(BaseCommand): class Command(BaseCommand):
@transaction.commit_on_success @transaction.commit_on_success
def handle(self, *args, **options): def handle(self, *args, **options):
@ -36,9 +37,9 @@ class Command(BaseCommand):
def create_user(counter): def create_user(counter):
user = User.objects.create( user = User.objects.create(
username = 'foouser%d' % (counter), username='foouser%d' % (counter),
first_name = 'foouser%d' % (counter), first_name='foouser%d' % (counter),
email = 'foouser%d@foodomain.com' % (counter), email='foouser%d@foodomain.com' % (counter),
) )
return user return user
@ -46,10 +47,10 @@ class Command(BaseCommand):
for x in xrange(3): for x in xrange(3):
# create project # create project
project = Project.objects.create( project = Project.objects.create(
name = 'Project Example %s' % (x), name='Project Example %s' % (x),
description = 'Project example %s description' % (x), description='Project example %s description' % (x),
owner = random.choice(list(User.objects.all()[:1])), owner=random.choice(list(User.objects.all()[:1])),
public = True, public=True,
) )
project.add_user(project.owner, "developer") project.add_user(project.owner, "developer")
@ -74,70 +75,69 @@ class Command(BaseCommand):
# create random milestones # create random milestones
for y in xrange(2): for y in xrange(2):
milestone = Milestone.objects.create( milestone = Milestone.objects.create(
project = project, project=project,
name = 'Sprint %s' % (y), name='Sprint %s' % (y),
owner = project.owner, owner=project.owner,
created_date = now_date, created_date=now_date,
modified_date = now_date, modified_date=now_date,
estimated_start = now_date, estimated_start=now_date,
estimated_finish = now_date + datetime.timedelta(15) estimated_finish=now_date + datetime.timedelta(15)
) )
now_date = now_date + datetime.timedelta(15) now_date = now_date + datetime.timedelta(15)
# create uss asociated to milestones # create uss asociated to milestones
for z in xrange(5): for z in xrange(5):
us = UserStory.objects.create( us = UserStory.objects.create(
subject = lorem_ipsum.words(random.randint(4,9), common=False), subject=lorem_ipsum.words(random.randint(4, 9), common=False),
priority = 6, priority=6,
points = 3, points=3,
project = project, project=project,
owner = random.choice(participants), owner=random.choice(participants),
description = lorem_ipsum.words(30, common=False), description=lorem_ipsum.words(30, common=False),
milestone = milestone, milestone=milestone,
status = 'completed', status='completed',
) )
for tag in lorem_ipsum.words(random.randint(1,5), common=True).split(" "): for tag in lorem_ipsum.words(random.randint(1, 5), common=True).split(" "):
us.tags.add(tag) us.tags.add(tag)
for w in xrange(3): for w in xrange(3):
task = Task.objects.create( Task.objects.create(
subject = "Task %s" % (w), subject="Task %s" % (w),
description = lorem_ipsum.words(30, common=False), description=lorem_ipsum.words(30, common=False),
project = project, project=project,
owner = random.choice(participants), owner=random.choice(participants),
milestone = milestone, milestone=milestone,
user_story = us, user_story=us,
status = 'completed', status='completed',
) )
# created unassociated uss. # created unassociated uss.
for y in xrange(10): for y in xrange(10):
us = UserStory.objects.create( us = UserStory.objects.create(
subject = lorem_ipsum.words(random.randint(4,9), common=False), subject=lorem_ipsum.words(random.randint(4, 9), common=False),
priority = 3, priority=3,
points = 3, points=3,
status = 'open', status='open',
owner = random.choice(participants), owner=random.choice(participants),
description = lorem_ipsum.words(30, common=False), description=lorem_ipsum.words(30, common=False),
milestone = None, milestone=None,
project = project, project=project,
) )
for tag in lorem_ipsum.words(random.randint(1,5), common=True).split(" "): for tag in lorem_ipsum.words(random.randint(1, 5), common=True).split(" "):
us.tags.add(tag) us.tags.add(tag)
# create bugs. # create bugs.
for y in xrange(20): for y in xrange(20):
bug = Task.objects.create( bug = Task.objects.create(
project = project, project=project,
type = "bug", type="bug",
severity = random.randint(1,5), severity=random.randint(1, 5),
subject = lorem_ipsum.words(random.randint(1,5), common=False), subject=lorem_ipsum.words(random.randint(1, 5), common=False),
description = lorem_ipsum.words(random.randint(1,15), common=False), description=lorem_ipsum.words(random.randint(1, 15), common=False),
owner = project.owner, owner=project.owner,
) )
for tag in lorem_ipsum.words(random.randint(1,5), common=True).split(" "): for tag in lorem_ipsum.words(random.randint(1, 5), common=True).split(" "):
bug.tags.add(tag) bug.tags.add(tag)

View File

@ -1,6 +1,6 @@
# -* coding: utf-8 -*- # -* coding: utf-8 -*-
from haystack import indexes from haystack import indexes
from .models import Project, Milestone, UserStory, Task from greenmine.scrum.models import UserStory, Task
class UserStoryIndex(indexes.SearchIndex, indexes.Indexable): class UserStoryIndex(indexes.SearchIndex, indexes.Indexable):

View File

@ -1,20 +1,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.db.models.signals import post_save
from django.dispatch import receiver from django.dispatch import receiver
from django.conf import settings from django.conf import settings
from django.utils import timezone
from django.utils.translation import ugettext from django.utils.translation import ugettext
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.contrib.auth.models import User from django.contrib.auth.models import User
from greenmine.profile.models import Profile from greenmine.scrum.models import ProjectUserRole
from greenmine.scrum.models import UserStory, Task, ProjectUserRole
from greenmine.base import signals from greenmine.base import signals
from greenmine.base.utils import normalize_tagname
from greenmine.base.utils.auth import set_token from greenmine.base.utils.auth import set_token
from greenmine.base.mail.tasks import send_email, send_bulk_email from greenmine.base.mail.tasks import send_mail, send_bulk_mail
@receiver(signals.mail_new_user) @receiver(signals.mail_new_user)
@ -62,6 +58,7 @@ def mail_milestone_created(sender, milestone, user, **kwargs):
send_bulk_mail.delay(emails_list) send_bulk_mail.delay(emails_list)
@receiver(signals.mail_userstory_created) @receiver(signals.mail_userstory_created)
def mail_userstory_created(sender, us, user, **kwargs): def mail_userstory_created(sender, us, user, **kwargs):
participants_ids = ProjectUserRole.objects\ participants_ids = ProjectUserRole.objects\

View File

@ -2,6 +2,7 @@ from django.conf import settings
__all__ = ('SCRUM_STATES',) __all__ = ('SCRUM_STATES',)
class GmScrumStates(object): class GmScrumStates(object):
def __init__(self): def __init__(self):
self._states = settings.GM_SCRUM_STATES self._states = settings.GM_SCRUM_STATES
@ -23,14 +24,14 @@ class GmScrumStates(object):
for us_state in self._states.values(): for us_state in self._states.values():
if us_state['is_finished']: if us_state['is_finished']:
finished_task_states += us_state['task_states'] finished_task_states += us_state['task_states']
return [ x[0] for x in finished_task_states ] return [x[0] for x in finished_task_states]
def get_unfinished_task_states(self): def get_unfinished_task_states(self):
unfinished_task_states = [] unfinished_task_states = []
for us_state in self._states.values(): for us_state in self._states.values():
if not us_state['is_finished']: if not us_state['is_finished']:
unfinished_task_states += us_state['task_states'] unfinished_task_states += us_state['task_states']
return [ x[0] for x in unfinished_task_states ] return [x[0] for x in unfinished_task_states]
def get_finished_us_states(self): def get_finished_us_states(self):
finished_us_states = [] finished_us_states = []
@ -48,17 +49,17 @@ class GmScrumStates(object):
def get_us_state_for_task_state(self, state): def get_us_state_for_task_state(self, state):
for key, value in self._states.iteritems(): for key, value in self._states.iteritems():
if state in [ x[0] for x in value['task_states'] ]: if state in [x[0] for x in value['task_states']]:
return key return key
return None return None
def get_task_states_for_us_state(self, state): def get_task_states_for_us_state(self, state):
if state in self._states.keys(): if state in self._states.keys():
return [ x[0] for x in self._states[state]['task_states'] ] return [x[0] for x in self._states[state]['task_states']]
return None return None
def ordered_us_states(self): def ordered_us_states(self):
ordered = sorted([ (value['order'], key) for key, value in self._states.iteritems() ]) ordered = sorted([(value['order'], key) for key, value in self._states.iteritems()])
return [ x[1] for x in ordered ] return [x[1] for x in ordered]
SCRUM_STATES = GmScrumStates() SCRUM_STATES = GmScrumStates()

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls.defaults import patterns, url from django.conf.urls.defaults import patterns, url
from .views import *
from greenmine.search.views import SearchView
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^$', SearchView.as_view(), name='search'), url(r'^$', SearchView.as_view(), name='search'),
) )

View File

@ -1,8 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from haystack.query import EmptySearchQuerySet
from django.core.paginator import Paginator, InvalidPage from django.core.paginator import Paginator, InvalidPage
from django.conf import settings from django.conf import settings
from django.http import Http404 from django.http import Http404
from haystack.query import EmptySearchQuerySet from django.utils.translation import ugettext as _
from greenmine.base.decorators import login_required from greenmine.base.decorators import login_required
from greenmine.base.generic import GenericView from greenmine.base.generic import GenericView
@ -53,4 +55,3 @@ class SearchView(GenericView):
} }
return self.render_to_response(self.template_path, context) return self.render_to_response(self.template_path, context)

View File

@ -9,6 +9,7 @@ from .models import Tag, TaggedItem
class TaggedItemInline(admin.StackedInline): class TaggedItemInline(admin.StackedInline):
model = TaggedItem model = TaggedItem
class TagAdmin(admin.ModelAdmin): class TagAdmin(admin.ModelAdmin):
list_display = ["name"] list_display = ["name"]
inlines = [ inlines = [

View File

@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
from tastypie.authentication import SessionAuthentication from tastypie.authentication import SessionAuthentication
from tastypie.authorization import DjangoAuthorization from tastypie.authorization import DjangoAuthorization
from greenmine.taggit.models import * from greenmine.taggit.models import Tag, TaggedItem
class TagResource(ModelResource): class TagResource(ModelResource):
class Meta: class Meta:
@ -12,6 +13,7 @@ class TagResource(ModelResource):
authentication = SessionAuthentication() authentication = SessionAuthentication()
authorization = DjangoAuthorization() authorization = DjangoAuthorization()
class TaggedItemResource(ModelResource): class TaggedItemResource(ModelResource):
class Meta: class Meta:
queryset = TaggedItem.objects.all() queryset = TaggedItem.objects.all()

View File

@ -6,11 +6,10 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.db.models.fields.related import ManyToManyRel, RelatedField, add_lazy_relation from django.db.models.fields.related import ManyToManyRel, RelatedField, add_lazy_relation
from django.db.models.related import RelatedObject from django.db.models.related import RelatedObject
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from .models import TaggedItem, GenericTaggedItemBase, Tag from greenmine.taggit.models import TaggedItem, GenericTaggedItemBase
from .utils import require_instance_manager from greenmine.taggit.utils import require_instance_manager
class TaggableRel(ManyToManyRel): class TaggableRel(ManyToManyRel):
@ -24,7 +23,8 @@ class TaggableRel(ManyToManyRel):
class TaggableManager(RelatedField): class TaggableManager(RelatedField):
def __init__(self, verbose_name=_("Tags"), def __init__(self, verbose_name=_("Tags"),
help_text=_("A comma-separated list of tags."), through=None, blank=False): help_text=_("A comma-separated list of tags."), through=None,
blank=False):
self.through = through or TaggedItem self.through = through or TaggedItem
self.rel = TaggableRel() self.rel = TaggableRel()
self.verbose_name = verbose_name self.verbose_name = verbose_name
@ -43,7 +43,7 @@ class TaggableManager(RelatedField):
def __get__(self, instance, model): def __get__(self, instance, model):
if instance is not None and instance.pk is None: if instance is not None and instance.pk is None:
raise ValueError("%s objects need to have a primary key value " raise ValueError("%s objects need to have a primary key value "
"before you can access their tags." % model.__name__) "before you can access their tags." % model.__name__)
manager = _TaggableManager( manager = _TaggableManager(
through=self.through, model=model, instance=instance through=self.through, model=model, instance=instance
) )
@ -216,7 +216,6 @@ def _get_subclasses(model):
subclasses = [model] subclasses = [model]
for f in model._meta.get_all_field_names(): for f in model._meta.get_all_field_names():
field = model._meta.get_field_by_name(f)[0] field = model._meta.get_field_by_name(f)[0]
if (isinstance(field, RelatedObject) and if (isinstance(field, RelatedObject) and getattr(field.field.rel, "parent_link", None)):
getattr(field.field.rel, "parent_link", None)):
subclasses.extend(_get_subclasses(field.model)) subclasses.extend(_get_subclasses(field.model))
return subclasses return subclasses

View File

@ -5,11 +5,11 @@ import django
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.generic import GenericForeignKey from django.contrib.contenttypes.generic import GenericForeignKey
from django.db import connection, models, IntegrityError, transaction from django.db import connection, models, IntegrityError, transaction
from django.db.models.query import QuerySet
from django.template.defaultfilters import slugify as default_slugify from django.template.defaultfilters import slugify as default_slugify
from django.utils.translation import ugettext_lazy as _, ugettext from django.utils.translation import ugettext_lazy as _, ugettext
qn = connection.ops.quote_name qn = connection.ops.quote_name
class TagBase(models.Model): class TagBase(models.Model):
name = models.CharField(verbose_name=_('Name'), max_length=100) name = models.CharField(verbose_name=_('Name'), max_length=100)
slug = models.SlugField(verbose_name=_('Slug'), unique=True, max_length=100) slug = models.SlugField(verbose_name=_('Slug'), unique=True, max_length=100)
@ -82,14 +82,13 @@ class TagManager(models.Manager):
extra_criteria = '' extra_criteria = ''
return self._get_usage(queryset.model, counts, min_count, extra_joins, extra_criteria, params) return self._get_usage(queryset.model, counts, min_count, extra_joins, extra_criteria, params)
def _get_usage(self, model, counts=False, min_count=None, extra_joins=None, extra_criteria=None, params=None): def _get_usage(self, model, counts=False, min_count=None, extra_joins=None, extra_criteria=None, params=None):
""" """
Perform the custom SQL query for ``usage_for_model`` and Perform the custom SQL query for ``usage_for_model`` and
``usage_for_queryset``. ``usage_for_queryset``.
""" """
if min_count is not None: counts = True if min_count is not None:
counts = True
model_table = qn(model._meta.db_table) model_table = qn(model._meta.db_table)
model_pk = '%s.%s' % (model_table, qn(model._meta.pk.column)) model_pk = '%s.%s' % (model_table, qn(model._meta.pk.column))
@ -216,7 +215,7 @@ class GenericTaggedItemBase(ItemBase):
content_object = GenericForeignKey() content_object = GenericForeignKey()
class Meta: class Meta:
abstract=True abstract = True
@classmethod @classmethod
def lookup_kwargs(cls, instance): def lookup_kwargs(cls, instance):

View File

@ -5,8 +5,6 @@ from django.utils.encoding import force_unicode
from django.utils.functional import wraps from django.utils.functional import wraps
from django.db.models import Count from django.db.models import Count
from .models import TaggedItem
def get_tags_for_queryset(queryset, tags_attribute='tags'): def get_tags_for_queryset(queryset, tags_attribute='tags'):
""" """

View File

@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
from tastypie.authentication import SessionAuthentication from tastypie.authentication import SessionAuthentication
from tastypie.authorization import DjangoAuthorization from tastypie.authorization import DjangoAuthorization
from greenmine.wiki.models import * from greenmine.wiki.models import WikiPage, WikiPageHistory, WikiPageAttachment
class WikiPageResource(ModelResource): class WikiPageResource(ModelResource):
class Meta: class Meta: