From 18e86f50bfa33997cf54733c7d24840cdec4e7aa Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Thu, 6 Jan 2011 10:25:00 -0600
Subject: Update readme
Signed-off-by: Dan McGee
---
README | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/README b/README
index dc43e9da..6b492d84 100644
--- a/README
+++ b/README
@@ -33,37 +33,41 @@ packages, you will probably want the following:
1. Run `virtualenv`.
- $ cd /path/to/archweb && virtualenv ../archweb
+ $ cd /path/to/archweb && virtualenv ../archweb-env
+
+2. Source the virtualenv.
+
+ $ . ../archweb-env/bin/activate
2. Install dependencies through `pip`.
- $ pip install -r requirements.txt
+ (archweb-env) $ pip install -r requirements.txt
3. Copy `local_settings.py.example` to `local_settings.py` and modify.
Make sure to uncomment the appropriate db section (either sqlite or mysql).
4. Sync the database to create it.
- $ ./manage.py syncdb
+ (archweb-env) $ ./manage.py syncdb
5. Migrate changes.
- $ ./manage.py migrate
+ (archweb-env) $ ./manage.py migrate
6. Load the fixtures to prepopulate some data.
- $ ./manage.py loaddata main/fixtures/arches.json
- # ./manage.py loaddata main/fixtures/repos.json
- # ./manage.py loaddata mirrors/fixtures/mirrorprotocols.json
+ (archweb-env) $ ./manage.py loaddata main/fixtures/arches.json
+ (archweb-env) $ ./manage.py loaddata main/fixtures/repos.json
+ (archweb-env) $ ./manage.py loaddata mirrors/fixtures/mirrorprotocols.json
7. Use the following commands to start a service instance
- $ ./manage.py runserver
+ (archweb-env) $ ./manage.py runserver
8. To optionally populate the database with real data:
- $ wget ftp://ftp.archlinux.org/core/os/i686/core.db.tar.gz
- $ ./manage.py reporead i686 core.db.tar.gz
+ (archweb-env) $ wget ftp://ftp.archlinux.org/core/os/i686/core.db.tar.gz
+ (archweb-env) $ ./manage.py reporead i686 core.db.tar.gz
Alter architecture and repo to get x86\_64 and packages from other repos if needed.
--
cgit v1.2.3-2-g168b
From d8b1f9982466a4a4e8c224f335767084a5c6a301 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Thu, 6 Jan 2011 10:28:06 -0600
Subject: Remove default admins
Set them in local_settings instead.
Signed-off-by: Dan McGee
---
settings.py | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/settings.py b/settings.py
index f98f709c..6b6e0cc6 100644
--- a/settings.py
+++ b/settings.py
@@ -6,9 +6,7 @@ DEBUG = False
TEMPLATE_DEBUG = DEBUG
## Notification admins
-ADMINS = (
- ('Dan McGee', 'dan@archlinux.org'),
-)
+ADMINS = ()
# Set managers to admins
MANAGERS = ADMINS
--
cgit v1.2.3-2-g168b
From 8d7941c1ddc40623d7050bb0809453603f6ccad9 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Thu, 6 Jan 2011 10:30:46 -0600
Subject: Settings file tweaks
Signed-off-by: Dan McGee
---
settings.py | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/settings.py b/settings.py
index 6b6e0cc6..8e916e36 100644
--- a/settings.py
+++ b/settings.py
@@ -29,14 +29,6 @@ DEFAULT_CHARSET = 'utf-8'
SITE_ID = 1
-# If you set this to False, Django will make some optimizations so as not
-# to load the internationalization machinery.
-USE_I18N = False
-
-# If you set this to False, Django will not format dates, numbers and
-# calendars according to the current locale
-USE_L10N = False
-
# Default date format in templates for 'date' filter
DATE_FORMAT = 'Y-m-d'
@@ -45,10 +37,13 @@ DATE_FORMAT = 'Y-m-d'
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/admin_media/'
-# login url
+# Login URL configuration
LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/'
+# Set django's User stuff to use our profile model
+AUTH_PROFILE_MODULE = 'main.UserProfile'
+
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
@@ -94,12 +89,8 @@ TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.Loader',
)
-# Set django's User stuff to use our profile model
-# format is app.model
-AUTH_PROFILE_MODULE = 'main.UserProfile'
-
+# Configure where sessions and messages should reside
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
-
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
INSTALLED_APPS = (
--
cgit v1.2.3-2-g168b
From bf3893768c42e7c0d4f4205819ef4e5ada1b2707 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Sat, 8 Jan 2011 11:05:10 -0600
Subject: Add pytz as a project requirement
Signed-off-by: Dan McGee
---
requirements.txt | 1 +
requirements_prod.txt | 1 +
2 files changed, 2 insertions(+)
diff --git a/requirements.txt b/requirements.txt
index f4d80eeb..ba21a59a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
Django==1.2.4
Markdown==2.0.3
South==0.7.3
+pytz>=2010o
diff --git a/requirements_prod.txt b/requirements_prod.txt
index 49ca44c4..b8665f35 100644
--- a/requirements_prod.txt
+++ b/requirements_prod.txt
@@ -3,3 +3,4 @@ Markdown==2.0.3
MySQL-python==1.2.3c1
South==0.7.3
python-memcached==1.47
+pytz>=2010o
--
cgit v1.2.3-2-g168b
From 9a1971e24fe15ccdb74f3a8a59d735504f2797be Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Sat, 8 Jan 2011 11:41:59 -0600
Subject: Add time zone field to developer profile
This will be used by the developer world clock page soon to come. Default
everyone to "UTC" for now.
Signed-off-by: Dan McGee
---
.../0037_auto__add_field_userprofile_time_zone.py | 154 +++++++++++++++++++++
main/models.py | 9 +-
2 files changed, 161 insertions(+), 2 deletions(-)
create mode 100644 main/migrations/0037_auto__add_field_userprofile_time_zone.py
diff --git a/main/migrations/0037_auto__add_field_userprofile_time_zone.py b/main/migrations/0037_auto__add_field_userprofile_time_zone.py
new file mode 100644
index 00000000..9b9b8beb
--- /dev/null
+++ b/main/migrations/0037_auto__add_field_userprofile_time_zone.py
@@ -0,0 +1,154 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'UserProfile.time_zone'
+ db.add_column('user_profiles', 'time_zone', self.gf('django.db.models.fields.CharField')(default='UTC', max_length=100), keep_default=False)
+
+ def backwards(self, orm):
+ # Deleting field 'UserProfile.time_zone'
+ db.delete_column('user_profiles', 'time_zone')
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'main.arch': {
+ 'Meta': {'ordering': "['name']", 'object_name': 'Arch', 'db_table': "'arches'"},
+ 'agnostic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+ },
+ 'main.donor': {
+ 'Meta': {'ordering': "['name']", 'object_name': 'Donor', 'db_table': "'donors'"},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
+ },
+ 'main.package': {
+ 'Meta': {'ordering': "('pkgname',)", 'object_name': 'Package', 'db_table': "'packages'"},
+ 'arch': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'to': "orm['main.Arch']"}),
+ 'build_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+ 'compressed_size': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}),
+ 'filename': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'files_last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'flag_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'installed_size': ('django.db.models.fields.BigIntegerField', [], {'null': 'True'}),
+ 'last_update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'license': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ 'packager': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'packager_str': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'pkgbase': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'pkgdesc': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+ 'pkgname': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'pkgrel': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'pkgver': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'repo': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'packages'", 'to': "orm['main.Repo']"}),
+ 'url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'})
+ },
+ 'main.packagedepend': {
+ 'Meta': {'object_name': 'PackageDepend', 'db_table': "'package_depends'"},
+ 'depname': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'depvcmp': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"})
+ },
+ 'main.packagefile': {
+ 'Meta': {'object_name': 'PackageFile', 'db_table': "'package_files'"},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"})
+ },
+ 'main.repo': {
+ 'Meta': {'ordering': "['name']", 'object_name': 'Repo', 'db_table': "'repos'"},
+ 'bugs_project': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'svn_root': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+ 'testing': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'main.signoff': {
+ 'Meta': {'object_name': 'Signoff'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'packager': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"}),
+ 'pkgrel': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'pkgver': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+ },
+ 'main.todolist': {
+ 'Meta': {'object_name': 'Todolist', 'db_table': "'todolists'"},
+ 'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'date_added': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'description': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+ },
+ 'main.todolistpkg': {
+ 'Meta': {'unique_together': "(('list', 'pkg'),)", 'object_name': 'TodolistPkg', 'db_table': "'todolist_pkgs'"},
+ 'complete': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'list': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Todolist']"}),
+ 'pkg': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['main.Package']"})
+ },
+ 'main.userprofile': {
+ 'Meta': {'object_name': 'UserProfile', 'db_table': "'user_profiles'"},
+ 'alias': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'allowed_repos': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['main.Repo']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'favorite_distros': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'interests': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'languages': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'location': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'notify': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'occupation': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'other_contact': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'picture': ('django.db.models.fields.files.FileField', [], {'default': "'devs/silhouette.png'", 'max_length': '100'}),
+ 'public_email': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'roles': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+ 'time_zone': ('django.db.models.fields.CharField', [], {'default': "'UTC'", 'max_length': '100'}),
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'userprofile'", 'unique': 'True', 'to': "orm['auth.User']"}),
+ 'website': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'yob': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ }
+ }
+
+ complete_apps = ['main']
diff --git a/main/models.py b/main/models.py
index 8858b17b..0e9e55a1 100644
--- a/main/models.py
+++ b/main/models.py
@@ -2,18 +2,23 @@ from django.db import models
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
-from main.utils import cache_function
+from main.utils import cache_function, make_choice
from packages.models import PackageRelation
from itertools import groupby
+import pytz
from operator import attrgetter
class UserProfile(models.Model):
- id = models.AutoField(primary_key=True) # not technically needed
notify = models.BooleanField(
"Send notifications",
default=True,
help_text="When enabled, send user 'flag out-of-date' notifications")
+ time_zone = models.CharField(
+ max_length=100,
+ choices=make_choice(pytz.all_timezones),
+ default="UTC",
+ help_text="Used for developer clock page")
alias = models.CharField(
max_length=50,
help_text="Required field")
--
cgit v1.2.3-2-g168b
From c04d4abc88cdf0891bff2b1ce6d1d746c5b9b3c9 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Sat, 8 Jan 2011 11:47:11 -0600
Subject: Add developer world clocks page
This should make it easier for everyone to figure out whether someone is
awake, sleeping, and all that fun stuff. It does require everyone to update
their profile and fill in the field, but that shouldn't be too hard of a
task.
Don't suggest jokes to me Saturday morning on IRC unless you really want to
see them implemented. Thanks, Pierre!
Signed-off-by: Dan McGee
---
devel/urls.py | 1 +
devel/views.py | 25 ++++++++++++++++++++++-
templates/devel/clock.html | 49 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 74 insertions(+), 1 deletion(-)
create mode 100644 templates/devel/clock.html
diff --git a/devel/urls.py b/devel/urls.py
index 23dd2d9f..0a050a92 100644
--- a/devel/urls.py
+++ b/devel/urls.py
@@ -2,6 +2,7 @@ from django.conf.urls.defaults import patterns
urlpatterns = patterns('devel.views',
(r'^$', 'index'),
+ (r'^clock/$', 'clock'),
(r'^notify/$', 'change_notify'),
(r'^profile/$', 'change_profile'),
(r'^newuser/$', 'new_user_form'),
diff --git a/devel/views.py b/devel/views.py
index 710bfff5..b26c7af0 100644
--- a/devel/views.py
+++ b/devel/views.py
@@ -13,6 +13,8 @@ from main.models import UserProfile
from packages.models import PackageRelation
from .utils import get_annotated_maintainers
+import datetime
+import pytz
import random
from string import ascii_letters, digits
@@ -38,10 +40,31 @@ def index(request):
'maintainers': maintainers,
'flagged' : flagged,
'todopkgs' : todopkgs,
- }
+ }
return direct_to_template(request, 'devel/index.html', page_dict)
+@login_required
+@never_cache
+def clock(request):
+ devs = User.objects.filter(is_active=True).order_by(
+ 'username').select_related('userprofile')
+
+ # now annotate each dev object with their current time
+ now = datetime.datetime.now()
+ utc_now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
+ for dev in devs:
+ tz = pytz.timezone(dev.userprofile.time_zone)
+ dev.current_time = utc_now.astimezone(tz)
+
+ page_dict = {
+ 'developers': devs,
+ 'now': now,
+ 'utc_now': utc_now,
+ }
+
+ return direct_to_template(request, 'devel/clock.html', page_dict)
+
@login_required
def change_notify(request):
maint = User.objects.get(username=request.user.username)
diff --git a/templates/devel/clock.html b/templates/devel/clock.html
new file mode 100644
index 00000000..ec567c2d
--- /dev/null
+++ b/templates/devel/clock.html
@@ -0,0 +1,49 @@
+{% extends "base.html" %}
+
+{% block title %}Arch Linux - Developer World Clocks{% endblock %}
+
+{% block content %}
+
+
Developer World Clocks
+
+
This page helps prevent you from waking a sleeping developer. It also
+ depends on developers keeping the time zone information up to date, so if
+ you see 'UTC' listed, pester them to update their settings.
+
+ Arch Server Time: {{ now|date:"Y-m-d H:i" }}
+ UTC Time: {{ utc_now|date:"Y-m-d H:i" }}
+
+
+
+
+
+ Developer |
+ Username |
+ Location |
+ Time Zone |
+ Current Time |
+
+
+
+ {% for dev in developers %}
+
+ {{ dev.get_full_name }} |
+ {{ dev.username }} |
+ {{ dev.userprofile.location }} |
+ {{ dev.userprofile.time_zone }} |
+ {{ dev.current_time|date:"Y-m-d H:i" }} |
+
+ {% endfor %}
+
+
+
+{% load cdn %}{% jquery %}
+
+
+
+{% endblock %}
--
cgit v1.2.3-2-g168b
From c18cd21e536592b6ed482126ee423f38b9ac9257 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Tue, 21 Dec 2010 19:02:22 -0600
Subject: Remove automatic ID column definitions
Signed-off-by: Dan McGee
---
main/models.py | 9 ---------
news/models.py | 1 -
2 files changed, 10 deletions(-)
diff --git a/main/models.py b/main/models.py
index 8858b17b..61282153 100644
--- a/main/models.py
+++ b/main/models.py
@@ -9,7 +9,6 @@ from itertools import groupby
from operator import attrgetter
class UserProfile(models.Model):
- id = models.AutoField(primary_key=True) # not technically needed
notify = models.BooleanField(
"Send notifications",
default=True,
@@ -49,7 +48,6 @@ class PackageManager(models.Manager):
class Donor(models.Model):
- id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, unique=True)
visible = models.BooleanField(default=True,
help_text="Should we show this donor on the public page?")
@@ -62,7 +60,6 @@ class Donor(models.Model):
ordering = ['name']
class Arch(models.Model):
- id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, unique=True)
agnostic = models.BooleanField(default=False,
help_text="Is this architecture non-platform specific?")
@@ -79,7 +76,6 @@ class Arch(models.Model):
verbose_name_plural = 'arches'
class Repo(models.Model):
- id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, unique=True)
testing = models.BooleanField(default=False,
help_text="Is this repo meant for package testing?")
@@ -100,7 +96,6 @@ class Repo(models.Model):
verbose_name_plural = 'repos'
class Package(models.Model):
- id = models.AutoField(primary_key=True)
repo = models.ForeignKey(Repo, related_name="packages")
arch = models.ForeignKey(Arch, related_name="packages")
pkgname = models.CharField(max_length=255, db_index=True)
@@ -308,14 +303,12 @@ class Signoff(models.Model):
packager = models.ForeignKey(User)
class PackageFile(models.Model):
- id = models.AutoField(primary_key=True)
pkg = models.ForeignKey('Package')
path = models.CharField(max_length=255)
class Meta:
db_table = 'package_files'
class PackageDepend(models.Model):
- id = models.AutoField(primary_key=True)
pkg = models.ForeignKey('Package')
depname = models.CharField(db_index=True, max_length=255)
depvcmp = models.CharField(max_length=255)
@@ -323,7 +316,6 @@ class PackageDepend(models.Model):
db_table = 'package_depends'
class Todolist(models.Model):
- id = models.AutoField(primary_key=True)
creator = models.ForeignKey(User)
name = models.CharField(max_length=255)
description = models.TextField()
@@ -351,7 +343,6 @@ class Todolist(models.Model):
return '/todo/%i/' % self.id
class TodolistPkg(models.Model):
- id = models.AutoField(primary_key=True)
list = models.ForeignKey('Todolist')
pkg = models.ForeignKey('Package')
complete = models.BooleanField(default=False)
diff --git a/news/models.py b/news/models.py
index e2486c96..c2d644b7 100644
--- a/news/models.py
+++ b/news/models.py
@@ -2,7 +2,6 @@ from django.db import models
from django.contrib.auth.models import User
class News(models.Model):
- id = models.AutoField(primary_key=True)
slug = models.SlugField(max_length=255, unique=True)
author = models.ForeignKey(User, related_name='news_author')
postdate = models.DateTimeField("post date", auto_now_add=True, db_index=True)
--
cgit v1.2.3-2-g168b
From 139181399e43fc25b99482cfb8acd80934e1ed52 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Sat, 8 Jan 2011 12:14:37 -0600
Subject: Link to dev clocks page
Signed-off-by: Dan McGee
---
templates/base.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/templates/base.html b/templates/base.html
index c7b26a9e..03795dd9 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -39,7 +39,7 @@
News
Signoffs
Todos
- Arch Differences
+ Dev Clocks
Archives
Mirrors
--
cgit v1.2.3-2-g168b
From ef016929a9863810cb0e9078c13bd1142922a63d Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Sat, 8 Jan 2011 12:31:22 -0600
Subject: Add time zone format spec to clock page
Signed-off-by: Dan McGee
---
templates/devel/clock.html | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/templates/devel/clock.html b/templates/devel/clock.html
index ec567c2d..1bc9a849 100644
--- a/templates/devel/clock.html
+++ b/templates/devel/clock.html
@@ -10,8 +10,8 @@
depends on developers keeping the time zone information up to date, so if
you see 'UTC' listed, pester them to update their settings.
- Arch Server Time: {{ now|date:"Y-m-d H:i" }}
- UTC Time: {{ utc_now|date:"Y-m-d H:i" }}
+ Arch Server Time: {{ now|date:"Y-m-d H:i T" }}
+ UTC Time: {{ utc_now|date:"Y-m-d H:i T" }}
@@ -31,7 +31,7 @@
{{ dev.username }} |
{{ dev.userprofile.location }} |
{{ dev.userprofile.time_zone }} |
- {{ dev.current_time|date:"Y-m-d H:i" }} |
+ {{ dev.current_time|date:"Y-m-d H:i T" }} |
{% endfor %}
--
cgit v1.2.3-2-g168b
From ec5649fada6d91ea7d1a75efe7e42699d0f0f7b6 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Sat, 8 Jan 2011 17:38:26 -0600
Subject: Use common timezones only
No need to show historical and deprecated zone names.
Signed-off-by: Dan McGee
---
main/models.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/main/models.py b/main/models.py
index 7ce2d2f4..ff2ecf02 100644
--- a/main/models.py
+++ b/main/models.py
@@ -16,7 +16,7 @@ class UserProfile(models.Model):
help_text="When enabled, send user 'flag out-of-date' notifications")
time_zone = models.CharField(
max_length=100,
- choices=make_choice(pytz.all_timezones),
+ choices=make_choice(pytz.common_timezones),
default="UTC",
help_text="Used for developer clock page")
alias = models.CharField(
--
cgit v1.2.3-2-g168b
From 09bccb50e7c1bcbe15ca4f0e26c2f82cd816accb Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Sat, 8 Jan 2011 18:40:47 -0600
Subject: Only match full text on built-in short date parser
Signed-off-by: Dan McGee
---
media/jquery.tablesorter.min.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/media/jquery.tablesorter.min.js b/media/jquery.tablesorter.min.js
index 64c70071..7d54b3bc 100644
--- a/media/jquery.tablesorter.min.js
+++ b/media/jquery.tablesorter.min.js
@@ -1,2 +1,2 @@
-(function($){$.extend({tablesorter:new function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'.',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}var rows=table.tBodies[0].rows;if(table.tBodies[0].rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;ib)?1:0));};function sortTextDesc(a,b){return((ba)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){$this.trigger("sortStart");var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){var $cell=$(this);var i=this.column;this.order=this.count++%2;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;ib)?1:0));};function sortTextDesc(a,b){return((ba)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){$this.trigger("sortStart");var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){var $cell=$(this);var i=this.column;this.order=this.count++%2;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i
Date: Sat, 8 Jan 2011 18:41:23 -0600
Subject: Add a long datetime parser to table sorting code
This comes into play on our new developer clocks page, where the last column
was not sorting at all as expected.
Signed-off-by: Dan McGee
---
media/archweb.js | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/media/archweb.js b/media/archweb.js
index c5025ded..1c80ab64 100644
--- a/media/archweb.js
+++ b/media/archweb.js
@@ -36,18 +36,34 @@ if(typeof $.tablesorter !== "undefined") {
$.tablesorter.addParser({
/* sorts duration; put '', 'unknown', and '∞' last. */
id: 'duration',
- is: function(s,table) {
+ re: /^([0-9]+):([0-5][0-9])$/,
+ is: function(s) {
var special = ['', 'unknown', '∞'];
- return ($.inArray(s, special) > -1) || /^[0-9]+:[0-5][0-9]$/.test(s);
+ return ($.inArray(s, special) > -1) || this.re.test(s);
},
format: function(s) {
var special = ['', 'unknown', '∞'];
if($.inArray(s, special) > -1) return Number.MAX_VALUE;
- matches = /^([0-9]+):([0-5][0-9])$/.exec(s);
+ var matches = this.re.exec(s);
return matches[1] * 60 + matches[2];
},
type: 'numeric'
});
+ $.tablesorter.addParser({
+ id: 'longDateTime',
+ re: /^(\d{4})-(\d{2})-(\d{2}) ([012]\d):([0-5]\d)(:([0-5]\d))?( (\w+))?$/,
+ is: function (s) {
+ return this.re.test(s);
+ },
+ format: function (s) {
+ var matches = this.re.exec(s);
+ /* skip group 6, group 7 is optional seconds */
+ if(matches[7] == undefined) matches[7] = "0";
+ return $.tablesorter.formatFloat(new Date(
+ matches[1],matches[2],matches[3],matches[4],matches[5],matches[7]).getTime());
+ },
+ type: "numeric"
+ });
}
/* news/add.html */
--
cgit v1.2.3-2-g168b