# HG changeset patch # User Madhusudan.C.S # Date 1294321024 -19800 # Node ID 3c8f3b0e5b0080b6e41cbd8487a9e1aa733c146f # Parent 679c7e2370522d14ff5a6e070ed757d09af816c5 Add support for buildout and move the files to the directory to support buildout structure. diff -r 679c7e237052 -r 3c8f3b0e5b00 __init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 bootstrap.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bootstrap.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,260 @@ +############################################################################## +# +# Copyright (c) 2006 Zope Foundation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Bootstrap a buildout-based project + +Simply run this script in a directory containing a buildout.cfg. +The script accepts buildout command-line options, so you can +use the -c option to specify an alternate configuration file. +""" + +import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess +from optparse import OptionParser + +if sys.platform == 'win32': + def quote(c): + if ' ' in c: + return '"%s"' % c # work around spawn lamosity on windows + else: + return c +else: + quote = str + +# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments. +stdout, stderr = subprocess.Popen( + [sys.executable, '-Sc', + 'try:\n' + ' import ConfigParser\n' + 'except ImportError:\n' + ' print 1\n' + 'else:\n' + ' print 0\n'], + stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() +has_broken_dash_S = bool(int(stdout.strip())) + +# In order to be more robust in the face of system Pythons, we want to +# run without site-packages loaded. This is somewhat tricky, in +# particular because Python 2.6's distutils imports site, so starting +# with the -S flag is not sufficient. However, we'll start with that: +if not has_broken_dash_S and 'site' in sys.modules: + # We will restart with python -S. + args = sys.argv[:] + args[0:0] = [sys.executable, '-S'] + args = map(quote, args) + os.execv(sys.executable, args) +# Now we are running with -S. We'll get the clean sys.path, import site +# because distutils will do it later, and then reset the path and clean +# out any namespace packages from site-packages that might have been +# loaded by .pth files. +clean_path = sys.path[:] +import site +sys.path[:] = clean_path +for k, v in sys.modules.items(): + if k in ('setuptools', 'pkg_resources') or ( + hasattr(v, '__path__') and + len(v.__path__)==1 and + not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))): + # This is a namespace package. Remove it. + sys.modules.pop(k) + +is_jython = sys.platform.startswith('java') + +setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py' +distribute_source = 'http://python-distribute.org/distribute_setup.py' + +# parsing arguments +def normalize_to_url(option, opt_str, value, parser): + if value: + if '://' not in value: # It doesn't smell like a URL. + value = 'file://%s' % ( + urllib.pathname2url( + os.path.abspath(os.path.expanduser(value))),) + if opt_str == '--download-base' and not value.endswith('/'): + # Download base needs a trailing slash to make the world happy. + value += '/' + else: + value = None + name = opt_str[2:].replace('-', '_') + setattr(parser.values, name, value) + +usage = '''\ +[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] + +Bootstraps a buildout-based project. + +Simply run this script in a directory containing a buildout.cfg, using the +Python that you want bin/buildout to use. + +Note that by using --setup-source and --download-base to point to +local resources, you can keep this script from going over the network. +''' + +parser = OptionParser(usage=usage) +parser.add_option("-v", "--version", dest="version", + help="use a specific zc.buildout version") +parser.add_option("-d", "--distribute", + action="store_true", dest="use_distribute", default=False, + help="Use Distribute rather than Setuptools.") +parser.add_option("--setup-source", action="callback", dest="setup_source", + callback=normalize_to_url, nargs=1, type="string", + help=("Specify a URL or file location for the setup file. " + "If you use Setuptools, this will default to " + + setuptools_source + "; if you use Distribute, this " + "will default to " + distribute_source +".")) +parser.add_option("--download-base", action="callback", dest="download_base", + callback=normalize_to_url, nargs=1, type="string", + help=("Specify a URL or directory for downloading " + "zc.buildout and either Setuptools or Distribute. " + "Defaults to PyPI.")) +parser.add_option("--eggs", + help=("Specify a directory for storing eggs. Defaults to " + "a temporary directory that is deleted when the " + "bootstrap script completes.")) +parser.add_option("-t", "--accept-buildout-test-releases", + dest='accept_buildout_test_releases', + action="store_true", default=False, + help=("Normally, if you do not specify a --version, the " + "bootstrap script and buildout gets the newest " + "*final* versions of zc.buildout and its recipes and " + "extensions for you. If you use this flag, " + "bootstrap and buildout will get the newest releases " + "even if they are alphas or betas.")) +parser.add_option("-c", None, action="store", dest="config_file", + help=("Specify the path to the buildout configuration " + "file to be used.")) + +options, args = parser.parse_args() + +# if -c was provided, we push it back into args for buildout's main function +if options.config_file is not None: + args += ['-c', options.config_file] + +if options.eggs: + eggs_dir = os.path.abspath(os.path.expanduser(options.eggs)) +else: + eggs_dir = tempfile.mkdtemp() + +if options.setup_source is None: + if options.use_distribute: + options.setup_source = distribute_source + else: + options.setup_source = setuptools_source + +if options.accept_buildout_test_releases: + args.append('buildout:accept-buildout-test-releases=true') +args.append('bootstrap') + +try: + import pkg_resources + import setuptools # A flag. Sometimes pkg_resources is installed alone. + if not hasattr(pkg_resources, '_distribute'): + raise ImportError +except ImportError: + ez_code = urllib2.urlopen( + options.setup_source).read().replace('\r\n', '\n') + ez = {} + exec ez_code in ez + setup_args = dict(to_dir=eggs_dir, download_delay=0) + if options.download_base: + setup_args['download_base'] = options.download_base + if options.use_distribute: + setup_args['no_fake'] = True + ez['use_setuptools'](**setup_args) + if 'pkg_resources' in sys.modules: + reload(sys.modules['pkg_resources']) + import pkg_resources + # This does not (always?) update the default working set. We will + # do it. + for path in sys.path: + if path not in pkg_resources.working_set.entries: + pkg_resources.working_set.add_entry(path) + +cmd = [quote(sys.executable), + '-c', + quote('from setuptools.command.easy_install import main; main()'), + '-mqNxd', + quote(eggs_dir)] + +if not has_broken_dash_S: + cmd.insert(1, '-S') + +find_links = options.download_base +if not find_links: + find_links = os.environ.get('bootstrap-testing-find-links') +if find_links: + cmd.extend(['-f', quote(find_links)]) + +if options.use_distribute: + setup_requirement = 'distribute' +else: + setup_requirement = 'setuptools' +ws = pkg_resources.working_set +setup_requirement_path = ws.find( + pkg_resources.Requirement.parse(setup_requirement)).location +env = dict( + os.environ, + PYTHONPATH=setup_requirement_path) + +requirement = 'zc.buildout' +version = options.version +if version is None and not options.accept_buildout_test_releases: + # Figure out the most recent final version of zc.buildout. + import setuptools.package_index + _final_parts = '*final-', '*final' + def _final_version(parsed_version): + for part in parsed_version: + if (part[:1] == '*') and (part not in _final_parts): + return False + return True + index = setuptools.package_index.PackageIndex( + search_path=[setup_requirement_path]) + if find_links: + index.add_find_links((find_links,)) + req = pkg_resources.Requirement.parse(requirement) + if index.obtain(req) is not None: + best = [] + bestv = None + for dist in index[req.project_name]: + distv = dist.parsed_version + if _final_version(distv): + if bestv is None or distv > bestv: + best = [dist] + bestv = distv + elif distv == bestv: + best.append(dist) + if best: + best.sort() + version = best[-1].version +if version: + requirement = '=='.join((requirement, version)) +cmd.append(requirement) + +if is_jython: + import subprocess + exitcode = subprocess.Popen(cmd, env=env).wait() +else: # Windows prefers this, apparently; otherwise we would prefer subprocess + exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env])) +if exitcode != 0: + sys.stdout.flush() + sys.stderr.flush() + print ("An error occurred when trying to install zc.buildout. " + "Look above this message for any errors that " + "were output by easy_install.") + sys.exit(exitcode) + +ws.add_entry(eggs_dir) +ws.require(requirement) +import zc.buildout.buildout +zc.buildout.buildout.main(args) +if not options.eggs: # clean up temporary egg directory + shutil.rmtree(eggs_dir) diff -r 679c7e237052 -r 3c8f3b0e5b00 buildout.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/buildout.cfg Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,36 @@ +[buildout] +parts = django tagging django-robots south registration +eggs = + python-pgsql + PIL + + +[django] +recipe = djangorecipe +version = 1.2.4 +project = pytask +settings = settings +eggs = + ${buildout:eggs} +pythonpath = + ${tagging:location} + ${django-robots:location} + ${south:location} + ${registration:location} + +[tagging] +recipe = infrae.subversion +urls = http://django-tagging.googlecode.com/svn/trunk/ . + +[django-robots] +recipe = mercurialrecipe +repository = http://bitbucket.org/jezdez/django-robots/ + +[south] +recipe = mercurialrecipe +repository = http://bitbucket.org/andrewgodwin/south/ + +[registration] +recipe = mercurialrecipe +repository = http://bitbucket.org/ubernostrum/django-registration/ + diff -r 679c7e237052 -r 3c8f3b0e5b00 manage.py --- a/manage.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -#!/usr/bin/python -from django.core.management import execute_manager -try: - import settings # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) - sys.exit(1) - -if __name__ == "__main__": - execute_manager(settings) diff -r 679c7e237052 -r 3c8f3b0e5b00 project/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 project/development.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project/development.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,4 @@ + +from project.settings import * +DEBUG=True +TEMPLATE_DEBUG=DEBUG diff -r 679c7e237052 -r 3c8f3b0e5b00 project/production.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project/production.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,2 @@ + +from project.settings import * diff -r 679c7e237052 -r 3c8f3b0e5b00 project/settings.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project/settings.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,64 @@ + +import os + +ADMINS = ( + # ('Your Name', 'your_email@domain.com'), +) + +MANAGERS = ADMINS + +DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. +DATABASE_NAME = 'project.db' +DATABASE_USER = '' # Not used with sqlite3. +DATABASE_PASSWORD = '' # Not used with sqlite3. +DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. +DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. + +TIME_ZONE = 'America/Chicago' + +LANGUAGE_CODE = 'en-us' + +# Absolute path to the directory that holds media. +# Example: "/home/media/media.lawrence.com/" +MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'media') + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash if there is a path component (optional in other cases). +# Examples: "http://media.lawrence.com", "http://example.com/media/" +MEDIA_URL = '/media/' + +# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a +# trailing slash. +# Examples: "http://foo.com/media/", "/media/". +ADMIN_MEDIA_PREFIX = '/admin_media/' + +# Don't share this with anybody. +SECRET_KEY = '%(7736-vn4562yhn4^@c%st00h3ed6-v@=ce1m(68c1j5c6!j4' + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.middleware.doc.XViewMiddleware', +) + +ROOT_URLCONF = 'project.urls' + + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.admin', +) + +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.load_template_source', + 'django.template.loaders.app_directories.load_template_source', +) + +TEMPLATE_DIRS = ( + os.path.join(os.path.dirname(__file__), "templates"), +) + + diff -r 679c7e237052 -r 3c8f3b0e5b00 project/urls.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project/urls.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,19 @@ + +from django.conf.urls.defaults import patterns, include, handler500 +from django.conf import settings +from django.contrib import admin +admin.autodiscover() + +handler500 # Pyflakes + +urlpatterns = patterns( + '', + (r'^admin/(.*)', admin.site.root), + (r'^accounts/login/$', 'django.contrib.auth.views.login'), +) + +if settings.DEBUG: + urlpatterns += patterns('', + (r'^media/(?P.*)$', 'django.views.static.serve', + {'document_root': settings.MEDIA_ROOT}), + ) diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/settings.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/settings.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,92 @@ +# Django settings for pytask project. + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( + # ('Your Name', 'your_email@domain.com'), +) + +MANAGERS = ADMINS + +DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. +DATABASE_NAME = 'pytask.db' # Or path to database file if using sqlite3. +DATABASE_USER = '' # Not used with sqlite3. +DATABASE_PASSWORD = '' # Not used with sqlite3. +DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. +DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# If running in a Windows environment this must be set to the same as your +# system time zone. +TIME_ZONE = 'America/Chicago' + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +LANGUAGE_CODE = 'en-us' + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +# Absolute path to the directory that holds media. +# Example: "/home/media/media.lawrence.com/" +MEDIA_ROOT = './images/' + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash if there is a path component (optional in other cases). +# Examples: "http://media.lawrence.com", "http://example.com/media/" +MEDIA_URL = '/images/' + +# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a +# trailing slash. +# Examples: "http://foo.com/media/", "/media/". +ADMIN_MEDIA_PREFIX = '/media/' + +# Make this unique, and don't share it with anybody. +SECRET_KEY = '#7bo8^p1gc=$85gv09z5d_d9-8xk1p=me7_c^3ito@jjth6^^w' + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.load_template_source', + 'django.template.loaders.app_directories.load_template_source', +# 'django.template.loaders.eggs.load_template_source', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', +) + +ROOT_URLCONF = 'pytask.urls' + +TEMPLATE_DIRS = ( + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. + './templates', +) + +ACCOUNT_ACTIVATION_DAYS = 5 +DEFAULT_FROM_EMAIL = 'no-reply@pytask.in' + +LOGIN_REDIRECT_URL = '/' +FORCE_LOWERCASE_TAGS = True + +INSTALLED_APPS = ( + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.sites', + 'django.contrib.admin', + 'pytask.taskapp', + 'registration', + 'tagging' +) + +AUTH_PROFILE_MODULE = 'taskapp.Profile' diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/admin.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/admin.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,9 @@ +from django.contrib import admin + +from pytask.taskapp.models import Profile, Task, Comment, Notification, Request + +admin.site.register(Profile) +admin.site.register(Task) +admin.site.register(Comment) +admin.site.register(Notification) +admin.site.register(Request) diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/events/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/events/request.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/events/request.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,130 @@ +from datetime import datetime +from pytask.taskapp.models import Profile +from pytask.taskapp.events.task import addMentor +from pytask.taskapp.events.user import changeRole +from pytask.taskapp.utilities.notification import create_notification + +def reply_to_request(request_obj, reply, replied_by): + """ + makes a request replied with the given reply. + arguments: + request_obj - Request object for which change is intended + reply - a boolean value to be given as reply (True/False) + replied_by - the user object who replies to the request + """ + if not request_obj.is_replied: + request_obj.reply = reply + request_obj.is_replied = True + request_obj.reply_date = datetime.now() + request_obj.replied_by = replied_by + request_obj.save() + + if request_obj.role == "PY": + ## note that we are not doing any check. we make requests invalid when an event like closing task happens. + task = request_obj.task + pynts = request_obj.pynts + receiving_user = request_obj.receiving_user + requested_by = request_obj.sent_by + create_notification(request_obj.role, receiving_user, replied_by, reply, task, request_obj.remarks, requested_by, receiving_user, pynts) + if receiving_user != requested_by: + create_notification(request_obj.role, requested_by, replied_by, reply, task, request_obj.remarks, requested_by, receiving_user, pynts) + + elif request_obj.role == "MT": + task = request_obj.task + requested_by = request_obj.sent_by + if reply: + ## tell the replied user that he is mentor for this task and give him learn more link + create_notification("NT", request_obj.replied_by, task=task) + + ## now check if there are such similar requests and mark them as invalid + ## they cannot be of type PY and so we can use the replied_by to get requests + pending_requests = replied_by.request_sent_to.filter(is_valid=True, is_replied=False, role="MT",task=task) + for req in pending_requests: + create_notification("MT", req.sent_by, replied_by, False, task=req.task, remarks = "User has already accepted one such request and is a mentor.", requested_by = req.sent_by) + req.is_valid = False + req.save() + + ## alert all the mentors including who made request and all assigned users + for a_mentor in task.mentors.all(): + create_notification(request_obj.role, a_mentor, replied_by, True, task, request_obj.remarks, requested_by) + for a_user in task.assigned_users.all(): + create_notification(request_obj.role, a_user, replied_by, True, task, request_obj.remarks, requested_by) + + addMentor(task, request_obj.replied_by) + else: + ## tell the requested user that his request was rejected due to these reasons. + create_notification(request_obj.role, requested_by, replied_by, False, task, request_obj.remarks, requested_by) + + elif request_obj.role == "DV": + if reply: + ## here we look for requests that are similar => requesting for DV and make them invalid + ## also we drop a notification to user who made request + pending_requests = request_obj.replied_by.request_sent_to.filter(is_valid=True,is_replied=False,role="DV") + for req in pending_requests: + req.is_valid = False + req.save() + create_notification(role = req.role, sent_to = req.sent_by, sent_from = replied_by, reply = False, \ + remarks = "User has accepted a similar request and has rights same or higher privileged than the request", \ + requested_by = req.sent_by ) + + ## tell only the user who made him a DV + ## drop a welcome message to that fucker + create_notification(request_obj.role, request_obj.sent_by, request_obj.replied_by, reply, requested_by=request_obj.sent_by) + create_notification("ND", request_obj.replied_by, requested_by=request_obj.sent_by) + changeRole(role=request_obj.role, user=request_obj.replied_by) + + else: + create_notification(request_obj.role, request_obj.sent_by, request_obj.replied_by, reply, remarks=request_obj.remarks, requested_by=request_obj.sent_by) + + elif request_obj.role == "MG": + if reply: + ## tell all the MG and AD + alerting_users = Profile.objects.filter(user__is_active=True).exclude(rights="CT").exclude(rights="DV") + for a_profile in alerting_users: + create_notification(request_obj.role, a_profile.user, request_obj.replied_by, reply, requested_by=request_obj.sent_by) + + ## here we look for requests that less or similar => requesting for DV or MG and make them invalid + ## also we drop a notification to user who made request + active_requests = request_obj.replied_by.request_sent_to.filter(is_valid=True,is_replied=False) + pending_requests = active_requests.filter(role="DV") | active_requests.filter(role="MG") + for req in pending_requests: + req.is_valid = False + req.save() + create_notification(role = req.role, sent_to = req.sent_by, sent_from = replied_by, reply = False, \ + remarks = "User has accepted a similar request and has rights same or higher privileged than the request", \ + requested_by = req.sent_by ) + + ## drop a welcome message to that fucker + create_notification("NG", request_obj.replied_by, requested_by=request_obj.sent_by) + changeRole(role=request_obj.role, user=request_obj.replied_by) + + else: + create_notification(request_obj.role, request_obj.sent_by, request_obj.replied_by, reply, remarks=request_obj.remarks, requested_by=request_obj.sent_by) + + elif request_obj.role == "AD": + if reply: + + ## here we look for requests that less or similar => requesting for DV or MG or AD and make them invalid + ## also we drop a notification to user who made request + active_requests = request_obj.replied_by.request_sent_to.filter(is_valid=True,is_replied=False) + pending_requests = active_requests.filter(role="DV") | active_requests.filter(role="MG") | active_requests.filter(role="AD") + for req in pending_requests: + req.is_valid = False + req.save() + create_notification(role = req.role, sent_to = req.sent_by, sent_from = replied_by, reply = False, \ + remarks = "User has accepted a similar request and has rights same or higher privileged than the request", \ + requested_by = req.sent_by ) + ## tell all the AD + alerting_users = Profile.objects.filter(user__is_active=True).filter(rights="AD") + for a_profile in alerting_users: + create_notification(request_obj.role, a_profile.user, request_obj.replied_by, reply, requested_by=request_obj.sent_by) + + ## drop a welcome message to that fucker + create_notification("NA", request_obj.replied_by, requested_by=request_obj.sent_by) + changeRole(role=request_obj.role, user=request_obj.replied_by) + + else: + create_notification(request_obj.role, request_obj.sent_by, request_obj.replied_by, reply, remarks=request_obj.remarks, requested_by=request_obj.sent_by) + + return True #Reply has been added successfully + return False #Already replied diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/events/task.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/events/task.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,271 @@ +from datetime import datetime +from pytask.taskapp.models import Profile, Task, Comment, Map +from pytask.taskapp.utilities.task import getTask +from pytask.taskapp.utilities.request import create_request +from pytask.taskapp.utilities.helper import get_key +from pytask.taskapp.utilities.notification import create_notification + +def publishTask(task, rem_mentors=True, rem_comments=True): + """ set the task status to open """ + + # if task.sub_type == 'D': + # deps, subs = task.map_subs.all(), [] + #else: + # subs, deps = task.map_subs.all(), [] + + task = getTask(task.id) + if task.subs or any(map(lambda t:t.status!="CM",task.deps)): + task.status = "LO" + else: + task.status = "OP" + + if rem_mentors: + task.mentors.clear() + task.mentors.add(task.created_by) + + if rem_comments: + task.comment_set.update(is_deleted=True) + task.comment_set.update(deleted_by=task.created_by) + + task.published_datetime = datetime.now() + task.save() + + pending_requests = task.request_task.filter(is_valid=True, is_replied=False) + pending_requests.update(is_valid=False) + + return task + +def addSubTask(main_task, sub_task): + """ add the task to subs attribute of the task and update its status. + sub task can be added only if a task is in UP/OP/LO state. + """ + + ## Shall modify after talking to pr about subtasks + ## I think i might even remove the concept of subtasks + + main_task.sub_type = "S" + main_task.save() + + try: + mapobj = Map.objects.get(main=main_task) + except Map.DoesNotExist: + mapobj = Map() + mapobj.main = main_task + mapobj.save() + mapobj.subs.add(sub_task) + mapobj.save() + + sub_tasks = getTask(main_task.id).subs + if main_task.status == "OP": + if any(map(lambda t:t.status!="CM",sub_tasks)): + main_task.status = "LO" + else: + "CM" + main_task.save() + +def addDep(main_task, dependency): + """ add the dependency task to deps attribute of the task. + update the status of main_task accordingly. + note that deps can be added only if task is in UP/OP/LO state. + And also if the task doesn't have any subs. + """ + + main_task.sub_type = "D" + main_task.save() + + try: + mapobj = Map.objects.get(main=main_task) + except Map.DoesNotExist: + mapobj = Map() + mapobj.main = main_task + mapobj.save() + + mapobj.subs.add(dependency) + mapobj.save() + + deps = getTask(main_task.id).deps + + if main_task.status in ["OP", "LO"]: + if all(map(lambda t:t.status=="CM",deps)): + main_task.status = "OP" + else: + main_task.status = "LO" + + main_task.save() + +def reqMentor(task, mentor, req_by): + """ create a request object with role as MT. + """ + + create_request(sent_by=req_by, role="MT", sent_to=mentor, task=task) + +def addMentor(task,mentor): + """ add the mentor to mentors list of the task """ + + task.mentors.add(mentor) + task.save() + return task + +def createTask(title,desc,created_by,credits): + """ creates a bare minimum task with title, description and credits. + the creator of the task will be assigned as a mentor for the task. + """ + + while True: + id = get_key() + try: + task = Task.objects.get(id__iexact=id) + continue + except Task.DoesNotExist: + break + + try: + task = Task.objects.exclude(status="DL").get(title__iexact=title) + return None + except: + task = Task(title=title) + + task.id = id + task.desc = desc + task.created_by = created_by + task.credits = credits + task.creation_datetime = datetime.now() + task.published_datetime = datetime.now() + task.save() + return task + +def addClaim(task, message, user): + """ add claim data to the database if it does not exist + and also update the claimed users field of the task. + """ + + task.claimed_users.add(user) + task.save() + + pending_reqs = user.request_sent_to.filter(is_replied=False, is_valid=True, role="MT", task=task).all() + for req in pending_reqs: + req.is_valid = False + req.save() + user_url = '%s'%(user.id, user.username) + reason = "User has claimed the task and hence cannot be a mentor and this request was made invalid." + create_notification("MT", req.sent_by, user, task=task, reply=False, remarks=reason, requested_by=req.sent_by) + + for a_mentor in task.mentors.all(): + create_notification("CL", a_mentor, user, task=task, remarks=message) + +def assignTask(task, added_user, assigned_by): + """ check for the status of task and assign it to the particular user """ + + if task.status in ['OP', 'WR']: + task.assigned_users.add(added_user) + task.claimed_users.remove(added_user) + task.status = "WR" + task.save() + + create_notification("AU", added_user, assigned_by, task=task) + + +def updateTask(task, title=None, desc=None, credits=None, tags_field=None): + """ update the property accordingly. + while updating title, check for uniqueness of title. + return None if any error. + """ + + if title: + try: + task.title = title + task.save() + except Task.IntegrityError: + return None + if desc:task.desc = desc + if credits:task.credits = credits + if tags_field:task.tags_field = tags_field + task.save() + return task + +def removeTask(main_task, sub_task): + """ get the corresponding map object and remove the sub_task. + """ + + mapobj = Map.objects.get(main=main_task) + mapobj.subs.remove(sub_task) + mapobj.save() + +def removeUser(main_task, rem_user, removed_by, reason=None): + """ right now, just remove the user from the list of assigned_users. + """ + + main_task.assigned_users.remove(rem_user) + main_task.save() + + ## TODiscuss : when a user is kicked off, his pending requests for pynts is made invalid + rem_user.request_receiving_user.filter(task=main_task,role="PY",is_valid=True,is_replied=False).update(is_valid=False) + + create_notification("RU", rem_user, removed_by, task=main_task, remarks=reason) + ## TODO : create notification to the victim + +def assignCredits(task, given_by, given_to, points): + """ make a proper request object. + """ + + create_request(sent_by=given_by, role="PY", task=task, receiving_user=given_to, pynts=points ) + +def completeTask(task, marked_by): + """ set the status of task as completed. + We dont have to inform parent tasks. + That part is taken care by getTask method. + """ + + task.status = "CM" + task.save() + + pending_requests = task.request_task.filter(is_replied=False) + pending_requests.update(is_valid=False) + + ## generate notification appropriately using marked_by + ## we also have to mark unread requests as invalid + + for a_user in task.assigned_users.all(): + create_notification(role="CM", sent_to=a_user, sent_from=marked_by, task=task) + + for a_user in task.claimed_users.all(): + create_notification(role="CM", sent_to=a_user, sent_from=marked_by, task=task) + + for a_mentor in task.mentors.all(): + create_notification(role="CM", sent_to=a_mentor, sent_from=marked_by, task=task) + +def closeTask(task, closed_by, reason=None): + """ set the status of task as CD. + generate notifications accordingly. + """ + + task.status = "CD" + task.save() + + pending_requests = task.request_task.filter(is_replied=False) + pending_requests.update(is_valid=False) + + ## generate notifications here + + for a_user in task.assigned_users.all(): + create_notification(role="CD", sent_to=a_user, sent_from=closed_by, task=task, remarks=reason) + + for a_user in task.claimed_users.all(): + create_notification(role="CD", sent_to=a_user, sent_from=closed_by, task=task, remarks=reason) + + for a_mentor in task.mentors.all(): + create_notification(role="CD", sent_to=a_mentor, sent_from=closed_by, task=task, remarks=reason) + +def deleteTask(task, deleted_by, reason=None): + """ set the task status as DL + notify all its other viewers about the deleting of task. + """ + + task.status = "DL" + task.save() + + pending_requests = task.request_task.filter(is_replied=False,is_valid=True) + pending_requests.update(is_valid=False) + + for a_mentor in task.mentors.exclude(id=deleted_by.id): + create_notification("DL", sent_to=a_mentor, sent_from=deleted_by, task=task, remarks=reason) diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/events/user.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/events/user.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,56 @@ +from django.contrib.auth.models import User +from pytask.taskapp.models import Profile, Task, Comment + +""" A collection of helper methods. note that there is no validation done here. +we take care of validation and others checks in methods that invoke these methods. +""" + +def updateProfile(user_profile, properties): + """ updates the given properties in the profile for a user. + args: + user_profile : a profile object + properties : a dictionary with attributes to set as keys and corresponding values + """ + + for attr,value in properties.items(): + user_profile.__setattr__(attr,value) + user_profile.save() + +def createUser(username,email,password,dob,gender): + """ create a user and create a profile and update its properties + args: + username : a username that does not exist + email : a valid email + password : a password + dob : a date object + gender : u'M'/u'F' + """ + + try: + user = User.objects.get(username=username) + return user + except: + user = User(username=username, email=email) + user.set_password(password) + user.save() + properties = {'dob':dob, 'gender':gender} + user_profile = Profile(user=user) + updateProfile(user_profile, properties) + return user + +def createSuUser(username,email,password,dob,gender): + """ create user using createUser method and set the is_superuser flag """ + + su_user = createUser(username,email,password,dob,gender) + su_user.is_staff = True + su_user.is_superuser = True + su_user.save() + return su_user + +def changeRole(role, user): + """ change the status of user to role. + """ + + user_profile = user.get_profile() + user_profile.rights = role + user_profile.save() diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/forms/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/forms/task.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/forms/task.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,101 @@ +from django import forms +from pytask.taskapp.models import Task + +class TaskCreateForm(forms.ModelForm): + class Meta: + model = Task + fields = ['title', 'desc', 'tags_field', 'credits'] + #publish = forms.BooleanField(required=False) + + def clean_title(self): + data = self.cleaned_data['title'].strip() + try: + Task.objects.exclude(status="DL").get(title__iexact=data) + raise forms.ValidationError("Another task with same title exists") + except Task.DoesNotExist: + return data + + def clean_desc(self): + data = self.cleaned_data['desc'].strip() + if not data: + raise forms.ValidationError("Enter some description for the task") + + return data + +class EditTaskForm(forms.ModelForm): + class Meta: + model = Task + fields = ['title', 'desc', 'tags_field', 'credits'] + + def clean_desc(self): + data = self.cleaned_data['desc'].strip() + if not data: + raise forms.ValidationError("Enter some description for the task") + + return data + + def clean_title(self): + data = self.cleaned_data['title'].strip() + try: + prev_task = Task.objects.exclude(status="DL").get(title__iexact=data) + if prev_task.id != self.instance.id: + raise forms.ValidationError("Another task with same title exists") + else: + return data + except Task.DoesNotExist: + return data + +def AddMentorForm(choices,instance=None): + """ return a form object with appropriate choices """ + + class myform(forms.Form): + mentor = forms.ChoiceField(choices=choices, required=True) + form = myform(instance) if instance else myform() + return form + +class ClaimTaskForm(forms.Form): + message = forms.CharField(label="Proposal") + + def clean_message(self): + data = self.cleaned_data['message'].strip() + if not data: + raise forms.ValidationError('Enter something as a proposal') + return data + + +def ChoiceForm(choices, instance=None): + """ return a form object with appropriate choices """ + + class myform(forms.Form): + choice = forms.ChoiceField(choices=choices, required=True) + form = myform(instance) if instance else myform() + return form + +def AddTaskForm(task_choices, is_plain=False): + """ if is_plain is true, it means the task has no subs/deps. + so we also give a radio button to choose between subs and dependencies. + else we only give choices. + """ + + class myForm(forms.Form): + if is_plain: + type_choices = [('S','Subtasks'),('D','Dependencies')] + type = forms.ChoiceField(type_choices, widget=forms.RadioSelect) + + task = forms.ChoiceField(choices=task_choices) + return myForm() + +def AssignCreditForm(choices, instance=None): + + class myForm(forms.Form): + user = forms.ChoiceField(choices=choices, required=True) + pynts = forms.IntegerField(min_value=0, required=True, help_text="Choose wisely since it cannot be undone.") + return myForm(instance) if instance else myForm() + +def RemoveUserForm(choices, instance=None): + + class myForm(forms.Form): + user = forms.ChoiceField(choices=choices, required=True) + reason = forms.CharField(min_length=1, required=True) + return myForm(instance) if instance else myForm() + diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/forms/user.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/forms/user.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,65 @@ +#!/usr/bin/python2.5 + +import os +import PIL + +from pytask.taskapp.utilities.helper import get_key + +from django import forms +from pytask.taskapp.models import GENDER_CHOICES, Profile +from registration.forms import RegistrationFormUniqueEmail +from registration.models import RegistrationProfile +from pytask.taskapp.utilities.notification import create_notification + +class UserProfileEditForm(forms.ModelForm): + """Form used to edit the profile of a user""" + + class Meta: + model = Profile + exclude = ('user','rights','dob','credits') + + def clean_photo(self): + uploaded_photo = self.data.get('photo', None) + prev_photo = self.instance.photo + if uploaded_photo: + if uploaded_photo.size > 1048576: + raise forms.ValidationError('Images only smaller than 1MB allowed') + tmp_im_path = '/tmp/'+get_key() + tmp_file = open(tmp_im_path, 'w') + tmp_file.write(uploaded_photo.read()) + tmp_file.close() + try: + PIL.Image.open(tmp_im_path) + except IOError: + raise forms.ValidationError('Image format unknown') + os.remove(tmp_im_path) + + if prev_photo: os.remove(prev_photo.path) + return uploaded_photo + else: + return prev_photo + + +class RegistrationFormCustom(RegistrationFormUniqueEmail): + """Used instead of RegistrationForm used by default django-registration backend, this adds date of birth and gender to the default django-registration RegistrationForm""" + + dob = forms.DateField(help_text = "YYYY-MM-DD", required=True, label=u'date of birth') + gender = forms.ChoiceField(choices = GENDER_CHOICES, required=True, label=u'gender') + + def save(self,profile_callback=None): + new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'],password=self.cleaned_data['password1'],email=self.cleaned_data['email']) + + new_profile = Profile(user=new_user,dob=self.cleaned_data['dob'],gender=self.cleaned_data['gender']) + new_profile.save() + + create_notification('NU',new_user) + + return new_user + +def UserChoiceForm(choices, instance=None): + """ take a list of users and return a choice form. + """ + + class myForm(forms.Form): + user = forms.ChoiceField(choices, required=True) + return myForm(instance) if instance else myForm() diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/management/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/management/__init__.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,1 @@ + diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/management/commands/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/management/commands/seed_db.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/management/commands/seed_db.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,58 @@ +import sys +from datetime import datetime +from django.core.management.base import NoArgsCommand + +from django.contrib.auth.models import User + +from pytask.taskapp.events import task as taskEvents +from pytask.taskapp.events import user as userEvents + +from pytask.taskapp.utilities.request import create_request +from pytask.taskapp.utilities.notification import create_notification + + +def seed_db(): + """ a method to seed the database with random data """ + + defaultMentor = userEvents.createSuUser("admin", "admin@example.com", "123456", datetime.now(), "M") + mentor_profile = defaultMentor.get_profile() + userEvents.updateProfile(mentor_profile, {'rights':"AD"}) + + for i in range(1,21): + + username = 'user'+str(i) + email = username+'@example.com' + password = '123456' + dob = datetime.now() + gender = "M" + user = userEvents.createUser(username,email,password,dob,gender) + create_notification("NU", user) + + if i%4==0: + create_request(defaultMentor, "MG", user) + elif i%3==0: + create_request(defaultMentor, "DV", user) + elif i%2==0: + create_request(defaultMentor, "AD", user) + elif i in [7, 13]: + user.is_active = False + user.save() + + for i in range(1,21): + + title = "Task "+str(i) + desc = "I am "+title + created_by = defaultMentor + credits = 20 + + task = taskEvents.createTask(title,desc,created_by,credits) + if task: + taskEvents.addMentor(task, defaultMentor) + if i%2==0:taskEvents.publishTask(task) + +class Command(NoArgsCommand): + + def handle_noargs(self, **options): + """ Just copied the code from seed_db.py """ + + seed_db() diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/models.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/models.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,173 @@ +import os + +from django.core.files.storage import FileSystemStorage +from django.db import models +from django.contrib.auth.models import User + +import tagging +from tagging.fields import TagField + +from pytask.taskapp.utilities.helper import get_key + +GENDER_CHOICES = (( 'M', 'Male'), ('F', 'Female')) +RIGHTS_CHOICES = ( + ("AD", "Admin"), + ("MG", "Manager"), + ("DV", "Developer"), + ("CT", "Contributor"),) + +STATUS_CHOICES = ( + ("UP", "Unpublished"), + ("OP", "Open"), + ("LO", "Locked"), + ("WR", "Working"), + ("CD", "Closed"), + ("DL", "Deleted"), + ("CM", "Completed")) + +NOTIFY_CHOICES = ( + ("MT", "Add Mentor"), + ("DV", "Developer"), + ("MG", "Manager"), + ("AD", "Admin"), + ("PY", "Assign credits"), + ("CM", "Task completed"), + ("CD", "Task closed"), + ("DL", "Task deleted"), + ("NU", "New User"), + ("NT", "New Mentor"), + ("ND", "New Developer"), + ("NG", "New Manager"), + ("NA", "New Admin"), + ("AU", "Assign user"), ## i mean assign the task + ("RU", "Remove user"), ## remove from working users list in task +) + +IMAGES_DIR = "./images" +UPLOADS_DIR = "./uploads" + +class CustomImageStorage(FileSystemStorage): + + def path(self, name): + """ we return images directory path. + """ + + return os.path.join(IMAGES_DIR, name) + + def get_available_name(self, name): + """ here we are going with username as the name of image. + """ + + root, ext = os.path.splitext(name) + file_name = get_key() + ext + while self.exists(file_name): + file_name = get_key() + ext + return file_name + +class Profile(models.Model): + + user = models.ForeignKey(User, unique = True) + dob = models.DateField(verbose_name = u"Date of Birth", help_text = "YYYY-MM-DD") + gender = models.CharField(max_length = 1, choices = GENDER_CHOICES) + rights = models.CharField(max_length = 2, choices = RIGHTS_CHOICES, default = u"CT") + credits = models.PositiveSmallIntegerField(default = 0) + + aboutme = models.TextField(blank = True) + foss_comm = TagField(verbose_name="FOSS Communities") + phonenum = models.CharField(max_length = 15, blank = True, verbose_name = u"Phone Number") + homepage = models.URLField(blank = True, verbose_name = u"Homepage/Blog") + street = models.CharField(max_length = 80, blank = True) + city = models.CharField(max_length = 25, blank = True) + country = models.CharField(max_length = 25, blank = True) + nick = models.CharField(max_length = 20, blank = True) + photo = models.ImageField(storage = CustomImageStorage(),upload_to = IMAGES_DIR, blank = True) + + def __unicode__(self): + return unicode(self.user.username) + +class Task(models.Model): + + prim_key = models.AutoField(primary_key = True) + id = models.CharField(max_length = 10, unique = True) + title = models.CharField(max_length = 100, verbose_name = u"Title", help_text = u"Keep it simple and below 100 chars.") + desc = models.TextField(verbose_name = u"Description") + status = models.CharField(max_length = 2, choices = STATUS_CHOICES, default = "UP") + tags_field = TagField(verbose_name = u"Tags", help_text = u"Give comma seperated tags") + + credits = models.PositiveSmallIntegerField(help_text = u"No.of credits a user gets on completing the task") + progress = models.PositiveSmallIntegerField(default = 0) + + mentors = models.ManyToManyField(User, related_name = "%(class)s_mentors") + created_by = models.ForeignKey(User, related_name = "%(class)s_created_by") + claimed_users = models.ManyToManyField(User, blank = True, related_name = "%(class)s_claimed_users") + assigned_users = models.ManyToManyField(User, blank = True, related_name = "%(class)s_assigned_users") + + creation_datetime = models.DateTimeField() + published_datetime = models.DateTimeField() + sub_type = models.CharField(max_length=1, choices = (('D','Dependency'),('S','Subtask')), default = 'D') + + def __unicode__(self): + return unicode(self.title) + +class Map(models.Model): + + main = models.ForeignKey('Task', related_name = "%(class)s_main") + subs = models.ManyToManyField('Task', blank = True, null = True, related_name = "%(class)s_subs") + +class Comment(models.Model): + + task = models.ForeignKey('Task') + data = models.TextField() + created_by = models.ForeignKey(User, related_name = "%(class)s_created_by") + creation_datetime = models.DateTimeField() + deleted_by = models.ForeignKey(User, null = True, blank = True, related_name = "%(class)s_deleted_by") + is_deleted = models.BooleanField() + attachment = models.FileField(upload_to = UPLOADS_DIR, blank = True) + + def __unicode__(self): + return unicode(self.task.title) + +class Request(models.Model): + + sent_to = models.ManyToManyField(User, related_name = "%(class)s_sent_to", blank = False) + sent_by = models.ForeignKey(User, related_name = "%(class)s_sent_by", blank = False) + role = models.CharField(max_length = 2, blank = False) + reply = models.BooleanField(default = False, blank = False) + remarks = models.TextField(default = "",blank = True) + + is_read = models.BooleanField(default = False, blank = False) + is_valid = models.BooleanField(default = True, blank = False) + + creation_date = models.DateTimeField() + reply_date = models.DateTimeField() + is_replied = models.BooleanField(default = False) + replied_by = models.ForeignKey(User, related_name = "%(class)s_replied_by", blank = True, null = True) + + task = models.ForeignKey(Task,related_name = "%(class)s_task", blank = True, null = True) + receiving_user = models.ForeignKey(User, related_name = "%(class)s_receiving_user", blank = True, null = True) + pynts = models.PositiveIntegerField(default=0) + + def __unicode__(self): + + return u"Request %s %s"%(self.sent_by.username, self.role) + +class Notification(models.Model): + + role = models.CharField(max_length = 2, choices = NOTIFY_CHOICES, blank = False) + sent_to = models.ForeignKey(User, related_name = "%(class)s_sent_to", blank = False) + sent_from = models.ForeignKey(User, related_name = "%(class)s_sent_from", null = True, blank = True) + task = models.ForeignKey(Task, related_name = "%(class)s_task", null = True, blank = True) + + sub = models.CharField(max_length = 100) + message = models.TextField() + remarks = models.CharField(max_length = 100) + + sent_date = models.DateTimeField() + is_read = models.BooleanField(default = False) + is_deleted = models.BooleanField(default = False) + + def __unicode__(self): + return u"%s %s %s"%(self.sent_to, self.message, self.sent_date.ctime()) + +tagging.register(Profile) +tagging.register(Task) diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/tests.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/tests.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,23 @@ +""" +This file demonstrates two different styles of tests (one doctest and one +unittest). These will both pass when you run "manage.py test". + +Replace these with more appropriate tests for your application. +""" + +from django.test import TestCase + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.failUnlessEqual(1 + 1, 2) + +__test__ = {"doctest": """ +Another way to test that 1 + 1 is equal to 2. + +>>> 1 + 1 == 2 +True +"""} + diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/utilities/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/utilities/helper.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/utilities/helper.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,8 @@ +import string,random + +def get_key(): + """ return a 10 character random key. + """ + + return ''.join([ random.choice(string.uppercase+string.digits) for i in range(10)]) + diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/utilities/notification.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/utilities/notification.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,300 @@ +from datetime import datetime +from django.contrib.auth.models import User +from pytask.taskapp.models import Notification, RIGHTS_CHOICES + +def create_notification(role, sent_to, sent_from=None, reply=None, task=None, remarks=None, requested_by=None, receiving_user=None, pynts=None): + """ + creates a notification based on the passed arguments. + role: role of the notification - look at choices in models + sent_to: a user to which the notification is to be sent + sent_from : a user from which the message has originated + A user who approves/rejects in case of request + A mentor who closes/complets the task + reply: A boolean + task: a task if applicable + requested_by: a user makes the request + A mentor who assigns credits in case of pynts + A mentor who requests to act as a mentor + remarks: any remarks for rejecting + receiving_user: user receiving pynts + pynts: the obvious + """ + + notification = Notification(sent_date = datetime.now()) + notification.role = role + notification.sent_to = sent_to + notification.save() + + if role == "PY": + + notification.sent_from = sent_from + notification.task = task + notification.pynts = pynts + + task_url= '%s'%(task.id, task.title) + credits_url = '%s'%(task.id, "click here") + mentor_url = '%s'%(requested_by.id, requested_by.username) + admin_url = '%s'%(sent_from.id, sent_from.username) + user_url = '%s'%(receiving_user.id, receiving_user.username) + + if reply: + notification.sub = "Approved request for assign of credits for %s"%task.title[:20] + notification.message = """ Request made by %s to assign %s pynts to %s for the task %s has been approved by %s
+ %s if you want the view/assign pynts page of the task.
"""%(mentor_url, pynts, user_url, task_url, admin_url, credits_url) + + else: + notification.sub = "Rejected request for assign of credits for %s"%task.title[:20] + notification.message = """ Request made by %s to assign %s pynts to %s for the task %s has been rejected by %s.
"""%(mentor_url, pynts, user_url, task_url, admin_url) + if remarks: + notification.remarks = remarks + notification.message += "Reason: %s
"%remarks + notification.message += "
" + + elif role == "MT": + + notification.task = task + notification.sent_from = sent_from + + task_url= '%s'%(task.id, task.title) + requested_mentor_url = '%s'%(requested_by.id, requested_by.username) + new_mentor = sent_from + new_mentor_url = '%s'%(new_mentor.id, new_mentor.username) + + if reply: + notification.sub = "New mentor for the task %s"%task.title[:20] + notification.message = "%s has accepted the request made by %s, asking him act as a mentor for the task %s
"%(new_mentor_url, requested_mentor_url, task_url) + notification.message += "He can be contacted on %s"%new_mentor.email + + else: + notification.sub = "%s rejected request to act as a mentor"%new_mentor.username + notification.message = "%s has rejected your request asking him to act as a mentor for %s.
"%(new_mentor_url, task_url) + if remarks: + notification.remarks = remarks + notification.message += "Remarks: %s
"%remarks + + elif role in ["DV", "MG", "AD"]: + + notification.sent_from = sent_from + accepting_user = sent_from + user_url = '%s'%(accepting_user.id, accepting_user.username) ## i mean the user who has accepted it + requested_by_url = '%s'%(requested_by.id, requested_by.username) + role_rights = dict(RIGHTS_CHOICES)[role] + role_learn_url = "/about/%s"%role_rights.lower() + a_or_an = "an" if role_rights == "AD" else "a" + + if reply: + notification.sub = "New %s for the site"%role_rights + notification.message = "%s has accepted request made by %s asking him to act as %s %s for the website.
"%(user_url, requested_by_url, a_or_an, role_rights) + else: + notification.sub = "Rejected your request to act as %s"%role_rights + notification.message = "%s has rejected your request asking him to act as %s %s.
"%(user_url, a_or_an, role_rights) + if remarks: + notification.remarks = remarks + notification.message += "Remarks: %s
"%remarks + + elif role == "NT": + + notification.task = task + new_mentor = sent_to + mentor_learn_url = 'learn more' + task_url= '%s'%(task.id, task.title) + + notification.sub = "You are mentoring the task %s"%task.title[:20] + notification.message = "You have accepted to act as a mentor%s for the task %s.
"%(mentor_learn_url, task_url) + notification.message += " Here is a list of other mentors and their email addresses.
" + + working_users = task.assigned_users.all() + if working_users: + notification.message += "List of users working on the task.
" + notification.message += "
" + notification.message += "Happy Mentoring." + + elif role == "NU": + + start_here_url = 'click here' + notification.sub = "Welcome %s"%sent_to.username + notification.message = "Welcome to PyTasks %s.
"%sent_to.username + notification.message += "%s to know more."%start_here_url + + elif role in ["ND", "NG", "NA"]: + + rights_dict = dict(RIGHTS_CHOICES) + + if role == "ND": + role_rights = rights_dict["DV"] + elif role == "NG": + role_rights = rights_dict["MG"] + elif role == "NA": + role_rights = rights_dict["AD"] + + requested_by_url = r'%s'%(requested_by.id, requested_by.username) + role_learn_url = r'click here'%role_rights.lower() + a_or_an = "an" if role_rights == "Admin" else "a" + + notification.sub = "You are now %s %s"%(a_or_an, role_rights) + notification.message = r"You have accepted the request made by %s asking you to act as %s %s in the site "%(requested_by_url, a_or_an, role_rights) + notification.message += "and you are now %s %s in the site.
%s to learn more on %s."%(a_or_an, role_rights, role_learn_url, role_rights) + + + elif role in ["CM", "CD"]: + + notification.sent_from = sent_from + notification.role = role + notification.task = task + notification.remarks = remarks + + mentor = sent_from + mentor_url = '%s'%(mentor.id, mentor.username) + task_url= '%s'%(task.id, task.title) + + if role == "CM": + notification.sub = "%s has been marked complete"%task.title + notification.message = "The task %s has been marked complete by %s.
"%(task_url, mentor_url) + + elif role == "CD": + notification.sub = "%s has been closed"%task.title + notification.message = "The task %s has been closed by %s.
"%(task_url, mentor_url) + + if remarks: + notification.remarks = remarks + notification.message += "Remarks: %s"%remarks + + elif role == "AU": + + notification.task = task + notification.sent_from = sent_from + added_user = sent_to + mentor = sent_from + assigned_by_url = '%s'%(mentor.id, mentor.username) + task_url= '%s'%(task.id, task.title) + + notification.sub = "Your claim for the task %s accepted."%task.title[:20] + notification.message = "You have been selected to work on the task %s by %s.
"%(task_url, assigned_by_url) + notification.message += "You can now start working on the task and will be credited by the mentors for your work.
" + + notification.message += " Here is a list of mentors for the task and their email addresses.
" + + working_users = task.assigned_users.exclude(id=added_user.id) + if working_users: + notification.message += "List of other users working on the task.
" + notification.message += "
" + + elif role == "RU": + + notification.task = task + notification.sent_from = sent_from + removed_user = sent_to + mentor = sent_from + removed_by_url = '%s'%(mentor.id, mentor.username) + task_url = '%s'%(task.id, task.title) + claim_url = '%s'%(task.id, "clicking here") + + notification.sub = "You have been removed from working users of %s"%task.title[:20] + notification.message = "%s has removed you from the working users list of %s.
"%(removed_by_url, task_url) + notification.message += "if you want to work on the task again, you can claim the task by %s.
"%claim_url + if remarks: + notification.remarks = remarks + notification.message += "Reason: %s"%(remarks) + + elif role == "DL": + + notification.sent_from = sent_from + notification.task = task + deleted_by_url = '%s'%(sent_from.id, sent_from.username) + + notification.sub = "Task deleted" + notification.message = 'The unpublished task "%s" viewable by you has been deleted by its creator %s.
'%(task.title, deleted_by_url) + + if remarks: + notification.remarks = remarks + notification.message += "Reason: %s"%remarks + + elif role == "CL": + + notification.sent_from = sent_from + notification.task = task + notification.remarks = remarks + + claimed_by_url = '%s'%(sent_from.id, sent_from.username) + claim_url = 'claim'%(task.id) + task_url = '%s'%(task.id, task.title) + + notification.sub = 'New claim for the task "%s"'%(task.title[:20]) + notification.message = '%s has submitted a %s for the task "%s" mentored by you.
'%(claimed_by_url, claim_url, task_url) + notification.message += 'Claim proposal: %s'%(remarks) + + + + notification.save() + +def mark_notification_read(notification_id): + """ + makes a notification identified by the notification_id read. + arguments: + notification_id - a number denoting the id of the Notification object + """ + try: + notification = Notification.objects.get(id = notification_id) + except Notification.DoesNotExist: + return False + notification.is_read = True + notification.save() + return True + +def delete_notification(notification_id): + """ + deletes a notification identified by the notification_id. + arguments: + notification_id - a number denoting the id of the Notification object + """ + try: + notification = Notification.objects.get(id = notification_id) + except Notification.DoesNotExist: + return False + notification.is_deleted = True + notification.save() + return True + +def get_notification(nid, user): + """ if notification exists, and belongs to the current user, return it. + else return None. + """ + + user_notifications = user.notification_sent_to.filter(is_deleted=False).order_by('sent_date') + current_notifications = user_notifications.filter(id=nid) + if user_notifications: + current_notification = current_notifications[0] + + try: + newer_notification = current_notification.get_next_by_sent_date(sent_to=user, is_deleted=False) + newest_notification = user_notifications.reverse()[0] + if newest_notification == newer_notification: + newest_notification = None + except Notification.DoesNotExist: + newest_notification, newer_notification = None, None + + try: + older_notification = current_notification.get_previous_by_sent_date(sent_to=user, is_deleted=False) + oldest_notification = user_notifications[0] + if oldest_notification == older_notification: + oldest_notification = None + except: + oldest_notification, older_notification = None, None + + return newest_notification, newer_notification, current_notification, older_notification, oldest_notification + + else: + return None, None, None, None, None diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/utilities/request.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/utilities/request.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,62 @@ +from datetime import datetime + +from django.contrib.auth.models import User +from pytask.taskapp.models import Request, Profile + +def create_request(sent_by,role,sent_to=None,task=None,receiving_user=None,pynts=0): + """ + creates an unreplied request, based on the passed arguments + sent_to - a list of users to which the request is to be sent + sent_by - sender of request + role - a two character field which represents the role requested, if role = 'PY' then sent to all admins + task - a requesting task (useful for sending admins a request to give Pynts to the user) + receiving_user - user to whom the Pynts is assigned to(useful for sending admins a request to give Pynts to the user) + pynts - the pynts assigned to the receiving user + """ + req = Request(creation_date=datetime.now()) + req.sent_by = sent_by + req.reply_date = datetime(1970,01,01) + req.role = role + req.pynts = pynts + if task: + req.task = task + req.save() + if role == 'PY': + admin_profiles = Profile.objects.filter(rights='AD') + for admin_profile in admin_profiles: + req.sent_to.add(admin_profile.user) + req.receiving_user = receiving_user + else: + req.sent_to.add(sent_to) + req.save() + +def get_request(rid, user): + """ see if the request is replied or if he can not view the request, + raise 404 error. else return request. + """ + + active_requests = user.request_sent_to.filter(is_valid=True, is_replied=False).order_by('creation_date') + current_requests = active_requests.filter(id=rid) + if current_requests: + current_request = current_requests[0] + + try: + newer_request = current_request.get_next_by_creation_date(sent_to=user, is_replied=False, is_valid=True) + newest_request = active_requests.reverse()[0] + if newer_request == newest_request: + newest_request = None + except Request.DoesNotExist: + newer_request, newest_request = None, None + + try: + older_request = current_request.get_previous_by_creation_date(sent_to=user, is_replied=False, is_valid=True) + oldest_request = active_requests[0] + if oldest_request == older_request: + oldest_request = None + except Request.DoesNotExist: + older_request, oldest_request = None, None + + return newest_request, newer_request, current_request, older_request, oldest_request + + else: + return None, None, None, None, None diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/utilities/task.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/utilities/task.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,37 @@ +from django.http import Http404 +from pytask.taskapp.models import Task, Map + +def getTask(tid): + """ retreive the task from database. + if the task has deps or subs, update its status correspondingly. + """ + + try: + task = Task.objects.get(id=tid) + except Task.DoesNotExist: + raise Http404 + try: + mapobj = Map.objects.get(main=task) + except Map.DoesNotExist: + mapobj = Map() + mapobj.main = task + mapobj.save() + + task_subs = mapobj.subs.all() + + if task.sub_type == "D": + task.deps, task.subs = task_subs, [] + elif task.sub_type == "S": + task.subs, task.deps = task_subs, [] + + deps, subs = task.deps, task.subs + if deps and task.status in ["OP", "LO"]: + task.status = "OP" if all(map(lambda t:t.status=="CM",deps)) else "LO" + + ## a task with subs will remain in "LO" and will be made "OP" only if all subs are removed. + if subs and task.status in ["OP", "LO"]: + task.status = "LO" + + task.save() + return task + diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/utilities/user.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/utilities/user.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,17 @@ +""" +A collection of utility functions for user. +""" + +def get_user(user): + """ get the no of unread requests and notifications and add them as properties for user. + """ + + unread_notifications = user.notification_sent_to.filter(is_read=False,is_deleted=False) + unread_requests = user.request_sent_to.filter(is_valid=True,is_replied=False,is_read=False) + + user.unread_notifications = unread_notifications + user.unread_requests = unread_requests + + return user + + diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/views/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/views/__init__.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,1 @@ + diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/views/task.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/views/task.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,660 @@ +from datetime import datetime + +from django.http import HttpResponse, Http404 +from django.shortcuts import render_to_response, redirect + +from pytask.taskapp.models import User, Task, Comment, Request, Notification +from pytask.taskapp.utilities.task import getTask +from pytask.taskapp.forms.task import TaskCreateForm, AddMentorForm, AddTaskForm, ChoiceForm, AssignCreditForm, RemoveUserForm, EditTaskForm, ClaimTaskForm +from pytask.taskapp.events.task import createTask, reqMentor, publishTask, addSubTask, addDep, addClaim, assignTask, updateTask, removeTask, removeUser, assignCredits, completeTask, closeTask, addMentor, deleteTask +from pytask.taskapp.views.user import show_msg +from pytask.taskapp.utilities.user import get_user + +## everywhere if there is no task, django should display 500 message.. but take care of that in sensitive views like add mentor and all +## do not create su user thro syncdb + +def browse_tasks(request): + """ display all the tasks """ + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task_list = Task.objects.exclude(status="UP").exclude(status="DL").order_by('published_datetime').reverse() + + context = {'user':user, + 'task_list':task_list, + } + return render_to_response('task/browse.html', context) + +def publish_task(request, tid): + """ check if user is the mentor and also if the task status is UP. + """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + is_guest = True if not user.is_authenticated() else False + is_mentor = True if user in task.mentors.all() else False + + if user == task.created_by: + context = { + 'user':user, + } + if task.status == "UP": + if request.method == "POST": + publishTask(task) + return show_msg(user, "The task has been published", task_url, "view the task") + else: + return render_to_response('task/publish.html', context) + else: + return show_msg(user, "The task is already published", task_url, "view the task") + else: + return show_msg(user, "You are not authorised to do this", '/task/browse/', "browse tasks") + +def view_task(request, tid): + """ get the task depending on its tid and display accordingly if it is a get. + check for authentication and add a comment if it is a post request. + """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + if task.status == "DL": + return show_msg(user, 'This task no longer exists', '/task/browse/','browse the tasks') + comments = task.comment_set.filter(is_deleted=False).order_by('creation_datetime') + mentors = task.mentors.all() + + deps, subs = task.deps, task.subs + + is_guest = True if not user.is_authenticated() else False + is_mentor = True if user in task.mentors.all() else False + context = {'user':user, + 'task':task, + 'comments':comments, + 'mentors':mentors, + 'subs':subs, + 'deps':deps, + 'is_guest':is_guest, + 'is_mentor':is_mentor, + } + + claimed_users = task.claimed_users.all() + + + is_requested_mentor = True if user.is_authenticated() and user.request_sent_to.filter(is_valid=True,is_replied=False,role="MT",task=task) else False + task_viewable = True if ( task.status != "UP" ) or is_mentor or is_requested_mentor else False + if not task_viewable: + return show_msg(user, "You are not authorised to view this task", "/task/browse/", "browse the tasks") + + context['is_requested_mentor'] = is_requested_mentor + + context['can_publish'] = True if task.status == "UP" and user == task.created_by else False + context['can_edit'] = True if task.status == "UP" and is_mentor else False + context['can_close'] = True if task.status not in ["UP", "CD", "CM"] and is_mentor else False + context['can_delete'] = True if task.status == "UP" and user == task.created_by else False + + context['can_mod_mentors'] = True if task.status in ["UP", "OP", "LO", "WR"] and is_mentor else False + context['can_mod_tasks'] = True if task.status in ["UP", "OP", "LO"] and is_mentor else False + + context['can_assign_credits'] = True if task.status in ["OP", "WR"] and is_mentor else False + context['task_claimable'] = True if task.status in ["OP", "WR"] and not is_guest else False + + if task.status == "CD": + context['closing_notification'] = Notification.objects.filter(task=task,role="CD")[0] + elif task.status == "CM": + context['completed_notification'] = Notifications.objects.filter(task=task,role="CM")[0] + elif task.status == "WR": + context['assigned_users'] = task.assigned_users.all() + + if request.method == 'POST': + if not is_guest: + data = request.POST.get("data", "").strip() + if not data: + context['error_msg'] = "Enter some message to comment" + return render_to_response('task/view.html', context) + new_comment = Comment(task=task, data=data, created_by=user, creation_datetime=datetime.now()) + new_comment.save() + return redirect(task_url) + else: + errors.append("You must be logged in to post a comment") + return render_to_response('task/view.html', context) + else: + return render_to_response('task/view.html', context) + +def create_task(request): + """ check for rights and create a task if applicable. + if user cannot create a task, redirect to homepage. + """ + + user = get_user(request.user) if request.user.is_authenticated() else request.user + is_guest = True if not user.is_authenticated() else False + + if not is_guest: + user_profile = user.get_profile() + can_create_task = False if user_profile.rights == "CT" else True + if can_create_task: + if request.method == "POST": + form = TaskCreateForm(request.POST) + if form.is_valid(): + data = form.cleaned_data + title = data['title'] + desc = data['desc'] + credits = data['credits'] + #publish = data['publish'] # just in case if we have to show the option + task = createTask(title,desc,user,credits) + + addMentor(task, user) + updateTask(task,tags_field=data['tags_field']) + # if publish: publishTask(task) + task_url = '/task/view/tid=%s'%task.id + return redirect(task_url) + else: + return render_to_response('task/create.html',{'user':user, 'form':form}) + else: + form = TaskCreateForm() + return render_to_response('task/create.html',{'user':user, 'form':form}) + else: + return show_msg(user, 'You are not authorised to create a task.') + else: + return show_msg(user, 'You are not authorised to create a task.', "/", "home page") + +def add_mentor(request, tid): + """ check if the current user has the rights to edit the task and add him. + if user is not authenticated, redirect him to concerned page. """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + errors = [] + + is_guest = True if not user.is_authenticated() else False + + if (not is_guest) and user in task.mentors.all(): + + pending_requests = Request.objects.filter(is_replied=False,is_valid=True,role="MT",task=task).order_by('creation_date').reverse() + user_pending_requests = pending_requests.filter(sent_by=user) + + ## now iam going for a brute force method + user_list = list(User.objects.filter(is_active=True)) + for mentor in task.mentors.all(): + user_list.remove(mentor) + + for a_user in task.claimed_users.all(): + user_list.remove(a_user) + + for a_user in task.assigned_users.all(): + user_list.remove(a_user) + + for req in user_pending_requests: + user_list.remove(req.sent_to.all()[0]) + + non_mentors = ((_.id, _.username) for _ in user_list) + non_mentor_ids = [ str(a_user.id) for a_user in user_list ] + ## code till must be made elegant and not brute force like above + + form = AddMentorForm(non_mentors) + + context = { + 'user':user, + 'task':task, + 'pending_requests':pending_requests, + 'form':form, + } + + if request.method == "POST": + data = request.POST + uid = data.get('mentor', None) + if uid in non_mentor_ids: + new_mentor = User.objects.get(id=int(uid)) + reqMentor(task, new_mentor, user) + return redirect('/task/addmentor/tid=%s'%task.id) + else: + ## bogus post request + raise Http404 + else: + return render_to_response('task/addmentor.html', context) + else: + return show_msg(user, 'You are not authorised to add mentors for this task', task_url, 'view the task') + +def add_tasks(request, tid): + """ first display tasks which can be subtasks for the task and do the rest. + """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + deps, subs = task.deps, task.subs + is_plain = False if deps or subs else True + + ## again a brute force method + valid_tasks = [] + for a_task in Task.objects.all(): + if not ( a_task in deps or a_task in subs or a_task.status=="CD" or a_task==task ): + valid_tasks.append(a_task) + + task_choices = [ (_.id,_.title) for _ in valid_tasks ] + errors = [] + + is_guest = True if not user.is_authenticated() else False + + if (not is_guest) and user in task.mentors.all(): + if task.status in ["UP", "OP", "LO"]: + form = AddTaskForm(task_choices, is_plain) + if request.method == "POST": + ## first decide if adding subs and deps can be in same page + ## only exclude tasks with status deleted + data = request.POST + if is_plain and not data.get('type', None): errors.append('Please choose which type of task(s) do you want to add.') + if not data.get('task', None): errors.append('Please choose a one task') + + if not errors: + if is_plain: + update_method = addDep if data['type'] == "D" else addSubTask + elif deps: + update_method = addDep + elif subs: + update_method = addSubTask + else: + print "Screw you" + + ## we might iterate over a task list later on + task_id = data['task'] + sub_or_dep = getTask(task_id) + update_method(task, sub_or_dep) + + return redirect(task_url) + else: + return render_to_response('task/addtask.html', {'user':user, 'form':form, 'errors':errors}) + else: + return render_to_response('task/addtask.html', {'user':user, 'form':form, 'errors':errors}) + else: + errors = ["The task cannot be added subtasks or dependencies in this state"] +# return render_to_response('task/add.html', {'form':form, 'errors':errors}) + return show_msg(user, 'The task cannot be added subtasks or dependencies now', task_url, 'view the task') + else: + return show_msg(user, 'You are not authorised to add subtasks or dependencies for this task', task_url, 'view the task') + +def remove_task(request, tid): + """ display a list of tasks and remove the selectes ones. + """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + is_guest = True if not user.is_authenticated() else False + if (not is_guest) and user in task.mentors.all(): + + if task.status in ["UP", "LO", "OP"]: + + deps, subs = task.deps, task.subs + task_list = deps if task.sub_type == "D" else subs + + if task_list: + choices = [(_.id,_.title) for _ in task_list ] + form = ChoiceForm(choices) + + errors = [] + + context = { + 'user':user, + 'task':task, + 'form':form, + } + + if request.method == "POST": + data = request.POST + if not data.get('choice', None): + errors.append("Please choose a task to remove.") + context['errors'] = errors + if not errors: + tid = data['choice'] + sub_task = getTask(tid) + removeTask(task, sub_task) + return redirect(task_url) + else: + return render_to_response('task/removetask.html', context) + else: + return render_to_response('task/removetask.html', context) + else: + return show_msg(user, "The task has no subtasks/dependencies to be removed", task_url, "view the task") + else: + return show_msg(user, "subtasks/dependencies cannot be removed at this stage", task_url, "view the task") + else: + return show_msg(user, "You are not authorised to do this", task_url, "view the task") + +def claim_task(request, tid): + """ display a list of claims for get and display submit only if claimable """ + + ## create claims model and create a new database with required tables for it + ## see if that "one to n" or "n to one" relationship has a special field + + task_url = "/task/view/tid=%s"%tid + claim_url = "/task/claim/tid=%s"%tid + + errors = [] + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + #claims = task.notifications_task.filter(role="CL",sent_to=task.created_by) + # this is what the next line should be when i re sync the db + claims = Notification.objects.filter(task=task, sent_to=task.created_by, role="CL") + + mentors = task.mentors.all() + claimed_users = task.claimed_users.all() + assigned_users = task.assigned_users.all() + + is_guest = True if not user.is_authenticated() else False + is_mentor = True if user in mentors else False + + task_claimable = True if task.status in ["OP", "WR"] else False + user_can_claim = True if task_claimable and not ( is_guest or is_mentor ) and ( user not in claimed_users ) and ( user not in assigned_users ) else False + task_claimed = True if claimed_users else False + + context = {'user':user, + 'is_mentor':is_mentor, + 'task':task, + 'claims':claims, + 'user_can_claim':user_can_claim, + 'task_claimable':task_claimable, + 'task_claimed':task_claimed, + 'errors':errors} + + if not is_guest: + form = ClaimTaskForm() + context['form'] = form + if request.method == "POST": + form = ClaimTaskForm(request.POST) + context['form'] = form + if form.is_valid(): + claim_proposal = form.cleaned_data['message'] + addClaim(task, claim_proposal, user) + return redirect(claim_url) + else: + return render_to_response('task/claim.html', context) + else: + return render_to_response('task/claim.html', context) + else: + return show_msg(user, 'You are not logged in to view claims for this task', task_url, 'view the task') + +def rem_user(request, tid): + """ show a list of working users and ask for a message/reason for removing user. + """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + is_guest = True if not user.is_authenticated() else False + is_mentor = True if user in task.mentors.all() else False + + if (not is_guest) and is_mentor: + + assigned_users = task.assigned_users.all() + choices = [ (_.id,_.username) for _ in assigned_users ] + context = { + 'user':user, + 'task':task, + } + + if task.status in ["WR"]: + if assigned_users: + form = RemoveUserForm(choices) + context['form'] = form + if request.method == "POST": + data = request.POST + form = RemoveUserForm(choices, data) + if form.is_valid(): + data = form.cleaned_data + uid = data['user'] + reason = data['reason'] + rem_user = User.objects.get(id=uid) + removeUser(task, rem_user, user, reason) + return redirect(task_url) + else: + context['form'] = form + return render_to_response('task/remove_user.html', context) + else: + return render_to_response('task/remove_user.html',context) + else: + return show_msg(user, "There is no one working on this task to be kicked off", task_url, "view the task") + else: + return show_msg(user, "This is not the stage to remove users", task_url, "view the task") + else: + return show_msg(user, "You are not authorised to do this", task_url, "view the task") + +def assign_task(request, tid): + """ first get the status of the task and then assign it to one of claimed users + generate list of claimed users by passing it as an argument to a function. + """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + is_guest = True if not user.is_authenticated() else False + is_mentor = True if user in task.mentors.all() else False + + claimed_users = task.claimed_users.all() + assigned_users = task.assigned_users.all() + + task_claimed = True if claimed_users else False + + if (not is_guest) and is_mentor: + if task.status in ["OP", "WR"]: + if task_claimed: + user_list = ((user.id,user.username) for user in claimed_users) + form = ChoiceForm(user_list) + + if request.method == "POST": + uid = request.POST['choice'] + assigned_user = User.objects.get(id=uid) + assignTask(task, assigned_user, user) + return redirect(task_url) + else: + return render_to_response('task/assign.html',{'user':user, 'task':task,'form':form}) + elif assigned_users: + return show_msg(user, 'When the no of users you need for the task is more than the no of users willing to do the task, I\'d say please re consider the task :P',task_url, 'view the task') + else: + return show_msg(user, 'Wait for ppl to claim dude... slow and steady wins the race :)', task_url, 'view the task') + else: + return show_msg(user, "The task cannot be assigned to users at this stage", task_url, 'view the task') + else: + return show_msg(user, 'You are not authorised to perform this action', task_url, 'view the task') + +def assign_credits(request, tid): + """ Check if the user is a mentor and credits can be assigned. + Then display all the approved credits. + Then see if mentor can assign credits to users also or only mentors. + Then put up a form for mentor to assign credits accordingly. + """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + ## the moment we see that user had requested credits, it means he had worked and hence we change the status to WR + ## we have to discuss on this since, credits may also be given to mentor + task.status = "WR" + task.save() + + is_guest = True if not user.is_authenticated() else False + is_mentor = True if (not is_guest) and user in task.mentors.all() else False + + if is_mentor: + if task.status in ["OP", "WR"]: + choices = [(_.id,_.username) for _ in task.mentors.all()] + if task.status == "WR": + choices.extend([(_.id, _.username) for _ in task.assigned_users.all() ]) + prev_credits = task.request_task.filter(role="PY",is_valid=True,is_replied=True,reply=True).count() + credit_requests = task.request_task.filter(role="PY",is_valid=True).order_by('creation_date').reverse() + form = AssignCreditForm(choices) + + context = { + 'user':user, + 'task':task, + 'prev_credits':prev_credits, + 'credit_requests':credit_requests, + 'form':form, + } + + if request.method == "POST": + data = request.POST + form = AssignCreditForm(choices, data) + if form.is_valid(): + data = form.cleaned_data + uid = data['user'] + points = data['pynts'] + given_to = User.objects.get(id=uid) + assignCredits(task=task, given_by=user, given_to=given_to, points=points) + return redirect('/task/assigncredits/tid=%s'%task.id) + else: + context['form'] = form + return render_to_response('task/assigncredits.html', context) + else: + return render_to_response('task/assigncredits.html', context) + else: + return show_msg(user, "Credits cannot be assigned at this stage", task_url, "view the task") + else: + return show_msg(user, "You are not authorised to perform this action", task_url, "view the task") + +def edit_task(request, tid): + """ see what are the attributes that can be edited depending on the current status + and then give the user fields accordingly. + """ + + task = getTask(tid) + + task_url = "/task/view/tid=%s"%tid + user = get_user(request.user) if request.user.is_authenticated() else request.user + + is_mentor = True if user in task.mentors.all() else False + can_edit = True if is_mentor and task.status == "UP" else False + + if can_edit: + form = EditTaskForm(instance=task) + if request.method=="POST": + data = request.POST + form = EditTaskForm(data, instance=task) + if form.is_valid(): + form.save() + return redirect(task_url) + else: + return render_to_response('task/edittask.html',{'user':user, 'form':form}) + else: + return render_to_response('task/edittask.html',{'user':user, 'form':form}) + else: + return show_msg(user, "You cannot edit the task at this stage", task_url, "view the task") + +def complete_task(request, tid): + """ call the event called complete task. + and also pass it the current user to know who marked it as complete. + """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + is_guest = True if not user.is_authenticated() else False + is_mentor = True if user in task.mentors.all() else False + + claimed_users = task.claimed_users.all() + assigned_users = task.assigned_users.all() + + assign_credits_url = '/task/assigncredits/tid=%s'%task.id + task_assigned_credits = task.credit_set.all() + + + if is_mentor: + if task.status in ["OP", "WR"]: + + context = { + 'user':user, + 'task':task, + } + + if task_assigned_credits: + if request.method=="POST": + completeTask(task, user) + return redirect(task_url) + else: + return render_to_response('task/complete.html', context) + else: + return show_msg(user, "Nobody has been credited for doing this task.", assign_credits_url, "assign credits") + else: + return show_msg(user, "The task cannot be marked as completed at this stage", task_url, "view the task") + else: + return show_msg(user, "You are not authorised to do this", task_url, "view the task") + +def close_task(request, tid): + """ task can be closed only if task is published. + call the event close task if everything is fine. + """ + + task_url = "/task/view/tid=%s"%tid + + user = get_user(request.user) if request.user.is_authenticated() else request.user + task = getTask(tid) + + is_guest = True if not user.is_authenticated() else False + is_mentor = True if user in task.mentors.all() else False + + if is_mentor: + + context = { + 'user':user, + 'task':task, + } + + if not task.status in ["UP", "CD", "DL", "CM"]: + if request.method == "POST": + data = request.POST + if not data.get("reason", None): + context["error"] = "Please enter a reason for closing the task" + return render_to_response('task/close.html', context) + else: + closeTask(task, user, data['reason']) + return show_msg(user, "The task has been closed.", task_url, "view the task.") + else: + return render_to_response('task/close.html', context) + else: + return show_msg(user, "The task is either already closed or cannot be closed at this stage", task_url, "view the task") + else: + return show_msg(user, "You are not authorised to do this", task_url, "view the task") + +def delete_task(request, tid): + """ mark the task status as DL. + take a reason from the user and pass on to all the other mentors. + """ + + task_url = "/task/view/tid=%s"%tid + + task = getTask(tid) + user = get_user(request.user) if request.user.is_authenticated() else request.user + + if task.status == "DL": + return show_msg(user, "This task no longer exists", '/task/browse/', "to browse other tasks") + + can_delete = True if task.status == "UP" and task.created_by == user else False + + if can_delete: + if request.method == "POST": + data = request.POST + reason = data.get('reason', None) + deleteTask(task, user, reason) + return show_msg(user, "The task is deleted", '/', "to return to home page") + else: + return render_to_response('task/delete.html',{'user':user,}) + else: + return show_msg(user, "You are not authorised to do this at this stage", task_url, "view the task") diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/taskapp/views/user.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/taskapp/views/user.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,347 @@ +import os + +from django.http import HttpResponse, Http404 +from django.shortcuts import redirect, render_to_response +from django.contrib.auth.models import User +from django.contrib.auth.decorators import login_required + +from pytask.taskapp.models import Task, Profile, Request + +from pytask.taskapp.events.user import createUser +from pytask.taskapp.events.request import reply_to_request + +from pytask.taskapp.forms.user import UserProfileEditForm, UserChoiceForm + +from pytask.taskapp.utilities.request import get_request, create_request +from pytask.taskapp.utilities.notification import get_notification, create_notification +from pytask.taskapp.utilities.user import get_user + +about = { + "addmentors": "about/addmentors.html", + "mentor": "about/mentor.html", + "starthere": "about/starthere.html", + "task": "about/task.html", + "tasklife": "about/tasklife.html", + "developer": "about/developer.html", + "notification": "about/notification.html", + "request": "about/request.html", + "manager": "about/manager.html", + "admin": "about/admin.html", +} + +def show_msg(user, message, redirect_url=None, url_desc=None): + """ simply redirect to homepage """ + + return render_to_response('show_msg.html',{'user':user, 'message':message, 'redirect_url':redirect_url, 'url_desc':url_desc}) + +def homepage(request): + """ check for authentication and display accordingly. """ + + user = request.user + is_guest = False + is_mentor = False + can_create_task = False + task_list = [] + + if not user.is_authenticated(): + is_guest = True + disp_num = 10 + task_list = Task.objects.exclude(status="UP").exclude(status="CD").exclude(status="CM").order_by('published_datetime').reverse()[:10] + return render_to_response('index.html', {'user':user, 'is_guest':is_guest, 'task_list':task_list}) + + else: + user = get_user(request.user) + user_profile = user.get_profile() + is_mentor = True if user.task_mentors.all() else False + can_create_task = False if user_profile.rights == u"CT" else True + + context = {'user':user, + 'is_guest':is_guest, + 'is_mentor':is_mentor, + 'task_list':task_list, + 'can_create_task':can_create_task, + } + + context["unpublished_tasks"] = user.task_mentors.filter(status="UP") + context["mentored_tasks"] = user.task_mentors.exclude(status="UP").exclude(status="CM").exclude(status="CD").exclude(status="DL") + context["claimed_tasks"] = user.task_claimed_users.exclude(status="UP").exclude(status="CM").exclude(status="CD").exclude(status="DL") + context["working_tasks"] = user.task_assigned_users.filter(status="WR") + + return render_to_response('index.html', context) + +@login_required +def learn_more(request, what): + """ depending on what was asked for, we render different pages. + """ + + user = get_user(request.user) + disp_template = about.get(what, None) + if not disp_template: + raise Http404 + else: + return render_to_response(disp_template, {'user':user}) + +@login_required +def view_my_profile(request,uid=None): + """ allows the user to view the profiles of users """ + user = get_user(request.user) + request_user_profile = request.user.get_profile() + request_user_privilege = True if request_user_profile.rights in ['AD','MG'] else False + if uid == None: + edit_profile = True + profile = Profile.objects.get(user = request.user) + return render_to_response('user/my_profile.html', {'edit_profile':edit_profile,'profile':profile, 'user':user, 'privilege':request_user_privilege}) + edit_profile = True if request.user == User.objects.get(pk=uid) else False + try: + profile = Profile.objects.get(user = User.objects.get(pk=uid)) + except Profile.DoesNotExist: + raise Http404 + return render_to_response('user/my_profile.html', {'edit_profile':edit_profile,'profile':profile, 'user':user, 'privilege':request_user_privilege}) + +@login_required +def edit_my_profile(request): + """ enables the user to edit his/her user profile """ + + user = get_user(request.user) + user_profile = user.get_profile() + + edit_profile_form = UserProfileEditForm(instance = user_profile) + if request.method == 'POST': + + data = request.POST.copy() + uploaded_photo = request.FILES.get('photo', None) + data.__setitem__('photo', uploaded_photo) + + edit_profile_form = UserProfileEditForm(data, instance=user_profile) + if edit_profile_form.is_valid(): + edit_profile_form.save() + return redirect('/user/view/uid='+str(user.id)) + else: + return render_to_response('user/edit_profile.html',{'user':user, 'edit_profile_form' : edit_profile_form}) + else: + profile = user.get_profile() + edit_profile_form = UserProfileEditForm(instance = profile) + return render_to_response('user/edit_profile.html',{'edit_profile_form' : edit_profile_form, 'user':user}) + +@login_required +def browse_requests(request): + + user = get_user(request.user) + active_reqs = user.request_sent_to.filter(is_replied=False).exclude(is_valid=False) + reqs = active_reqs.order_by('creation_date').reverse() + + context = { + 'user':user, + 'reqs':reqs, + } + + return render_to_response('user/browse_requests.html', context) + +@login_required +def view_request(request, rid): + """ please note that request variable in this method is that of django. + our app request is called user_request. + """ + + user = get_user(request.user) + user_rights = user.get_profile().rights + newest, newer, user_request, older, oldest = get_request(rid, user) + if not user_request: + raise Http404 + + user_request.is_read = True + user_request.save() + + context = { + 'user':user, + 'req':user_request, + 'sent_users':user_request.sent_to.all(), + 'newest':newest, + 'newer':newer, + 'older':older, + 'oldest':oldest, + } + + return render_to_response('user/view_request.html', context) + +@login_required +def process_request(request, rid, reply): + """ check if the method is post and then update the request. + if it is get, display a 404 error. + """ + + user = get_user(request.user) + browse_request_url= '/user/requests' + newest, newer, req_obj, older, oldest = get_request(rid, user) + + if not req_obj: + return show_msg(user, "Your reply has been processed", browse_request_url, "view other requests") + + if request.method=="POST": + reply = True if reply == "yes" else False + req_obj.remarks = request.POST.get('remarks', "") + req_obj.save() + + reply_to_request(req_obj, reply, user) + + return redirect('/user/requests/') + return show_msg(user, "Your reply has been processed", browse_request_url, "view other requests") + else: + return show_msg(user, "You are not authorised to do this", browse_request_url, "view other requests") + +@login_required +def browse_notifications(request): + """ get the list of notifications that are not deleted and display in datetime order. + """ + + user = get_user(request.user) + + active_notifications = user.notification_sent_to.filter(is_deleted=False).order_by('sent_date').reverse() + + context = { + 'user':user, + 'notifications':active_notifications, + } + + return render_to_response('user/browse_notifications.html', context) + +@login_required +def view_notification(request, nid): + """ get the notification depending on nid. + Display it. + """ + + user = get_user(request.user) + newest, newer, notification, older, oldest = get_notification(nid, user) + if not notification: + raise Http404 + + notification.is_read = True + notification.save() + + context = { + 'user':user, + 'notification':notification, + 'newest':newest, + 'newer':newer, + 'older':older, + 'oldest':oldest, + } + + return render_to_response('user/view_notification.html', context) + +@login_required +def edit_notification(request, nid, action): + """ if action is delete, set is_deleted. + if it is unread, unset is_read. + save the notification and redirect to browse_notifications. + """ + + user = get_user(request.user) + newest, newer, notification, older, oldest = get_notification(nid, user) + + if not notification: + raise Http404 + + notifications_url = "/user/notifications/" + + if request.method == "POST": + if action == "delete": + notification.is_deleted = True + elif action == "unread": + notification.is_read = False + + notification.save() + if older: + return redirect('/user/notifications/nid=%s'%older.id) + else: + return redirect(notifications_url) + else: + return show_msg(user, 'This is wrong', notification_url, "view the notification") + +@login_required +def change_rights(request, role): + """ check if the current user has privileges to do this. + """ + + user = get_user(request.user) + role = role.upper() + user_profile = user.get_profile() + user_rights = user_profile.rights + + user_can_view = True if user_rights == "AD" or ( user_rights == "MG" and role in ["MG", "DV"] ) else False + + if user_can_view: + if role == "DV": + current_contributors = list(User.objects.filter(is_active=True,profile__rights="CT")) + pending_requests = user.request_sent_by.filter(is_replied=False,is_valid=True) + pending_dv_requests = pending_requests.filter(role="DV") + + ## one cannot make same request many times + for req in pending_dv_requests: + current_contributors.remove(req.sent_to.all()[0]) + + choices = [ (_.id,_.username ) for _ in current_contributors ] + + elif role == "MG": + active_users = User.objects.filter(is_active=True) + dv_ct_users = list(active_users.filter(profile__rights="CT") | active_users.filter(profile__rights="DV")) + pending_requests = user.request_sent_by.filter(is_replied=False,is_valid=True) + pending_mg_requests = pending_requests.filter(role="MG") + + ## same logic here. you cannot make another request exactly the same. + ## but iam still not decided whether someone who requests a user to be admin, + ## can be given a chance to request the same user to be a manager or developer + for req in pending_mg_requests: + dv_ct_users.remove(req.sent_to.all()[0]) + + choices = [ (_.id, _.username ) for _ in dv_ct_users ] + + elif role == "AD": + active_users = User.objects.filter(is_active=True) + non_ad_users = list(active_users.exclude(profile__rights="AD")) + pending_requests = user.request_sent_by.filter(is_replied=False,is_valid=True) + pending_ad_requests = pending_requests.filter(role="AD") + + ## we filter out users who have already been requested by the user to be an admin + for req in pending_ad_requests: + non_ad_users.remove(req.sent_to.all()[0]) + + choices = [ (_.id,_.username ) for _ in non_ad_users ] + + form = UserChoiceForm(choices) + + context = { + 'user':user, + 'form':form, + } + + if request.method=="POST": + data = request.POST + form = UserChoiceForm(choices, data) + if form.is_valid(): + user_to_change = User.objects.get(id=form.cleaned_data['user']) + create_request(sent_by=user, role=role, sent_to=user_to_change) + return show_msg(user, "A request has been sent", "/", "return to home page") + else: + raise Http404 + else: + return render_to_response('user/changerole.html', context) + else: + raise Http404 + + + + + + + + + + + + + + + + diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/404.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/404.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,5 @@ +{% extends 'base.html' %} +{% block content %} + The page you requested does not exist.
+ Click here to get back to the previous page. +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/addmentors.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/addmentors.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,24 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - About - Add Mentors +{% endblock %} +{% block content %} + + A Mentor learn more + of the task can request other users to mentor the task by clicking the link "Add more mentors" available on the task page. + A request will be sent to the user. If a user has claimed the task or is working on the task, he cannot be requested to be a mentor. + If the requested user accepts the request, he will also become the mentor of the task.

+ + Since mentors can view unpublished tasks, mentors can be requested to view, edit and comment upon unpublished tasks. + They can also add or remove subtasks/dependencies in unpublished state. Thereby, the creator of task can fix on the task. + Publishing/Deleting of an unpublished task is available only to the creator of the task.

+ + Users can also be requested to mentor an published task. If the user accepts the request, he also becomes the mentor of the task. + In this case, the mentor is equivalent to the creator of the task. He can select/remove users; request pynts; close/complete the task. + He will have complete control over the task.

+ + If a mentor requests a user to act as a mentor, he cannot make the same request to the same user again untill the previous one is + rejected. However, another mentor in the task can request the same user to be a mentor, unless there is already a similar request to the user + from this mentor also. + +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/admin.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/admin.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,8 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - About - Admin +{% endblock %} +{% block content %} + Admin is the user who has to approve assign of credits to any user for his/her work on the task.
+ An Admin also has the right to request normal users to become admins or managers or developers. +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/developer.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/developer.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,8 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - About - Developer +{% endblock %} +{% block content %} + A Developer has the right to post a task. The link is available on your homepage.
+ click here to know the complete life cycle of a task. +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/manager.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/manager.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,7 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - About - Manager +{% endblock %} +{% block content %} + A Manager has the right to request normal users to become managers or developers. +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/mentor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/mentor.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,21 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - About - Mentor +{% endblock %} +{% block content %} + Mentoring is a right specific to the task. The user who creates a task will become the mentor for the task. A Mentor can request + other learn more users also to mentor the task. + Mentor is a person who mentors the task. Mentor has all the rights over the task.
+ + + click here to know the complete life cycle of a task. +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/notification.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/notification.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,7 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - About - Notification +{% endblock %} +{% block content %} + Notification is a message generated by the system to inform you about any events. +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/request.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/request.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,25 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - About - Request +{% endblock %} +{% block content %} + Request is a request made by a user, requesting you to become someone else. It can also be request of assigning pynts to a user + for a task ( goes to all the admins only ). + You can accept or reject a request. You can also provide optional remarks when rejecting. When you respond to a request, it is + automatically removed from your requests and you will be redirected to browse requests page. + Redundant requests are automatically removed.

+ The following can be redundant requests. + + These redundant requests when removed, a notification is sent to the requested user. + + +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/starthere.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/starthere.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,14 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - Start here +{% endblock %} +{% block content %} + PyTasks is a website designed to encourage open source participation of people. Now that you are registered, you are a + contributor in the website. + You can see your notifications and requests from the links available in side bar. + You can browse all the tasks through the tasks link in the side bar.
+ Choose a task learn more of your choice and claim it to start working on it.
+ + + +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/task.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/task.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,22 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - About - Task +{% endblock %} +{% block content %} + A task is an entity that people can work on and get pynts for their work. Every task has credits which are given to + users working on the task. A task is created by a privileged user and he becomes a + mentor learn more for the task. + The task if open, can be claimed by other users if they would like to work on the task.

+ + The task can be claimed by submitting a proposal in the view claims page. The link to view claims page is available on the task page. + By claiming the task, you are actually proposing that you would like to do the task and hence the mentor of the task will + be given an option to choose you for the task. A user can only submit one claim per task. But if a user is assigned a task + and for some reason, is removed from the task later on, he can submit a second claim requesting to continue working on the task.

+ + A task can also have subtasks and dependencies. + The task can only be calimed when it is open for people to work on. If the link is unavailable it implies that the task is locked + since it has subtasks or it has dependencies that are not complete or the task is closed or the task is complete.

+ + click here to know the complete life cycle of a task. + +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/about/tasklife.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/about/tasklife.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,39 @@ +{% extends 'base.html' %} +{% block title %} + PyTasks - About - Task life cycle +{% endblock %} +{% block content %} + The task is created by a user and will start life in unpublished state. The creator has all rights over the task. The task in this + stage will be visible only to the creator. He can anyways request other users to view and review the task. Then the requested user + can view the task untill he does not reply to the request. If the user accepts the request, he can view, edit and comment on the task. + The user can also add/remove subtasks or dependencies. If he rejects the request he is just like other users and cannot view the task. + When the creator decides the task is ready to be published, he publishes the task. Through out this phase, + the creator of the task can delete the task at any point in time. +

+ + If the task survives and is published, the task is available to be viewed by all the users. The task cannot be edited after this + point but subtasks/dependencies can be added/removed. If the task has subtasks, the task is locked forever. It implies that the task + cannot be claimed by anyone and exists only to show all of its subtasks in one place.

+ If a task has dependencies, the task is locked untill all of its dependencies are completed. If all its dependencies are completed, + the task is open for claims and can be claimed by users. + If a task has neither subtasks nor dependencies, it is open as well and users claim the task. Any of the mentors can select user(s) + from the claimed users to work on the task . Dependencies can be added/removed only untill a user is selected to work on the task. This is due + to the fact that user had a chance to claim when the task had no dependencies or all its dependencies were satisfied. + Also selecting a user to work on the task implies the task has all its dependencies satisfied.

+ + During the working stage of task, a mentor can request assign of pynts to users working on task or the mentors. The assign pynts link + will be available to mentor on the task page. If there are no users working, the mentor can request assign of credits to himself + or one of the other mentors, who ever has done work on the task. Even if there are no users working on task, if there is a + request for assign of credits to the task implies that someone has worked on the task and hence dependencies cannot be + added after that.

+ + The users can be selected to work or removed from working users at any point in time. If a user is removed, he can claim again + to request to continue working on the task. If a user is removed, all the pending requests for assigning pynts to user will be made invalid. + After a considerable amount of work has been done and all the users and mentors have been assigned pynts properly, any mentor in the + task can mark the task as complete. The link is available on assign pynts page just in case + the mentor wants to assign more pynts before marking the task as complete.
+ If a mentor feels that the task is invalid or decides to delete the task, he will not be allowed to do it. Instead he can close the task + by providing a closing message. The link to close task will be available to mentors on the task page itself.

+ + Now all this can be done by any of the mentors and hence think twice before you request a user to mentor the task. +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/admin/login.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/admin/login.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,34 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block extrastyle %}{% load adminmedia %}{{ block.super }}{% endblock %} + +{% block bodyclass %}login{% endblock %} + +{% block content_title %}{% endblock %} + +{% block breadcrumbs %}{% endblock %} + +{% block content %} +{% if error_message %} +

{{ error_message }}

+{% endif %} +
+
+
+ +
+
+ + +
+
+ +
+
+ + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/base.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/base.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,175 @@ + + + {% block title %}PyTasks{% endblock %} + {% block js_script %} {% endblock %} + + + + + + + + diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/index.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,124 @@ +{% extends 'base.html' %} +{% block content %} + {% if is_guest %} + Welcome Guest
+ Register + Login

+ Recent Tasks:
+ {% for task in task_list %} + {{ task.title }}
+ {% endfor %} + {% else %} + Logged in as {{ user.username }}

+ {% endif %} + + {% if can_create_task %} + Create a task
+
+ {% endif %} + {% ifequal user.get_profile.rights "MG" %} + Request another user to be a Developer
+ Request another user to act as manager
+
+ {% endifequal %} + {% ifequal user.get_profile.rights "AD" %} + Request another user to be a Developer
+ Request another user to act as a Manager
+ Request another user to act as an Admin
+
+ {% endifequal %} + + + {% if user.unread_notifications.count %} + You have {{ user.unread_notifications.count }} unread + {% ifnotequal user.unread_notifications.count 1 %} + notifications + {% else %} + notification + {% endifnotequal %} +
+ {% endif %} + + {% if user.unread_requests.count %} + You have {{ user.unread_requests.count }} unread + {% ifnotequal user.unread_requests.count 1 %} + requests + {% else %} + request + {% endifnotequal %} +

+ {% else %} + {% if user.unread_notifications.count %} +
+ {% endif %} + {% endif %} + + + + + {% if unpublished_tasks %} + Unpublished tasks viewable by you: +
+ {% endif %} + + {% if mentored_tasks %} + Tasks you are mentoring: +
+ {% endif %} + + {% if working_tasks %} + Tasks that have been assigned to you: +
+ {% endif %} + + {% if claimed_tasks %} + Tasks claimed but still not assigned to you: +
+ {% endif %} + +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/activate.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/activate.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,4 @@ +{% extends 'base.html' %} +{% block content %} +Your account has been successfully activated. +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/activation_email.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/activation_email.txt Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,9 @@ +Welcome to PyTasks: + +Click on the following link +http://{{site}}/accounts/activate/{{activation_key}} +and activate your account. +Note that the account has to activated within {{expiration_days}} days + +Regards, +PyTasks Team diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/activation_email_subject.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/activation_email_subject.txt Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,1 @@ +Welcome to PyTasks! diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/logged_out.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/logged_out.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block breadcrumbs %}{% endblock %} + +{% block content %} + +

{% trans "Thanks for spending some quality time with the Web site today." %}

+ +

{% trans 'Log in again' %}

+ +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/login.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/login.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,8 @@ +{% extends 'base.html' %} +{% block content %} +
+{{ form.as_p }} + +
+Forgot password? +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/logout.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/logout.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,6 @@ +{% extends 'base.html' %} +{% block content %} +You have successfully logged out of PyTasks. +

+Click here to go back to PyTask Homepage +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/password_change_done.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/password_change_done.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,14 @@ +{% extends "base.html" %} +{% load i18n %} +{% block userlinks %}{% url django-admindocs-docroot as docsroot %}{% if docsroot %}{% trans 'Documentation' %} / {% endif %}{% trans 'Change password' %} / {% trans 'Log out' %}{% endblock %} +{% block breadcrumbs %}{% endblock %} + +{% block title %}{% trans 'Password change successful' %}{% endblock %} + +{% block content %} + +

{% trans 'Password change successful' %}

+ +

{% trans 'Your password was changed.' %}

+ +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/password_change_form.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/password_change_form.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,26 @@ +{% extends "base.html" %} +{% load i18n %} +{% block userlinks %}{% url django-admindocs-docroot as docsroot %}{% if docsroot %}{% trans 'Documentation' %} / {% endif %} {% trans 'Change password' %} / {% trans 'Log out' %}{% endblock %} +{% block breadcrumbs %}{% endblock %} + +{% block title %}{% trans 'Password change' %}{% endblock %} + +{% block content %} + +

{% trans 'Password change' %}

+ +

{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}

+ +
+ +{{ form.old_password.errors }} +

{{ form.old_password }}

+{{ form.new_password1.errors }} +

{{ form.new_password1 }}

+{{ form.new_password2.errors }} +

{{ form.new_password2 }}

+ +

+
+ +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/password_reset_complete.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/password_reset_complete.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,16 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block breadcrumbs %}{% endblock %} + +{% block title %}{% trans 'Password reset complete' %}{% endblock %} + +{% block content %} + +

{% trans 'Password reset complete' %}

+ +

{% trans "Your password has been set. You may go ahead and log in now." %}

+ +

{% trans 'Log in' %}

+ +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/password_reset_confirm.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/password_reset_confirm.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,32 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block breadcrumbs %}{% endblock %} + +{% block title %}{% trans 'Password reset' %}{% endblock %} + +{% block content %} + +{% if validlink %} + +

{% trans 'Enter new password' %}

+ +

{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}

+ +
+{{ form.new_password1.errors }} +

{{ form.new_password1 }}

+{{ form.new_password2.errors }} +

{{ form.new_password2 }}

+

+
+ +{% else %} + +

{% trans 'Password reset unsuccessful' %}

+ +

{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}

+ +{% endif %} + +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/password_reset_done.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/password_reset_done.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,14 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block breadcrumbs %}{% endblock %} + +{% block title %}{% trans 'Password reset successful' %}{% endblock %} + +{% block content %} + +

{% trans 'Password reset successful' %}

+ +

{% trans "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly." %}

+ +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/password_reset_email.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/password_reset_email.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,15 @@ +{% load i18n %}{% autoescape off %} +{% trans "You're receiving this e-mail because you requested a password reset" %} +{% blocktrans %}for your user account at {{ site_name }}{% endblocktrans %}. + +{% trans "Please go to the following page and choose a new password:" %} +{% block reset_link %} +{{ protocol }}://{{ domain }}{% url django.contrib.auth.views.password_reset_confirm uidb36=uid, token=token %} +{% endblock %} +{% trans "Your username, in case you've forgotten:" %} {{ user.username }} + +{% trans "Thanks for using our site!" %} + +{% blocktrans %}The {{ site_name }} team{% endblocktrans %} + +{% endautoescape %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/password_reset_form.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/password_reset_form.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block breadcrumbs %}{% endblock %} + +{% block title %}{% trans "Password reset" %}{% endblock %} + +{% block content %} + +

{% trans "Password reset" %}

+ +

{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}

+ +
+{{ form.email.errors }} +

{{ form.email }}

+
+ +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/registration_complete.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/registration_complete.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,4 @@ +{% extends 'base.html' %} +{% block content %} +Please check your email for instructions on activating your account. +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/registration/registration_form.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/registration/registration_form.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,7 @@ +{% extends 'base.html' %} +{% block content %} +
+{{ form.as_p }} + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/show_msg.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/show_msg.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,27 @@ +{% extends 'base.html' %} +{% block js_script %} + +{% endblock %} +{% block content %} + + {% if message %} + {{message}}
+ {% endif %} + You will be redirected to {{url_desc}} page in 5 seconds + +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/addmentor.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/addmentor.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,26 @@ +{% extends 'base.html' %} +{% block content %} + Click here to return to the task.

+ Requesting a user to act as a mentor for the task sends him a request. If he accepts the request, he will also be the mentor for this task + {% ifequal task.status "UP" %} + and can view/editlearn more the task. But only the creator of a task can publish the task. + {% else %} + and will have all the rightslearn more you posses over the task. + {% endifequal %} +
+
+
+ {{form.as_table}} + +
+ {% if pending_requests %} + Pending requests:
+ {% for req in pending_requests %} + {{req.sent_by.username}} requested + {% for a_user in req.sent_to.all %} + {{a_user.username}} to act as a mentor + {% endfor %} + on {{req.creation_date|date:"D d M Y"}} at {{req.creation_date|time:"H:i"}}
+ {% endfor %} + {% endif %} +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/addtask.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/addtask.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% block title %} + Add tasks for {{task.title}} +{% endblock %} +{% block content %} + {% if errors %} + Please correct the following errors.
+ {% for err in errors %} + {{err}}
+ {% endfor %} + {% endif %} +
+ {{form.as_p}} + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/assign.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/assign.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,9 @@ +{% extends 'base.html' %} +{% block content %} + click here to return to the claims page.

+ Select a user to assign this task.
+
+ {{form.as_table}} + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/assigncredits.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/assigncredits.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,42 @@ +{% extends 'base.html' %} +{% block title %} + {{task.title}} +{% endblock %} +{% block content %} + Click here to return to the task.
+ +
+ {{form.as_p}} + +
+ {% if prev_credits %} + Mark task as complete. +
+ {% endif %} + {% if credit_requests %} +
Previous credits:
+ {% for req in credit_requests %} +
+ {{req.sent_by.username}} requested assigning of {{req.pynts}} pynts to + {{req.receiving_user.username}} + on {{req.creation_date|date:"D d M Y"}} at {{req.creation_date|time:"H:i"}}
+ {% if req.is_replied %} + status: + {% if req.reply %} + Approved by {{req.replied_by.username}} + on {{req.reply_date|date:"D d M Y"}} at {{req.reply_date|time:"H:i"}}
+ {% else %} + Rejected by {{req.replied_by.username}} + on {{req.reply_date|date:"D d M Y"}} at {{req.reply_date|time:"H:i"}}
+ {% if req.remarks %} + Reason: {{req.remarks}} + {% endif %} + {% endif %} + {% else %} + status: Request pending + {% endif %} + {% endfor %} + {% else %} + No assigning of pynts has been made for this task. + {% endif %} +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/browse.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/browse.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,8 @@ +{% extends 'base.html' %} +{% block content %} + List of all the tasks: +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/claim.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/claim.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,52 @@ +{% extends 'base.html' %} +{% block content %} + {% if user_can_claim %} + Propose a claim to work on this task.learn more

+ {% endif %} + {% if claims %} + List of all the claims for the task {{task.title}}
+ {% for claim in claims %} +
+ {{claim.sent_from.username}} + on {{claim.sent_date|date:"D d M Y"}} at {{claim.sent_date|time:"H:i"}} wrote:
+ {{claim.remarks}}
+ {% endfor %} + {% else %} + {% if task_claimable %} + There are no claims for this task yet.
+ {% if user_can_claim %} + Be the first to claim the task.
+ {% endif %} + {% else %} + The task cannot be claimed at this stage.
+ {% endif %} + Click here to view the task.
+ {% endif %} + {% if task_claimed and is_mentor %} + Select a user to assign the work.learn more + {% endif %} + {% if user_can_claim %} + +
+
+ {{form.as_p}} +
+ Please note that you can claim only once and so write your proposal carefully.
+
+ {% endif %} + +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/close.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/close.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,22 @@ +{% extends 'base.html' %} +{% block title %} + {{task.title}} +{% endblock %} +{% block content %} + Disclaimer:
+ If a task is closed, it implies the task is no more a valid task. The task cannot be edited or added subtasks/dependencies. + Please click here to return to assign credits page if you want to request assign of credits. + You cannot request assign of credits and all the pending requests on this task will be made invalid when a task is closed.

+ + The only difference between marking a task as closed and completed is that the tasks depending on completed tasks will be free to be claimed + and worked on. This action cannot be undone. If you have double checked every thing, please provide a reason and close the task.
+ +
+ {% if error %} + Please provide a reason for closing the task. + {% endif %} +
+ Reason: + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/complete.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/complete.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,19 @@ +{% extends 'base.html' %} +{% block title %} + {{task.title}} +{% endblock %} +{% block content %} + Disclaimer:
+ Marking a task as complete implies the task has been completed successfully. It implies that all the required files + are available as attatchments in comments and all the users worked on this task were credited accordingly.

+ This action sets the task as completed and frees all the tasks depending on this task. Henceforth, the task can not be + commented upon or edited by anyone.

+ If there are pending requests for assigning credits, they will be deleted and admins will not be able to approve those requests. + Hence you cannot assign credits to anyone for this task anymore. You must wait for the requests to be approved by any of the admins. + If you would like to request for assigning more credits, return to assign credits page by clicking + here.

+ If you have double checked everything, confirm this action by clicking the button below. +
+ +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/create.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/create.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,10 @@ +{% extends 'base.html' %} +{% block content %} + {% if error_msg %} + {{ error_msg }}
+ {% endif %} +
+ {{form.as_p}} + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/delete.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/delete.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,12 @@ +{% extends 'base.html' %} +{% block title %} + {{task.title}} +{% endblock %} +{% block content %} + Are you sure you want to delete the task. This action cannot be undone.
+ +
+ Reason: + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/edittask.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/edittask.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,10 @@ +{% extends 'base.html' %} +{% block content %} + {% if error_msg %} + {{ error_msg }}
+ {% endif %} +
+ {{form.as_p}} + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/publish.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/publish.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% block title %} + {{task.title}} +{% endblock %} +{% block content %} + Disclaimer:
+ Publishing a task will make the task visible to every one and cannot be edited there after.

+ Only you will have mentoring rights on this task. But you can request other users also to mentor the task. + learn more

+ This action cannot be undone. +
+ Please confirm if you want to publish. +
+ +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/remove_user.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/remove_user.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% block title %} + Remove users for {{task.title}} +{% endblock %} +{% block content %} + Click here to return to {{task.title}} +
+ {{form.as_p}} + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/removetask.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/removetask.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,17 @@ +{% extends 'base.html' %} +{% block title %} + Remove tasks for {{task.title}} +{% endblock %} +{% block content %} + Click here to return to task.
+ {% if errors %} + Please correct the following errors.
+ {% for err in errors %} + {{err}}
+ {% endfor %} + {% endif %} +
+ {{form.as_p}} + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/task/view.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/task/view.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,172 @@ +{% extends 'base.html' %} +{% block title %} + {{task.title}} +{% endblock %} +{% block content %} +

{{ task.title }}

+ + {% if can_edit %} + Edit task + {% endif %} + + {% if can_publish %} + Publish task + {% endif %} + + {% if can_close %} + Close this task + {% endif %} + + {% if can_delete %} + Delete task + {% endif %} + +
created by {{ task.created_by.username }} + on {{task.creation_datetime|date:"D d M Y"}} at {{task.creation_datetime|time:"H:i"}}
+ + {% ifequal task.status "UP" %} + Task can be viewed by: + {% else %} + Mentors: + {% endifequal %} + + {% for mentor in mentors %} + {{mentor.username}} + {% endfor %} + + {% if can_mod_mentors %} + + {% ifequal task.status "UP" %} + Request others to view/edit the task + {% else %} + Add another Mentor to this task + {% endifequal %} + {% endif %} +
+ +
+ Description:
+ {{ task.desc|linebreaksbr }} +


+ {% if task.tags.count %} + Tags: + {% for tag in task.tags %} + {{tag}} + {% endfor %} +
+ {% endif %} + + {% if deps %} + +
The task has following dependencies. + + {% if can_mod_tasks %} + add more dependencies + remove an existing dependency + {% endif %} + + {% else %} + + {% if subs %} + The task has following sub tasks. + + {% if can_mod_tasks %} + add more subtasks + remove an existing subtask + {% endif %} + + {% else %} + + {% if can_mod_tasks %} + add a subtask/dependency + {% endif %} + + {% endif %} + {% endif %} + + {% ifequal task.status "CD" %} + Task has been closed by {{closing_notification.sent_from.username}} + on {{closing_notification.sent_date|date:"D d M Y"}} at {{closing_notification.sent_date|time:"H:i"}}
+ Reason: {{closing_notification.remarks}}
+ {% endifequal %} + + {% ifequal task.status "CM" %} + Task has been marked complete by + {{completed_notification.sent_from.username}} + on {{completed_notification.sent_date|date:"D d M Y"}} at {{completed_notification.sent_date|time:"H:i"}}
+ {% endifequal %} + + {% ifequal task.status "OP" %} +
There are no users working on this task.
+ {% endifequal %} + + {% if subs %} +
This task cannot be claimed.. It exists only to show all of its sub tasks in one place.
+ {% endif %} + + {% if assigned_users %} + Users working on this task: + {% for user in assigned_users %} + {{user.username}} + {% endfor %} + {% if is_mentor %} + Remove an existing user + {% endif %} +
+ {% endif %} + + {% if can_assign_credits %} + View/Assign credits + {% endif %} + + {% if task_claimable %} + + {% if is_mentor %} + View claims + {% else %} + Claim the task + {% endif %} + {% endif %} + + {% if comments %} +
+ comments:

+ {% for comment in comments %} + {{ comment.created_by.username }} + on {{ comment.creation_datetime|date:"D d M Y"}} at {{comment.creation_datetime|time:"H:i"}} wrote:
+ {{ comment.data|linebreaksbr }}

+ {% endfor %} + {% endif %} + + {% if not is_guest %} +
+ {% if error_msg %} + {{error_msg}}
+ {% endif %} + {% ifnotequal task.status "UP" %} + Add comment:
+
+ +
+ +
+ {% else %} + {% if is_mentor %} + Add comment:
+
+ +
+ +
+ {% endif %} + {% endifnotequal %} + {% endif %} +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/user/browse_notifications.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/user/browse_notifications.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,14 @@ +{% extends 'base.html' %} +{% block content %} + {% if not notifications %} + You have no notifications.learn more
+ {% else %} + Notifications for you: learn more
+ {% for notification in notifications %} + + {% if not notification.is_read %} {% endif %} + {{notification.sub}} + {% if not notification.is_read %} {% endif %}
+ {% endfor %} + {% endif %} +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/user/browse_requests.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/user/browse_requests.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,36 @@ +{% extends 'base.html' %} +{% block content %} + {% if not reqs %} + You have no unreplied requests learn more
+ {% else %} + You have not yet replied to these requests.learn more

+ {% for req in reqs %} + + {% if not req.is_read %}{% endif %} + + {% ifequal req.role "PY" %} + Assign of pynts to {{req.receiving_user}} for the task "{{req.task.title|slice:":20"}}" + {% endifequal %} + + {% ifequal req.role "MT" %} + Request to mentor the task "{{req.task.title|slice:":20"}}" + {% endifequal %} + + {% ifequal req.role "DV" %} + Request to act as a developer in the website + {% endifequal %} + + {% ifequal req.role "MG" %} + Request to act as a manager in the website + {% endifequal %} + + {% ifequal req.role "AD" %} + Request to act as an admin in the website + {% endifequal %} + + + {% if not req.is_read %}{% endif %}
+
+ {% endfor %} + {% endif %} +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/user/changerole.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/user/changerole.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% block title %} + {{task.title}} +{% endblock %} +{% block content %} + Click here to return to home page.
+
+ {{form.as_p}} + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/user/edit_profile.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/user/edit_profile.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,7 @@ +{% extends 'base.html' %} +{% block content %} +
+ {{ edit_profile_form.as_p }} + +
+{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/user/my_profile.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/user/my_profile.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,64 @@ +{% extends 'base.html' %} + +{% block title %} + {{ profile.user }}'s Profile +{% endblock %} + +{% block content %} + + +

{{ profile }}'s Profile

+
+ {% if edit_profile %} + edit profile | change password +
+ {% endif %} + {% if profile.photo %} + + + + {% endif %} + {% if privilege or edit_profile %} +

E-Mail


{{ profile.user.email }} + {% endif %} + {% if profile.aboutme %} +

About Me


{{ profile.aboutme }} + {% endif %} + {% if profile.nick %} +

Nick Name


{{ profile.nick }} + {% endif %} + {% if profile.dob %} +

Date of Birth


{{ profile.dob }} + {% endif %} + {% if profile.credits %} +

Credits


{{ profile.credits }} + {% endif %} + {% if profile.foss_comm %} +

Foss Community


{{ profile.foss_comm }} + {% endif %} + {% if privilege or edit_profile %} + {% if profile.phonenum %} +

Phone Number


{{ profile.phonenum }} + {% endif %} + {% endif %} + {% if profile.homepage %} +

Homepage


{{ profile.homepage }} + {% endif %} + {% if privilege or edit_profile %} + {% if profile.street or profile.city or profile.country %} +

Address


+ {% if profile.street %} + {{ profile.street }} +
+ {% endif %} + {% if profile.city %} + {{ profile.city }} +
+ {% endif %} + {% if profile.country %} + {{ profile.country }} + {% endif %} + {% endif %} + {% else %} + {% endif %} +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/user/view_notification.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/user/view_notification.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,24 @@ +{% extends 'base.html' %} +{% block content %} + {% if newest %} + <<newest + {% endif %} + {% if newer %} + <newer + {% endif %} + {% if older %} + older> + {% endif %} + {% if oldest %} + oldest>> + {% endif %} +
+ +
+
+
+ sent on {{notification.sent_date|date:"D d M Y"}} at {{notification.sent_date|time:"H:i"}}
+ Sub: {{notification.sub}}
+
+ {{notification.message|safe}} +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/templates/user/view_request.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/templates/user/view_request.html Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,59 @@ +{% extends 'base.html' %} +{% block content %} + {% if newest %} + <<newest + {% endif %} + {% if newer %} + <newer + {% endif %} + {% if older %} + older> + {% endif %} + {% if oldest %} + oldest>> + {% endif %} +
+ From:  {{req.sent_by.username}}
+ To: + {% for to_user in sent_users %} + {{to_user.username}}  + {% endfor %} +
+ sent on {{req.sent_date|date:"D d M Y"}} at {{req.sent_date|time:"H:i"}}
+ Message:
+ {% ifequal "PY" req.role %} + {{req.sent_by.username}} assigned {{req.pynts}} pynts to + {{req.receiving_user.username}} for the task + {{req.task.title}}
+ {% else %} + + {% ifequal "MT" req.role %} + {{req.sent_by.username}} requested you to act as a mentor for the task + {{req.task.title}}
+ {% else %} + You have been requested to act as + {% ifequal "AD" req.role %} + an Admin + {% else %} + {% ifequal "MG" req.role %} + a Manager + {% else %} + a Developer + {% endifequal %} + {% endifequal %} + for the website by {{req.sent_by.username}}.
+ {% endifequal %} + {% endifequal %} +
+ + Please accept or reject the request.
+
+ +
+
+ Remarks: + +
+ Click here to return to the requests page. + +{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 pytask/urls.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pytask/urls.py Thu Jan 06 19:07:04 2011 +0530 @@ -0,0 +1,62 @@ +from django.conf.urls.defaults import * + +# Uncomment the next two lines to enable the admin: +from django.contrib import admin +admin.autodiscover() + +from pytask.taskapp.views import user as userViews +from pytask.taskapp.views import task as taskViews + +from pytask.taskapp.forms.user import RegistrationFormCustom +from registration.views import register + +urlpatterns = patterns('', + # Example: + # (r'^pytask/', include('pytask.foo.urls')), + + # Uncomment the admin/doc line below and add 'django.contrib.admindocs' + # to INSTALLED_APPS to enable admin documentation: + # (r'^admin/doc/', include('django.contrib.admindocs.urls')), + + (r'^images/(?P.*)$', 'django.views.static.serve', + {'document_root': './images/'}), + + (r'^$', userViews.homepage), + + (r'^task/browse/$', taskViews.browse_tasks), + (r'^task/view/tid=(\w+)$', taskViews.view_task), + (r'^task/create/$', taskViews.create_task), + (r'^task/publish/tid=(\w+)/$', taskViews.publish_task), + (r'^task/addmentor/tid=(\w+)$', taskViews.add_mentor), + (r'^task/edit/tid=(\w+)$', taskViews.edit_task), + (r'^task/claim/tid=(\w+)$', taskViews.claim_task), + (r'^task/assign/tid=(\w+)$', taskViews.assign_task), + (r'^task/remuser/tid=(\w+)$', taskViews.rem_user), + (r'^task/addtask/tid=(\w+)$', taskViews.add_tasks), + (r'^task/remtask/tid=(\w+)$', taskViews.remove_task), + (r'^task/assigncredits/tid=(\w+)$', taskViews.assign_credits), + (r'^task/complete/tid=(\w+)$', taskViews.complete_task), + (r'^task/close/tid=(\w+)$', taskViews.close_task), + (r'^task/delete/tid=(\w+)$', taskViews.delete_task), + + (r'^admin/', include(admin.site.urls)), + + url(r'^accounts/register/$',register,{'form_class' : RegistrationFormCustom},name='registration_register'), + (r'^accounts/', include('registration.urls')), + (r'^accounts/profile/$', userViews.view_my_profile), + + (r'^user/view/uid=(\d+)$', userViews.view_my_profile), + (r'^user/edit/?$', userViews.edit_my_profile), + + (r'^user/requests/$', userViews.browse_requests), + (r'^user/requests/rid=(\d+)/$', userViews.view_request), + (r'^user/requests/rid=(\d+)/(\w+)/$', userViews.process_request), + + (r'^user/notifications/$', userViews.browse_notifications), + (r'^user/notifications/nid=(\d+)/$', userViews.view_notification), + (r'^user/notifications/nid=(\d+)/(\w+)/$', userViews.edit_notification), + (r'^user/make/(\w+)/$', userViews.change_rights), + + (r'^about/(\w+)/$', userViews.learn_more), + +) diff -r 679c7e237052 -r 3c8f3b0e5b00 settings.py --- a/settings.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -# Django settings for pytask project. - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - # ('Your Name', 'your_email@domain.com'), -) - -MANAGERS = ADMINS - -DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. -DATABASE_NAME = 'pytask.db' # Or path to database file if using sqlite3. -DATABASE_USER = '' # Not used with sqlite3. -DATABASE_PASSWORD = '' # Not used with sqlite3. -DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. -DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = 'America/Chicago' - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' - -SITE_ID = 1 - -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True - -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = './images/' - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash if there is a path component (optional in other cases). -# Examples: "http://media.lawrence.com", "http://example.com/media/" -MEDIA_URL = '/images/' - -# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a -# trailing slash. -# Examples: "http://foo.com/media/", "/media/". -ADMIN_MEDIA_PREFIX = '/media/' - -# Make this unique, and don't share it with anybody. -SECRET_KEY = '#7bo8^p1gc=$85gv09z5d_d9-8xk1p=me7_c^3ito@jjth6^^w' - -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.load_template_source', - 'django.template.loaders.app_directories.load_template_source', -# 'django.template.loaders.eggs.load_template_source', -) - -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', -) - -ROOT_URLCONF = 'pytask.urls' - -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. - './templates', -) - -ACCOUNT_ACTIVATION_DAYS = 5 -DEFAULT_FROM_EMAIL = 'no-reply@pytask.in' - -LOGIN_REDIRECT_URL = '/' -FORCE_LOWERCASE_TAGS = True - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.admin', - 'pytask.taskapp', - 'registration', - 'tagging' -) - -AUTH_PROFILE_MODULE = 'taskapp.Profile' diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/admin.py --- a/taskapp/admin.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -from django.contrib import admin - -from pytask.taskapp.models import Profile, Task, Comment, Notification, Request - -admin.site.register(Profile) -admin.site.register(Task) -admin.site.register(Comment) -admin.site.register(Notification) -admin.site.register(Request) diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/events/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/events/request.py --- a/taskapp/events/request.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -from datetime import datetime -from pytask.taskapp.models import Profile -from pytask.taskapp.events.task import addMentor -from pytask.taskapp.events.user import changeRole -from pytask.taskapp.utilities.notification import create_notification - -def reply_to_request(request_obj, reply, replied_by): - """ - makes a request replied with the given reply. - arguments: - request_obj - Request object for which change is intended - reply - a boolean value to be given as reply (True/False) - replied_by - the user object who replies to the request - """ - if not request_obj.is_replied: - request_obj.reply = reply - request_obj.is_replied = True - request_obj.reply_date = datetime.now() - request_obj.replied_by = replied_by - request_obj.save() - - if request_obj.role == "PY": - ## note that we are not doing any check. we make requests invalid when an event like closing task happens. - task = request_obj.task - pynts = request_obj.pynts - receiving_user = request_obj.receiving_user - requested_by = request_obj.sent_by - create_notification(request_obj.role, receiving_user, replied_by, reply, task, request_obj.remarks, requested_by, receiving_user, pynts) - if receiving_user != requested_by: - create_notification(request_obj.role, requested_by, replied_by, reply, task, request_obj.remarks, requested_by, receiving_user, pynts) - - elif request_obj.role == "MT": - task = request_obj.task - requested_by = request_obj.sent_by - if reply: - ## tell the replied user that he is mentor for this task and give him learn more link - create_notification("NT", request_obj.replied_by, task=task) - - ## now check if there are such similar requests and mark them as invalid - ## they cannot be of type PY and so we can use the replied_by to get requests - pending_requests = replied_by.request_sent_to.filter(is_valid=True, is_replied=False, role="MT",task=task) - for req in pending_requests: - create_notification("MT", req.sent_by, replied_by, False, task=req.task, remarks = "User has already accepted one such request and is a mentor.", requested_by = req.sent_by) - req.is_valid = False - req.save() - - ## alert all the mentors including who made request and all assigned users - for a_mentor in task.mentors.all(): - create_notification(request_obj.role, a_mentor, replied_by, True, task, request_obj.remarks, requested_by) - for a_user in task.assigned_users.all(): - create_notification(request_obj.role, a_user, replied_by, True, task, request_obj.remarks, requested_by) - - addMentor(task, request_obj.replied_by) - else: - ## tell the requested user that his request was rejected due to these reasons. - create_notification(request_obj.role, requested_by, replied_by, False, task, request_obj.remarks, requested_by) - - elif request_obj.role == "DV": - if reply: - ## here we look for requests that are similar => requesting for DV and make them invalid - ## also we drop a notification to user who made request - pending_requests = request_obj.replied_by.request_sent_to.filter(is_valid=True,is_replied=False,role="DV") - for req in pending_requests: - req.is_valid = False - req.save() - create_notification(role = req.role, sent_to = req.sent_by, sent_from = replied_by, reply = False, \ - remarks = "User has accepted a similar request and has rights same or higher privileged than the request", \ - requested_by = req.sent_by ) - - ## tell only the user who made him a DV - ## drop a welcome message to that fucker - create_notification(request_obj.role, request_obj.sent_by, request_obj.replied_by, reply, requested_by=request_obj.sent_by) - create_notification("ND", request_obj.replied_by, requested_by=request_obj.sent_by) - changeRole(role=request_obj.role, user=request_obj.replied_by) - - else: - create_notification(request_obj.role, request_obj.sent_by, request_obj.replied_by, reply, remarks=request_obj.remarks, requested_by=request_obj.sent_by) - - elif request_obj.role == "MG": - if reply: - ## tell all the MG and AD - alerting_users = Profile.objects.filter(user__is_active=True).exclude(rights="CT").exclude(rights="DV") - for a_profile in alerting_users: - create_notification(request_obj.role, a_profile.user, request_obj.replied_by, reply, requested_by=request_obj.sent_by) - - ## here we look for requests that less or similar => requesting for DV or MG and make them invalid - ## also we drop a notification to user who made request - active_requests = request_obj.replied_by.request_sent_to.filter(is_valid=True,is_replied=False) - pending_requests = active_requests.filter(role="DV") | active_requests.filter(role="MG") - for req in pending_requests: - req.is_valid = False - req.save() - create_notification(role = req.role, sent_to = req.sent_by, sent_from = replied_by, reply = False, \ - remarks = "User has accepted a similar request and has rights same or higher privileged than the request", \ - requested_by = req.sent_by ) - - ## drop a welcome message to that fucker - create_notification("NG", request_obj.replied_by, requested_by=request_obj.sent_by) - changeRole(role=request_obj.role, user=request_obj.replied_by) - - else: - create_notification(request_obj.role, request_obj.sent_by, request_obj.replied_by, reply, remarks=request_obj.remarks, requested_by=request_obj.sent_by) - - elif request_obj.role == "AD": - if reply: - - ## here we look for requests that less or similar => requesting for DV or MG or AD and make them invalid - ## also we drop a notification to user who made request - active_requests = request_obj.replied_by.request_sent_to.filter(is_valid=True,is_replied=False) - pending_requests = active_requests.filter(role="DV") | active_requests.filter(role="MG") | active_requests.filter(role="AD") - for req in pending_requests: - req.is_valid = False - req.save() - create_notification(role = req.role, sent_to = req.sent_by, sent_from = replied_by, reply = False, \ - remarks = "User has accepted a similar request and has rights same or higher privileged than the request", \ - requested_by = req.sent_by ) - ## tell all the AD - alerting_users = Profile.objects.filter(user__is_active=True).filter(rights="AD") - for a_profile in alerting_users: - create_notification(request_obj.role, a_profile.user, request_obj.replied_by, reply, requested_by=request_obj.sent_by) - - ## drop a welcome message to that fucker - create_notification("NA", request_obj.replied_by, requested_by=request_obj.sent_by) - changeRole(role=request_obj.role, user=request_obj.replied_by) - - else: - create_notification(request_obj.role, request_obj.sent_by, request_obj.replied_by, reply, remarks=request_obj.remarks, requested_by=request_obj.sent_by) - - return True #Reply has been added successfully - return False #Already replied diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/events/task.py --- a/taskapp/events/task.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,271 +0,0 @@ -from datetime import datetime -from pytask.taskapp.models import Profile, Task, Comment, Map -from pytask.taskapp.utilities.task import getTask -from pytask.taskapp.utilities.request import create_request -from pytask.taskapp.utilities.helper import get_key -from pytask.taskapp.utilities.notification import create_notification - -def publishTask(task, rem_mentors=True, rem_comments=True): - """ set the task status to open """ - - # if task.sub_type == 'D': - # deps, subs = task.map_subs.all(), [] - #else: - # subs, deps = task.map_subs.all(), [] - - task = getTask(task.id) - if task.subs or any(map(lambda t:t.status!="CM",task.deps)): - task.status = "LO" - else: - task.status = "OP" - - if rem_mentors: - task.mentors.clear() - task.mentors.add(task.created_by) - - if rem_comments: - task.comment_set.update(is_deleted=True) - task.comment_set.update(deleted_by=task.created_by) - - task.published_datetime = datetime.now() - task.save() - - pending_requests = task.request_task.filter(is_valid=True, is_replied=False) - pending_requests.update(is_valid=False) - - return task - -def addSubTask(main_task, sub_task): - """ add the task to subs attribute of the task and update its status. - sub task can be added only if a task is in UP/OP/LO state. - """ - - ## Shall modify after talking to pr about subtasks - ## I think i might even remove the concept of subtasks - - main_task.sub_type = "S" - main_task.save() - - try: - mapobj = Map.objects.get(main=main_task) - except Map.DoesNotExist: - mapobj = Map() - mapobj.main = main_task - mapobj.save() - mapobj.subs.add(sub_task) - mapobj.save() - - sub_tasks = getTask(main_task.id).subs - if main_task.status == "OP": - if any(map(lambda t:t.status!="CM",sub_tasks)): - main_task.status = "LO" - else: - "CM" - main_task.save() - -def addDep(main_task, dependency): - """ add the dependency task to deps attribute of the task. - update the status of main_task accordingly. - note that deps can be added only if task is in UP/OP/LO state. - And also if the task doesn't have any subs. - """ - - main_task.sub_type = "D" - main_task.save() - - try: - mapobj = Map.objects.get(main=main_task) - except Map.DoesNotExist: - mapobj = Map() - mapobj.main = main_task - mapobj.save() - - mapobj.subs.add(dependency) - mapobj.save() - - deps = getTask(main_task.id).deps - - if main_task.status in ["OP", "LO"]: - if all(map(lambda t:t.status=="CM",deps)): - main_task.status = "OP" - else: - main_task.status = "LO" - - main_task.save() - -def reqMentor(task, mentor, req_by): - """ create a request object with role as MT. - """ - - create_request(sent_by=req_by, role="MT", sent_to=mentor, task=task) - -def addMentor(task,mentor): - """ add the mentor to mentors list of the task """ - - task.mentors.add(mentor) - task.save() - return task - -def createTask(title,desc,created_by,credits): - """ creates a bare minimum task with title, description and credits. - the creator of the task will be assigned as a mentor for the task. - """ - - while True: - id = get_key() - try: - task = Task.objects.get(id__iexact=id) - continue - except Task.DoesNotExist: - break - - try: - task = Task.objects.exclude(status="DL").get(title__iexact=title) - return None - except: - task = Task(title=title) - - task.id = id - task.desc = desc - task.created_by = created_by - task.credits = credits - task.creation_datetime = datetime.now() - task.published_datetime = datetime.now() - task.save() - return task - -def addClaim(task, message, user): - """ add claim data to the database if it does not exist - and also update the claimed users field of the task. - """ - - task.claimed_users.add(user) - task.save() - - pending_reqs = user.request_sent_to.filter(is_replied=False, is_valid=True, role="MT", task=task).all() - for req in pending_reqs: - req.is_valid = False - req.save() - user_url = '%s'%(user.id, user.username) - reason = "User has claimed the task and hence cannot be a mentor and this request was made invalid." - create_notification("MT", req.sent_by, user, task=task, reply=False, remarks=reason, requested_by=req.sent_by) - - for a_mentor in task.mentors.all(): - create_notification("CL", a_mentor, user, task=task, remarks=message) - -def assignTask(task, added_user, assigned_by): - """ check for the status of task and assign it to the particular user """ - - if task.status in ['OP', 'WR']: - task.assigned_users.add(added_user) - task.claimed_users.remove(added_user) - task.status = "WR" - task.save() - - create_notification("AU", added_user, assigned_by, task=task) - - -def updateTask(task, title=None, desc=None, credits=None, tags_field=None): - """ update the property accordingly. - while updating title, check for uniqueness of title. - return None if any error. - """ - - if title: - try: - task.title = title - task.save() - except Task.IntegrityError: - return None - if desc:task.desc = desc - if credits:task.credits = credits - if tags_field:task.tags_field = tags_field - task.save() - return task - -def removeTask(main_task, sub_task): - """ get the corresponding map object and remove the sub_task. - """ - - mapobj = Map.objects.get(main=main_task) - mapobj.subs.remove(sub_task) - mapobj.save() - -def removeUser(main_task, rem_user, removed_by, reason=None): - """ right now, just remove the user from the list of assigned_users. - """ - - main_task.assigned_users.remove(rem_user) - main_task.save() - - ## TODiscuss : when a user is kicked off, his pending requests for pynts is made invalid - rem_user.request_receiving_user.filter(task=main_task,role="PY",is_valid=True,is_replied=False).update(is_valid=False) - - create_notification("RU", rem_user, removed_by, task=main_task, remarks=reason) - ## TODO : create notification to the victim - -def assignCredits(task, given_by, given_to, points): - """ make a proper request object. - """ - - create_request(sent_by=given_by, role="PY", task=task, receiving_user=given_to, pynts=points ) - -def completeTask(task, marked_by): - """ set the status of task as completed. - We dont have to inform parent tasks. - That part is taken care by getTask method. - """ - - task.status = "CM" - task.save() - - pending_requests = task.request_task.filter(is_replied=False) - pending_requests.update(is_valid=False) - - ## generate notification appropriately using marked_by - ## we also have to mark unread requests as invalid - - for a_user in task.assigned_users.all(): - create_notification(role="CM", sent_to=a_user, sent_from=marked_by, task=task) - - for a_user in task.claimed_users.all(): - create_notification(role="CM", sent_to=a_user, sent_from=marked_by, task=task) - - for a_mentor in task.mentors.all(): - create_notification(role="CM", sent_to=a_mentor, sent_from=marked_by, task=task) - -def closeTask(task, closed_by, reason=None): - """ set the status of task as CD. - generate notifications accordingly. - """ - - task.status = "CD" - task.save() - - pending_requests = task.request_task.filter(is_replied=False) - pending_requests.update(is_valid=False) - - ## generate notifications here - - for a_user in task.assigned_users.all(): - create_notification(role="CD", sent_to=a_user, sent_from=closed_by, task=task, remarks=reason) - - for a_user in task.claimed_users.all(): - create_notification(role="CD", sent_to=a_user, sent_from=closed_by, task=task, remarks=reason) - - for a_mentor in task.mentors.all(): - create_notification(role="CD", sent_to=a_mentor, sent_from=closed_by, task=task, remarks=reason) - -def deleteTask(task, deleted_by, reason=None): - """ set the task status as DL - notify all its other viewers about the deleting of task. - """ - - task.status = "DL" - task.save() - - pending_requests = task.request_task.filter(is_replied=False,is_valid=True) - pending_requests.update(is_valid=False) - - for a_mentor in task.mentors.exclude(id=deleted_by.id): - create_notification("DL", sent_to=a_mentor, sent_from=deleted_by, task=task, remarks=reason) diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/events/user.py --- a/taskapp/events/user.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -from django.contrib.auth.models import User -from pytask.taskapp.models import Profile, Task, Comment - -""" A collection of helper methods. note that there is no validation done here. -we take care of validation and others checks in methods that invoke these methods. -""" - -def updateProfile(user_profile, properties): - """ updates the given properties in the profile for a user. - args: - user_profile : a profile object - properties : a dictionary with attributes to set as keys and corresponding values - """ - - for attr,value in properties.items(): - user_profile.__setattr__(attr,value) - user_profile.save() - -def createUser(username,email,password,dob,gender): - """ create a user and create a profile and update its properties - args: - username : a username that does not exist - email : a valid email - password : a password - dob : a date object - gender : u'M'/u'F' - """ - - try: - user = User.objects.get(username=username) - return user - except: - user = User(username=username, email=email) - user.set_password(password) - user.save() - properties = {'dob':dob, 'gender':gender} - user_profile = Profile(user=user) - updateProfile(user_profile, properties) - return user - -def createSuUser(username,email,password,dob,gender): - """ create user using createUser method and set the is_superuser flag """ - - su_user = createUser(username,email,password,dob,gender) - su_user.is_staff = True - su_user.is_superuser = True - su_user.save() - return su_user - -def changeRole(role, user): - """ change the status of user to role. - """ - - user_profile = user.get_profile() - user_profile.rights = role - user_profile.save() diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/forms/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/forms/task.py --- a/taskapp/forms/task.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -from django import forms -from pytask.taskapp.models import Task - -class TaskCreateForm(forms.ModelForm): - class Meta: - model = Task - fields = ['title', 'desc', 'tags_field', 'credits'] - #publish = forms.BooleanField(required=False) - - def clean_title(self): - data = self.cleaned_data['title'].strip() - try: - Task.objects.exclude(status="DL").get(title__iexact=data) - raise forms.ValidationError("Another task with same title exists") - except Task.DoesNotExist: - return data - - def clean_desc(self): - data = self.cleaned_data['desc'].strip() - if not data: - raise forms.ValidationError("Enter some description for the task") - - return data - -class EditTaskForm(forms.ModelForm): - class Meta: - model = Task - fields = ['title', 'desc', 'tags_field', 'credits'] - - def clean_desc(self): - data = self.cleaned_data['desc'].strip() - if not data: - raise forms.ValidationError("Enter some description for the task") - - return data - - def clean_title(self): - data = self.cleaned_data['title'].strip() - try: - prev_task = Task.objects.exclude(status="DL").get(title__iexact=data) - if prev_task.id != self.instance.id: - raise forms.ValidationError("Another task with same title exists") - else: - return data - except Task.DoesNotExist: - return data - -def AddMentorForm(choices,instance=None): - """ return a form object with appropriate choices """ - - class myform(forms.Form): - mentor = forms.ChoiceField(choices=choices, required=True) - form = myform(instance) if instance else myform() - return form - -class ClaimTaskForm(forms.Form): - message = forms.CharField(label="Proposal") - - def clean_message(self): - data = self.cleaned_data['message'].strip() - if not data: - raise forms.ValidationError('Enter something as a proposal') - return data - - -def ChoiceForm(choices, instance=None): - """ return a form object with appropriate choices """ - - class myform(forms.Form): - choice = forms.ChoiceField(choices=choices, required=True) - form = myform(instance) if instance else myform() - return form - -def AddTaskForm(task_choices, is_plain=False): - """ if is_plain is true, it means the task has no subs/deps. - so we also give a radio button to choose between subs and dependencies. - else we only give choices. - """ - - class myForm(forms.Form): - if is_plain: - type_choices = [('S','Subtasks'),('D','Dependencies')] - type = forms.ChoiceField(type_choices, widget=forms.RadioSelect) - - task = forms.ChoiceField(choices=task_choices) - return myForm() - -def AssignCreditForm(choices, instance=None): - - class myForm(forms.Form): - user = forms.ChoiceField(choices=choices, required=True) - pynts = forms.IntegerField(min_value=0, required=True, help_text="Choose wisely since it cannot be undone.") - return myForm(instance) if instance else myForm() - -def RemoveUserForm(choices, instance=None): - - class myForm(forms.Form): - user = forms.ChoiceField(choices=choices, required=True) - reason = forms.CharField(min_length=1, required=True) - return myForm(instance) if instance else myForm() - diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/forms/user.py --- a/taskapp/forms/user.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -#!/usr/bin/python2.5 - -import os -import PIL - -from pytask.taskapp.utilities.helper import get_key - -from django import forms -from pytask.taskapp.models import GENDER_CHOICES, Profile -from registration.forms import RegistrationFormUniqueEmail -from registration.models import RegistrationProfile -from pytask.taskapp.utilities.notification import create_notification - -class UserProfileEditForm(forms.ModelForm): - """Form used to edit the profile of a user""" - - class Meta: - model = Profile - exclude = ('user','rights','dob','credits') - - def clean_photo(self): - uploaded_photo = self.data.get('photo', None) - prev_photo = self.instance.photo - if uploaded_photo: - if uploaded_photo.size > 1048576: - raise forms.ValidationError('Images only smaller than 1MB allowed') - tmp_im_path = '/tmp/'+get_key() - tmp_file = open(tmp_im_path, 'w') - tmp_file.write(uploaded_photo.read()) - tmp_file.close() - try: - PIL.Image.open(tmp_im_path) - except IOError: - raise forms.ValidationError('Image format unknown') - os.remove(tmp_im_path) - - if prev_photo: os.remove(prev_photo.path) - return uploaded_photo - else: - return prev_photo - - -class RegistrationFormCustom(RegistrationFormUniqueEmail): - """Used instead of RegistrationForm used by default django-registration backend, this adds date of birth and gender to the default django-registration RegistrationForm""" - - dob = forms.DateField(help_text = "YYYY-MM-DD", required=True, label=u'date of birth') - gender = forms.ChoiceField(choices = GENDER_CHOICES, required=True, label=u'gender') - - def save(self,profile_callback=None): - new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'],password=self.cleaned_data['password1'],email=self.cleaned_data['email']) - - new_profile = Profile(user=new_user,dob=self.cleaned_data['dob'],gender=self.cleaned_data['gender']) - new_profile.save() - - create_notification('NU',new_user) - - return new_user - -def UserChoiceForm(choices, instance=None): - """ take a list of users and return a choice form. - """ - - class myForm(forms.Form): - user = forms.ChoiceField(choices, required=True) - return myForm(instance) if instance else myForm() diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/management/__init__.py --- a/taskapp/management/__init__.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ - diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/management/commands/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/management/commands/seed_db.py --- a/taskapp/management/commands/seed_db.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -import sys -from datetime import datetime -from django.core.management.base import NoArgsCommand - -from django.contrib.auth.models import User - -from pytask.taskapp.events import task as taskEvents -from pytask.taskapp.events import user as userEvents - -from pytask.taskapp.utilities.request import create_request -from pytask.taskapp.utilities.notification import create_notification - - -def seed_db(): - """ a method to seed the database with random data """ - - defaultMentor = userEvents.createSuUser("admin", "admin@example.com", "123456", datetime.now(), "M") - mentor_profile = defaultMentor.get_profile() - userEvents.updateProfile(mentor_profile, {'rights':"AD"}) - - for i in range(1,21): - - username = 'user'+str(i) - email = username+'@example.com' - password = '123456' - dob = datetime.now() - gender = "M" - user = userEvents.createUser(username,email,password,dob,gender) - create_notification("NU", user) - - if i%4==0: - create_request(defaultMentor, "MG", user) - elif i%3==0: - create_request(defaultMentor, "DV", user) - elif i%2==0: - create_request(defaultMentor, "AD", user) - elif i in [7, 13]: - user.is_active = False - user.save() - - for i in range(1,21): - - title = "Task "+str(i) - desc = "I am "+title - created_by = defaultMentor - credits = 20 - - task = taskEvents.createTask(title,desc,created_by,credits) - if task: - taskEvents.addMentor(task, defaultMentor) - if i%2==0:taskEvents.publishTask(task) - -class Command(NoArgsCommand): - - def handle_noargs(self, **options): - """ Just copied the code from seed_db.py """ - - seed_db() diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/models.py --- a/taskapp/models.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +0,0 @@ -import os - -from django.core.files.storage import FileSystemStorage -from django.db import models -from django.contrib.auth.models import User - -import tagging -from tagging.fields import TagField - -from pytask.taskapp.utilities.helper import get_key - -GENDER_CHOICES = (( 'M', 'Male'), ('F', 'Female')) -RIGHTS_CHOICES = ( - ("AD", "Admin"), - ("MG", "Manager"), - ("DV", "Developer"), - ("CT", "Contributor"),) - -STATUS_CHOICES = ( - ("UP", "Unpublished"), - ("OP", "Open"), - ("LO", "Locked"), - ("WR", "Working"), - ("CD", "Closed"), - ("DL", "Deleted"), - ("CM", "Completed")) - -NOTIFY_CHOICES = ( - ("MT", "Add Mentor"), - ("DV", "Developer"), - ("MG", "Manager"), - ("AD", "Admin"), - ("PY", "Assign credits"), - ("CM", "Task completed"), - ("CD", "Task closed"), - ("DL", "Task deleted"), - ("NU", "New User"), - ("NT", "New Mentor"), - ("ND", "New Developer"), - ("NG", "New Manager"), - ("NA", "New Admin"), - ("AU", "Assign user"), ## i mean assign the task - ("RU", "Remove user"), ## remove from working users list in task -) - -IMAGES_DIR = "./images" -UPLOADS_DIR = "./uploads" - -class CustomImageStorage(FileSystemStorage): - - def path(self, name): - """ we return images directory path. - """ - - return os.path.join(IMAGES_DIR, name) - - def get_available_name(self, name): - """ here we are going with username as the name of image. - """ - - root, ext = os.path.splitext(name) - file_name = get_key() + ext - while self.exists(file_name): - file_name = get_key() + ext - return file_name - -class Profile(models.Model): - - user = models.ForeignKey(User, unique = True) - dob = models.DateField(verbose_name = u"Date of Birth", help_text = "YYYY-MM-DD") - gender = models.CharField(max_length = 1, choices = GENDER_CHOICES) - rights = models.CharField(max_length = 2, choices = RIGHTS_CHOICES, default = u"CT") - credits = models.PositiveSmallIntegerField(default = 0) - - aboutme = models.TextField(blank = True) - foss_comm = TagField(verbose_name="FOSS Communities") - phonenum = models.CharField(max_length = 15, blank = True, verbose_name = u"Phone Number") - homepage = models.URLField(blank = True, verbose_name = u"Homepage/Blog") - street = models.CharField(max_length = 80, blank = True) - city = models.CharField(max_length = 25, blank = True) - country = models.CharField(max_length = 25, blank = True) - nick = models.CharField(max_length = 20, blank = True) - photo = models.ImageField(storage = CustomImageStorage(),upload_to = IMAGES_DIR, blank = True) - - def __unicode__(self): - return unicode(self.user.username) - -class Task(models.Model): - - prim_key = models.AutoField(primary_key = True) - id = models.CharField(max_length = 10, unique = True) - title = models.CharField(max_length = 100, verbose_name = u"Title", help_text = u"Keep it simple and below 100 chars.") - desc = models.TextField(verbose_name = u"Description") - status = models.CharField(max_length = 2, choices = STATUS_CHOICES, default = "UP") - tags_field = TagField(verbose_name = u"Tags", help_text = u"Give comma seperated tags") - - credits = models.PositiveSmallIntegerField(help_text = u"No.of credits a user gets on completing the task") - progress = models.PositiveSmallIntegerField(default = 0) - - mentors = models.ManyToManyField(User, related_name = "%(class)s_mentors") - created_by = models.ForeignKey(User, related_name = "%(class)s_created_by") - claimed_users = models.ManyToManyField(User, blank = True, related_name = "%(class)s_claimed_users") - assigned_users = models.ManyToManyField(User, blank = True, related_name = "%(class)s_assigned_users") - - creation_datetime = models.DateTimeField() - published_datetime = models.DateTimeField() - sub_type = models.CharField(max_length=1, choices = (('D','Dependency'),('S','Subtask')), default = 'D') - - def __unicode__(self): - return unicode(self.title) - -class Map(models.Model): - - main = models.ForeignKey('Task', related_name = "%(class)s_main") - subs = models.ManyToManyField('Task', blank = True, null = True, related_name = "%(class)s_subs") - -class Comment(models.Model): - - task = models.ForeignKey('Task') - data = models.TextField() - created_by = models.ForeignKey(User, related_name = "%(class)s_created_by") - creation_datetime = models.DateTimeField() - deleted_by = models.ForeignKey(User, null = True, blank = True, related_name = "%(class)s_deleted_by") - is_deleted = models.BooleanField() - attachment = models.FileField(upload_to = UPLOADS_DIR, blank = True) - - def __unicode__(self): - return unicode(self.task.title) - -class Request(models.Model): - - sent_to = models.ManyToManyField(User, related_name = "%(class)s_sent_to", blank = False) - sent_by = models.ForeignKey(User, related_name = "%(class)s_sent_by", blank = False) - role = models.CharField(max_length = 2, blank = False) - reply = models.BooleanField(default = False, blank = False) - remarks = models.TextField(default = "",blank = True) - - is_read = models.BooleanField(default = False, blank = False) - is_valid = models.BooleanField(default = True, blank = False) - - creation_date = models.DateTimeField() - reply_date = models.DateTimeField() - is_replied = models.BooleanField(default = False) - replied_by = models.ForeignKey(User, related_name = "%(class)s_replied_by", blank = True, null = True) - - task = models.ForeignKey(Task,related_name = "%(class)s_task", blank = True, null = True) - receiving_user = models.ForeignKey(User, related_name = "%(class)s_receiving_user", blank = True, null = True) - pynts = models.PositiveIntegerField(default=0) - - def __unicode__(self): - - return u"Request %s %s"%(self.sent_by.username, self.role) - -class Notification(models.Model): - - role = models.CharField(max_length = 2, choices = NOTIFY_CHOICES, blank = False) - sent_to = models.ForeignKey(User, related_name = "%(class)s_sent_to", blank = False) - sent_from = models.ForeignKey(User, related_name = "%(class)s_sent_from", null = True, blank = True) - task = models.ForeignKey(Task, related_name = "%(class)s_task", null = True, blank = True) - - sub = models.CharField(max_length = 100) - message = models.TextField() - remarks = models.CharField(max_length = 100) - - sent_date = models.DateTimeField() - is_read = models.BooleanField(default = False) - is_deleted = models.BooleanField(default = False) - - def __unicode__(self): - return u"%s %s %s"%(self.sent_to, self.message, self.sent_date.ctime()) - -tagging.register(Profile) -tagging.register(Task) diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/tests.py --- a/taskapp/tests.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -""" -This file demonstrates two different styles of tests (one doctest and one -unittest). These will both pass when you run "manage.py test". - -Replace these with more appropriate tests for your application. -""" - -from django.test import TestCase - -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.failUnlessEqual(1 + 1, 2) - -__test__ = {"doctest": """ -Another way to test that 1 + 1 is equal to 2. - ->>> 1 + 1 == 2 -True -"""} - diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/utilities/__init__.py diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/utilities/helper.py --- a/taskapp/utilities/helper.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -import string,random - -def get_key(): - """ return a 10 character random key. - """ - - return ''.join([ random.choice(string.uppercase+string.digits) for i in range(10)]) - diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/utilities/notification.py --- a/taskapp/utilities/notification.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,300 +0,0 @@ -from datetime import datetime -from django.contrib.auth.models import User -from pytask.taskapp.models import Notification, RIGHTS_CHOICES - -def create_notification(role, sent_to, sent_from=None, reply=None, task=None, remarks=None, requested_by=None, receiving_user=None, pynts=None): - """ - creates a notification based on the passed arguments. - role: role of the notification - look at choices in models - sent_to: a user to which the notification is to be sent - sent_from : a user from which the message has originated - A user who approves/rejects in case of request - A mentor who closes/complets the task - reply: A boolean - task: a task if applicable - requested_by: a user makes the request - A mentor who assigns credits in case of pynts - A mentor who requests to act as a mentor - remarks: any remarks for rejecting - receiving_user: user receiving pynts - pynts: the obvious - """ - - notification = Notification(sent_date = datetime.now()) - notification.role = role - notification.sent_to = sent_to - notification.save() - - if role == "PY": - - notification.sent_from = sent_from - notification.task = task - notification.pynts = pynts - - task_url= '%s'%(task.id, task.title) - credits_url = '%s'%(task.id, "click here") - mentor_url = '%s'%(requested_by.id, requested_by.username) - admin_url = '%s'%(sent_from.id, sent_from.username) - user_url = '%s'%(receiving_user.id, receiving_user.username) - - if reply: - notification.sub = "Approved request for assign of credits for %s"%task.title[:20] - notification.message = """ Request made by %s to assign %s pynts to %s for the task %s has been approved by %s
- %s if you want the view/assign pynts page of the task.
"""%(mentor_url, pynts, user_url, task_url, admin_url, credits_url) - - else: - notification.sub = "Rejected request for assign of credits for %s"%task.title[:20] - notification.message = """ Request made by %s to assign %s pynts to %s for the task %s has been rejected by %s.
"""%(mentor_url, pynts, user_url, task_url, admin_url) - if remarks: - notification.remarks = remarks - notification.message += "Reason: %s
"%remarks - notification.message += "
" - - elif role == "MT": - - notification.task = task - notification.sent_from = sent_from - - task_url= '%s'%(task.id, task.title) - requested_mentor_url = '%s'%(requested_by.id, requested_by.username) - new_mentor = sent_from - new_mentor_url = '%s'%(new_mentor.id, new_mentor.username) - - if reply: - notification.sub = "New mentor for the task %s"%task.title[:20] - notification.message = "%s has accepted the request made by %s, asking him act as a mentor for the task %s
"%(new_mentor_url, requested_mentor_url, task_url) - notification.message += "He can be contacted on %s"%new_mentor.email - - else: - notification.sub = "%s rejected request to act as a mentor"%new_mentor.username - notification.message = "%s has rejected your request asking him to act as a mentor for %s.
"%(new_mentor_url, task_url) - if remarks: - notification.remarks = remarks - notification.message += "Remarks: %s
"%remarks - - elif role in ["DV", "MG", "AD"]: - - notification.sent_from = sent_from - accepting_user = sent_from - user_url = '%s'%(accepting_user.id, accepting_user.username) ## i mean the user who has accepted it - requested_by_url = '%s'%(requested_by.id, requested_by.username) - role_rights = dict(RIGHTS_CHOICES)[role] - role_learn_url = "/about/%s"%role_rights.lower() - a_or_an = "an" if role_rights == "AD" else "a" - - if reply: - notification.sub = "New %s for the site"%role_rights - notification.message = "%s has accepted request made by %s asking him to act as %s %s for the website.
"%(user_url, requested_by_url, a_or_an, role_rights) - else: - notification.sub = "Rejected your request to act as %s"%role_rights - notification.message = "%s has rejected your request asking him to act as %s %s.
"%(user_url, a_or_an, role_rights) - if remarks: - notification.remarks = remarks - notification.message += "Remarks: %s
"%remarks - - elif role == "NT": - - notification.task = task - new_mentor = sent_to - mentor_learn_url = 'learn more' - task_url= '%s'%(task.id, task.title) - - notification.sub = "You are mentoring the task %s"%task.title[:20] - notification.message = "You have accepted to act as a mentor%s for the task %s.
"%(mentor_learn_url, task_url) - notification.message += " Here is a list of other mentors and their email addresses.
    " - - for a_mentor in task.mentors.exclude(id=new_mentor.id): - notification.message += "
  • %s - %s
  • "%(a_mentor.username, a_mentor.email) - notification.message += "
" - - working_users = task.assigned_users.all() - if working_users: - notification.message += "List of users working on the task.
" - notification.message += "
    " - for a_user in working_users: - notification.message += "
  • %s - %s
  • "%(a_user.username, a_user.email) - notification.message += "

" - notification.message += "Happy Mentoring." - - elif role == "NU": - - start_here_url = 'click here' - notification.sub = "Welcome %s"%sent_to.username - notification.message = "Welcome to PyTasks %s.
"%sent_to.username - notification.message += "%s to know more."%start_here_url - - elif role in ["ND", "NG", "NA"]: - - rights_dict = dict(RIGHTS_CHOICES) - - if role == "ND": - role_rights = rights_dict["DV"] - elif role == "NG": - role_rights = rights_dict["MG"] - elif role == "NA": - role_rights = rights_dict["AD"] - - requested_by_url = r'%s'%(requested_by.id, requested_by.username) - role_learn_url = r'click here'%role_rights.lower() - a_or_an = "an" if role_rights == "Admin" else "a" - - notification.sub = "You are now %s %s"%(a_or_an, role_rights) - notification.message = r"You have accepted the request made by %s asking you to act as %s %s in the site "%(requested_by_url, a_or_an, role_rights) - notification.message += "and you are now %s %s in the site.
%s to learn more on %s."%(a_or_an, role_rights, role_learn_url, role_rights) - - - elif role in ["CM", "CD"]: - - notification.sent_from = sent_from - notification.role = role - notification.task = task - notification.remarks = remarks - - mentor = sent_from - mentor_url = '%s'%(mentor.id, mentor.username) - task_url= '%s'%(task.id, task.title) - - if role == "CM": - notification.sub = "%s has been marked complete"%task.title - notification.message = "The task %s has been marked complete by %s.
"%(task_url, mentor_url) - - elif role == "CD": - notification.sub = "%s has been closed"%task.title - notification.message = "The task %s has been closed by %s.
"%(task_url, mentor_url) - - if remarks: - notification.remarks = remarks - notification.message += "Remarks: %s"%remarks - - elif role == "AU": - - notification.task = task - notification.sent_from = sent_from - added_user = sent_to - mentor = sent_from - assigned_by_url = '%s'%(mentor.id, mentor.username) - task_url= '%s'%(task.id, task.title) - - notification.sub = "Your claim for the task %s accepted."%task.title[:20] - notification.message = "You have been selected to work on the task %s by %s.
"%(task_url, assigned_by_url) - notification.message += "You can now start working on the task and will be credited by the mentors for your work.
" - - notification.message += " Here is a list of mentors for the task and their email addresses.
    " - for a_mentor in task.mentors.all(): - notification.message += "
  • %s - %s
  • "%(a_mentor.username, a_mentor.email) - notification.message += "
" - - working_users = task.assigned_users.exclude(id=added_user.id) - if working_users: - notification.message += "List of other users working on the task.
" - notification.message += "
    " - for a_user in working_users: - notification.message += "
  • %s - %s
  • "%(a_user.username, a_user.email) - notification.message += "

" - - elif role == "RU": - - notification.task = task - notification.sent_from = sent_from - removed_user = sent_to - mentor = sent_from - removed_by_url = '%s'%(mentor.id, mentor.username) - task_url = '%s'%(task.id, task.title) - claim_url = '%s'%(task.id, "clicking here") - - notification.sub = "You have been removed from working users of %s"%task.title[:20] - notification.message = "%s has removed you from the working users list of %s.
"%(removed_by_url, task_url) - notification.message += "if you want to work on the task again, you can claim the task by %s.
"%claim_url - if remarks: - notification.remarks = remarks - notification.message += "Reason: %s"%(remarks) - - elif role == "DL": - - notification.sent_from = sent_from - notification.task = task - deleted_by_url = '%s'%(sent_from.id, sent_from.username) - - notification.sub = "Task deleted" - notification.message = 'The unpublished task "%s" viewable by you has been deleted by its creator %s.
'%(task.title, deleted_by_url) - - if remarks: - notification.remarks = remarks - notification.message += "Reason: %s"%remarks - - elif role == "CL": - - notification.sent_from = sent_from - notification.task = task - notification.remarks = remarks - - claimed_by_url = '%s'%(sent_from.id, sent_from.username) - claim_url = 'claim'%(task.id) - task_url = '%s'%(task.id, task.title) - - notification.sub = 'New claim for the task "%s"'%(task.title[:20]) - notification.message = '%s has submitted a %s for the task "%s" mentored by you.
'%(claimed_by_url, claim_url, task_url) - notification.message += 'Claim proposal: %s'%(remarks) - - - - notification.save() - -def mark_notification_read(notification_id): - """ - makes a notification identified by the notification_id read. - arguments: - notification_id - a number denoting the id of the Notification object - """ - try: - notification = Notification.objects.get(id = notification_id) - except Notification.DoesNotExist: - return False - notification.is_read = True - notification.save() - return True - -def delete_notification(notification_id): - """ - deletes a notification identified by the notification_id. - arguments: - notification_id - a number denoting the id of the Notification object - """ - try: - notification = Notification.objects.get(id = notification_id) - except Notification.DoesNotExist: - return False - notification.is_deleted = True - notification.save() - return True - -def get_notification(nid, user): - """ if notification exists, and belongs to the current user, return it. - else return None. - """ - - user_notifications = user.notification_sent_to.filter(is_deleted=False).order_by('sent_date') - current_notifications = user_notifications.filter(id=nid) - if user_notifications: - current_notification = current_notifications[0] - - try: - newer_notification = current_notification.get_next_by_sent_date(sent_to=user, is_deleted=False) - newest_notification = user_notifications.reverse()[0] - if newest_notification == newer_notification: - newest_notification = None - except Notification.DoesNotExist: - newest_notification, newer_notification = None, None - - try: - older_notification = current_notification.get_previous_by_sent_date(sent_to=user, is_deleted=False) - oldest_notification = user_notifications[0] - if oldest_notification == older_notification: - oldest_notification = None - except: - oldest_notification, older_notification = None, None - - return newest_notification, newer_notification, current_notification, older_notification, oldest_notification - - else: - return None, None, None, None, None diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/utilities/request.py --- a/taskapp/utilities/request.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -from datetime import datetime - -from django.contrib.auth.models import User -from pytask.taskapp.models import Request, Profile - -def create_request(sent_by,role,sent_to=None,task=None,receiving_user=None,pynts=0): - """ - creates an unreplied request, based on the passed arguments - sent_to - a list of users to which the request is to be sent - sent_by - sender of request - role - a two character field which represents the role requested, if role = 'PY' then sent to all admins - task - a requesting task (useful for sending admins a request to give Pynts to the user) - receiving_user - user to whom the Pynts is assigned to(useful for sending admins a request to give Pynts to the user) - pynts - the pynts assigned to the receiving user - """ - req = Request(creation_date=datetime.now()) - req.sent_by = sent_by - req.reply_date = datetime(1970,01,01) - req.role = role - req.pynts = pynts - if task: - req.task = task - req.save() - if role == 'PY': - admin_profiles = Profile.objects.filter(rights='AD') - for admin_profile in admin_profiles: - req.sent_to.add(admin_profile.user) - req.receiving_user = receiving_user - else: - req.sent_to.add(sent_to) - req.save() - -def get_request(rid, user): - """ see if the request is replied or if he can not view the request, - raise 404 error. else return request. - """ - - active_requests = user.request_sent_to.filter(is_valid=True, is_replied=False).order_by('creation_date') - current_requests = active_requests.filter(id=rid) - if current_requests: - current_request = current_requests[0] - - try: - newer_request = current_request.get_next_by_creation_date(sent_to=user, is_replied=False, is_valid=True) - newest_request = active_requests.reverse()[0] - if newer_request == newest_request: - newest_request = None - except Request.DoesNotExist: - newer_request, newest_request = None, None - - try: - older_request = current_request.get_previous_by_creation_date(sent_to=user, is_replied=False, is_valid=True) - oldest_request = active_requests[0] - if oldest_request == older_request: - oldest_request = None - except Request.DoesNotExist: - older_request, oldest_request = None, None - - return newest_request, newer_request, current_request, older_request, oldest_request - - else: - return None, None, None, None, None diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/utilities/task.py --- a/taskapp/utilities/task.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -from django.http import Http404 -from pytask.taskapp.models import Task, Map - -def getTask(tid): - """ retreive the task from database. - if the task has deps or subs, update its status correspondingly. - """ - - try: - task = Task.objects.get(id=tid) - except Task.DoesNotExist: - raise Http404 - try: - mapobj = Map.objects.get(main=task) - except Map.DoesNotExist: - mapobj = Map() - mapobj.main = task - mapobj.save() - - task_subs = mapobj.subs.all() - - if task.sub_type == "D": - task.deps, task.subs = task_subs, [] - elif task.sub_type == "S": - task.subs, task.deps = task_subs, [] - - deps, subs = task.deps, task.subs - if deps and task.status in ["OP", "LO"]: - task.status = "OP" if all(map(lambda t:t.status=="CM",deps)) else "LO" - - ## a task with subs will remain in "LO" and will be made "OP" only if all subs are removed. - if subs and task.status in ["OP", "LO"]: - task.status = "LO" - - task.save() - return task - diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/utilities/user.py --- a/taskapp/utilities/user.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -""" -A collection of utility functions for user. -""" - -def get_user(user): - """ get the no of unread requests and notifications and add them as properties for user. - """ - - unread_notifications = user.notification_sent_to.filter(is_read=False,is_deleted=False) - unread_requests = user.request_sent_to.filter(is_valid=True,is_replied=False,is_read=False) - - user.unread_notifications = unread_notifications - user.unread_requests = unread_requests - - return user - - diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/views/__init__.py --- a/taskapp/views/__init__.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ - diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/views/task.py --- a/taskapp/views/task.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,660 +0,0 @@ -from datetime import datetime - -from django.http import HttpResponse, Http404 -from django.shortcuts import render_to_response, redirect - -from pytask.taskapp.models import User, Task, Comment, Request, Notification -from pytask.taskapp.utilities.task import getTask -from pytask.taskapp.forms.task import TaskCreateForm, AddMentorForm, AddTaskForm, ChoiceForm, AssignCreditForm, RemoveUserForm, EditTaskForm, ClaimTaskForm -from pytask.taskapp.events.task import createTask, reqMentor, publishTask, addSubTask, addDep, addClaim, assignTask, updateTask, removeTask, removeUser, assignCredits, completeTask, closeTask, addMentor, deleteTask -from pytask.taskapp.views.user import show_msg -from pytask.taskapp.utilities.user import get_user - -## everywhere if there is no task, django should display 500 message.. but take care of that in sensitive views like add mentor and all -## do not create su user thro syncdb - -def browse_tasks(request): - """ display all the tasks """ - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task_list = Task.objects.exclude(status="UP").exclude(status="DL").order_by('published_datetime').reverse() - - context = {'user':user, - 'task_list':task_list, - } - return render_to_response('task/browse.html', context) - -def publish_task(request, tid): - """ check if user is the mentor and also if the task status is UP. - """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - is_guest = True if not user.is_authenticated() else False - is_mentor = True if user in task.mentors.all() else False - - if user == task.created_by: - context = { - 'user':user, - } - if task.status == "UP": - if request.method == "POST": - publishTask(task) - return show_msg(user, "The task has been published", task_url, "view the task") - else: - return render_to_response('task/publish.html', context) - else: - return show_msg(user, "The task is already published", task_url, "view the task") - else: - return show_msg(user, "You are not authorised to do this", '/task/browse/', "browse tasks") - -def view_task(request, tid): - """ get the task depending on its tid and display accordingly if it is a get. - check for authentication and add a comment if it is a post request. - """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - if task.status == "DL": - return show_msg(user, 'This task no longer exists', '/task/browse/','browse the tasks') - comments = task.comment_set.filter(is_deleted=False).order_by('creation_datetime') - mentors = task.mentors.all() - - deps, subs = task.deps, task.subs - - is_guest = True if not user.is_authenticated() else False - is_mentor = True if user in task.mentors.all() else False - context = {'user':user, - 'task':task, - 'comments':comments, - 'mentors':mentors, - 'subs':subs, - 'deps':deps, - 'is_guest':is_guest, - 'is_mentor':is_mentor, - } - - claimed_users = task.claimed_users.all() - - - is_requested_mentor = True if user.is_authenticated() and user.request_sent_to.filter(is_valid=True,is_replied=False,role="MT",task=task) else False - task_viewable = True if ( task.status != "UP" ) or is_mentor or is_requested_mentor else False - if not task_viewable: - return show_msg(user, "You are not authorised to view this task", "/task/browse/", "browse the tasks") - - context['is_requested_mentor'] = is_requested_mentor - - context['can_publish'] = True if task.status == "UP" and user == task.created_by else False - context['can_edit'] = True if task.status == "UP" and is_mentor else False - context['can_close'] = True if task.status not in ["UP", "CD", "CM"] and is_mentor else False - context['can_delete'] = True if task.status == "UP" and user == task.created_by else False - - context['can_mod_mentors'] = True if task.status in ["UP", "OP", "LO", "WR"] and is_mentor else False - context['can_mod_tasks'] = True if task.status in ["UP", "OP", "LO"] and is_mentor else False - - context['can_assign_credits'] = True if task.status in ["OP", "WR"] and is_mentor else False - context['task_claimable'] = True if task.status in ["OP", "WR"] and not is_guest else False - - if task.status == "CD": - context['closing_notification'] = Notification.objects.filter(task=task,role="CD")[0] - elif task.status == "CM": - context['completed_notification'] = Notifications.objects.filter(task=task,role="CM")[0] - elif task.status == "WR": - context['assigned_users'] = task.assigned_users.all() - - if request.method == 'POST': - if not is_guest: - data = request.POST.get("data", "").strip() - if not data: - context['error_msg'] = "Enter some message to comment" - return render_to_response('task/view.html', context) - new_comment = Comment(task=task, data=data, created_by=user, creation_datetime=datetime.now()) - new_comment.save() - return redirect(task_url) - else: - errors.append("You must be logged in to post a comment") - return render_to_response('task/view.html', context) - else: - return render_to_response('task/view.html', context) - -def create_task(request): - """ check for rights and create a task if applicable. - if user cannot create a task, redirect to homepage. - """ - - user = get_user(request.user) if request.user.is_authenticated() else request.user - is_guest = True if not user.is_authenticated() else False - - if not is_guest: - user_profile = user.get_profile() - can_create_task = False if user_profile.rights == "CT" else True - if can_create_task: - if request.method == "POST": - form = TaskCreateForm(request.POST) - if form.is_valid(): - data = form.cleaned_data - title = data['title'] - desc = data['desc'] - credits = data['credits'] - #publish = data['publish'] # just in case if we have to show the option - task = createTask(title,desc,user,credits) - - addMentor(task, user) - updateTask(task,tags_field=data['tags_field']) - # if publish: publishTask(task) - task_url = '/task/view/tid=%s'%task.id - return redirect(task_url) - else: - return render_to_response('task/create.html',{'user':user, 'form':form}) - else: - form = TaskCreateForm() - return render_to_response('task/create.html',{'user':user, 'form':form}) - else: - return show_msg(user, 'You are not authorised to create a task.') - else: - return show_msg(user, 'You are not authorised to create a task.', "/", "home page") - -def add_mentor(request, tid): - """ check if the current user has the rights to edit the task and add him. - if user is not authenticated, redirect him to concerned page. """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - errors = [] - - is_guest = True if not user.is_authenticated() else False - - if (not is_guest) and user in task.mentors.all(): - - pending_requests = Request.objects.filter(is_replied=False,is_valid=True,role="MT",task=task).order_by('creation_date').reverse() - user_pending_requests = pending_requests.filter(sent_by=user) - - ## now iam going for a brute force method - user_list = list(User.objects.filter(is_active=True)) - for mentor in task.mentors.all(): - user_list.remove(mentor) - - for a_user in task.claimed_users.all(): - user_list.remove(a_user) - - for a_user in task.assigned_users.all(): - user_list.remove(a_user) - - for req in user_pending_requests: - user_list.remove(req.sent_to.all()[0]) - - non_mentors = ((_.id, _.username) for _ in user_list) - non_mentor_ids = [ str(a_user.id) for a_user in user_list ] - ## code till must be made elegant and not brute force like above - - form = AddMentorForm(non_mentors) - - context = { - 'user':user, - 'task':task, - 'pending_requests':pending_requests, - 'form':form, - } - - if request.method == "POST": - data = request.POST - uid = data.get('mentor', None) - if uid in non_mentor_ids: - new_mentor = User.objects.get(id=int(uid)) - reqMentor(task, new_mentor, user) - return redirect('/task/addmentor/tid=%s'%task.id) - else: - ## bogus post request - raise Http404 - else: - return render_to_response('task/addmentor.html', context) - else: - return show_msg(user, 'You are not authorised to add mentors for this task', task_url, 'view the task') - -def add_tasks(request, tid): - """ first display tasks which can be subtasks for the task and do the rest. - """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - deps, subs = task.deps, task.subs - is_plain = False if deps or subs else True - - ## again a brute force method - valid_tasks = [] - for a_task in Task.objects.all(): - if not ( a_task in deps or a_task in subs or a_task.status=="CD" or a_task==task ): - valid_tasks.append(a_task) - - task_choices = [ (_.id,_.title) for _ in valid_tasks ] - errors = [] - - is_guest = True if not user.is_authenticated() else False - - if (not is_guest) and user in task.mentors.all(): - if task.status in ["UP", "OP", "LO"]: - form = AddTaskForm(task_choices, is_plain) - if request.method == "POST": - ## first decide if adding subs and deps can be in same page - ## only exclude tasks with status deleted - data = request.POST - if is_plain and not data.get('type', None): errors.append('Please choose which type of task(s) do you want to add.') - if not data.get('task', None): errors.append('Please choose a one task') - - if not errors: - if is_plain: - update_method = addDep if data['type'] == "D" else addSubTask - elif deps: - update_method = addDep - elif subs: - update_method = addSubTask - else: - print "Screw you" - - ## we might iterate over a task list later on - task_id = data['task'] - sub_or_dep = getTask(task_id) - update_method(task, sub_or_dep) - - return redirect(task_url) - else: - return render_to_response('task/addtask.html', {'user':user, 'form':form, 'errors':errors}) - else: - return render_to_response('task/addtask.html', {'user':user, 'form':form, 'errors':errors}) - else: - errors = ["The task cannot be added subtasks or dependencies in this state"] -# return render_to_response('task/add.html', {'form':form, 'errors':errors}) - return show_msg(user, 'The task cannot be added subtasks or dependencies now', task_url, 'view the task') - else: - return show_msg(user, 'You are not authorised to add subtasks or dependencies for this task', task_url, 'view the task') - -def remove_task(request, tid): - """ display a list of tasks and remove the selectes ones. - """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - is_guest = True if not user.is_authenticated() else False - if (not is_guest) and user in task.mentors.all(): - - if task.status in ["UP", "LO", "OP"]: - - deps, subs = task.deps, task.subs - task_list = deps if task.sub_type == "D" else subs - - if task_list: - choices = [(_.id,_.title) for _ in task_list ] - form = ChoiceForm(choices) - - errors = [] - - context = { - 'user':user, - 'task':task, - 'form':form, - } - - if request.method == "POST": - data = request.POST - if not data.get('choice', None): - errors.append("Please choose a task to remove.") - context['errors'] = errors - if not errors: - tid = data['choice'] - sub_task = getTask(tid) - removeTask(task, sub_task) - return redirect(task_url) - else: - return render_to_response('task/removetask.html', context) - else: - return render_to_response('task/removetask.html', context) - else: - return show_msg(user, "The task has no subtasks/dependencies to be removed", task_url, "view the task") - else: - return show_msg(user, "subtasks/dependencies cannot be removed at this stage", task_url, "view the task") - else: - return show_msg(user, "You are not authorised to do this", task_url, "view the task") - -def claim_task(request, tid): - """ display a list of claims for get and display submit only if claimable """ - - ## create claims model and create a new database with required tables for it - ## see if that "one to n" or "n to one" relationship has a special field - - task_url = "/task/view/tid=%s"%tid - claim_url = "/task/claim/tid=%s"%tid - - errors = [] - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - #claims = task.notifications_task.filter(role="CL",sent_to=task.created_by) - # this is what the next line should be when i re sync the db - claims = Notification.objects.filter(task=task, sent_to=task.created_by, role="CL") - - mentors = task.mentors.all() - claimed_users = task.claimed_users.all() - assigned_users = task.assigned_users.all() - - is_guest = True if not user.is_authenticated() else False - is_mentor = True if user in mentors else False - - task_claimable = True if task.status in ["OP", "WR"] else False - user_can_claim = True if task_claimable and not ( is_guest or is_mentor ) and ( user not in claimed_users ) and ( user not in assigned_users ) else False - task_claimed = True if claimed_users else False - - context = {'user':user, - 'is_mentor':is_mentor, - 'task':task, - 'claims':claims, - 'user_can_claim':user_can_claim, - 'task_claimable':task_claimable, - 'task_claimed':task_claimed, - 'errors':errors} - - if not is_guest: - form = ClaimTaskForm() - context['form'] = form - if request.method == "POST": - form = ClaimTaskForm(request.POST) - context['form'] = form - if form.is_valid(): - claim_proposal = form.cleaned_data['message'] - addClaim(task, claim_proposal, user) - return redirect(claim_url) - else: - return render_to_response('task/claim.html', context) - else: - return render_to_response('task/claim.html', context) - else: - return show_msg(user, 'You are not logged in to view claims for this task', task_url, 'view the task') - -def rem_user(request, tid): - """ show a list of working users and ask for a message/reason for removing user. - """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - is_guest = True if not user.is_authenticated() else False - is_mentor = True if user in task.mentors.all() else False - - if (not is_guest) and is_mentor: - - assigned_users = task.assigned_users.all() - choices = [ (_.id,_.username) for _ in assigned_users ] - context = { - 'user':user, - 'task':task, - } - - if task.status in ["WR"]: - if assigned_users: - form = RemoveUserForm(choices) - context['form'] = form - if request.method == "POST": - data = request.POST - form = RemoveUserForm(choices, data) - if form.is_valid(): - data = form.cleaned_data - uid = data['user'] - reason = data['reason'] - rem_user = User.objects.get(id=uid) - removeUser(task, rem_user, user, reason) - return redirect(task_url) - else: - context['form'] = form - return render_to_response('task/remove_user.html', context) - else: - return render_to_response('task/remove_user.html',context) - else: - return show_msg(user, "There is no one working on this task to be kicked off", task_url, "view the task") - else: - return show_msg(user, "This is not the stage to remove users", task_url, "view the task") - else: - return show_msg(user, "You are not authorised to do this", task_url, "view the task") - -def assign_task(request, tid): - """ first get the status of the task and then assign it to one of claimed users - generate list of claimed users by passing it as an argument to a function. - """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - is_guest = True if not user.is_authenticated() else False - is_mentor = True if user in task.mentors.all() else False - - claimed_users = task.claimed_users.all() - assigned_users = task.assigned_users.all() - - task_claimed = True if claimed_users else False - - if (not is_guest) and is_mentor: - if task.status in ["OP", "WR"]: - if task_claimed: - user_list = ((user.id,user.username) for user in claimed_users) - form = ChoiceForm(user_list) - - if request.method == "POST": - uid = request.POST['choice'] - assigned_user = User.objects.get(id=uid) - assignTask(task, assigned_user, user) - return redirect(task_url) - else: - return render_to_response('task/assign.html',{'user':user, 'task':task,'form':form}) - elif assigned_users: - return show_msg(user, 'When the no of users you need for the task is more than the no of users willing to do the task, I\'d say please re consider the task :P',task_url, 'view the task') - else: - return show_msg(user, 'Wait for ppl to claim dude... slow and steady wins the race :)', task_url, 'view the task') - else: - return show_msg(user, "The task cannot be assigned to users at this stage", task_url, 'view the task') - else: - return show_msg(user, 'You are not authorised to perform this action', task_url, 'view the task') - -def assign_credits(request, tid): - """ Check if the user is a mentor and credits can be assigned. - Then display all the approved credits. - Then see if mentor can assign credits to users also or only mentors. - Then put up a form for mentor to assign credits accordingly. - """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - ## the moment we see that user had requested credits, it means he had worked and hence we change the status to WR - ## we have to discuss on this since, credits may also be given to mentor - task.status = "WR" - task.save() - - is_guest = True if not user.is_authenticated() else False - is_mentor = True if (not is_guest) and user in task.mentors.all() else False - - if is_mentor: - if task.status in ["OP", "WR"]: - choices = [(_.id,_.username) for _ in task.mentors.all()] - if task.status == "WR": - choices.extend([(_.id, _.username) for _ in task.assigned_users.all() ]) - prev_credits = task.request_task.filter(role="PY",is_valid=True,is_replied=True,reply=True).count() - credit_requests = task.request_task.filter(role="PY",is_valid=True).order_by('creation_date').reverse() - form = AssignCreditForm(choices) - - context = { - 'user':user, - 'task':task, - 'prev_credits':prev_credits, - 'credit_requests':credit_requests, - 'form':form, - } - - if request.method == "POST": - data = request.POST - form = AssignCreditForm(choices, data) - if form.is_valid(): - data = form.cleaned_data - uid = data['user'] - points = data['pynts'] - given_to = User.objects.get(id=uid) - assignCredits(task=task, given_by=user, given_to=given_to, points=points) - return redirect('/task/assigncredits/tid=%s'%task.id) - else: - context['form'] = form - return render_to_response('task/assigncredits.html', context) - else: - return render_to_response('task/assigncredits.html', context) - else: - return show_msg(user, "Credits cannot be assigned at this stage", task_url, "view the task") - else: - return show_msg(user, "You are not authorised to perform this action", task_url, "view the task") - -def edit_task(request, tid): - """ see what are the attributes that can be edited depending on the current status - and then give the user fields accordingly. - """ - - task = getTask(tid) - - task_url = "/task/view/tid=%s"%tid - user = get_user(request.user) if request.user.is_authenticated() else request.user - - is_mentor = True if user in task.mentors.all() else False - can_edit = True if is_mentor and task.status == "UP" else False - - if can_edit: - form = EditTaskForm(instance=task) - if request.method=="POST": - data = request.POST - form = EditTaskForm(data, instance=task) - if form.is_valid(): - form.save() - return redirect(task_url) - else: - return render_to_response('task/edittask.html',{'user':user, 'form':form}) - else: - return render_to_response('task/edittask.html',{'user':user, 'form':form}) - else: - return show_msg(user, "You cannot edit the task at this stage", task_url, "view the task") - -def complete_task(request, tid): - """ call the event called complete task. - and also pass it the current user to know who marked it as complete. - """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - is_guest = True if not user.is_authenticated() else False - is_mentor = True if user in task.mentors.all() else False - - claimed_users = task.claimed_users.all() - assigned_users = task.assigned_users.all() - - assign_credits_url = '/task/assigncredits/tid=%s'%task.id - task_assigned_credits = task.credit_set.all() - - - if is_mentor: - if task.status in ["OP", "WR"]: - - context = { - 'user':user, - 'task':task, - } - - if task_assigned_credits: - if request.method=="POST": - completeTask(task, user) - return redirect(task_url) - else: - return render_to_response('task/complete.html', context) - else: - return show_msg(user, "Nobody has been credited for doing this task.", assign_credits_url, "assign credits") - else: - return show_msg(user, "The task cannot be marked as completed at this stage", task_url, "view the task") - else: - return show_msg(user, "You are not authorised to do this", task_url, "view the task") - -def close_task(request, tid): - """ task can be closed only if task is published. - call the event close task if everything is fine. - """ - - task_url = "/task/view/tid=%s"%tid - - user = get_user(request.user) if request.user.is_authenticated() else request.user - task = getTask(tid) - - is_guest = True if not user.is_authenticated() else False - is_mentor = True if user in task.mentors.all() else False - - if is_mentor: - - context = { - 'user':user, - 'task':task, - } - - if not task.status in ["UP", "CD", "DL", "CM"]: - if request.method == "POST": - data = request.POST - if not data.get("reason", None): - context["error"] = "Please enter a reason for closing the task" - return render_to_response('task/close.html', context) - else: - closeTask(task, user, data['reason']) - return show_msg(user, "The task has been closed.", task_url, "view the task.") - else: - return render_to_response('task/close.html', context) - else: - return show_msg(user, "The task is either already closed or cannot be closed at this stage", task_url, "view the task") - else: - return show_msg(user, "You are not authorised to do this", task_url, "view the task") - -def delete_task(request, tid): - """ mark the task status as DL. - take a reason from the user and pass on to all the other mentors. - """ - - task_url = "/task/view/tid=%s"%tid - - task = getTask(tid) - user = get_user(request.user) if request.user.is_authenticated() else request.user - - if task.status == "DL": - return show_msg(user, "This task no longer exists", '/task/browse/', "to browse other tasks") - - can_delete = True if task.status == "UP" and task.created_by == user else False - - if can_delete: - if request.method == "POST": - data = request.POST - reason = data.get('reason', None) - deleteTask(task, user, reason) - return show_msg(user, "The task is deleted", '/', "to return to home page") - else: - return render_to_response('task/delete.html',{'user':user,}) - else: - return show_msg(user, "You are not authorised to do this at this stage", task_url, "view the task") diff -r 679c7e237052 -r 3c8f3b0e5b00 taskapp/views/user.py --- a/taskapp/views/user.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,347 +0,0 @@ -import os - -from django.http import HttpResponse, Http404 -from django.shortcuts import redirect, render_to_response -from django.contrib.auth.models import User -from django.contrib.auth.decorators import login_required - -from pytask.taskapp.models import Task, Profile, Request - -from pytask.taskapp.events.user import createUser -from pytask.taskapp.events.request import reply_to_request - -from pytask.taskapp.forms.user import UserProfileEditForm, UserChoiceForm - -from pytask.taskapp.utilities.request import get_request, create_request -from pytask.taskapp.utilities.notification import get_notification, create_notification -from pytask.taskapp.utilities.user import get_user - -about = { - "addmentors": "about/addmentors.html", - "mentor": "about/mentor.html", - "starthere": "about/starthere.html", - "task": "about/task.html", - "tasklife": "about/tasklife.html", - "developer": "about/developer.html", - "notification": "about/notification.html", - "request": "about/request.html", - "manager": "about/manager.html", - "admin": "about/admin.html", -} - -def show_msg(user, message, redirect_url=None, url_desc=None): - """ simply redirect to homepage """ - - return render_to_response('show_msg.html',{'user':user, 'message':message, 'redirect_url':redirect_url, 'url_desc':url_desc}) - -def homepage(request): - """ check for authentication and display accordingly. """ - - user = request.user - is_guest = False - is_mentor = False - can_create_task = False - task_list = [] - - if not user.is_authenticated(): - is_guest = True - disp_num = 10 - task_list = Task.objects.exclude(status="UP").exclude(status="CD").exclude(status="CM").order_by('published_datetime').reverse()[:10] - return render_to_response('index.html', {'user':user, 'is_guest':is_guest, 'task_list':task_list}) - - else: - user = get_user(request.user) - user_profile = user.get_profile() - is_mentor = True if user.task_mentors.all() else False - can_create_task = False if user_profile.rights == u"CT" else True - - context = {'user':user, - 'is_guest':is_guest, - 'is_mentor':is_mentor, - 'task_list':task_list, - 'can_create_task':can_create_task, - } - - context["unpublished_tasks"] = user.task_mentors.filter(status="UP") - context["mentored_tasks"] = user.task_mentors.exclude(status="UP").exclude(status="CM").exclude(status="CD").exclude(status="DL") - context["claimed_tasks"] = user.task_claimed_users.exclude(status="UP").exclude(status="CM").exclude(status="CD").exclude(status="DL") - context["working_tasks"] = user.task_assigned_users.filter(status="WR") - - return render_to_response('index.html', context) - -@login_required -def learn_more(request, what): - """ depending on what was asked for, we render different pages. - """ - - user = get_user(request.user) - disp_template = about.get(what, None) - if not disp_template: - raise Http404 - else: - return render_to_response(disp_template, {'user':user}) - -@login_required -def view_my_profile(request,uid=None): - """ allows the user to view the profiles of users """ - user = get_user(request.user) - request_user_profile = request.user.get_profile() - request_user_privilege = True if request_user_profile.rights in ['AD','MG'] else False - if uid == None: - edit_profile = True - profile = Profile.objects.get(user = request.user) - return render_to_response('user/my_profile.html', {'edit_profile':edit_profile,'profile':profile, 'user':user, 'privilege':request_user_privilege}) - edit_profile = True if request.user == User.objects.get(pk=uid) else False - try: - profile = Profile.objects.get(user = User.objects.get(pk=uid)) - except Profile.DoesNotExist: - raise Http404 - return render_to_response('user/my_profile.html', {'edit_profile':edit_profile,'profile':profile, 'user':user, 'privilege':request_user_privilege}) - -@login_required -def edit_my_profile(request): - """ enables the user to edit his/her user profile """ - - user = get_user(request.user) - user_profile = user.get_profile() - - edit_profile_form = UserProfileEditForm(instance = user_profile) - if request.method == 'POST': - - data = request.POST.copy() - uploaded_photo = request.FILES.get('photo', None) - data.__setitem__('photo', uploaded_photo) - - edit_profile_form = UserProfileEditForm(data, instance=user_profile) - if edit_profile_form.is_valid(): - edit_profile_form.save() - return redirect('/user/view/uid='+str(user.id)) - else: - return render_to_response('user/edit_profile.html',{'user':user, 'edit_profile_form' : edit_profile_form}) - else: - profile = user.get_profile() - edit_profile_form = UserProfileEditForm(instance = profile) - return render_to_response('user/edit_profile.html',{'edit_profile_form' : edit_profile_form, 'user':user}) - -@login_required -def browse_requests(request): - - user = get_user(request.user) - active_reqs = user.request_sent_to.filter(is_replied=False).exclude(is_valid=False) - reqs = active_reqs.order_by('creation_date').reverse() - - context = { - 'user':user, - 'reqs':reqs, - } - - return render_to_response('user/browse_requests.html', context) - -@login_required -def view_request(request, rid): - """ please note that request variable in this method is that of django. - our app request is called user_request. - """ - - user = get_user(request.user) - user_rights = user.get_profile().rights - newest, newer, user_request, older, oldest = get_request(rid, user) - if not user_request: - raise Http404 - - user_request.is_read = True - user_request.save() - - context = { - 'user':user, - 'req':user_request, - 'sent_users':user_request.sent_to.all(), - 'newest':newest, - 'newer':newer, - 'older':older, - 'oldest':oldest, - } - - return render_to_response('user/view_request.html', context) - -@login_required -def process_request(request, rid, reply): - """ check if the method is post and then update the request. - if it is get, display a 404 error. - """ - - user = get_user(request.user) - browse_request_url= '/user/requests' - newest, newer, req_obj, older, oldest = get_request(rid, user) - - if not req_obj: - return show_msg(user, "Your reply has been processed", browse_request_url, "view other requests") - - if request.method=="POST": - reply = True if reply == "yes" else False - req_obj.remarks = request.POST.get('remarks', "") - req_obj.save() - - reply_to_request(req_obj, reply, user) - - return redirect('/user/requests/') - return show_msg(user, "Your reply has been processed", browse_request_url, "view other requests") - else: - return show_msg(user, "You are not authorised to do this", browse_request_url, "view other requests") - -@login_required -def browse_notifications(request): - """ get the list of notifications that are not deleted and display in datetime order. - """ - - user = get_user(request.user) - - active_notifications = user.notification_sent_to.filter(is_deleted=False).order_by('sent_date').reverse() - - context = { - 'user':user, - 'notifications':active_notifications, - } - - return render_to_response('user/browse_notifications.html', context) - -@login_required -def view_notification(request, nid): - """ get the notification depending on nid. - Display it. - """ - - user = get_user(request.user) - newest, newer, notification, older, oldest = get_notification(nid, user) - if not notification: - raise Http404 - - notification.is_read = True - notification.save() - - context = { - 'user':user, - 'notification':notification, - 'newest':newest, - 'newer':newer, - 'older':older, - 'oldest':oldest, - } - - return render_to_response('user/view_notification.html', context) - -@login_required -def edit_notification(request, nid, action): - """ if action is delete, set is_deleted. - if it is unread, unset is_read. - save the notification and redirect to browse_notifications. - """ - - user = get_user(request.user) - newest, newer, notification, older, oldest = get_notification(nid, user) - - if not notification: - raise Http404 - - notifications_url = "/user/notifications/" - - if request.method == "POST": - if action == "delete": - notification.is_deleted = True - elif action == "unread": - notification.is_read = False - - notification.save() - if older: - return redirect('/user/notifications/nid=%s'%older.id) - else: - return redirect(notifications_url) - else: - return show_msg(user, 'This is wrong', notification_url, "view the notification") - -@login_required -def change_rights(request, role): - """ check if the current user has privileges to do this. - """ - - user = get_user(request.user) - role = role.upper() - user_profile = user.get_profile() - user_rights = user_profile.rights - - user_can_view = True if user_rights == "AD" or ( user_rights == "MG" and role in ["MG", "DV"] ) else False - - if user_can_view: - if role == "DV": - current_contributors = list(User.objects.filter(is_active=True,profile__rights="CT")) - pending_requests = user.request_sent_by.filter(is_replied=False,is_valid=True) - pending_dv_requests = pending_requests.filter(role="DV") - - ## one cannot make same request many times - for req in pending_dv_requests: - current_contributors.remove(req.sent_to.all()[0]) - - choices = [ (_.id,_.username ) for _ in current_contributors ] - - elif role == "MG": - active_users = User.objects.filter(is_active=True) - dv_ct_users = list(active_users.filter(profile__rights="CT") | active_users.filter(profile__rights="DV")) - pending_requests = user.request_sent_by.filter(is_replied=False,is_valid=True) - pending_mg_requests = pending_requests.filter(role="MG") - - ## same logic here. you cannot make another request exactly the same. - ## but iam still not decided whether someone who requests a user to be admin, - ## can be given a chance to request the same user to be a manager or developer - for req in pending_mg_requests: - dv_ct_users.remove(req.sent_to.all()[0]) - - choices = [ (_.id, _.username ) for _ in dv_ct_users ] - - elif role == "AD": - active_users = User.objects.filter(is_active=True) - non_ad_users = list(active_users.exclude(profile__rights="AD")) - pending_requests = user.request_sent_by.filter(is_replied=False,is_valid=True) - pending_ad_requests = pending_requests.filter(role="AD") - - ## we filter out users who have already been requested by the user to be an admin - for req in pending_ad_requests: - non_ad_users.remove(req.sent_to.all()[0]) - - choices = [ (_.id,_.username ) for _ in non_ad_users ] - - form = UserChoiceForm(choices) - - context = { - 'user':user, - 'form':form, - } - - if request.method=="POST": - data = request.POST - form = UserChoiceForm(choices, data) - if form.is_valid(): - user_to_change = User.objects.get(id=form.cleaned_data['user']) - create_request(sent_by=user, role=role, sent_to=user_to_change) - return show_msg(user, "A request has been sent", "/", "return to home page") - else: - raise Http404 - else: - return render_to_response('user/changerole.html', context) - else: - raise Http404 - - - - - - - - - - - - - - - - diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/404.html --- a/templates/404.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,5 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - The page you requested does not exist.
- Click here to get back to the previous page. -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/addmentors.html --- a/templates/about/addmentors.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - About - Add Mentors -{% endblock %} -{% block content %} - - A Mentor learn more - of the task can request other users to mentor the task by clicking the link "Add more mentors" available on the task page. - A request will be sent to the user. If a user has claimed the task or is working on the task, he cannot be requested to be a mentor. - If the requested user accepts the request, he will also become the mentor of the task.

- - Since mentors can view unpublished tasks, mentors can be requested to view, edit and comment upon unpublished tasks. - They can also add or remove subtasks/dependencies in unpublished state. Thereby, the creator of task can fix on the task. - Publishing/Deleting of an unpublished task is available only to the creator of the task.

- - Users can also be requested to mentor an published task. If the user accepts the request, he also becomes the mentor of the task. - In this case, the mentor is equivalent to the creator of the task. He can select/remove users; request pynts; close/complete the task. - He will have complete control over the task.

- - If a mentor requests a user to act as a mentor, he cannot make the same request to the same user again untill the previous one is - rejected. However, another mentor in the task can request the same user to be a mentor, unless there is already a similar request to the user - from this mentor also. - -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/admin.html --- a/templates/about/admin.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - About - Admin -{% endblock %} -{% block content %} - Admin is the user who has to approve assign of credits to any user for his/her work on the task.
- An Admin also has the right to request normal users to become admins or managers or developers. -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/developer.html --- a/templates/about/developer.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - About - Developer -{% endblock %} -{% block content %} - A Developer has the right to post a task. The link is available on your homepage.
- click here to know the complete life cycle of a task. -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/manager.html --- a/templates/about/manager.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - About - Manager -{% endblock %} -{% block content %} - A Manager has the right to request normal users to become managers or developers. -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/mentor.html --- a/templates/about/mentor.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - About - Mentor -{% endblock %} -{% block content %} - Mentoring is a right specific to the task. The user who creates a task will become the mentor for the task. A Mentor can request - other learn more users also to mentor the task. - Mentor is a person who mentors the task. Mentor has all the rights over the task.
- -
    -
  • Mentor can view the task even if it is unpublished.
  • -
  • Mentor can edit the task when it is in unpublished state.
  • -
  • Mentor can add/remove subtasks/dependencies to a task.
  • -
  • Mentor decides whom to assign the task (choose from claimed users).
  • -
  • Mentor also has the rights to remove a working user from a task.
  • -
  • Mentor requests assigning of pynts to users/mentors for the task.
  • -
  • Mentor has the rights to close a task or mark the task as complete.
  • -
  • Publishing/Deleting an unpublished task is a special right available only to the creator of the task.
  • -
- click here to know the complete life cycle of a task. -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/notification.html --- a/templates/about/notification.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - About - Notification -{% endblock %} -{% block content %} - Notification is a message generated by the system to inform you about any events. -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/request.html --- a/templates/about/request.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - About - Request -{% endblock %} -{% block content %} - Request is a request made by a user, requesting you to become someone else. It can also be request of assigning pynts to a user - for a task ( goes to all the admins only ). - You can accept or reject a request. You can also provide optional remarks when rejecting. When you respond to a request, it is - automatically removed from your requests and you will be redirected to browse requests page. - Redundant requests are automatically removed.

- The following can be redundant requests. -
    -
  • You are requested to act as a mentor and the task is published or deleted or closed or completed
  • -
  • There are requests for assigning pynts to a user for a task and the task is closed or completed
  • -
  • There are requests for assigning pynts to a user and the user is removed from the working users of the task
  • -
- These redundant requests when removed, a notification is sent to the requested user. -
    -
  • You accept a request to act as mentor for a task and there are similar requests
  • -
  • You accept a request to act as an admin and there are similar or less privileged requests ("Manager", "Developer")
  • -
  • You accept a request to act as a manager and there are similar or less privileged requests ("Developer")
  • -
  • You accept a request to act as a developer and there are similar requests
  • -
- -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/starthere.html --- a/templates/about/starthere.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - Start here -{% endblock %} -{% block content %} - PyTasks is a website designed to encourage open source participation of people. Now that you are registered, you are a - contributor in the website. - You can see your notifications and requests from the links available in side bar. - You can browse all the tasks through the tasks link in the side bar.
- Choose a task learn more of your choice and claim it to start working on it.
- - - -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/task.html --- a/templates/about/task.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - About - Task -{% endblock %} -{% block content %} - A task is an entity that people can work on and get pynts for their work. Every task has credits which are given to - users working on the task. A task is created by a privileged user and he becomes a - mentor learn more for the task. - The task if open, can be claimed by other users if they would like to work on the task.

- - The task can be claimed by submitting a proposal in the view claims page. The link to view claims page is available on the task page. - By claiming the task, you are actually proposing that you would like to do the task and hence the mentor of the task will - be given an option to choose you for the task. A user can only submit one claim per task. But if a user is assigned a task - and for some reason, is removed from the task later on, he can submit a second claim requesting to continue working on the task.

- - A task can also have subtasks and dependencies. - The task can only be calimed when it is open for people to work on. If the link is unavailable it implies that the task is locked - since it has subtasks or it has dependencies that are not complete or the task is closed or the task is complete.

- - click here to know the complete life cycle of a task. - -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/about/tasklife.html --- a/templates/about/tasklife.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - PyTasks - About - Task life cycle -{% endblock %} -{% block content %} - The task is created by a user and will start life in unpublished state. The creator has all rights over the task. The task in this - stage will be visible only to the creator. He can anyways request other users to view and review the task. Then the requested user - can view the task untill he does not reply to the request. If the user accepts the request, he can view, edit and comment on the task. - The user can also add/remove subtasks or dependencies. If he rejects the request he is just like other users and cannot view the task. - When the creator decides the task is ready to be published, he publishes the task. Through out this phase, - the creator of the task can delete the task at any point in time. -

- - If the task survives and is published, the task is available to be viewed by all the users. The task cannot be edited after this - point but subtasks/dependencies can be added/removed. If the task has subtasks, the task is locked forever. It implies that the task - cannot be claimed by anyone and exists only to show all of its subtasks in one place.

- If a task has dependencies, the task is locked untill all of its dependencies are completed. If all its dependencies are completed, - the task is open for claims and can be claimed by users. - If a task has neither subtasks nor dependencies, it is open as well and users claim the task. Any of the mentors can select user(s) - from the claimed users to work on the task . Dependencies can be added/removed only untill a user is selected to work on the task. This is due - to the fact that user had a chance to claim when the task had no dependencies or all its dependencies were satisfied. - Also selecting a user to work on the task implies the task has all its dependencies satisfied.

- - During the working stage of task, a mentor can request assign of pynts to users working on task or the mentors. The assign pynts link - will be available to mentor on the task page. If there are no users working, the mentor can request assign of credits to himself - or one of the other mentors, who ever has done work on the task. Even if there are no users working on task, if there is a - request for assign of credits to the task implies that someone has worked on the task and hence dependencies cannot be - added after that.

- - The users can be selected to work or removed from working users at any point in time. If a user is removed, he can claim again - to request to continue working on the task. If a user is removed, all the pending requests for assigning pynts to user will be made invalid. - After a considerable amount of work has been done and all the users and mentors have been assigned pynts properly, any mentor in the - task can mark the task as complete. The link is available on assign pynts page just in case - the mentor wants to assign more pynts before marking the task as complete.
- If a mentor feels that the task is invalid or decides to delete the task, he will not be allowed to do it. Instead he can close the task - by providing a closing message. The link to close task will be available to mentors on the task page itself.

- - Now all this can be done by any of the mentors and hence think twice before you request a user to mentor the task. -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/admin/login.html --- a/templates/admin/login.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} - -{% block extrastyle %}{% load adminmedia %}{{ block.super }}{% endblock %} - -{% block bodyclass %}login{% endblock %} - -{% block content_title %}{% endblock %} - -{% block breadcrumbs %}{% endblock %} - -{% block content %} -{% if error_message %} -

{{ error_message }}

-{% endif %} -
-
-
- -
-
- - -
-
- -
-
- - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/base.html --- a/templates/base.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,175 +0,0 @@ - - - {% block title %}PyTasks{% endblock %} - {% block js_script %} {% endblock %} - - - - - - - - diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/index.html --- a/templates/index.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - {% if is_guest %} - Welcome Guest
- Register - Login

- Recent Tasks:
- {% for task in task_list %} - {{ task.title }}
- {% endfor %} - {% else %} - Logged in as {{ user.username }}

- {% endif %} - - {% if can_create_task %} - Create a task
-
- {% endif %} - {% ifequal user.get_profile.rights "MG" %} - Request another user to be a Developer
- Request another user to act as manager
-
- {% endifequal %} - {% ifequal user.get_profile.rights "AD" %} - Request another user to be a Developer
- Request another user to act as a Manager
- Request another user to act as an Admin
-
- {% endifequal %} - - - {% if user.unread_notifications.count %} - You have {{ user.unread_notifications.count }} unread - {% ifnotequal user.unread_notifications.count 1 %} - notifications - {% else %} - notification - {% endifnotequal %} -
- {% endif %} - - {% if user.unread_requests.count %} - You have {{ user.unread_requests.count }} unread - {% ifnotequal user.unread_requests.count 1 %} - requests - {% else %} - request - {% endifnotequal %} -

- {% else %} - {% if user.unread_notifications.count %} -
- {% endif %} - {% endif %} - - - - - {% if unpublished_tasks %} - Unpublished tasks viewable by you: -
- {% endif %} - - {% if mentored_tasks %} - Tasks you are mentoring: -
- {% endif %} - - {% if working_tasks %} - Tasks that have been assigned to you: -
- {% endif %} - - {% if claimed_tasks %} - Tasks claimed but still not assigned to you: -
- {% endif %} - -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/activate.html --- a/templates/registration/activate.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -{% extends 'base.html' %} -{% block content %} -Your account has been successfully activated. -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/activation_email.txt --- a/templates/registration/activation_email.txt Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -Welcome to PyTasks: - -Click on the following link -http://{{site}}/accounts/activate/{{activation_key}} -and activate your account. -Note that the account has to activated within {{expiration_days}} days - -Regards, -PyTasks Team diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/activation_email_subject.txt --- a/templates/registration/activation_email_subject.txt Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -Welcome to PyTasks! diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/logged_out.html --- a/templates/registration/logged_out.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} - -{% block breadcrumbs %}{% endblock %} - -{% block content %} - -

{% trans "Thanks for spending some quality time with the Web site today." %}

- -

{% trans 'Log in again' %}

- -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/login.html --- a/templates/registration/login.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -{% extends 'base.html' %} -{% block content %} -
-{{ form.as_p }} - -
-Forgot password? -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/logout.html --- a/templates/registration/logout.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -{% extends 'base.html' %} -{% block content %} -You have successfully logged out of PyTasks. -

-Click here to go back to PyTask Homepage -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/password_change_done.html --- a/templates/registration/password_change_done.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} -{% block userlinks %}{% url django-admindocs-docroot as docsroot %}{% if docsroot %}{% trans 'Documentation' %} / {% endif %}{% trans 'Change password' %} / {% trans 'Log out' %}{% endblock %} -{% block breadcrumbs %}{% endblock %} - -{% block title %}{% trans 'Password change successful' %}{% endblock %} - -{% block content %} - -

{% trans 'Password change successful' %}

- -

{% trans 'Your password was changed.' %}

- -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/password_change_form.html --- a/templates/registration/password_change_form.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} -{% block userlinks %}{% url django-admindocs-docroot as docsroot %}{% if docsroot %}{% trans 'Documentation' %} / {% endif %} {% trans 'Change password' %} / {% trans 'Log out' %}{% endblock %} -{% block breadcrumbs %}{% endblock %} - -{% block title %}{% trans 'Password change' %}{% endblock %} - -{% block content %} - -

{% trans 'Password change' %}

- -

{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}

- -
- -{{ form.old_password.errors }} -

{{ form.old_password }}

-{{ form.new_password1.errors }} -

{{ form.new_password1 }}

-{{ form.new_password2.errors }} -

{{ form.new_password2 }}

- -

-
- -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/password_reset_complete.html --- a/templates/registration/password_reset_complete.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} - -{% block breadcrumbs %}{% endblock %} - -{% block title %}{% trans 'Password reset complete' %}{% endblock %} - -{% block content %} - -

{% trans 'Password reset complete' %}

- -

{% trans "Your password has been set. You may go ahead and log in now." %}

- -

{% trans 'Log in' %}

- -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/password_reset_confirm.html --- a/templates/registration/password_reset_confirm.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} - -{% block breadcrumbs %}{% endblock %} - -{% block title %}{% trans 'Password reset' %}{% endblock %} - -{% block content %} - -{% if validlink %} - -

{% trans 'Enter new password' %}

- -

{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}

- -
-{{ form.new_password1.errors }} -

{{ form.new_password1 }}

-{{ form.new_password2.errors }} -

{{ form.new_password2 }}

-

-
- -{% else %} - -

{% trans 'Password reset unsuccessful' %}

- -

{% trans "The password reset link was invalid, possibly because it has already been used. Please request a new password reset." %}

- -{% endif %} - -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/password_reset_done.html --- a/templates/registration/password_reset_done.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} - -{% block breadcrumbs %}{% endblock %} - -{% block title %}{% trans 'Password reset successful' %}{% endblock %} - -{% block content %} - -

{% trans 'Password reset successful' %}

- -

{% trans "We've e-mailed you instructions for setting your password to the e-mail address you submitted. You should be receiving it shortly." %}

- -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/password_reset_email.html --- a/templates/registration/password_reset_email.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -{% load i18n %}{% autoescape off %} -{% trans "You're receiving this e-mail because you requested a password reset" %} -{% blocktrans %}for your user account at {{ site_name }}{% endblocktrans %}. - -{% trans "Please go to the following page and choose a new password:" %} -{% block reset_link %} -{{ protocol }}://{{ domain }}{% url django.contrib.auth.views.password_reset_confirm uidb36=uid, token=token %} -{% endblock %} -{% trans "Your username, in case you've forgotten:" %} {{ user.username }} - -{% trans "Thanks for using our site!" %} - -{% blocktrans %}The {{ site_name }} team{% endblocktrans %} - -{% endautoescape %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/password_reset_form.html --- a/templates/registration/password_reset_form.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -{% extends "base.html" %} -{% load i18n %} - -{% block breadcrumbs %}{% endblock %} - -{% block title %}{% trans "Password reset" %}{% endblock %} - -{% block content %} - -

{% trans "Password reset" %}

- -

{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}

- -
-{{ form.email.errors }} -

{{ form.email }}

-
- -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/registration_complete.html --- a/templates/registration/registration_complete.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -{% extends 'base.html' %} -{% block content %} -Please check your email for instructions on activating your account. -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/registration/registration_form.html --- a/templates/registration/registration_form.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -{% extends 'base.html' %} -{% block content %} -
-{{ form.as_p }} - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/show_msg.html --- a/templates/show_msg.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -{% extends 'base.html' %} -{% block js_script %} - -{% endblock %} -{% block content %} - - {% if message %} - {{message}}
- {% endif %} - You will be redirected to {{url_desc}} page in 5 seconds - -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/addmentor.html --- a/templates/task/addmentor.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - Click here to return to the task.

- Requesting a user to act as a mentor for the task sends him a request. If he accepts the request, he will also be the mentor for this task - {% ifequal task.status "UP" %} - and can view/editlearn more the task. But only the creator of a task can publish the task. - {% else %} - and will have all the rightslearn more you posses over the task. - {% endifequal %} -
-
-
- {{form.as_table}} - -
- {% if pending_requests %} - Pending requests:
- {% for req in pending_requests %} - {{req.sent_by.username}} requested - {% for a_user in req.sent_to.all %} - {{a_user.username}} to act as a mentor - {% endfor %} - on {{req.creation_date|date:"D d M Y"}} at {{req.creation_date|time:"H:i"}}
- {% endfor %} - {% endif %} -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/addtask.html --- a/templates/task/addtask.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - Add tasks for {{task.title}} -{% endblock %} -{% block content %} - {% if errors %} - Please correct the following errors.
- {% for err in errors %} - {{err}}
- {% endfor %} - {% endif %} -
- {{form.as_p}} - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/assign.html --- a/templates/task/assign.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - click here to return to the claims page.

- Select a user to assign this task.
-
- {{form.as_table}} - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/assigncredits.html --- a/templates/task/assigncredits.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - {{task.title}} -{% endblock %} -{% block content %} - Click here to return to the task.
- -
- {{form.as_p}} - -
- {% if prev_credits %} - Mark task as complete. -
- {% endif %} - {% if credit_requests %} -
Previous credits:
- {% for req in credit_requests %} -
- {{req.sent_by.username}} requested assigning of {{req.pynts}} pynts to - {{req.receiving_user.username}} - on {{req.creation_date|date:"D d M Y"}} at {{req.creation_date|time:"H:i"}}
- {% if req.is_replied %} - status: - {% if req.reply %} - Approved by {{req.replied_by.username}} - on {{req.reply_date|date:"D d M Y"}} at {{req.reply_date|time:"H:i"}}
- {% else %} - Rejected by {{req.replied_by.username}} - on {{req.reply_date|date:"D d M Y"}} at {{req.reply_date|time:"H:i"}}
- {% if req.remarks %} - Reason: {{req.remarks}} - {% endif %} - {% endif %} - {% else %} - status: Request pending - {% endif %} - {% endfor %} - {% else %} - No assigning of pynts has been made for this task. - {% endif %} -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/browse.html --- a/templates/task/browse.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - List of all the tasks: -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/claim.html --- a/templates/task/claim.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - {% if user_can_claim %} - Propose a claim to work on this task.learn more

- {% endif %} - {% if claims %} - List of all the claims for the task {{task.title}}
- {% for claim in claims %} -
- {{claim.sent_from.username}} - on {{claim.sent_date|date:"D d M Y"}} at {{claim.sent_date|time:"H:i"}} wrote:
- {{claim.remarks}}
- {% endfor %} - {% else %} - {% if task_claimable %} - There are no claims for this task yet.
- {% if user_can_claim %} - Be the first to claim the task.
- {% endif %} - {% else %} - The task cannot be claimed at this stage.
- {% endif %} - Click here to view the task.
- {% endif %} - {% if task_claimed and is_mentor %} - Select a user to assign the work.learn more - {% endif %} - {% if user_can_claim %} - -
-
- {{form.as_p}} -
- Please note that you can claim only once and so write your proposal carefully.
-
- {% endif %} - -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/close.html --- a/templates/task/close.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - {{task.title}} -{% endblock %} -{% block content %} - Disclaimer:
- If a task is closed, it implies the task is no more a valid task. The task cannot be edited or added subtasks/dependencies. - Please click here to return to assign credits page if you want to request assign of credits. - You cannot request assign of credits and all the pending requests on this task will be made invalid when a task is closed.

- - The only difference between marking a task as closed and completed is that the tasks depending on completed tasks will be free to be claimed - and worked on. This action cannot be undone. If you have double checked every thing, please provide a reason and close the task.
- -
- {% if error %} - Please provide a reason for closing the task. - {% endif %} -
- Reason: - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/complete.html --- a/templates/task/complete.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - {{task.title}} -{% endblock %} -{% block content %} - Disclaimer:
- Marking a task as complete implies the task has been completed successfully. It implies that all the required files - are available as attatchments in comments and all the users worked on this task were credited accordingly.

- This action sets the task as completed and frees all the tasks depending on this task. Henceforth, the task can not be - commented upon or edited by anyone.

- If there are pending requests for assigning credits, they will be deleted and admins will not be able to approve those requests. - Hence you cannot assign credits to anyone for this task anymore. You must wait for the requests to be approved by any of the admins. - If you would like to request for assigning more credits, return to assign credits page by clicking - here.

- If you have double checked everything, confirm this action by clicking the button below. -
- -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/create.html --- a/templates/task/create.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - {% if error_msg %} - {{ error_msg }}
- {% endif %} -
- {{form.as_p}} - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/delete.html --- a/templates/task/delete.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - {{task.title}} -{% endblock %} -{% block content %} - Are you sure you want to delete the task. This action cannot be undone.
- -
- Reason: - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/edittask.html --- a/templates/task/edittask.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - {% if error_msg %} - {{ error_msg }}
- {% endif %} -
- {{form.as_p}} - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/publish.html --- a/templates/task/publish.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - {{task.title}} -{% endblock %} -{% block content %} - Disclaimer:
- Publishing a task will make the task visible to every one and cannot be edited there after.

- Only you will have mentoring rights on this task. But you can request other users also to mentor the task. - learn more

- This action cannot be undone. -
- Please confirm if you want to publish. -
- -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/remove_user.html --- a/templates/task/remove_user.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - Remove users for {{task.title}} -{% endblock %} -{% block content %} - Click here to return to {{task.title}} -
- {{form.as_p}} - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/removetask.html --- a/templates/task/removetask.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - Remove tasks for {{task.title}} -{% endblock %} -{% block content %} - Click here to return to task.
- {% if errors %} - Please correct the following errors.
- {% for err in errors %} - {{err}}
- {% endfor %} - {% endif %} -
- {{form.as_p}} - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/task/view.html --- a/templates/task/view.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,172 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - {{task.title}} -{% endblock %} -{% block content %} -

{{ task.title }}

- - {% if can_edit %} - Edit task - {% endif %} - - {% if can_publish %} - Publish task - {% endif %} - - {% if can_close %} - Close this task - {% endif %} - - {% if can_delete %} - Delete task - {% endif %} - -
created by {{ task.created_by.username }} - on {{task.creation_datetime|date:"D d M Y"}} at {{task.creation_datetime|time:"H:i"}}
- - {% ifequal task.status "UP" %} - Task can be viewed by: - {% else %} - Mentors: - {% endifequal %} - - {% for mentor in mentors %} - {{mentor.username}} - {% endfor %} - - {% if can_mod_mentors %} - - {% ifequal task.status "UP" %} - Request others to view/edit the task - {% else %} - Add another Mentor to this task - {% endifequal %} - {% endif %} -
- -
- Description:
- {{ task.desc|linebreaksbr }} -


- {% if task.tags.count %} - Tags: - {% for tag in task.tags %} - {{tag}} - {% endfor %} -
- {% endif %} - - {% if deps %} - -
The task has following dependencies. - - {% if can_mod_tasks %} - add more dependencies - remove an existing dependency - {% endif %} - - {% else %} - - {% if subs %} - The task has following sub tasks. - - {% if can_mod_tasks %} - add more subtasks - remove an existing subtask - {% endif %} - - {% else %} - - {% if can_mod_tasks %} - add a subtask/dependency - {% endif %} - - {% endif %} - {% endif %} - - {% ifequal task.status "CD" %} - Task has been closed by {{closing_notification.sent_from.username}} - on {{closing_notification.sent_date|date:"D d M Y"}} at {{closing_notification.sent_date|time:"H:i"}}
- Reason: {{closing_notification.remarks}}
- {% endifequal %} - - {% ifequal task.status "CM" %} - Task has been marked complete by - {{completed_notification.sent_from.username}} - on {{completed_notification.sent_date|date:"D d M Y"}} at {{completed_notification.sent_date|time:"H:i"}}
- {% endifequal %} - - {% ifequal task.status "OP" %} -
There are no users working on this task.
- {% endifequal %} - - {% if subs %} -
This task cannot be claimed.. It exists only to show all of its sub tasks in one place.
- {% endif %} - - {% if assigned_users %} - Users working on this task: - {% for user in assigned_users %} - {{user.username}} - {% endfor %} - {% if is_mentor %} - Remove an existing user - {% endif %} -
- {% endif %} - - {% if can_assign_credits %} - View/Assign credits - {% endif %} - - {% if task_claimable %} - - {% if is_mentor %} - View claims - {% else %} - Claim the task - {% endif %} - {% endif %} - - {% if comments %} -
- comments:

- {% for comment in comments %} - {{ comment.created_by.username }} - on {{ comment.creation_datetime|date:"D d M Y"}} at {{comment.creation_datetime|time:"H:i"}} wrote:
- {{ comment.data|linebreaksbr }}

- {% endfor %} - {% endif %} - - {% if not is_guest %} -
- {% if error_msg %} - {{error_msg}}
- {% endif %} - {% ifnotequal task.status "UP" %} - Add comment:
-
- -
- -
- {% else %} - {% if is_mentor %} - Add comment:
-
- -
- -
- {% endif %} - {% endifnotequal %} - {% endif %} -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/user/browse_notifications.html --- a/templates/user/browse_notifications.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - {% if not notifications %} - You have no notifications.learn more
- {% else %} - Notifications for you: learn more
- {% for notification in notifications %} - - {% if not notification.is_read %} {% endif %} - {{notification.sub}} - {% if not notification.is_read %} {% endif %}
- {% endfor %} - {% endif %} -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/user/browse_requests.html --- a/templates/user/browse_requests.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - {% if not reqs %} - You have no unreplied requests learn more
- {% else %} - You have not yet replied to these requests.learn more

- {% for req in reqs %} - - {% if not req.is_read %}{% endif %} - - {% ifequal req.role "PY" %} - Assign of pynts to {{req.receiving_user}} for the task "{{req.task.title|slice:":20"}}" - {% endifequal %} - - {% ifequal req.role "MT" %} - Request to mentor the task "{{req.task.title|slice:":20"}}" - {% endifequal %} - - {% ifequal req.role "DV" %} - Request to act as a developer in the website - {% endifequal %} - - {% ifequal req.role "MG" %} - Request to act as a manager in the website - {% endifequal %} - - {% ifequal req.role "AD" %} - Request to act as an admin in the website - {% endifequal %} - - - {% if not req.is_read %}{% endif %}
-
- {% endfor %} - {% endif %} -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/user/changerole.html --- a/templates/user/changerole.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -{% extends 'base.html' %} -{% block title %} - {{task.title}} -{% endblock %} -{% block content %} - Click here to return to home page.
-
- {{form.as_p}} - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/user/edit_profile.html --- a/templates/user/edit_profile.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -{% extends 'base.html' %} -{% block content %} -
- {{ edit_profile_form.as_p }} - -
-{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/user/my_profile.html --- a/templates/user/my_profile.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -{% extends 'base.html' %} - -{% block title %} - {{ profile.user }}'s Profile -{% endblock %} - -{% block content %} - - -

{{ profile }}'s Profile

-
- {% if edit_profile %} - edit profile | change password -
- {% endif %} - {% if profile.photo %} - - - - {% endif %} - {% if privilege or edit_profile %} -

E-Mail


{{ profile.user.email }} - {% endif %} - {% if profile.aboutme %} -

About Me


{{ profile.aboutme }} - {% endif %} - {% if profile.nick %} -

Nick Name


{{ profile.nick }} - {% endif %} - {% if profile.dob %} -

Date of Birth


{{ profile.dob }} - {% endif %} - {% if profile.credits %} -

Credits


{{ profile.credits }} - {% endif %} - {% if profile.foss_comm %} -

Foss Community


{{ profile.foss_comm }} - {% endif %} - {% if privilege or edit_profile %} - {% if profile.phonenum %} -

Phone Number


{{ profile.phonenum }} - {% endif %} - {% endif %} - {% if profile.homepage %} -

Homepage


{{ profile.homepage }} - {% endif %} - {% if privilege or edit_profile %} - {% if profile.street or profile.city or profile.country %} -

Address


- {% if profile.street %} - {{ profile.street }} -
- {% endif %} - {% if profile.city %} - {{ profile.city }} -
- {% endif %} - {% if profile.country %} - {{ profile.country }} - {% endif %} - {% endif %} - {% else %} - {% endif %} -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/user/view_notification.html --- a/templates/user/view_notification.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - {% if newest %} - <<newest - {% endif %} - {% if newer %} - <newer - {% endif %} - {% if older %} - older> - {% endif %} - {% if oldest %} - oldest>> - {% endif %} -
- -
-
-
- sent on {{notification.sent_date|date:"D d M Y"}} at {{notification.sent_date|time:"H:i"}}
- Sub: {{notification.sub}}
-
- {{notification.message|safe}} -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 templates/user/view_request.html --- a/templates/user/view_request.html Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - {% if newest %} - <<newest - {% endif %} - {% if newer %} - <newer - {% endif %} - {% if older %} - older> - {% endif %} - {% if oldest %} - oldest>> - {% endif %} -
- From:  {{req.sent_by.username}}
- To: - {% for to_user in sent_users %} - {{to_user.username}}  - {% endfor %} -
- sent on {{req.sent_date|date:"D d M Y"}} at {{req.sent_date|time:"H:i"}}
- Message:
- {% ifequal "PY" req.role %} - {{req.sent_by.username}} assigned {{req.pynts}} pynts to - {{req.receiving_user.username}} for the task - {{req.task.title}}
- {% else %} - - {% ifequal "MT" req.role %} - {{req.sent_by.username}} requested you to act as a mentor for the task - {{req.task.title}}
- {% else %} - You have been requested to act as - {% ifequal "AD" req.role %} - an Admin - {% else %} - {% ifequal "MG" req.role %} - a Manager - {% else %} - a Developer - {% endifequal %} - {% endifequal %} - for the website by {{req.sent_by.username}}.
- {% endifequal %} - {% endifequal %} -
- - Please accept or reject the request.
-
- -
-
- Remarks: - -
- Click here to return to the requests page. - -{% endblock %} diff -r 679c7e237052 -r 3c8f3b0e5b00 urls.py --- a/urls.py Tue Mar 09 11:39:34 2010 +0530 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -from django.conf.urls.defaults import * - -# Uncomment the next two lines to enable the admin: -from django.contrib import admin -admin.autodiscover() - -from pytask.taskapp.views import user as userViews -from pytask.taskapp.views import task as taskViews - -from pytask.taskapp.forms.user import RegistrationFormCustom -from registration.views import register - -urlpatterns = patterns('', - # Example: - # (r'^pytask/', include('pytask.foo.urls')), - - # Uncomment the admin/doc line below and add 'django.contrib.admindocs' - # to INSTALLED_APPS to enable admin documentation: - # (r'^admin/doc/', include('django.contrib.admindocs.urls')), - - (r'^images/(?P.*)$', 'django.views.static.serve', - {'document_root': './images/'}), - - (r'^$', userViews.homepage), - - (r'^task/browse/$', taskViews.browse_tasks), - (r'^task/view/tid=(\w+)$', taskViews.view_task), - (r'^task/create/$', taskViews.create_task), - (r'^task/publish/tid=(\w+)/$', taskViews.publish_task), - (r'^task/addmentor/tid=(\w+)$', taskViews.add_mentor), - (r'^task/edit/tid=(\w+)$', taskViews.edit_task), - (r'^task/claim/tid=(\w+)$', taskViews.claim_task), - (r'^task/assign/tid=(\w+)$', taskViews.assign_task), - (r'^task/remuser/tid=(\w+)$', taskViews.rem_user), - (r'^task/addtask/tid=(\w+)$', taskViews.add_tasks), - (r'^task/remtask/tid=(\w+)$', taskViews.remove_task), - (r'^task/assigncredits/tid=(\w+)$', taskViews.assign_credits), - (r'^task/complete/tid=(\w+)$', taskViews.complete_task), - (r'^task/close/tid=(\w+)$', taskViews.close_task), - (r'^task/delete/tid=(\w+)$', taskViews.delete_task), - - (r'^admin/', include(admin.site.urls)), - - url(r'^accounts/register/$',register,{'form_class' : RegistrationFormCustom},name='registration_register'), - (r'^accounts/', include('registration.urls')), - (r'^accounts/profile/$', userViews.view_my_profile), - - (r'^user/view/uid=(\d+)$', userViews.view_my_profile), - (r'^user/edit/?$', userViews.edit_my_profile), - - (r'^user/requests/$', userViews.browse_requests), - (r'^user/requests/rid=(\d+)/$', userViews.view_request), - (r'^user/requests/rid=(\d+)/(\w+)/$', userViews.process_request), - - (r'^user/notifications/$', userViews.browse_notifications), - (r'^user/notifications/nid=(\d+)/$', userViews.view_notification), - (r'^user/notifications/nid=(\d+)/(\w+)/$', userViews.edit_notification), - (r'^user/make/(\w+)/$', userViews.change_rights), - - (r'^about/(\w+)/$', userViews.learn_more), - -)