summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--devel/views.py12
-rw-r--r--sitestatic/archweb.css5
-rw-r--r--sitestatic/archweb.js17
-rw-r--r--templates/devel/index.html10
-rw-r--r--templates/todolists/email_notification.txt2
-rw-r--r--templates/todolists/list.html4
-rw-r--r--templates/todolists/public_list.html18
-rw-r--r--templates/todolists/view.html27
-rw-r--r--todolists/urls.py2
-rw-r--r--todolists/utils.py14
-rw-r--r--todolists/views.py76
11 files changed, 97 insertions, 90 deletions
diff --git a/devel/views.py b/devel/views.py
index 7d5947d..e01590a 100644
--- a/devel/views.py
+++ b/devel/views.py
@@ -20,11 +20,12 @@ from django.utils.http import http_date
from django.utils.timezone import now
from .forms import ProfileForm, UserProfileForm, NewUserForm
-from main.models import Package, PackageFile, TodolistPkg
+from main.models import Package, PackageFile
from main.models import Arch, Repo
from news.models import News
from packages.models import PackageRelation, Signoff, FlagRequest, Depend
from packages.utils import get_signoff_groups
+from todolists.models import TodolistPackage
from todolists.utils import get_annotated_todolists
from .utils import get_annotated_maintainers, UserFinder
@@ -41,10 +42,11 @@ def index(request):
flagged = Package.objects.normal().filter(
flag_date__isnull=False, pkgbase__in=inner_q).order_by('pkgname')
- todopkgs = TodolistPkg.objects.select_related(
- 'pkg', 'pkg__arch', 'pkg__repo').filter(complete=False)
- todopkgs = todopkgs.filter(pkg__pkgbase__in=inner_q).order_by(
- 'list__name', 'pkg__pkgname')
+ todopkgs = TodolistPackage.objects.select_related(
+ 'todolist', 'pkg', 'arch', 'repo').exclude(
+ status=TodolistPackage.COMPLETE)
+ todopkgs = todopkgs.filter(pkgbase__in=inner_q).order_by(
+ 'todolist__name', 'pkgname')
todolists = get_annotated_todolists(incomplete_only=True)
diff --git a/sitestatic/archweb.css b/sitestatic/archweb.css
index 6d6e156..cfa30f5 100644
--- a/sitestatic/archweb.css
+++ b/sitestatic/archweb.css
@@ -999,6 +999,11 @@ ul.admin-actions {
.todo-table .incomplete {
color: red;
}
+
+.todo-table .inprogress {
+ color: darkorange;
+}
+
.todo-info {
margin: 0; color: #999;
}
diff --git a/sitestatic/archweb.js b/sitestatic/archweb.js
index 42efb3f..4a02fb6 100644
--- a/sitestatic/archweb.js
+++ b/sitestatic/archweb.js
@@ -15,7 +15,12 @@ if (typeof $ !== 'undefined' && typeof $.tablesorter !== 'undefined') {
id: 'todostatus',
is: function(s) { return false; },
format: function(s) {
- return s.match(/incomplete/i) ? 1 : 0;
+ if (s.match(/incomplete/i)) {
+ return 1;
+ } else if (s.match(/in-progress/i)) {
+ return 0.5;
+ }
+ return 0;
},
type: 'numeric'
});
@@ -304,13 +309,9 @@ function todolist_flag() {
// TODO: fix usage of this
var link = this;
$.getJSON(link.href, function(data) {
- if (data.complete) {
- $(link).text('Complete').addClass(
- 'complete').removeClass('incomplete');
- } else {
- $(link).text('Incomplete').addClass(
- 'incomplete').removeClass('complete');
- }
+ $(link).text(data.status).removeClass(
+ 'complete inprogress incomplete').addClass(
+ data.css_class.toLowerCase());
/* let tablesorter know the cell value has changed */
$('.results').trigger('updateCell', [$(link).closest('td')[0], false, null]);
});
diff --git a/templates/devel/index.html b/templates/devel/index.html
index a07a419..5715104 100644
--- a/templates/devel/index.html
+++ b/templates/devel/index.html
@@ -59,11 +59,11 @@
<tbody>
{% for todopkg in todopkgs %}
<tr class="{% cycle 'odd' 'even' %}">
- <td><a href="{{ todopkg.list.get_absolute_url }}"
- title="View todo list: {{ todopkg.list.name }}">{{ todopkg.list.name }}</a></td>
+ <td><a href="{{ todopkg.todolist.get_absolute_url }}"
+ title="View todo list: {{ todopkg.todolist.name }}">{{ todopkg.todolist.name }}</a></td>
<td>{% pkg_details_link todopkg.pkg %}</td>
- <td>{{ todopkg.pkg.repo.name }}</td>
- <td>{{ todopkg.pkg.arch.name }}</td>
+ <td>{{ todopkg.repo.name }}</td>
+ <td>{{ todopkg.arch.name }}</td>
<td>{{ todopkg.pkg.maintainers|join:', ' }}</td>
</tr>
{% empty %}
@@ -90,7 +90,7 @@
<tr class="{% cycle 'odd' 'even' %}">
<td><a href="{{ todo.get_absolute_url }}"
title="View todo list: {{ todo.name }}">{{ todo.name }}</a></td>
- <td>{{ todo.date_added|date }}</td>
+ <td>{{ todo.created|date }}</td>
<td>{{ todo.creator.get_full_name }}</td>
<td class="wrap">{{ todo.description|urlize }}</td>
<td>{{ todo.pkg_count }}</td>
diff --git a/templates/todolists/email_notification.txt b/templates/todolists/email_notification.txt
index 8b22b46..e454ec7 100644
--- a/templates/todolists/email_notification.txt
+++ b/templates/todolists/email_notification.txt
@@ -1,7 +1,7 @@
{% autoescape off %}The todo list "{{ todolist.name }}" has had the following packages added to it for which you are a maintainer:
{% for tpkg in todo_packages %}
-* {{ tpkg.pkg.repo.name|lower }}/{{ tpkg.pkg.pkgname }} ({{ tpkg.pkg.arch.name }}) - {{ tpkg.pkg.get_full_url }}{% endfor %}
+* {{ tpkg.repo.name|lower }}/{{ tpkg.pkgname }} ({{ tpkg.arch.name }}) - {{ tpkg.pkg.get_full_url }}{% endfor %}
Todo list information:
Name: {{ todolist.name }}
diff --git a/templates/todolists/list.html b/templates/todolists/list.html
index 51f9b57..4e456d2 100644
--- a/templates/todolists/list.html
+++ b/templates/todolists/list.html
@@ -8,7 +8,7 @@
<h2>Package Todo Lists</h2>
- {% if perms.main.add_todolist %}
+ {% if perms.todolists.add_todolist %}
<ul class="admin-actions">
<li><a href="/todo/add/" title="Add new todo list">Add Todo List</a></li>
</ul>
@@ -31,7 +31,7 @@
<tr class="{% cycle 'odd' 'even' %}">
<td><a href="{{ list.get_absolute_url }}"
title="View todo list: {{ list.name }}">{{ list.name }}</a></td>
- <td>{{ list.date_added|date }}</td>
+ <td>{{ list.created|date }}</td>
<td>{{ list.creator.get_full_name }}</td>
<td class="wrap">{{ list.description|urlize }}</td>
<td>{{ list.pkg_count }}</td>
diff --git a/templates/todolists/public_list.html b/templates/todolists/public_list.html
index 9e0e523..41caf5b 100644
--- a/templates/todolists/public_list.html
+++ b/templates/todolists/public_list.html
@@ -30,7 +30,7 @@
<div class="todo-list">
<a name="{{ list.id }}"></a>
<h4>{{ list.name }}</h4>
- <p class="todo-info">{{ list.date_added|date }} - {{ list.creator.get_full_name }}</p>
+ <p class="todo-info">{{ list.created|date }} - {{ list.creator.get_full_name }}</p>
<div>{{ list.description|urlize|linebreaks }}</div>
<table id="todo-pkglist-{{ list.id }}" class="results todo-table">
<thead>
@@ -45,17 +45,11 @@
<tbody>
{% for pkg in list.packages %}
<tr class="{% cycle 'odd' 'even' %}">
- <td>{% pkg_details_link pkg.pkg %}</td>
- <td>{{ pkg.pkg.arch.name }}</td>
- <td>{{ pkg.pkg.repo.name|capfirst }}</td>
- <td>{{ pkg.pkg.maintainers|join:', ' }}</td>
- <td>
- {% if pkg.complete %}
- <span class="complete">Complete</span>
- {% else %}
- <span class="incomplete">Incomplete</span>
- {% endif %}
- </td>
+ <td>{% pkg_details_link pkg.pkg pkg.pkgname %}</td>
+ <td>{{ pkg.arch.name }}</td>
+ <td>{{ pkg.repo.name|capfirst }}</td>
+ <td>{{ pkg.maintainers|join:', ' }}</td>
+ <td><span class="{{ pkg.status_css_class }}">{{ pkg.get_status_display }}</span></td>
</tr>
{% endfor %}
</tbody>
diff --git a/templates/todolists/view.html b/templates/todolists/view.html
index b6f5970..0f3475a 100644
--- a/templates/todolists/view.html
+++ b/templates/todolists/view.html
@@ -10,17 +10,17 @@
<h2>Todo List: {{ list.name }}</h2>
<ul class="admin-actions">
- {% if perms.main.delete_todolist %}
+ {% if perms.todolists.delete_todolist %}
<li><a href="/todo/delete/{{list.id}}/"
title="Delete this todo list">Delete Todo List</a></li>
{% endif %}
- {% if perms.main.change_todolist %}
+ {% if perms.todolists.change_todolist %}
<li><a href="/todo/edit/{{list.id}}/"
title="Edit this todo list">Edit Todo List</a></li>
{% endif %}
</ul>
- <p class="todo-info">{{ list.date_added|date }} - {{ list.creator.get_full_name }}</p>
+ <p class="todo-info">{{ list.created|date }} - {{ list.creator.get_full_name }}</p>
<div>{{list.description|urlize|linebreaks}}</div>
@@ -68,27 +68,22 @@
</thead>
<tbody>
{% for pkg in list.packages %}
- <tr class="{% cycle 'odd' 'even' %}{% if user in pkg.pkg.maintainers %} mine{% endif %} {{ pkg.pkg.arch.name }} {{ pkg.pkg.repo.name|lower }}">
- <td>{{ pkg.pkg.arch.name }}</td>
- <td>{{ pkg.pkg.repo.name|capfirst }}</td>
- <td>{% pkg_details_link pkg.pkg %}</td>
+ <tr class="{% cycle 'odd' 'even' %}{% if user in pkg.maintainers %} mine{% endif %} {{ pkg.arch.name }} {{ pkg.repo.name|lower }}">
+ <td>{{ pkg.arch.name }}</td>
+ <td>{{ pkg.repo.name|capfirst }}</td>
+ <td>{% pkg_details_link pkg.pkg pkg.pkgname %}</td>
{% if pkg.pkg.flag_date %}
<td><span class="flagged">{{ pkg.pkg.full_version }}</span></td>
{% else %}
<td>{{ pkg.pkg.full_version }}</td>
{% endif %}
- <td>{{ pkg.pkg.maintainers|join:', ' }}</td>
+ <td>{{ pkg.maintainers|join:', ' }}</td>
<td>
- {% if perms.main.change_todolistpkg %}
- {% if pkg.complete %}
+ {% if perms.todolist.change_todolistpackage %}
<a href="/todo/flag/{{ list.id }}/{{ pkg.id }}/"
- class="status-link complete" title="Toggle completion status">Complete</a>
+ class="status-link {{ pkg.status_css_class }}" title="Toggle completion status">{{ pkg.get_status_display }}</a>
{% else %}
- <a href="/todo/flag/{{ list.id }}/{{ pkg.id }}/"
- class="status-link incomplete" title="Toggle completion status">Incomplete</a>
- {% endif %}
- {% else %}
- {% if pkg.complete %}<span class="complete">Complete</span>{% else %}<span class="incomplete">Incomplete</span>{% endif %}
+ <span class="{{ pkg.status_css_class }}">{{ pkg.get_status_display }}</span>
{% endif %}
</td>
</tr>
diff --git a/todolists/urls.py b/todolists/urls.py
index a379468..81ac11f 100644
--- a/todolists/urls.py
+++ b/todolists/urls.py
@@ -11,7 +11,7 @@ urlpatterns = patterns('todolists.views',
(r'^edit/(?P<list_id>\d+)/$', 'edit'),
(r'^flag/(\d+)/(\d+)/$', 'flag'),
(r'^delete/(?P<pk>\d+)/$',
- permission_required('main.delete_todolist')(DeleteTodolist.as_view())),
+ permission_required('todolists.delete_todolist')(DeleteTodolist.as_view())),
)
# vim: set ts=4 sw=4 et:
diff --git a/todolists/utils.py b/todolists/utils.py
index 03c4793..d084c64 100644
--- a/todolists/utils.py
+++ b/todolists/utils.py
@@ -1,26 +1,26 @@
from django.db import connections, router
from django.db.models import Count
-from main.models import Todolist, TodolistPkg
+from .models import Todolist, TodolistPackage
def todo_counts():
sql = """
-SELECT list_id, count(*), sum(CASE WHEN complete THEN 1 ELSE 0 END)
- FROM todolist_pkgs
- GROUP BY list_id
+SELECT todolist_id, count(*), sum(CASE WHEN status = %s THEN 1 ELSE 0 END)
+ FROM todolists_todolistpackage
+ GROUP BY todolist_id
"""
- database = router.db_for_write(TodolistPkg)
+ database = router.db_for_write(TodolistPackage)
connection = connections[database]
cursor = connection.cursor()
- cursor.execute(sql)
+ cursor.execute(sql, [TodolistPackage.COMPLETE])
results = cursor.fetchall()
return {row[0]: (row[1], row[2]) for row in results}
def get_annotated_todolists(incomplete_only=False):
lists = Todolist.objects.all().select_related(
- 'creator').order_by('-date_added')
+ 'creator').order_by('-created')
lookup = todo_counts()
# tag each list with package counts
diff --git a/todolists/views.py b/todolists/views.py
index 9984ef9..9416439 100644
--- a/todolists/views.py
+++ b/todolists/views.py
@@ -10,39 +10,45 @@ from django.views.decorators.cache import never_cache
from django.views.generic import DeleteView
from django.template import Context, loader
-from main.models import Todolist, TodolistPkg, Package, Repo
+from main.models import Package, Repo
from packages.utils import attach_maintainers
+from .models import Todolist, TodolistPackage
from .utils import get_annotated_todolists
+
class TodoListForm(forms.ModelForm):
- packages = forms.CharField(required=False,
+ raw = forms.CharField(label='Packages', required=False,
help_text='(one per line)',
widget=forms.Textarea(attrs={'rows': '20', 'cols': '60'}))
- def clean_packages(self):
- package_names = [s.strip() for s in
- self.cleaned_data['packages'].split("\n")]
- package_names = set(package_names)
- packages = Package.objects.filter(pkgname__in=package_names).filter(
- repo__testing=False, repo__staging=False).select_related(
- 'arch', 'repo').order_by('arch')
- return packages
+ def packages(self):
+ package_names = {s.strip() for s in
+ self.cleaned_data['raw'].split("\n")}
+ return Package.objects.normal().filter(pkgname__in=package_names,
+ repo__testing=False, repo__staging=False).order_by('arch')
class Meta:
model = Todolist
- fields = ('name', 'description')
+ fields = ('name', 'description', 'raw')
+
-@permission_required('main.change_todolistpkg')
+@permission_required('todolists.change_todolistpackage')
@never_cache
def flag(request, list_id, pkg_id):
todolist = get_object_or_404(Todolist, id=list_id)
- pkg = get_object_or_404(TodolistPkg, id=pkg_id)
- pkg.complete = not pkg.complete
- pkg.save()
+ tlpkg = get_object_or_404(TodolistPackage, id=pkg_id)
+ # TODO: none of this; require absolute value on submit
+ if tlpkg.status == TodolistPackage.INCOMPLETE:
+ tlpkg.status = TodolistPackage.COMPLETE
+ else:
+ tlpkg.status = TodolistPackage.INCOMPLETE
+ tlpkg.save()
if request.is_ajax():
- return HttpResponse(
- json.dumps({'complete': pkg.complete}),
- mimetype='application/json')
+ data = {
+ 'status': tlpkg.get_status_display(),
+ 'css_class': tlpkg.status_css_class(),
+ }
+ return HttpResponse(json.dumps(data), mimetype='application/json')
return redirect(todolist)
@login_required
@@ -52,9 +58,9 @@ def view(request, list_id):
'svn_root', flat=True).order_by().distinct()
# we don't hold onto the result, but the objects are the same here,
# so accessing maintainers in the template is now cheap
- attach_maintainers(tp.pkg for tp in todolist.packages)
- arches = {tp.pkg.arch for tp in todolist.packages}
- repos = {tp.pkg.repo for tp in todolist.packages}
+ attach_maintainers(todolist.packages())
+ arches = {tp.arch for tp in todolist.packages()}
+ repos = {tp.repo for tp in todolist.packages()}
return render(request, 'todolists/view.html', {
'list': todolist,
'svn_roots': svn_roots,
@@ -67,9 +73,9 @@ def list_pkgbases(request, list_id, svn_root):
'''Used to make bulk moves of packages a lot easier.'''
todolist = get_object_or_404(Todolist, id=list_id)
repos = get_list_or_404(Repo, svn_root=svn_root)
- pkgbases = {tp.pkg.pkgbase for tp in todolist.packages
- if tp.pkg.repo in repos}
- return HttpResponse('\n'.join(sorted(pkgbases)),
+ pkgbases = TodolistPackage.objects.values_list('pkgbase', flat=True).filter(
+ todolist=todolist, repo__in=repos).distinct().order_by('pkgbase')
+ return HttpResponse('\n'.join(pkgbases),
mimetype='text/plain')
@login_required
@@ -77,7 +83,7 @@ def todolist_list(request):
lists = get_annotated_todolists()
return render(request, 'todolists/list.html', {'lists': lists})
-@permission_required('main.add_todolist')
+@permission_required('todolists.add_todolist')
@never_cache
def add(request):
if request.POST:
@@ -98,7 +104,7 @@ def add(request):
return render(request, 'general_form.html', page_dict)
# TODO: this calls for transaction management and async emailing
-@permission_required('main.change_todolist')
+@permission_required('todolists.change_todolist')
@never_cache
def edit(request, list_id):
todo_list = get_object_or_404(Todolist, id=list_id)
@@ -110,7 +116,7 @@ def edit(request, list_id):
return redirect(todo_list)
else:
form = TodoListForm(instance=todo_list,
- initial={ 'packages': '\n'.join(todo_list.package_names) })
+ initial={ 'packages': todo_list.raw })
page_dict = {
'title': 'Edit Todo List: %s' % todo_list.name,
@@ -128,7 +134,7 @@ class DeleteTodolist(DeleteView):
@transaction.commit_on_success
def create_todolist_packages(form, creator=None):
- packages = form.cleaned_data['packages']
+ packages = form.packages()
if creator:
# todo list is new
todolist = form.save(commit=False)
@@ -140,18 +146,22 @@ def create_todolist_packages(form, creator=None):
# todo list already existed
form.save()
todolist = form.instance
+
# first delete any packages not in the new list
- for todo_pkg in todolist.packages:
+ for todo_pkg in todolist.packages():
if todo_pkg.pkg not in packages:
todo_pkg.delete()
# save the old package list so we know what to add
- old_packages = [p.pkg for p in todolist.packages]
+ old_packages = [todo_pkg.pkg for todo_pkg in todolist.packages()]
todo_pkgs = []
for package in packages:
if package not in old_packages:
- todo_pkg = TodolistPkg.objects.create(list=todolist, pkg=package)
+ todo_pkg = TodolistPackage.objects.create(todolist=todolist,
+ pkg=package, pkgname=package.pkgname,
+ pkgbase=package.pkgbase,
+ arch=package.arch, repo=package.repo)
todo_pkgs.append(todo_pkg)
return todo_pkgs
@@ -186,8 +196,8 @@ def send_todolist_emails(todo_list, new_packages):
def public_list(request):
todo_lists = Todolist.objects.incomplete()
# total hackjob, but it makes this a lot less query-intensive.
- all_pkgs = [tp for tl in todo_lists for tp in tl.packages]
- attach_maintainers([tp.pkg for tp in all_pkgs])
+ all_pkgs = [tp for tl in todo_lists for tp in tl.packages()]
+ attach_maintainers(all_pkgs)
return render(request, "todolists/public_list.html",
{"todo_lists": todo_lists})