From 7896779ff18b304f8246c24123b8cbf9b82ec5b0 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Fri, 23 Mar 2012 17:46:10 -0500
Subject: Bump requirements to Django 1.4 and add new manage.py
The default manage.py script has been updated in Django 1.4, and the old
version and functions it calls is deprecated.
Signed-off-by: Dan McGee
---
manage.py | 16 ++++++----------
requirements.txt | 6 +++---
requirements_prod.txt | 6 +++---
3 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/manage.py b/manage.py
index 317dd156..debb55e5 100755
--- a/manage.py
+++ b/manage.py
@@ -1,16 +1,12 @@
#!/usr/bin/env python2
+import os
+import sys
-from django.core.management import execute_manager
+if __name__ == "__main__":
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
-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" % __file__)
- sys.exit(1)
+ from django.core.management import execute_from_command_line
-if __name__ == "__main__":
- execute_manager(settings)
+ execute_from_command_line(sys.argv)
# vim: set ts=4 sw=4 et:
-
diff --git a/requirements.txt b/requirements.txt
index 83355a9e..1c1578cb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,5 @@
-Django==1.3.1
+Django==1.4
Markdown==2.1.1
-South==0.7.3
+South==0.7.4
pgpdump==1.1
-pytz>=2011n
+pytz>=2012b
diff --git a/requirements_prod.txt b/requirements_prod.txt
index ebac73ca..7f7663a8 100644
--- a/requirements_prod.txt
+++ b/requirements_prod.txt
@@ -1,8 +1,8 @@
-Django==1.3.1
+Django==1.4
Markdown==2.1.1
MySQL-python==1.2.3
-South==0.7.3
+South==0.7.4
pgpdump==1.1
pyinotify==0.9.3
python-memcached==1.48
-pytz>=2011n
+pytz>=2012b
--
cgit v1.2.3-54-g00ecf
From 6218ccc570c674bfaaf1c636382ac6f9adbf212b Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Fri, 23 Mar 2012 17:48:43 -0500
Subject: Use python hashlib directly
Django hashcompat is now deprecated.
Signed-off-by: Dan McGee
---
feeds.py | 6 +++---
main/utils.py | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/feeds.py b/feeds.py
index 74ae9ff9..ee856f62 100644
--- a/feeds.py
+++ b/feeds.py
@@ -1,10 +1,10 @@
+import hashlib
import pytz
from django.contrib.sites.models import Site
from django.contrib.syndication.views import Feed
from django.db.models import Q
from django.utils.feedgenerator import Rss201rev2Feed
-from django.utils.hashcompat import md5_constructor
from django.views.decorators.http import condition
from main.utils import retrieve_latest
@@ -32,7 +32,7 @@ def write_items(self, handler):
def package_etag(request, *args, **kwargs):
latest = retrieve_latest(Package)
if latest:
- return md5_constructor(str(kwargs) + str(latest)).hexdigest()
+ return hashlib.md5(str(kwargs) + str(latest)).hexdigest()
return None
def package_last_modified(request, *args, **kwargs):
@@ -108,7 +108,7 @@ def item_categories(self, item):
def news_etag(request, *args, **kwargs):
latest = retrieve_latest(News)
if latest:
- return md5_constructor(str(latest)).hexdigest()
+ return hashlib.md5(str(latest)).hexdigest()
return None
def news_last_modified(request, *args, **kwargs):
diff --git a/main/utils.py b/main/utils.py
index 81f689e7..03441c15 100644
--- a/main/utils.py
+++ b/main/utils.py
@@ -4,9 +4,9 @@
import pickle
from datetime import datetime
+import hashlib
from django.core.cache import cache
-from django.utils.hashcompat import md5_constructor
CACHE_TIMEOUT = 1800
INVALIDATE_TIMEOUT = 10
@@ -15,7 +15,7 @@
def cache_function_key(func, args, kwargs):
raw = [func.__name__, func.__module__, args, kwargs]
pickled = pickle.dumps(raw, protocol=pickle.HIGHEST_PROTOCOL)
- key = md5_constructor(pickled).hexdigest()
+ key = hashlib.md5(pickled).hexdigest()
return 'cache_function.' + func.__name__ + '.' + key
def cache_function(length):
--
cgit v1.2.3-54-g00ecf
From 5575b68272f1bc773f98ecdfd679e58e8be2ac9b Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Fri, 23 Mar 2012 17:59:54 -0500
Subject: reporead: use Django 1.4 select_for_update()
As per TODO comments in the existing code.
Signed-off-by: Dan McGee
---
devel/management/commands/reporead.py | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py
index 8369b6ec..ebf17111 100644
--- a/devel/management/commands/reporead.py
+++ b/devel/management/commands/reporead.py
@@ -286,17 +286,6 @@ def populate_files(dbpkg, repopkg, force=False):
dbpkg.save()
-def select_pkg_for_update(dbpkg):
- database = router.db_for_write(Package, instance=dbpkg)
- connection = connections[database]
- if 'sqlite' in connection.settings_dict['ENGINE'].lower():
- return dbpkg
- new_pkg = Package.objects.raw(
- 'SELECT * FROM packages WHERE id = %s FOR UPDATE',
- [dbpkg.id])
- return list(new_pkg)[0]
-
-
def update_common(archname, reponame, pkgs, sanity_check=True):
# If isolation level is repeatable-read, we need to ensure each package
# update starts a new transaction and re-queries the database as
@@ -396,8 +385,7 @@ def db_update(archname, reponame, pkgs, force=False):
# simultaneous updates don't happen on a package, causing
# files/depends/all related items to be double-imported.
with transaction.commit_on_success():
- # TODO Django 1.4 select_for_update() will work once released
- dbpkg = select_pkg_for_update(dbpkg)
+ dbpkg = Package.objects.select_for_update().get(id=dbpkg.id)
if not force and pkg_same_version(pkg, dbpkg):
logger.debug("Package %s was already updated", pkg.name)
continue
@@ -428,8 +416,7 @@ def filesonly_update(archname, reponame, pkgs, force=False):
elif not force and dbpkg.files_last_update > dbpkg.last_update:
logger.debug("Files for %s are up to date", pkg.name)
continue
- # TODO Django 1.4 select_for_update() will work once released
- dbpkg = select_pkg_for_update(dbpkg)
+ dbpkg = Package.objects.select_for_update().get(id=dbpkg.id)
logger.debug("Checking files for package %s", pkg.name)
populate_files(dbpkg, pkg, force=force)
--
cgit v1.2.3-54-g00ecf
From 95520ae26485e5c62ea1431ca82a7b42d01b923a Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Fri, 23 Mar 2012 18:03:28 -0500
Subject: reporead: use Django 1.4 bulk_create() for package files
Signed-off-by: Dan McGee
---
devel/management/commands/reporead.py | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py
index ebf17111..a8c58ba7 100644
--- a/devel/management/commands/reporead.py
+++ b/devel/management/commands/reporead.py
@@ -270,18 +270,17 @@ def populate_files(dbpkg, repopkg, force=False):
delete_pkg_files(dbpkg)
logger.info("adding %d files for package %s",
len(repopkg.files), dbpkg.pkgname)
+ pkg_files = []
for f in repopkg.files:
dirname, filename = f.rsplit('/', 1)
if filename == '':
filename = None
- # this is basically like calling dbpkg.packagefile_set.create(),
- # but much faster as we can skip a lot of the repeated code paths
- # TODO use Django 1.4 bulk_create
pkgfile = PackageFile(pkg=dbpkg,
is_directory=(filename is None),
directory=dirname + '/',
filename=filename)
- pkgfile.save(force_insert=True)
+ pkg_files.append(pkgfile)
+ PackageFile.objects.bulk_create(pkg_files)
dbpkg.files_last_update = datetime.utcnow()
dbpkg.save()
--
cgit v1.2.3-54-g00ecf
From 0545e3e0ec864eaed4facc94158e3ed9da1dfb2b Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Fri, 23 Mar 2012 18:23:17 -0500
Subject: Django 1.4 admin and admin media changes
Signed-off-by: Dan McGee
---
templates/admin/index.html | 10 +++++-----
templates/devel/admin_log.html | 4 ++--
templates/packages/search.html | 12 ++++++++----
3 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/templates/admin/index.html b/templates/admin/index.html
index 1755d86f..203206d5 100644
--- a/templates/admin/index.html
+++ b/templates/admin/index.html
@@ -1,7 +1,7 @@
{% extends "admin/base_site.html" %}
-{% load i18n %}
+{% load i18n admin_static %}
-{% block extrastyle %}{{ block.super }} {% endblock %}
+{% block extrastyle %}{{ block.super }} {% endblock %}
{% block coltype %}colMS{% endblock %}
@@ -36,19 +36,19 @@
{% blocktrans with name=app.name %}{{ name }}{% endblocktrans %}
{% for model in app.models %}
- {% if model.perms.change %}
+ {% if model.admin_url %}
{{ model.name }}
{% else %}
{{ model.name }}
{% endif %}
- {% if model.perms.add %}
+ {% if model.add_url %}
{% trans 'Add' %}
{% else %}
{% endif %}
- {% if model.perms.change %}
+ {% if model.admin_url %}
{% trans 'Change' %}
{% else %}
diff --git a/templates/devel/admin_log.html b/templates/devel/admin_log.html
index 0f22ba2b..1629c104 100644
--- a/templates/devel/admin_log.html
+++ b/templates/devel/admin_log.html
@@ -1,7 +1,7 @@
{% extends "admin/base_site.html" %}
-{% load i18n %}
+{% load i18n admin_static %}
-{% block extrastyle %}{{ block.super }} {% endblock %}
+{% block extrastyle %}{{ block.super }} {% endblock %}
{% block breadcrumbs %}{% endblock %}
diff --git a/templates/packages/search.html b/templates/packages/search.html
index ae67b184..030f2671 100644
--- a/templates/packages/search.html
+++ b/templates/packages/search.html
@@ -1,13 +1,13 @@
{% extends "base.html" %}
{% load package_extras %}
-{% load adminmedia %}
+{% load admin_static %}
{% block title %}Arch Linux - Package Database{% endblock %}
{% block navbarclass %}anb-packages{% endblock %}
{% block head %}
{% if is_paginated and page_obj.number > 1 %} {% endif %}
-
+
{% endblock %}
{% block content %}
@@ -126,8 +126,12 @@ Package Search
title="AUR package database">Arch User Repository (AUR).
+{% load cdn %}{% jquery %}
-
-
+
+
{{search_form.media}}
{% endblock %}
--
cgit v1.2.3-54-g00ecf
From b8c20439c091aaa56e772441e6c3a7e57e8ef2d4 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Fri, 23 Mar 2012 18:29:42 -0500
Subject: Change Django urls.py import
Until Django 1.3, the functions include(), patterns() and url() plus
handler404, handler500 were located in a django.conf.urls.defaults
module.
In Django 1.4, they live in django.conf.urls.
Signed-off-by: Dan McGee
---
devel/urls.py | 2 +-
mirrors/urls.py | 2 +-
mirrors/urls_mirrorlist.py | 2 +-
news/urls.py | 2 +-
packages/urls.py | 2 +-
packages/urls_groups.py | 2 +-
releng/urls.py | 2 +-
todolists/urls.py | 2 +-
urls.py | 2 +-
visualize/urls.py | 2 +-
10 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/devel/urls.py b/devel/urls.py
index 07cb321b..31afc86b 100644
--- a/devel/urls.py
+++ b/devel/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import patterns
+from django.conf.urls import patterns
urlpatterns = patterns('devel.views',
(r'^admin_log/$','admin_log'),
diff --git a/mirrors/urls.py b/mirrors/urls.py
index fed9c807..f002e9d6 100644
--- a/mirrors/urls.py
+++ b/mirrors/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import patterns
+from django.conf.urls import patterns
urlpatterns = patterns('mirrors.views',
(r'^$', 'mirrors', {}, 'mirror-list'),
diff --git a/mirrors/urls_mirrorlist.py b/mirrors/urls_mirrorlist.py
index 70bc18d2..e0f44c78 100644
--- a/mirrors/urls_mirrorlist.py
+++ b/mirrors/urls_mirrorlist.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import patterns
+from django.conf.urls import patterns
urlpatterns = patterns('mirrors.views',
(r'^$', 'generate_mirrorlist', {}, 'mirrorlist'),
diff --git a/news/urls.py b/news/urls.py
index d938ef58..10020f31 100644
--- a/news/urls.py
+++ b/news/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import patterns
+from django.conf.urls import patterns
urlpatterns = patterns('news.views',
(r'^$', 'news_list', {}, 'news-list'),
diff --git a/packages/urls.py b/packages/urls.py
index 52b09d2c..7e12a239 100644
--- a/packages/urls.py
+++ b/packages/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import include, patterns
+from django.conf.urls import include, patterns
package_patterns = patterns('packages.views',
(r'^$', 'details'),
diff --git a/packages/urls_groups.py b/packages/urls_groups.py
index d609944b..49ced145 100644
--- a/packages/urls_groups.py
+++ b/packages/urls_groups.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import patterns
+from django.conf.urls import patterns
urlpatterns = patterns('packages.views',
(r'^$', 'groups', {}, 'groups-list'),
diff --git a/releng/urls.py b/releng/urls.py
index 239ad02b..8d1b8f24 100644
--- a/releng/urls.py
+++ b/releng/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import include, patterns
+from django.conf.urls import include, patterns
feedback_patterns = patterns('releng.views',
(r'^$', 'test_results_overview', {}, 'releng-test-overview'),
diff --git a/todolists/urls.py b/todolists/urls.py
index 0bd8817b..a379468f 100644
--- a/todolists/urls.py
+++ b/todolists/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import patterns
+from django.conf.urls import patterns
from django.contrib.auth.decorators import permission_required
from .views import DeleteTodolist
diff --git a/urls.py b/urls.py
index a061f030..9b9b4559 100644
--- a/urls.py
+++ b/urls.py
@@ -1,7 +1,7 @@
import os.path
# Stupid Django. Don't remove these "unused" handler imports
-from django.conf.urls.defaults import handler500, handler404, include, patterns
+from django.conf.urls import handler500, handler404, include, patterns
from django.conf import settings
from django.contrib import admin
diff --git a/visualize/urls.py b/visualize/urls.py
index 02d83bec..907f6a22 100644
--- a/visualize/urls.py
+++ b/visualize/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import patterns
+from django.conf.urls import patterns
urlpatterns = patterns('visualize.views',
(r'^$', 'index', {}, 'visualize-index'),
--
cgit v1.2.3-54-g00ecf
From bc1ba4e95a3e572779eb8ba8a947e8d3ce165845 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Fri, 23 Mar 2012 18:45:01 -0500
Subject: PEP8 cleanup with blank lines
Signed-off-by: Dan McGee
---
main/utils.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/main/utils.py b/main/utils.py
index 03441c15..8143ea6a 100644
--- a/main/utils.py
+++ b/main/utils.py
@@ -8,16 +8,19 @@
from django.core.cache import cache
+
CACHE_TIMEOUT = 1800
INVALIDATE_TIMEOUT = 10
CACHE_LATEST_PREFIX = 'cache_latest_'
+
def cache_function_key(func, args, kwargs):
raw = [func.__name__, func.__module__, args, kwargs]
pickled = pickle.dumps(raw, protocol=pickle.HIGHEST_PROTOCOL)
key = hashlib.md5(pickled).hexdigest()
return 'cache_function.' + func.__name__ + '.' + key
+
def cache_function(length):
"""
A variant of the snippet posted by Jeff Wheeler at
@@ -43,6 +46,7 @@ def inner_func(*args, **kwargs):
return inner_func
return decorator
+
def clear_cache_function(func, args, kwargs):
key = cache_function_key(func, args, kwargs)
cache.delete(key)
@@ -50,6 +54,7 @@ def clear_cache_function(func, args, kwargs):
# utility to make a pair of django choices
make_choice = lambda l: [(str(m), str(m)) for m in l]
+
# These are in here because we would be jumping around in some import circles
# and hoops otherwise. The only thing currently using these keys is the feed
# caching stuff.
@@ -65,6 +70,7 @@ def refresh_latest(**kwargs):
# will be valid again. See "Scaling Django" by Mike Malone, slide 30.
cache.set(cache_key, None, INVALIDATE_TIMEOUT)
+
def retrieve_latest(sender):
# we could break this down based on the request url, but it would probably
# cost us more in query time to do so.
@@ -84,6 +90,7 @@ def retrieve_latest(sender):
pass
return None
+
def set_created_field(sender, **kwargs):
'''This will set the 'created' field on any object to datetime.utcnow() if
it is unset. For use as a pre_save signal handler.'''
@@ -91,6 +98,7 @@ def set_created_field(sender, **kwargs):
if hasattr(obj, 'created') and not obj.created:
obj.created = datetime.utcnow()
+
def groupby_preserve_order(iterable, keyfunc):
'''Take an iterable and regroup using keyfunc to determine whether items
belong to the same group. The order of the iterable is preserved and
@@ -112,6 +120,7 @@ def groupby_preserve_order(iterable, keyfunc):
return result
+
class PackageStandin(object):
'''Resembles a Package object, and has a few of the same fields, but is
really a link to a pkgbase that has no package with matching pkgname.'''
--
cgit v1.2.3-54-g00ecf
From 90e08b4863dfaecafee5b151478bda4513b12e85 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Fri, 23 Mar 2012 19:29:40 -0500
Subject: Make all datetime objects fully timezone aware
This is most of the transition to Django 1.4 `USE_TZ = True`. We need to
ensure we don't mix aware and non-aware datetime objects when dealing
with datetimes in the code. Add a utc_now() helper method that we can
use most places, and ensure there is always a timezone attached when
necessary.
Signed-off-by: Dan McGee
---
devel/management/commands/reporead.py | 12 +++++---
devel/views.py | 33 +++++++++-------------
...mpressed_size__chg_field_package_installed_s.py | 5 +++-
.../0054_auto__add_field_donor_created.py | 5 +++-
main/models.py | 4 +--
main/utils.py | 12 ++++++--
mirrors/management/commands/mirrorcheck.py | 5 +++-
mirrors/utils.py | 13 +++++----
news/models.py | 7 +++--
packages/management/commands/signoff_report.py | 5 ++--
...0007_auto__add_field_packagerelation_created.py | 5 +++-
packages/views/flag.py | 5 ++--
packages/views/signoff.py | 4 +--
releng/management/commands/syncisos.py | 5 ++--
settings.py | 10 +++++--
sitemaps.py | 3 +-
templates/devel/clock.html | 4 +--
17 files changed, 80 insertions(+), 57 deletions(-)
diff --git a/devel/management/commands/reporead.py b/devel/management/commands/reporead.py
index a8c58ba7..60ee6ec0 100644
--- a/devel/management/commands/reporead.py
+++ b/devel/management/commands/reporead.py
@@ -22,6 +22,7 @@
import logging
from datetime import datetime
from optparse import make_option
+from pytz import utc
from django.core.management.base import BaseCommand, CommandError
from django.db import connections, router, transaction
@@ -29,8 +30,10 @@
from devel.utils import UserFinder
from main.models import Arch, Package, PackageDepend, PackageFile, Repo
+from main.utils import utc_now
from packages.models import Conflict, Provision, Replacement
+
logging.basicConfig(
level=logging.WARNING,
format='%(asctime)s -> %(levelname)s: %(message)s',
@@ -113,7 +116,8 @@ def populate(self, values):
self.epoch = int(match.group(2))
elif k == 'builddate':
try:
- self.builddate = datetime.utcfromtimestamp(int(v[0]))
+ builddate = datetime.utcfromtimestamp(int(v[0]))
+ self.builddate = builddate.replace(tzinfo=utc)
except ValueError:
try:
self.builddate = datetime.strptime(v[0],
@@ -281,7 +285,7 @@ def populate_files(dbpkg, repopkg, force=False):
filename=filename)
pkg_files.append(pkgfile)
PackageFile.objects.bulk_create(pkg_files)
- dbpkg.files_last_update = datetime.utcnow()
+ dbpkg.files_last_update = utc_now()
dbpkg.save()
@@ -351,7 +355,7 @@ def db_update(archname, reponame, pkgs, force=False):
dbpkg = Package(pkgname=pkg.name, arch=architecture, repo=repository)
try:
with transaction.commit_on_success():
- populate_pkg(dbpkg, pkg, timestamp=datetime.utcnow())
+ populate_pkg(dbpkg, pkg, timestamp=utc_now())
except IntegrityError:
logger.warning("Could not add package %s; "
"not fatal if another thread beat us to it.",
@@ -378,7 +382,7 @@ def db_update(archname, reponame, pkgs, force=False):
if not force and pkg_same_version(pkg, dbpkg):
continue
elif not force:
- timestamp = datetime.utcnow()
+ timestamp = utc_now()
# The odd select_for_update song and dance here are to ensure
# simultaneous updates don't happen on a package, causing
diff --git a/devel/views.py b/devel/views.py
index 328d52e4..3a9be757 100644
--- a/devel/views.py
+++ b/devel/views.py
@@ -1,3 +1,10 @@
+from datetime import datetime, timedelta
+import operator
+import pytz
+import random
+from string import ascii_letters, digits
+import time
+
from django import forms
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import \
@@ -16,19 +23,13 @@
from django.utils.http import http_date
from main.models import Package, PackageDepend, PackageFile, TodolistPkg
-from main.models import Arch, Repo
-from main.models import UserProfile
+from main.models import Arch, Repo, UserProfile
+from main.utils import utc_now
from packages.models import PackageRelation
from packages.utils import get_signoff_groups
from todolists.utils import get_annotated_todolists
from .utils import get_annotated_maintainers
-from datetime import datetime, timedelta
-import operator
-import pytz
-import random
-from string import ascii_letters, digits
-import time
@login_required
def index(request):
@@ -85,22 +86,14 @@ def clock(request):
devs = User.objects.filter(is_active=True).order_by(
'first_name', 'last_name').select_related('userprofile')
- now = datetime.now()
- utc_now = datetime.utcnow().replace(tzinfo=pytz.utc)
- # now annotate each dev object with their current time
- for dev in devs:
- tz = pytz.timezone(dev.userprofile.time_zone)
- dev.current_time = utc_now.astimezone(tz)
-
+ now = utc_now()
page_dict = {
'developers': devs,
- 'now': now,
- 'utc_now': utc_now,
+ 'utc_now': now,
}
response = direct_to_template(request, 'devel/clock.html', page_dict)
if not response.has_header('Expires'):
- # why this works only with the non-UTC date I have no idea...
expire_time = now.replace(second=0, microsecond=0)
expire_time += timedelta(minutes=1)
expire_time = time.mktime(expire_time.timetuple())
@@ -168,12 +161,12 @@ def report(request, report_name, username=None):
if report_name == 'old':
title = 'Packages last built more than two years ago'
- cutoff = datetime.utcnow() - timedelta(days=365 * 2)
+ cutoff = utc_now() - timedelta(days=365 * 2)
packages = packages.filter(
build_date__lt=cutoff).order_by('build_date')
elif report_name == 'long-out-of-date':
title = 'Packages marked out-of-date more than 90 days ago'
- cutoff = datetime.utcnow() - timedelta(days=90)
+ cutoff = utc_now() - timedelta(days=90)
packages = packages.filter(
flag_date__lt=cutoff).order_by('flag_date')
elif report_name == 'big':
diff --git a/main/migrations/0050_auto__chg_field_package_compressed_size__chg_field_package_installed_s.py b/main/migrations/0050_auto__chg_field_package_compressed_size__chg_field_package_installed_s.py
index 7aa09596..8368ae2e 100644
--- a/main/migrations/0050_auto__chg_field_package_compressed_size__chg_field_package_installed_s.py
+++ b/main/migrations/0050_auto__chg_field_package_compressed_size__chg_field_package_installed_s.py
@@ -1,5 +1,6 @@
# encoding: utf-8
import datetime
+from pytz import utc
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
@@ -9,7 +10,9 @@ class Migration(SchemaMigration):
def forwards(self, orm):
db.alter_column('packages', 'compressed_size', self.gf('main.models.PositiveBigIntegerField')(default=0))
db.alter_column('packages', 'installed_size', self.gf('main.models.PositiveBigIntegerField')(default=0))
- db.alter_column('packages', 'last_update', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(2000, 1, 1)))
+ old_date = datetime.datetime(2000, 1, 1)
+ old_date = old_date.replace(tzinfo=utc)
+ db.alter_column('packages', 'last_update', self.gf('django.db.models.fields.DateTimeField')(default=old_date))
def backwards(self, orm):
db.alter_column('packages', 'compressed_size', self.gf('django.db.models.fields.BigIntegerField')(null=True))
diff --git a/main/migrations/0054_auto__add_field_donor_created.py b/main/migrations/0054_auto__add_field_donor_created.py
index f4d5b157..c96c0f5d 100644
--- a/main/migrations/0054_auto__add_field_donor_created.py
+++ b/main/migrations/0054_auto__add_field_donor_created.py
@@ -1,5 +1,6 @@
# encoding: utf-8
import datetime
+from pytz import utc
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
@@ -8,7 +9,9 @@ class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Donor.created'
- db.add_column('donors', 'created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.date(2000, 1, 1)), keep_default=False)
+ old_date = datetime.datetime(2000, 1, 1)
+ old_date = old_date.replace(tzinfo=utc)
+ db.add_column('donors', 'created', self.gf('django.db.models.fields.DateTimeField')(default=old_date), keep_default=False)
def backwards(self, orm):
diff --git a/main/models.py b/main/models.py
index 4f2d64ea..7d017242 100644
--- a/main/models.py
+++ b/main/models.py
@@ -9,7 +9,7 @@
from django.contrib.sites.models import Site
from .fields import PositiveBigIntegerField, PGPKeyField
-from .utils import cache_function, make_choice, set_created_field
+from .utils import cache_function, make_choice, set_created_field, utc_now
class UserProfile(models.Model):
@@ -515,7 +515,7 @@ class Meta:
def set_todolist_fields(sender, **kwargs):
todolist = kwargs['instance']
if not todolist.date_added:
- todolist.date_added = datetime.utcnow()
+ todolist.date_added = utc_now()
# connect signals needed to keep cache in line with reality
from main.utils import refresh_latest
diff --git a/main/utils.py b/main/utils.py
index 8143ea6a..e7e47c53 100644
--- a/main/utils.py
+++ b/main/utils.py
@@ -5,6 +5,7 @@
from datetime import datetime
import hashlib
+from pytz import utc
from django.core.cache import cache
@@ -91,12 +92,17 @@ def retrieve_latest(sender):
return None
+def utc_now():
+ '''Returns a timezone-aware UTC date representing now.'''
+ return datetime.utcnow().replace(tzinfo=utc)
+
+
def set_created_field(sender, **kwargs):
- '''This will set the 'created' field on any object to datetime.utcnow() if
- it is unset. For use as a pre_save signal handler.'''
+ '''This will set the 'created' field on any object to the current UTC time
+ if it is unset. For use as a pre_save signal handler.'''
obj = kwargs['instance']
if hasattr(obj, 'created') and not obj.created:
- obj.created = datetime.utcnow()
+ obj.created = utc_now()
def groupby_preserve_order(iterable, keyfunc):
diff --git a/mirrors/management/commands/mirrorcheck.py b/mirrors/management/commands/mirrorcheck.py
index 8eb8b010..c2928e67 100644
--- a/mirrors/management/commands/mirrorcheck.py
+++ b/mirrors/management/commands/mirrorcheck.py
@@ -21,9 +21,11 @@
import time
from threading import Thread
import types
+from pytz import utc
from Queue import Queue, Empty
import urllib2
+from main.utils import utc_now
from mirrors.models import MirrorUrl, MirrorLog
logging.basicConfig(
@@ -50,7 +52,7 @@ def handle_noargs(self, **options):
def check_mirror_url(mirror_url):
url = mirror_url.url + 'lastsync'
logger.info("checking URL %s", url)
- log = MirrorLog(url=mirror_url, check_time=datetime.utcnow())
+ log = MirrorLog(url=mirror_url, check_time=utc_now())
try:
start = time.time()
result = urllib2.urlopen(url, timeout=10)
@@ -61,6 +63,7 @@ def check_mirror_url(mirror_url):
parsed_time = None
try:
parsed_time = datetime.utcfromtimestamp(int(data))
+ parsed_time = parsed_time.replace(tzinfo=utc)
except ValueError:
# it is bad news to try logging the lastsync value;
# sometimes we get a crazy-encoded web page.
diff --git a/mirrors/utils.py b/mirrors/utils.py
index f05ffc77..0f8fef84 100644
--- a/mirrors/utils.py
+++ b/mirrors/utils.py
@@ -1,11 +1,12 @@
+from datetime import timedelta
+
from django.db.models import Avg, Count, Max, Min, StdDev
-from main.utils import cache_function
+from main.utils import cache_function, utc_now
from .models import MirrorLog, MirrorProtocol, MirrorUrl
-import datetime
-default_cutoff = datetime.timedelta(hours=24)
+default_cutoff = timedelta(hours=24)
def annotate_url(url, delays):
'''Given a MirrorURL object, add a few more attributes to it regarding
@@ -13,7 +14,7 @@ def annotate_url(url, delays):
url.completion_pct = float(url.success_count) / url.check_count
if url.id in delays:
url_delays = delays[url.id]
- url.delay = sum(url_delays, datetime.timedelta()) / len(url_delays)
+ url.delay = sum(url_delays, timedelta()) / len(url_delays)
hours = url.delay.days * 24.0 + url.delay.seconds / 3600.0
if url.completion_pct > 0:
@@ -28,7 +29,7 @@ def annotate_url(url, delays):
@cache_function(123)
def get_mirror_statuses(cutoff=default_cutoff):
- cutoff_time = datetime.datetime.utcnow() - cutoff
+ cutoff_time = utc_now() - cutoff
protocols = list(MirrorProtocol.objects.filter(is_download=True))
# I swear, this actually has decent performance...
urls = MirrorUrl.objects.select_related('mirror', 'protocol').filter(
@@ -82,7 +83,7 @@ def get_mirror_statuses(cutoff=default_cutoff):
@cache_function(117)
def get_mirror_errors(cutoff=default_cutoff):
- cutoff_time = datetime.datetime.utcnow() - cutoff
+ cutoff_time = utc_now() - cutoff
errors = MirrorLog.objects.filter(
is_success=False, check_time__gte=cutoff_time,
url__mirror__active=True, url__mirror__public=True).values(
diff --git a/news/models.py b/news/models.py
index 33d958e0..95026e1d 100644
--- a/news/models.py
+++ b/news/models.py
@@ -1,9 +1,10 @@
-from datetime import datetime
-
from django.db import models
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
+from main.utils import utc_now
+
+
class News(models.Model):
slug = models.SlugField(max_length=255, unique=True)
author = models.ForeignKey(User, related_name='news_author',
@@ -28,7 +29,7 @@ class Meta:
def set_news_fields(sender, **kwargs):
news = kwargs['instance']
- now = datetime.utcnow()
+ now = utc_now()
news.last_modified = now
if not news.postdate:
news.postdate = now
diff --git a/packages/management/commands/signoff_report.py b/packages/management/commands/signoff_report.py
index 3b67f518..ddf930db 100644
--- a/packages/management/commands/signoff_report.py
+++ b/packages/management/commands/signoff_report.py
@@ -17,12 +17,13 @@
from django.template import loader, Context
from collections import namedtuple
-from datetime import datetime, timedelta
+from datetime import timedelta
import logging
from operator import attrgetter
import sys
from main.models import Repo
+from main.utils import utc_now
from packages.models import Signoff
from packages.utils import get_signoff_groups
@@ -65,7 +66,7 @@ def generate_report(email, repo_name):
new_hours = 24
old_days = 14
- now = datetime.utcnow()
+ now = utc_now()
new_cutoff = now - timedelta(hours=new_hours)
old_cutoff = now - timedelta(days=old_days)
diff --git a/packages/migrations/0007_auto__add_field_packagerelation_created.py b/packages/migrations/0007_auto__add_field_packagerelation_created.py
index 37321fdb..b030909e 100644
--- a/packages/migrations/0007_auto__add_field_packagerelation_created.py
+++ b/packages/migrations/0007_auto__add_field_packagerelation_created.py
@@ -1,5 +1,6 @@
# encoding: utf-8
import datetime
+from pytz import utc
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
@@ -7,7 +8,9 @@
class Migration(SchemaMigration):
def forwards(self, orm):
- db.add_column('packages_packagerelation', 'created', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.utcnow()), keep_default=False)
+ old_date = datetime.datetime(2000, 1, 1)
+ old_date = old_date.replace(tzinfo=utc)
+ db.add_column('packages_packagerelation', 'created', self.gf('django.db.models.fields.DateTimeField')(default=old_date), keep_default=False)
def backwards(self, orm):
db.delete_column('packages_packagerelation', 'created')
diff --git a/packages/views/flag.py b/packages/views/flag.py
index c0990e8e..0d2f9009 100644
--- a/packages/views/flag.py
+++ b/packages/views/flag.py
@@ -1,5 +1,3 @@
-from datetime import datetime
-
from django import forms
from django.conf import settings
from django.contrib.auth.decorators import permission_required
@@ -12,6 +10,7 @@
from ..models import FlagRequest
from main.models import Package
+from main.utils import utc_now
def flaghelp(request):
@@ -61,7 +60,7 @@ def flag(request, name, repo, arch):
@transaction.commit_on_success
def perform_updates():
- now = datetime.utcnow()
+ now = utc_now()
pkgs.update(flag_date=now)
# store our flag request
flag_request = FlagRequest(created=now,
diff --git a/packages/views/signoff.py b/packages/views/signoff.py
index e3daf0dd..cf00b0b9 100644
--- a/packages/views/signoff.py
+++ b/packages/views/signoff.py
@@ -1,4 +1,3 @@
-from datetime import datetime
from operator import attrgetter
from django import forms
@@ -13,6 +12,7 @@
from django.views.generic.simple import direct_to_template
from main.models import Package, Arch, Repo
+from main.utils import utc_now
from ..models import SignoffSpecification, Signoff
from ..utils import (get_signoff_groups, approved_by_signoffs,
PackageSignoffGroup)
@@ -45,7 +45,7 @@ def signoff_package(request, name, repo, arch, revoke=False):
package, request.user, False)
except Signoff.DoesNotExist:
raise Http404
- signoff.revoked = datetime.utcnow()
+ signoff.revoked = utc_now()
signoff.save()
created = False
else:
diff --git a/releng/management/commands/syncisos.py b/releng/management/commands/syncisos.py
index 270c6c34..62f005ff 100644
--- a/releng/management/commands/syncisos.py
+++ b/releng/management/commands/syncisos.py
@@ -1,4 +1,3 @@
-from datetime import datetime
import re
import urllib
from HTMLParser import HTMLParser, HTMLParseError
@@ -6,8 +5,10 @@
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
+from main.utils import utc_now
from releng.models import Iso
+
class IsoListParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
@@ -53,7 +54,7 @@ def handle(self, *args, **options):
existing.active = True
existing.removed = None
existing.save()
- now = datetime.utcnow()
+ now = utc_now()
# and then mark all other names as no longer active
Iso.objects.filter(active=True).exclude(name__in=active_isos).update(
active=False, removed=now)
diff --git a/settings.py b/settings.py
index 9aba3881..e1d4d4a9 100644
--- a/settings.py
+++ b/settings.py
@@ -18,9 +18,13 @@
# Full path to the data directory
DEPLOY_PATH = os.path.dirname(os.path.realpath(__file__))
-# Local time zone for this installation. All choices can be found here:
-# http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
-TIME_ZONE = 'US/Eastern'
+# If you set this to False, Django will not use timezone-aware datetimes.
+USE_TZ = True
+
+# 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.
+TIME_ZONE = 'UTC'
# Language code for this installation. All choices can be found here:
# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
diff --git a/sitemaps.py b/sitemaps.py
index 177555ff..8e9ba36f 100644
--- a/sitemaps.py
+++ b/sitemaps.py
@@ -1,4 +1,5 @@
from datetime import datetime, timedelta
+from pytz import utc
from django.contrib.sitemaps import Sitemap
from django.core.urlresolvers import reverse
@@ -62,7 +63,7 @@ class NewsSitemap(Sitemap):
priority = "0.8"
def __init__(self):
- now = datetime.utcnow()
+ now = datetime.utcnow().replace(tzinfo=utc)
self.one_day_ago = now - timedelta(days=1)
self.one_week_ago = now - timedelta(days=7)
diff --git a/templates/devel/clock.html b/templates/devel/clock.html
index 72a57d0f..3b00075f 100644
--- a/templates/devel/clock.html
+++ b/templates/devel/clock.html
@@ -1,4 +1,5 @@
{% extends "base.html" %}
+{% load tz %}
{% block title %}Arch Linux - Developer World Clocks{% endblock %}
@@ -10,7 +11,6 @@ Developer World Clocks
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 T" }}
UTC Time: {{ utc_now|date:"Y-m-d H:i T" }}
@@ -33,7 +33,7 @@ Developer World Clocks
{{ dev.userprofile.alias }}
{{ dev.userprofile.location }}
{{ dev.userprofile.time_zone }}
- {{ dev.current_time|date:"Y-m-d H:i T" }}
+ {{ utc_now|timezone:dev.userprofile.time_zone|date:"Y-m-d H:i T" }}
{% endfor %}
--
cgit v1.2.3-54-g00ecf
From 8e10699d53281be53c88a3695de6aa496e084dc6 Mon Sep 17 00:00:00 2001
From: Dan McGee
Date: Fri, 23 Mar 2012 20:09:38 -0500
Subject: Use 'url from future' everywhere
The old-style url template tag disappears in Django 1.5, so we can and
should convert to the new-style tag now.
Signed-off-by: Dan McGee
---
templates/base.html | 14 +++++++-------
templates/public/download.html | 5 +++--
templates/public/index.html | 31 ++++++++++++++++---------------
templates/releng/add.html | 3 ++-
templates/releng/iso_overview.html | 3 ++-
templates/releng/result_list.html | 3 ++-
templates/releng/result_section.html | 7 ++++---
templates/releng/results.html | 5 +++--
templates/releng/thanks.html | 7 ++++---
templates/visualize/index.html | 7 ++++---
10 files changed, 47 insertions(+), 38 deletions(-)
diff --git a/templates/base.html b/templates/base.html
index 0da77cf3..fa30df1a 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -1,4 +1,4 @@
-
+{% load url from future %}
{% block title %}Arch Linux{% endblock %}
@@ -10,7 +10,7 @@
-
+
{% block head %}{% endblock %}
@@ -25,7 +25,7 @@
Wiki
Bugs
AUR
- Download
+ Download
@@ -34,20 +34,20 @@
{% if user.is_authenticated %}
diff --git a/templates/public/index.html b/templates/public/index.html
index 00edf8c4..53ccd2d2 100644
--- a/templates/public/index.html
+++ b/templates/public/index.html
@@ -1,5 +1,6 @@
{% extends "base.html" %}
{% load markup cache cdn %}
+{% load url from future %}
{% block head %}
@@ -30,13 +31,13 @@
A simple, lightweight distribution
title="Arch Wiki">wiki
if you want to learn more about Arch.
-
Learn more...
@@ -57,7 +58,7 @@
{% else %}
{% if forloop.counter0 == 5 %}
@@ -137,7 +138,7 @@ Community
Support
Tools
@@ -181,17 +182,17 @@
Development
More Resources
diff --git a/templates/releng/add.html b/templates/releng/add.html
index 8488b40c..ed02984e 100644
--- a/templates/releng/add.html
+++ b/templates/releng/add.html
@@ -1,4 +1,5 @@
{% extends "base.html" %}
+{% load url from future %}
{% block title %}Arch Linux - Test Result Entry{% endblock %}
@@ -13,7 +14,7 @@ Arch Releng Testbuild Feedback Entry
installation properly. Some options require you to check several things (such as
config files), this will be mentioned alongside the option.
There is also an overview of all feedback on the
- results page . Once we have
+ results page . Once we have
builds that are properly tested (enough successful feedback for all
important features of the ISO or a slightly earlier ISO), we can release new
official media.
diff --git a/templates/releng/iso_overview.html b/templates/releng/iso_overview.html
index 5a4445b7..76479c52 100644
--- a/templates/releng/iso_overview.html
+++ b/templates/releng/iso_overview.html
@@ -1,10 +1,11 @@
{% extends "base.html" %}
+{% load url from future %}
{% block content %}
Failures and Successes for Testing ISOs
-
Go back to testing results
+
Go back to testing results
diff --git a/templates/releng/result_list.html b/templates/releng/result_list.html
index 512e1bf3..62264217 100644
--- a/templates/releng/result_list.html
+++ b/templates/releng/result_list.html
@@ -1,4 +1,5 @@
{% extends "base.html" %}
+{% load url from future %}
{% block content %}
@@ -7,7 +8,7 @@
Results for:
{{ iso_name|default:"" }}
-
Go back to testing results
+
Go back to testing results
diff --git a/templates/releng/result_section.html b/templates/releng/result_section.html
index 08e46fb7..c82a5532 100644
--- a/templates/releng/result_section.html
+++ b/templates/releng/result_section.html
@@ -1,3 +1,4 @@
+{% load url from future %}
{% if option.is_rollback %}Rollback: {% endif %}{{ option.name|title }}
Last Success
@@ -6,20 +7,20 @@
{% for item in option.values %}
-
+
{{ item.value.name|lower }}
{% if item.success %}
-
+
{{ item.success.name }}
{% else %}Never succeeded{% endif %}
{% if item.failure %}
-
+
{{ item.failure.name }}
{% else %}Never failed{% endif %}
diff --git a/templates/releng/results.html b/templates/releng/results.html
index 4ff3c864..71af708f 100644
--- a/templates/releng/results.html
+++ b/templates/releng/results.html
@@ -1,4 +1,5 @@
{% extends "base.html" %}
+{% load url from future %}
{% block title %}Arch Linux - Release Engineering Testbuild Results{% endblock %}
@@ -9,12 +10,12 @@ Release Engineering Testbuild Results
This is an overview screen showing a test results matrix of release
engineering produced ISOs. Various options and configurations are shown
with last success and last failure results, if known. To help improve ISO
- quality, you are encouraged to give feedback
+ quality, you are encouraged to give feedback
if you have tested and used any ISOs. Both successful and failed results
are encouraged and welcome.
For a overview of which ISOs tested best, have a look at
- the overview .
+ the overview .
For more information, see the documentation
diff --git a/templates/releng/thanks.html b/templates/releng/thanks.html
index 80018b03..66d65a5c 100644
--- a/templates/releng/thanks.html
+++ b/templates/releng/thanks.html
@@ -1,4 +1,5 @@
{% extends "base.html" %}
+{% load url from future %}
{% block title %}Arch Linux - Feedback - Thanks!{% endblock %}
@@ -7,9 +8,9 @@
Thanks!
Thank you for taking the time to give us this information!
Your results have been succesfully added to our database.
- You can now go back to the results ,
- give more feedback , or
- have a look at the look at
+ You can now go back to the results ,
+ give more feedback , or
+ have a look at the look at
the ISO test overview .
{% endblock %}
diff --git a/templates/visualize/index.html b/templates/visualize/index.html
index a7727b1f..a7855eb2 100644
--- a/templates/visualize/index.html
+++ b/templates/visualize/index.html
@@ -1,4 +1,5 @@
{% extends "base.html" %}
+{% load url from future %}
{% block title %}Arch Linux - Visualizations{% endblock %}
@@ -34,11 +35,11 @@ Visualization of PGP Master and Signing Keys
{% endblock %}
--
cgit v1.2.3-54-g00ecf