Refactoring with flake8
parent
a03fa3f3db
commit
4cb3df6ee9
|
@ -8,6 +8,7 @@ from django.contrib.auth.models import User
|
|||
|
||||
import json
|
||||
|
||||
|
||||
class Login(View):
|
||||
def post(self, request):
|
||||
username = request.POST.get('username', None)
|
||||
|
@ -30,6 +31,7 @@ class Login(View):
|
|||
def dispatch(self, *args, **kwargs):
|
||||
return super(Login, self).dispatch(*args, **kwargs)
|
||||
|
||||
|
||||
class Logout(View):
|
||||
def post(self, request):
|
||||
logout(request)
|
||||
|
|
|
@ -14,6 +14,7 @@ import logging
|
|||
|
||||
logger = logging.getLogger("niwi")
|
||||
|
||||
|
||||
class DictField(models.Field):
|
||||
""" Dictionary pickled field. """
|
||||
__metaclass__ = models.SubfieldBase
|
||||
|
@ -64,7 +65,7 @@ class ListField(models.Field):
|
|||
__pickleproto__ = -1
|
||||
|
||||
def to_python(self, value):
|
||||
if isinstance(value, (list,tuple)):
|
||||
if isinstance(value, (list, tuple)):
|
||||
return value
|
||||
|
||||
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):
|
||||
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__))
|
||||
else:
|
||||
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)
|
||||
|
||||
def to_python(self, value):
|
||||
if not value: return
|
||||
if not value:
|
||||
return
|
||||
if isinstance(value, list):
|
||||
return value
|
||||
return value.split(self.token)
|
||||
|
||||
def get_db_prep_value(self, value):
|
||||
if not value: return
|
||||
if not value:
|
||||
return
|
||||
assert(isinstance(value, list) or isinstance(value, tuple))
|
||||
return self.token.join([unicode(s) for s in value])
|
||||
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
|
||||
from celery import task
|
||||
|
||||
from django.template import loader
|
||||
from django.utils import translation
|
||||
from django.core import mail
|
||||
|
||||
from greenmine.base.utils.auth import set_token
|
||||
|
||||
@task(name='send-mail')
|
||||
def send_mail(subject, body, to):
|
||||
|
@ -16,10 +11,11 @@ def send_mail(subject, body, to):
|
|||
email_message.content_subtype = "html"
|
||||
email_message.send()
|
||||
|
||||
|
||||
@task(name='send-bulk-mail')
|
||||
def send_bulk_mail(emails):
|
||||
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:
|
||||
msg.content_subtype = "html"
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.cache import patch_vary_headers
|
|||
from django.utils.http import cookie_date
|
||||
from django.utils.importlib import import_module
|
||||
|
||||
|
||||
class GreenmineSessionMiddleware(object):
|
||||
def process_request(self, request):
|
||||
engine = import_module(settings.SESSION_ENGINE)
|
||||
|
@ -39,9 +40,11 @@ class GreenmineSessionMiddleware(object):
|
|||
if response.status_code != 500:
|
||||
request.session.save()
|
||||
response.set_cookie(settings.SESSION_COOKIE_NAME,
|
||||
request.session.session_key, max_age=max_age,
|
||||
expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
|
||||
path=settings.SESSION_COOKIE_PATH,
|
||||
secure=settings.SESSION_COOKIE_SECURE or None,
|
||||
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
|
||||
request.session.session_key,
|
||||
max_age=max_age,
|
||||
expires=expires,
|
||||
domain=settings.SESSION_COOKIE_DOMAIN,
|
||||
path=settings.SESSION_COOKIE_PATH,
|
||||
secure=settings.SESSION_COOKIE_SECURE or None,
|
||||
httponly=settings.SESSION_COOKIE_HTTPONLY or None)
|
||||
return response
|
||||
|
|
|
@ -7,6 +7,7 @@ from __future__ import absolute_import
|
|||
from greenmine.profile.models import Role
|
||||
from greenmine.scrum.models import ProjectUserRole
|
||||
|
||||
|
||||
def get_role(name):
|
||||
"""
|
||||
Helper method for a get role object
|
||||
|
@ -27,8 +28,7 @@ def has_perm(user, project, loc, perm, pur=None):
|
|||
except ProjectUserRole.DoesNotExist:
|
||||
return False
|
||||
|
||||
return getattr(pur.role, \
|
||||
'%s_%s' % (loc.lower(), perm.lower()), False)
|
||||
return getattr(pur.role, '%s_%s' % (loc.lower(), perm.lower()), False)
|
||||
|
||||
|
||||
def has_perms(user, project, perms=[]):
|
||||
|
@ -56,8 +56,8 @@ def has_perms(user, project, perms=[]):
|
|||
if not isinstance(locperms, (list, tuple)):
|
||||
locperms = [locperms]
|
||||
|
||||
valid = False not in [has_perm(user, project, loc, locperm, pur=pur)\
|
||||
for locperm in locperms]
|
||||
valid = False not in [has_perm(user, project, loc, locperm, pur=pur)
|
||||
for locperm in locperms]
|
||||
|
||||
if not valid:
|
||||
break
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.conf import settings
|
||||
import json
|
||||
|
||||
from django.test import TestCase
|
||||
from django.core import mail
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from ..models import *
|
||||
|
||||
from django.utils import timezone
|
||||
import datetime
|
||||
import json
|
||||
|
||||
from greenqueue import send_task
|
||||
|
||||
|
@ -20,11 +16,11 @@ class LowLevelEmailTests(TestCase):
|
|||
mail.outbox = []
|
||||
|
||||
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)
|
||||
|
||||
def test_send_bulk_mail(self):
|
||||
send_task("send-bulk-mail", args = [[
|
||||
send_task("send-bulk-mail", args=[[
|
||||
('s1', 't1', ['hola@niwi.be']),
|
||||
('s2', 't2', ['hola@niwi.be']),
|
||||
]])
|
||||
|
@ -35,19 +31,19 @@ class LowLevelEmailTests(TestCase):
|
|||
class UserMailTests(TestCase):
|
||||
def setUp(self):
|
||||
self.user1 = User.objects.create(
|
||||
username = 'test1',
|
||||
email = 'test1@test.com',
|
||||
is_active = True,
|
||||
is_staff = True,
|
||||
is_superuser = True,
|
||||
username='test1',
|
||||
email='test1@test.com',
|
||||
is_active=True,
|
||||
is_staff=True,
|
||||
is_superuser=True,
|
||||
)
|
||||
|
||||
self.user2 = User.objects.create(
|
||||
username = 'test2',
|
||||
email = 'test2@test.com',
|
||||
is_active = True,
|
||||
is_staff = False,
|
||||
is_superuser = False,
|
||||
username='test2',
|
||||
email='test2@test.com',
|
||||
is_active=True,
|
||||
is_staff=False,
|
||||
is_superuser=False,
|
||||
)
|
||||
|
||||
self.user1.set_password("test")
|
||||
|
@ -123,4 +119,3 @@ class UserMailTests(TestCase):
|
|||
|
||||
ok = self.client.login(username="test2", password="123123")
|
||||
self.assertTrue(ok)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import unicodedata
|
||||
|
||||
|
||||
class Singleton(type):
|
||||
""" Singleton metaclass. """
|
||||
def __init__(cls, name, bases, dct):
|
||||
|
@ -10,7 +11,7 @@ class Singleton(type):
|
|||
|
||||
def __call__(cls, *args, **kw):
|
||||
if cls.__instance is None:
|
||||
cls.__instance = type.__call__(cls, *args,**kw)
|
||||
cls.__instance = type.__call__(cls, *args, **kw)
|
||||
return cls.__instance
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import uuid
|
||||
|
||||
|
||||
def set_token(user):
|
||||
"""
|
||||
Set new token for user profile.
|
||||
|
@ -14,4 +15,3 @@ def set_token(user):
|
|||
user.save()
|
||||
profile.save()
|
||||
return token
|
||||
|
||||
|
|
|
@ -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]
|
|
@ -5,6 +5,7 @@ from django.template.defaultfilters import slugify
|
|||
|
||||
import time
|
||||
|
||||
|
||||
def slugify_uniquely(value, model, slugfield="slug"):
|
||||
"""
|
||||
Returns a slug on a name which is unique within a model's table
|
||||
|
|
|
@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
|
|||
from tastypie.authentication import SessionAuthentication
|
||||
from tastypie.authorization import DjangoAuthorization
|
||||
|
||||
from greenmine.documents.models import *
|
||||
from greenmine.documents.models import Document
|
||||
|
||||
|
||||
class DocumentResource(ModelResource):
|
||||
class Meta:
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
i# -*- coding: utf-8 -*-
|
||||
from .documents import *
|
|
@ -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 *
|
||||
|
||||
|
|
@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
|
|||
from tastypie.authentication import SessionAuthentication
|
||||
from tastypie.authorization import DjangoAuthorization
|
||||
|
||||
from greenmine.profile.models import *
|
||||
from greenmine.profile.models import Profile
|
||||
|
||||
|
||||
class ProfileResource(ModelResource):
|
||||
class Meta:
|
||||
|
|
|
@ -1,34 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.conf import settings
|
||||
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):
|
||||
user = models.OneToOneField("auth.User", related_name='profile')
|
||||
description = models.TextField(blank=True)
|
||||
photo = models.FileField(upload_to="files/msg",
|
||||
max_length=500, null=True, blank=True)
|
||||
photo = models.FileField(upload_to="files/msg", max_length=500, null=True,
|
||||
blank=True)
|
||||
|
||||
default_language = models.CharField(max_length=20,
|
||||
null=True, blank=True, default=None)
|
||||
default_timezone = models.CharField(max_length=20,
|
||||
null=True, blank=True, default=None)
|
||||
token = models.CharField(max_length=200, unique=True,
|
||||
null=True, blank=True, default=None)
|
||||
default_language = models.CharField(max_length=20, null=True, blank=True,
|
||||
default=None)
|
||||
default_timezone = models.CharField(max_length=20, null=True, blank=True,
|
||||
default=None)
|
||||
token = models.CharField(max_length=200, unique=True, null=True,
|
||||
blank=True, default=None)
|
||||
colorize_tags = models.BooleanField(default=False)
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ from django.contrib.auth.models import User
|
|||
|
||||
from .models import Profile
|
||||
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def user_post_save(sender, instance, created, **kwargs):
|
||||
"""
|
||||
|
|
|
@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
|
|||
from tastypie.authentication import SessionAuthentication
|
||||
from tastypie.authorization import DjangoAuthorization
|
||||
|
||||
from greenmine.questions.models import *
|
||||
from greenmine.questions.models import Question, QuestionResponse
|
||||
|
||||
|
||||
class QuestionResource(ModelResource):
|
||||
class Meta:
|
||||
|
@ -12,6 +13,7 @@ class QuestionResource(ModelResource):
|
|||
authentication = SessionAuthentication()
|
||||
authorization = DjangoAuthorization()
|
||||
|
||||
|
||||
class QuestionResponseResource(ModelResource):
|
||||
class Meta:
|
||||
queryset = QuestionResponse.objects.all()
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
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):
|
||||
|
|
|
@ -3,7 +3,9 @@ from tastypie.resources import ModelResource
|
|||
from tastypie.authentication import SessionAuthentication
|
||||
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 Meta:
|
||||
|
@ -12,6 +14,7 @@ class ProjectResource(ModelResource):
|
|||
authentication = SessionAuthentication()
|
||||
authorization = DjangoAuthorization()
|
||||
|
||||
|
||||
class ProjectUserRoleResource(ModelResource):
|
||||
class Meta:
|
||||
queryset = ProjectUserRole.objects.all()
|
||||
|
@ -19,6 +22,7 @@ class ProjectUserRoleResource(ModelResource):
|
|||
authentication = SessionAuthentication()
|
||||
authorization = DjangoAuthorization()
|
||||
|
||||
|
||||
class MilestoneResource(ModelResource):
|
||||
class Meta:
|
||||
queryset = Milestone.objects.all()
|
||||
|
@ -26,6 +30,7 @@ class MilestoneResource(ModelResource):
|
|||
authentication = SessionAuthentication()
|
||||
authorization = DjangoAuthorization()
|
||||
|
||||
|
||||
class UserStoryResource(ModelResource):
|
||||
class Meta:
|
||||
queryset = UserStory.objects.all()
|
||||
|
@ -33,6 +38,7 @@ class UserStoryResource(ModelResource):
|
|||
authentication = SessionAuthentication()
|
||||
authorization = DjangoAuthorization()
|
||||
|
||||
|
||||
class ChangeResource(ModelResource):
|
||||
class Meta:
|
||||
queryset = Change.objects.all()
|
||||
|
@ -40,6 +46,7 @@ class ChangeResource(ModelResource):
|
|||
authentication = SessionAuthentication()
|
||||
authorization = DjangoAuthorization()
|
||||
|
||||
|
||||
class ChangeAttachmentResource(ModelResource):
|
||||
class Meta:
|
||||
queryset = ChangeAttachment.objects.all()
|
||||
|
@ -47,6 +54,7 @@ class ChangeAttachmentResource(ModelResource):
|
|||
authentication = SessionAuthentication()
|
||||
authorization = DjangoAuthorization()
|
||||
|
||||
|
||||
class TaskResource(ModelResource):
|
||||
class Meta:
|
||||
queryset = Task.objects.all()
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# -*- 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.utils import IntegrityError
|
||||
from django.core import management
|
||||
from django.contrib.webdesign import lorem_ipsum
|
||||
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 *
|
||||
from greenmine.scrum.models import Project, Milestone, UserStory, Task
|
||||
|
||||
subjects = [
|
||||
"Fixing templates for Django 1.2.",
|
||||
|
@ -27,6 +27,7 @@ subjects = [
|
|||
"Support for bulk actions",
|
||||
]
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
@transaction.commit_on_success
|
||||
def handle(self, *args, **options):
|
||||
|
@ -36,9 +37,9 @@ class Command(BaseCommand):
|
|||
|
||||
def create_user(counter):
|
||||
user = User.objects.create(
|
||||
username = 'foouser%d' % (counter),
|
||||
first_name = 'foouser%d' % (counter),
|
||||
email = 'foouser%d@foodomain.com' % (counter),
|
||||
username='foouser%d' % (counter),
|
||||
first_name='foouser%d' % (counter),
|
||||
email='foouser%d@foodomain.com' % (counter),
|
||||
)
|
||||
return user
|
||||
|
||||
|
@ -46,10 +47,10 @@ class Command(BaseCommand):
|
|||
for x in xrange(3):
|
||||
# create project
|
||||
project = Project.objects.create(
|
||||
name = 'Project Example %s' % (x),
|
||||
description = 'Project example %s description' % (x),
|
||||
owner = random.choice(list(User.objects.all()[:1])),
|
||||
public = True,
|
||||
name='Project Example %s' % (x),
|
||||
description='Project example %s description' % (x),
|
||||
owner=random.choice(list(User.objects.all()[:1])),
|
||||
public=True,
|
||||
)
|
||||
|
||||
project.add_user(project.owner, "developer")
|
||||
|
@ -74,70 +75,69 @@ class Command(BaseCommand):
|
|||
# create random milestones
|
||||
for y in xrange(2):
|
||||
milestone = Milestone.objects.create(
|
||||
project = project,
|
||||
name = 'Sprint %s' % (y),
|
||||
owner = project.owner,
|
||||
created_date = now_date,
|
||||
modified_date = now_date,
|
||||
estimated_start = now_date,
|
||||
estimated_finish = now_date + datetime.timedelta(15)
|
||||
project=project,
|
||||
name='Sprint %s' % (y),
|
||||
owner=project.owner,
|
||||
created_date=now_date,
|
||||
modified_date=now_date,
|
||||
estimated_start=now_date,
|
||||
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
|
||||
for z in xrange(5):
|
||||
us = UserStory.objects.create(
|
||||
subject = lorem_ipsum.words(random.randint(4,9), common=False),
|
||||
priority = 6,
|
||||
points = 3,
|
||||
project = project,
|
||||
owner = random.choice(participants),
|
||||
description = lorem_ipsum.words(30, common=False),
|
||||
milestone = milestone,
|
||||
status = 'completed',
|
||||
subject=lorem_ipsum.words(random.randint(4, 9), common=False),
|
||||
priority=6,
|
||||
points=3,
|
||||
project=project,
|
||||
owner=random.choice(participants),
|
||||
description=lorem_ipsum.words(30, common=False),
|
||||
milestone=milestone,
|
||||
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)
|
||||
|
||||
for w in xrange(3):
|
||||
task = Task.objects.create(
|
||||
subject = "Task %s" % (w),
|
||||
description = lorem_ipsum.words(30, common=False),
|
||||
project = project,
|
||||
owner = random.choice(participants),
|
||||
milestone = milestone,
|
||||
user_story = us,
|
||||
status = 'completed',
|
||||
Task.objects.create(
|
||||
subject="Task %s" % (w),
|
||||
description=lorem_ipsum.words(30, common=False),
|
||||
project=project,
|
||||
owner=random.choice(participants),
|
||||
milestone=milestone,
|
||||
user_story=us,
|
||||
status='completed',
|
||||
)
|
||||
|
||||
# created unassociated uss.
|
||||
for y in xrange(10):
|
||||
us = UserStory.objects.create(
|
||||
subject = lorem_ipsum.words(random.randint(4,9), common=False),
|
||||
priority = 3,
|
||||
points = 3,
|
||||
status = 'open',
|
||||
owner = random.choice(participants),
|
||||
description = lorem_ipsum.words(30, common=False),
|
||||
milestone = None,
|
||||
project = project,
|
||||
subject=lorem_ipsum.words(random.randint(4, 9), common=False),
|
||||
priority=3,
|
||||
points=3,
|
||||
status='open',
|
||||
owner=random.choice(participants),
|
||||
description=lorem_ipsum.words(30, common=False),
|
||||
milestone=None,
|
||||
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)
|
||||
|
||||
# create bugs.
|
||||
for y in xrange(20):
|
||||
bug = Task.objects.create(
|
||||
project = project,
|
||||
type = "bug",
|
||||
severity = random.randint(1,5),
|
||||
subject = lorem_ipsum.words(random.randint(1,5), common=False),
|
||||
description = lorem_ipsum.words(random.randint(1,15), common=False),
|
||||
owner = project.owner,
|
||||
project=project,
|
||||
type="bug",
|
||||
severity=random.randint(1, 5),
|
||||
subject=lorem_ipsum.words(random.randint(1, 5), common=False),
|
||||
description=lorem_ipsum.words(random.randint(1, 15), common=False),
|
||||
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)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -* coding: utf-8 -*-
|
||||
from haystack import indexes
|
||||
from .models import Project, Milestone, UserStory, Task
|
||||
from greenmine.scrum.models import UserStory, Task
|
||||
|
||||
|
||||
class UserStoryIndex(indexes.SearchIndex, indexes.Indexable):
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import ugettext
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from greenmine.profile.models import Profile
|
||||
from greenmine.scrum.models import UserStory, Task, ProjectUserRole
|
||||
from greenmine.scrum.models import ProjectUserRole
|
||||
from greenmine.base import signals
|
||||
from greenmine.base.utils import normalize_tagname
|
||||
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)
|
||||
|
@ -62,6 +58,7 @@ def mail_milestone_created(sender, milestone, user, **kwargs):
|
|||
|
||||
send_bulk_mail.delay(emails_list)
|
||||
|
||||
|
||||
@receiver(signals.mail_userstory_created)
|
||||
def mail_userstory_created(sender, us, user, **kwargs):
|
||||
participants_ids = ProjectUserRole.objects\
|
||||
|
|
|
@ -2,6 +2,7 @@ from django.conf import settings
|
|||
|
||||
__all__ = ('SCRUM_STATES',)
|
||||
|
||||
|
||||
class GmScrumStates(object):
|
||||
def __init__(self):
|
||||
self._states = settings.GM_SCRUM_STATES
|
||||
|
@ -23,14 +24,14 @@ class GmScrumStates(object):
|
|||
for us_state in self._states.values():
|
||||
if us_state['is_finished']:
|
||||
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):
|
||||
unfinished_task_states = []
|
||||
for us_state in self._states.values():
|
||||
if not us_state['is_finished']:
|
||||
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):
|
||||
finished_us_states = []
|
||||
|
@ -48,17 +49,17 @@ class GmScrumStates(object):
|
|||
|
||||
def get_us_state_for_task_state(self, state):
|
||||
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 None
|
||||
|
||||
def get_task_states_for_us_state(self, state):
|
||||
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
|
||||
|
||||
def ordered_us_states(self):
|
||||
ordered = sorted([ (value['order'], key) for key, value in self._states.iteritems() ])
|
||||
return [ x[1] for x in ordered ]
|
||||
ordered = sorted([(value['order'], key) for key, value in self._states.iteritems()])
|
||||
return [x[1] for x in ordered]
|
||||
|
||||
SCRUM_STATES = GmScrumStates()
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
from .views import *
|
||||
|
||||
from greenmine.search.views import SearchView
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', SearchView.as_view(), name='search'),
|
||||
)
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from haystack.query import EmptySearchQuerySet
|
||||
|
||||
from django.core.paginator import Paginator, InvalidPage
|
||||
from django.conf import settings
|
||||
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.generic import GenericView
|
||||
|
@ -53,4 +55,3 @@ class SearchView(GenericView):
|
|||
}
|
||||
|
||||
return self.render_to_response(self.template_path, context)
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ from .models import Tag, TaggedItem
|
|||
class TaggedItemInline(admin.StackedInline):
|
||||
model = TaggedItem
|
||||
|
||||
|
||||
class TagAdmin(admin.ModelAdmin):
|
||||
list_display = ["name"]
|
||||
inlines = [
|
||||
|
|
|
@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
|
|||
from tastypie.authentication import SessionAuthentication
|
||||
from tastypie.authorization import DjangoAuthorization
|
||||
|
||||
from greenmine.taggit.models import *
|
||||
from greenmine.taggit.models import Tag, TaggedItem
|
||||
|
||||
|
||||
class TagResource(ModelResource):
|
||||
class Meta:
|
||||
|
@ -12,6 +13,7 @@ class TagResource(ModelResource):
|
|||
authentication = SessionAuthentication()
|
||||
authorization = DjangoAuthorization()
|
||||
|
||||
|
||||
class TaggedItemResource(ModelResource):
|
||||
class Meta:
|
||||
queryset = TaggedItem.objects.all()
|
||||
|
|
|
@ -6,11 +6,10 @@ from django.contrib.contenttypes.models import ContentType
|
|||
from django.db import models
|
||||
from django.db.models.fields.related import ManyToManyRel, RelatedField, add_lazy_relation
|
||||
from django.db.models.related import RelatedObject
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .models import TaggedItem, GenericTaggedItemBase, Tag
|
||||
from .utils import require_instance_manager
|
||||
from greenmine.taggit.models import TaggedItem, GenericTaggedItemBase
|
||||
from greenmine.taggit.utils import require_instance_manager
|
||||
|
||||
|
||||
class TaggableRel(ManyToManyRel):
|
||||
|
@ -24,7 +23,8 @@ class TaggableRel(ManyToManyRel):
|
|||
|
||||
class TaggableManager(RelatedField):
|
||||
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.rel = TaggableRel()
|
||||
self.verbose_name = verbose_name
|
||||
|
@ -43,7 +43,7 @@ class TaggableManager(RelatedField):
|
|||
def __get__(self, instance, model):
|
||||
if instance is not None and instance.pk is None:
|
||||
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(
|
||||
through=self.through, model=model, instance=instance
|
||||
)
|
||||
|
@ -216,7 +216,6 @@ def _get_subclasses(model):
|
|||
subclasses = [model]
|
||||
for f in model._meta.get_all_field_names():
|
||||
field = model._meta.get_field_by_name(f)[0]
|
||||
if (isinstance(field, RelatedObject) and
|
||||
getattr(field.field.rel, "parent_link", None)):
|
||||
if (isinstance(field, RelatedObject) and getattr(field.field.rel, "parent_link", None)):
|
||||
subclasses.extend(_get_subclasses(field.model))
|
||||
return subclasses
|
||||
|
|
|
@ -5,11 +5,11 @@ import django
|
|||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.contenttypes.generic import GenericForeignKey
|
||||
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.utils.translation import ugettext_lazy as _, ugettext
|
||||
qn = connection.ops.quote_name
|
||||
|
||||
|
||||
class TagBase(models.Model):
|
||||
name = models.CharField(verbose_name=_('Name'), max_length=100)
|
||||
slug = models.SlugField(verbose_name=_('Slug'), unique=True, max_length=100)
|
||||
|
@ -82,14 +82,13 @@ class TagManager(models.Manager):
|
|||
extra_criteria = ''
|
||||
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):
|
||||
"""
|
||||
Perform the custom SQL query for ``usage_for_model`` and
|
||||
``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_pk = '%s.%s' % (model_table, qn(model._meta.pk.column))
|
||||
|
@ -216,7 +215,7 @@ class GenericTaggedItemBase(ItemBase):
|
|||
content_object = GenericForeignKey()
|
||||
|
||||
class Meta:
|
||||
abstract=True
|
||||
abstract = True
|
||||
|
||||
@classmethod
|
||||
def lookup_kwargs(cls, instance):
|
||||
|
|
|
@ -5,8 +5,6 @@ from django.utils.encoding import force_unicode
|
|||
from django.utils.functional import wraps
|
||||
from django.db.models import Count
|
||||
|
||||
from .models import TaggedItem
|
||||
|
||||
|
||||
def get_tags_for_queryset(queryset, tags_attribute='tags'):
|
||||
"""
|
||||
|
|
|
@ -3,7 +3,8 @@ from tastypie.resources import ModelResource
|
|||
from tastypie.authentication import SessionAuthentication
|
||||
from tastypie.authorization import DjangoAuthorization
|
||||
|
||||
from greenmine.wiki.models import *
|
||||
from greenmine.wiki.models import WikiPage, WikiPageHistory, WikiPageAttachment
|
||||
|
||||
|
||||
class WikiPageResource(ModelResource):
|
||||
class Meta:
|
||||
|
|
Loading…
Reference in New Issue