mirror of
https://github.com/nikdoof/django-ett.git
synced 2025-12-13 05:32:15 +00:00
Fleshing out the Task model and related access points
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -28,3 +28,6 @@ pip-log.txt
|
|||||||
|
|
||||||
#Virtualenv
|
#Virtualenv
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
#databases
|
||||||
|
*.sqlite3
|
||||||
|
|||||||
@@ -112,11 +112,9 @@ INSTALLED_APPS = (
|
|||||||
'django.contrib.sites',
|
'django.contrib.sites',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
# Uncomment the next line to enable the admin:
|
|
||||||
# 'django.contrib.admin',
|
|
||||||
# Uncomment the next line to enable admin documentation:
|
|
||||||
# 'django.contrib.admindocs',
|
|
||||||
'south',
|
'south',
|
||||||
|
'tastypie',
|
||||||
|
'etasks',
|
||||||
)
|
)
|
||||||
|
|
||||||
# A sample logging configuration. The only tangible logging
|
# A sample logging configuration. The only tangible logging
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ from django.conf.urls import patterns, include, url
|
|||||||
# admin.autodiscover()
|
# admin.autodiscover()
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
|
url('', include('etasks.urls')),
|
||||||
# Examples:
|
# Examples:
|
||||||
# url(r'^$', 'django_ett.views.home', name='home'),
|
# url(r'^$', 'django_ett.views.home', name='home'),
|
||||||
# url(r'^django_ett/', include('django_ett.foo.urls')),
|
# url(r'^django_ett/', include('django_ett.foo.urls')),
|
||||||
|
|||||||
0
django_ett/etasks/__init__.py
Normal file
0
django_ett/etasks/__init__.py
Normal file
30
django_ett/etasks/api.py
Normal file
30
django_ett/etasks/api.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
from tastypie.resources import ModelResource
|
||||||
|
from tastypie.authentication import ApiKeyAuthentication
|
||||||
|
from tastypie.authorization import Authorization
|
||||||
|
from tastypie.api import Api
|
||||||
|
|
||||||
|
from .models import Task, TimeEntry
|
||||||
|
|
||||||
|
|
||||||
|
class EtasksAuthorization(Authorization):
|
||||||
|
|
||||||
|
def apply_limits(self, request, object_list):
|
||||||
|
|
||||||
|
if request and hasattr(request, 'user'):
|
||||||
|
return object_list.filter(user__pk=request.user.pk)
|
||||||
|
|
||||||
|
return object_list.none()
|
||||||
|
|
||||||
|
|
||||||
|
class TaskResource(ModelResource):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
queryset = Task.objects.all()
|
||||||
|
resource_name = 'task'
|
||||||
|
|
||||||
|
authentication = ApiKeyAuthentication()
|
||||||
|
authorization = EtasksAuthorization()
|
||||||
|
|
||||||
|
|
||||||
|
v1_api = Api(api_name='1.0')
|
||||||
|
v1_api.register(TaskResource())
|
||||||
54
django_ett/etasks/models.py
Normal file
54
django_ett/etasks/models.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from tastypie.models import create_api_key
|
||||||
|
|
||||||
|
|
||||||
|
# Connect the tastypie API key creation call
|
||||||
|
models.signals.post_save.connect(create_api_key, sender=User)
|
||||||
|
|
||||||
|
|
||||||
|
class Task(models.Model):
|
||||||
|
"""
|
||||||
|
Represents a user's task entry that time can be allocated to
|
||||||
|
"""
|
||||||
|
|
||||||
|
user = models.ForeignKey(User, related_name='tasks')
|
||||||
|
name = models.CharField('Task Name', max_length=200, blank=False)
|
||||||
|
created = models.DateTimeField('Created Date/Time', auto_now_add=True)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
if self.name:
|
||||||
|
return self.name
|
||||||
|
return u'Unknown'
|
||||||
|
|
||||||
|
|
||||||
|
class TimeEntry(models.Model):
|
||||||
|
"""
|
||||||
|
A entry of time against a task
|
||||||
|
"""
|
||||||
|
|
||||||
|
TYPE_OFF = 1
|
||||||
|
TYPE_ON = 2
|
||||||
|
TYPE_STRIKE = 3
|
||||||
|
|
||||||
|
TYPE_CHOICES = (
|
||||||
|
(TYPE_OFF, 'Off'),
|
||||||
|
(TYPE_ON, 'On'),
|
||||||
|
(TYPE_STRIKE, 'Strike'),
|
||||||
|
)
|
||||||
|
|
||||||
|
task = models.ForeignKey(Task, related_name='entries')
|
||||||
|
type = models.IntegerField('Type', choices=TYPE_CHOICES, default=TYPE_OFF)
|
||||||
|
date = models.DateField('Date')
|
||||||
|
segment = models.IntegerField('Segment')
|
||||||
|
|
||||||
|
created = models.DateTimeField('Created Date/Time', auto_now_add=True)
|
||||||
|
updated = models.DateTimeField('Updated Date/Time', auto_now=True)
|
||||||
|
|
||||||
|
def get_segment_time(self):
|
||||||
|
if segment:
|
||||||
|
return self.segment * 15
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return u'%s - %s %s' % (self.task.name, self.date, self.get_segment_time())
|
||||||
3
django_ett/etasks/templates/etasks/task_detail.html
Normal file
3
django_ett/etasks/templates/etasks/task_detail.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="page-header">
|
||||||
|
<h1>{{ task.name }}<h1>
|
||||||
|
</div>
|
||||||
24
django_ett/etasks/tests.py
Normal file
24
django_ett/etasks/tests.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
from __future__ import with_statement
|
||||||
|
from django.utils import unittest
|
||||||
|
from django.db import IntegrityError
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from .models import Task
|
||||||
|
|
||||||
|
|
||||||
|
class TaskTest(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.user, created = User.objects.get_or_create(username='TestUser')
|
||||||
|
self.task = Task.objects.create(user=self.user, name="Test Task 1")
|
||||||
|
|
||||||
|
def testDisplay(self):
|
||||||
|
self.assertEqual(str(self.task), "Test Task 1")
|
||||||
|
|
||||||
|
def testBadCreation(self):
|
||||||
|
with self.assertRaises(IntegrityError):
|
||||||
|
Task.objects.create(name='Bad Test')
|
||||||
|
with self.assertRaises(IntegrityError):
|
||||||
|
Task.objects.create(user=self.user)
|
||||||
|
with self.assertRaises(IntegrityError):
|
||||||
|
Task.objects.create()
|
||||||
11
django_ett/etasks/urls.py
Normal file
11
django_ett/etasks/urls.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from django.conf.urls import patterns, include, url
|
||||||
|
|
||||||
|
from .api import v1_api
|
||||||
|
from .views import TaskDetailView
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
url(r'^task/(?P<pk>.*)/$', TaskDetailView.as_view(), name='task-detail'),
|
||||||
|
|
||||||
|
url('^api/', include(v1_api.urls)),
|
||||||
|
)
|
||||||
7
django_ett/etasks/views.py
Normal file
7
django_ett/etasks/views.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from django.views.generic import DetailView
|
||||||
|
from .models import Task
|
||||||
|
|
||||||
|
|
||||||
|
class TaskDetailView(DetailView):
|
||||||
|
|
||||||
|
model = Task
|
||||||
19
fabfile.py
vendored
Normal file
19
fabfile.py
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
from __future__ import with_statement
|
||||||
|
from fabric.api import task, prefix, env, local
|
||||||
|
|
||||||
|
env.shell = '/bin/bash -l -c'
|
||||||
|
|
||||||
|
###### Local Tasks
|
||||||
|
|
||||||
|
@task
|
||||||
|
def runserver(port=3333):
|
||||||
|
with prefix('. .env/bin/activate'):
|
||||||
|
ip = local("""ip addr list eth0 |grep "inet " |cut -d' ' -f6|cut -d/ -f1""", capture=True)
|
||||||
|
local('django_ett/manage.py runserver %s:%s' % (ip, port), capture=False)
|
||||||
|
|
||||||
|
@task
|
||||||
|
def test():
|
||||||
|
with prefix('. .env/bin/activate'):
|
||||||
|
local('django_ett/manage.py test --noinput --failfast')
|
||||||
|
|
||||||
|
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
django>=1.4.2
|
django>=1.4.2
|
||||||
south>=0.7.6
|
south>=0.7.6
|
||||||
|
django-tastypie>=0.9.11
|
||||||
|
fabric>=1.4.3
|
||||||
|
|||||||
Reference in New Issue
Block a user