mirror of
https://github.com/django/django.git
synced 2025-07-04 01:39:20 +00:00
gis: Merged revisions 6021-6393 via svnmerge from [repos:django/trunk trunk].
git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6394 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
69452d6237
commit
7376474260
32
AUTHORS
32
AUTHORS
@ -49,6 +49,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
andy@jadedplanet.net
|
andy@jadedplanet.net
|
||||||
Fabrice Aneche <akh@nobugware.com>
|
Fabrice Aneche <akh@nobugware.com>
|
||||||
ant9000@netwise.it
|
ant9000@netwise.it
|
||||||
|
Florian Apolloner
|
||||||
David Ascher <http://ascher.ca/>
|
David Ascher <http://ascher.ca/>
|
||||||
david@kazserve.org
|
david@kazserve.org
|
||||||
Arthur <avandorp@gmail.com>
|
Arthur <avandorp@gmail.com>
|
||||||
@ -75,16 +76,20 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Chris Chamberlin <dja@cdc.msbx.net>
|
Chris Chamberlin <dja@cdc.msbx.net>
|
||||||
Amit Chakradeo <http://amit.chakradeo.net/>
|
Amit Chakradeo <http://amit.chakradeo.net/>
|
||||||
ChaosKCW
|
ChaosKCW
|
||||||
|
Sengtha Chay <sengtha@e-khmer.com>
|
||||||
ivan.chelubeev@gmail.com
|
ivan.chelubeev@gmail.com
|
||||||
Bryan Chow <bryan at verdjn dot com>
|
Bryan Chow <bryan at verdjn dot com>
|
||||||
Michal Chruszcz <troll@pld-linux.org>
|
Michal Chruszcz <troll@pld-linux.org>
|
||||||
Ian Clelland <clelland@gmail.com>
|
Ian Clelland <clelland@gmail.com>
|
||||||
|
Russell Cloran <russell@rucus.net>
|
||||||
colin@owlfish.com
|
colin@owlfish.com
|
||||||
crankycoder@gmail.com
|
crankycoder@gmail.com
|
||||||
|
Paul Collier <paul@paul-collier.com>
|
||||||
Pete Crosier <pete.crosier@gmail.com>
|
Pete Crosier <pete.crosier@gmail.com>
|
||||||
Matt Croydon <http://www.postneo.com/>
|
Matt Croydon <http://www.postneo.com/>
|
||||||
flavio.curella@gmail.com
|
flavio.curella@gmail.com
|
||||||
Jure Cuhalev <gandalf@owca.info>
|
Jure Cuhalev <gandalf@owca.info>
|
||||||
|
John D'Agostino <john.dagostino@gmail.com>
|
||||||
dackze+django@gmail.com
|
dackze+django@gmail.com
|
||||||
David Danier <goliath.mailinglist@gmx.de>
|
David Danier <goliath.mailinglist@gmx.de>
|
||||||
Dirk Datzert <dummy@habmalnefrage.de>
|
Dirk Datzert <dummy@habmalnefrage.de>
|
||||||
@ -111,18 +116,22 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Ludvig Ericson <ludvig.ericson@gmail.com>
|
Ludvig Ericson <ludvig.ericson@gmail.com>
|
||||||
Dirk Eschler <dirk.eschler@gmx.net>
|
Dirk Eschler <dirk.eschler@gmx.net>
|
||||||
Marc Fargas <telenieko@telenieko.com>
|
Marc Fargas <telenieko@telenieko.com>
|
||||||
|
Szilveszter Farkas <szilveszter.farkas@gmail.com>
|
||||||
favo@exoweb.net
|
favo@exoweb.net
|
||||||
Bill Fenner <fenner@gmail.com>
|
Bill Fenner <fenner@gmail.com>
|
||||||
Stefane Fermgier <sf@fermigier.com>
|
Stefane Fermgier <sf@fermigier.com>
|
||||||
Afonso Fernández Nogueira <fonzzo.django@gmail.com>
|
Afonso Fernández Nogueira <fonzzo.django@gmail.com>
|
||||||
Matthew Flanagan <http://wadofstuff.blogspot.com>
|
Matthew Flanagan <http://wadofstuff.blogspot.com>
|
||||||
Eric Floehr <eric@intellovations.com>
|
Eric Floehr <eric@intellovations.com>
|
||||||
|
Vincent Foley <vfoleybourgon@yahoo.ca>
|
||||||
Jorge Gajon <gajon@gajon.org>
|
Jorge Gajon <gajon@gajon.org>
|
||||||
gandalf@owca.info
|
gandalf@owca.info
|
||||||
Marc Garcia <marc.garcia@accopensys.com>
|
Marc Garcia <marc.garcia@accopensys.com>
|
||||||
Baishampayan Ghose
|
Baishampayan Ghose
|
||||||
|
Dimitris Glezos <dimitris@glezos.com>
|
||||||
glin@seznam.cz
|
glin@seznam.cz
|
||||||
martin.glueck@gmail.com
|
martin.glueck@gmail.com
|
||||||
|
Artyom Gnilov <boobsd@gmail.com>
|
||||||
GomoX <gomo@datafull.com>
|
GomoX <gomo@datafull.com>
|
||||||
Mario Gonzalez <gonzalemario@gmail.com>
|
Mario Gonzalez <gonzalemario@gmail.com>
|
||||||
pradeep.gowda@gmail.com
|
pradeep.gowda@gmail.com
|
||||||
@ -144,6 +153,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Sung-Jin Hong <serialx.net@gmail.com>
|
Sung-Jin Hong <serialx.net@gmail.com>
|
||||||
Richard House <Richard.House@i-logue.com>
|
Richard House <Richard.House@i-logue.com>
|
||||||
Robert Rock Howard <http://djangomojo.com/>
|
Robert Rock Howard <http://djangomojo.com/>
|
||||||
|
Rob Hudson <http://rob.cogit8.org/>
|
||||||
Jason Huggins <http://www.jrandolph.com/blog/>
|
Jason Huggins <http://www.jrandolph.com/blog/>
|
||||||
Hyun Mi Ae
|
Hyun Mi Ae
|
||||||
Tom Insam
|
Tom Insam
|
||||||
@ -155,6 +165,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
jpellerin@gmail.com
|
jpellerin@gmail.com
|
||||||
junzhang.jn@gmail.com
|
junzhang.jn@gmail.com
|
||||||
Antti Kaihola <http://akaihola.blogspot.com/>
|
Antti Kaihola <http://akaihola.blogspot.com/>
|
||||||
|
Nagy Károly <charlie@rendszergazda.com>
|
||||||
Ben Dean Kawamura <ben.dean.kawamura@gmail.com>
|
Ben Dean Kawamura <ben.dean.kawamura@gmail.com>
|
||||||
Ian G. Kelly <ian.g.kelly@gmail.com>
|
Ian G. Kelly <ian.g.kelly@gmail.com>
|
||||||
Ben Khoo <khoobks@westnet.com.au>
|
Ben Khoo <khoobks@westnet.com.au>
|
||||||
@ -176,6 +187,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
lakin.wecker@gmail.com
|
lakin.wecker@gmail.com
|
||||||
Nick Lane <nick.lane.au@gmail.com>
|
Nick Lane <nick.lane.au@gmail.com>
|
||||||
Stuart Langridge <http://www.kryogenix.org/>
|
Stuart Langridge <http://www.kryogenix.org/>
|
||||||
|
Paul Lanier <planier@google.com>
|
||||||
Nicola Larosa <nico@teknico.net>
|
Nicola Larosa <nico@teknico.net>
|
||||||
Eugene Lazutkin <http://lazutkin.com/blog/>
|
Eugene Lazutkin <http://lazutkin.com/blog/>
|
||||||
Jeong-Min Lee <falsetru@gmail.com>
|
Jeong-Min Lee <falsetru@gmail.com>
|
||||||
@ -185,10 +197,12 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Waylan Limberg <waylan@gmail.com>
|
Waylan Limberg <waylan@gmail.com>
|
||||||
limodou
|
limodou
|
||||||
Philip Lindborg <philip.lindborg@gmail.com>
|
Philip Lindborg <philip.lindborg@gmail.com>
|
||||||
|
msaelices <msaelices@gmail.com>
|
||||||
Matt McClanahan <http://mmcc.cx/>
|
Matt McClanahan <http://mmcc.cx/>
|
||||||
Martin Maney <http://www.chipy.org/Martin_Maney>
|
Martin Maney <http://www.chipy.org/Martin_Maney>
|
||||||
masonsimon+django@gmail.com
|
masonsimon+django@gmail.com
|
||||||
Manuzhai
|
Manuzhai
|
||||||
|
Petr Marhoun <petr.marhoun@gmail.com>
|
||||||
Petar Marić <http://www.petarmaric.com/>
|
Petar Marić <http://www.petarmaric.com/>
|
||||||
Nuno Mariz <nmariz@gmail.com>
|
Nuno Mariz <nmariz@gmail.com>
|
||||||
Marijn Vriens <marijn@metronomo.cl>
|
Marijn Vriens <marijn@metronomo.cl>
|
||||||
@ -226,22 +240,28 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
phil@produxion.net
|
phil@produxion.net
|
||||||
phil.h.smith@gmail.com
|
phil.h.smith@gmail.com
|
||||||
Gustavo Picon
|
Gustavo Picon
|
||||||
|
pigletto
|
||||||
Luke Plant <http://lukeplant.me.uk/>
|
Luke Plant <http://lukeplant.me.uk/>
|
||||||
plisk
|
plisk
|
||||||
Daniel Poelzleithner <http://poelzi.org/>
|
Daniel Poelzleithner <http://poelzi.org/>
|
||||||
polpak@yahoo.com
|
polpak@yahoo.com
|
||||||
Jyrki Pulliainen <jyrki.pulliainen@gmail.com>
|
Jyrki Pulliainen <jyrki.pulliainen@gmail.com>
|
||||||
Johann Queuniet <johann.queuniet@adh.naellia.eu>
|
Johann Queuniet <johann.queuniet@adh.naellia.eu>
|
||||||
J. Rademaker
|
Jan Rademaker
|
||||||
Michael Radziej <mir@noris.de>
|
Michael Radziej <mir@noris.de>
|
||||||
|
Amit Ramon <amit.ramon@gmail.com>
|
||||||
|
Philippe Raoult <philippe.raoult@n2nsoft.com>
|
||||||
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
|
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
|
||||||
Brian Ray <http://brianray.chipy.org/>
|
Brian Ray <http://brianray.chipy.org/>
|
||||||
remco@diji.biz
|
remco@diji.biz
|
||||||
rhettg@gmail.com
|
rhettg@gmail.com
|
||||||
|
Matt Riggott
|
||||||
Henrique Romano <onaiort@gmail.com>
|
Henrique Romano <onaiort@gmail.com>
|
||||||
Armin Ronacher
|
Armin Ronacher
|
||||||
Brian Rosner <brosner@gmail.com>
|
Brian Rosner <brosner@gmail.com>
|
||||||
Oliver Rutherfurd <http://rutherfurd.net/>
|
Oliver Rutherfurd <http://rutherfurd.net/>
|
||||||
|
ryankanno
|
||||||
|
Manuel Saelices <msaelices@yaco.es>
|
||||||
Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/>
|
Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/>
|
||||||
Vinay Sajip <vinay_sajip@yahoo.co.uk>
|
Vinay Sajip <vinay_sajip@yahoo.co.uk>
|
||||||
David Schein
|
David Schein
|
||||||
@ -252,22 +272,30 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Jozko Skrablin <jozko.skrablin@gmail.com>
|
Jozko Skrablin <jozko.skrablin@gmail.com>
|
||||||
SmileyChris <smileychris@gmail.com>
|
SmileyChris <smileychris@gmail.com>
|
||||||
smurf@smurf.noris.de
|
smurf@smurf.noris.de
|
||||||
|
Vsevolod Solovyov
|
||||||
sopel
|
sopel
|
||||||
|
Leo Soto <leo.soto@gmail.com>
|
||||||
Wiliam Alves de Souza <wiliamsouza83@gmail.com>
|
Wiliam Alves de Souza <wiliamsouza83@gmail.com>
|
||||||
|
Don Spaulding <donspauldingii@gmail.com>
|
||||||
|
Bjørn Stabell <bjorn@exoweb.net>
|
||||||
Georgi Stanojevski <glisha@gmail.com>
|
Georgi Stanojevski <glisha@gmail.com>
|
||||||
Vasiliy Stavenko <stavenko@gmail.com>
|
Vasiliy Stavenko <stavenko@gmail.com>
|
||||||
Thomas Steinacher <http://www.eggdrop.ch/>
|
Thomas Steinacher <http://www.eggdrop.ch/>
|
||||||
nowell strite
|
nowell strite
|
||||||
|
Thomas Stromberg <tstromberg@google.com>
|
||||||
Sundance
|
Sundance
|
||||||
SuperJared
|
SuperJared
|
||||||
Radek Švarz <http://www.svarz.cz/translate/>
|
Radek Švarz <http://www.svarz.cz/translate/>
|
||||||
Swaroop C H <http://www.swaroopch.info>
|
Swaroop C H <http://www.swaroopch.info>
|
||||||
Aaron Swartz <http://www.aaronsw.com/>
|
Aaron Swartz <http://www.aaronsw.com/>
|
||||||
Ville Säävuori <http://www.unessa.net/>
|
Ville Säävuori <http://www.unessa.net/>
|
||||||
|
Tyler Tarabula <tyler.tarabula@gmail.com>
|
||||||
Tyson Tate <tyson@fallingbullets.com>
|
Tyson Tate <tyson@fallingbullets.com>
|
||||||
Frank Tegtmeyer <fte@fte.to>
|
Frank Tegtmeyer <fte@fte.to>
|
||||||
thebjorn <bp@datakortet.no>
|
thebjorn <bp@datakortet.no>
|
||||||
Zach Thompson <zthompson47@gmail.com>
|
Zach Thompson <zthompson47@gmail.com>
|
||||||
|
Michael Thornhill
|
||||||
|
Deepak Thukral <deep.thukral@gmail.com>
|
||||||
tibimicu@gmax.net
|
tibimicu@gmax.net
|
||||||
tobias@neuyork.de
|
tobias@neuyork.de
|
||||||
Tom Tobin
|
Tom Tobin
|
||||||
@ -280,10 +308,12 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Amit Upadhyay
|
Amit Upadhyay
|
||||||
Geert Vanderkelen
|
Geert Vanderkelen
|
||||||
viestards.lists@gmail.com
|
viestards.lists@gmail.com
|
||||||
|
George Vilches <gav@thataddress.com>
|
||||||
Vlado <vlado@labath.org>
|
Vlado <vlado@labath.org>
|
||||||
Milton Waddams
|
Milton Waddams
|
||||||
wam-djangobug@wamber.net
|
wam-djangobug@wamber.net
|
||||||
wangchun <yaohua2000@gmail.com>
|
wangchun <yaohua2000@gmail.com>
|
||||||
|
Filip Wasilewski <filip.wasilewski@gmail.com>
|
||||||
Dan Watson <http://theidioteque.net/>
|
Dan Watson <http://theidioteque.net/>
|
||||||
Chris Wesseling <Chris.Wesseling@cwi.nl>
|
Chris Wesseling <Chris.Wesseling@cwi.nl>
|
||||||
James Wheare <django@sparemint.com>
|
James Wheare <django@sparemint.com>
|
||||||
|
@ -4,20 +4,31 @@ import optparse
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def compile_messages(locale=None):
|
try:
|
||||||
basedir = None
|
set
|
||||||
|
except NameError:
|
||||||
|
from sets import Set as set # For Python 2.3
|
||||||
|
|
||||||
if os.path.isdir(os.path.join('conf', 'locale')):
|
|
||||||
basedir = os.path.abspath(os.path.join('conf', 'locale'))
|
def compile_messages(locale=None):
|
||||||
elif os.path.isdir('locale'):
|
basedirs = [os.path.join('conf', 'locale'), 'locale']
|
||||||
basedir = os.path.abspath('locale')
|
if os.environ.get('DJANGO_SETTINGS_MODULE'):
|
||||||
else:
|
from django.conf import settings
|
||||||
print "This script should be run from the Django SVN tree or your project or app tree."
|
basedirs += settings.LOCALE_PATHS
|
||||||
|
|
||||||
|
# Gather existing directories.
|
||||||
|
basedirs = set(map(os.path.abspath, filter(os.path.isdir, basedirs)))
|
||||||
|
|
||||||
|
if not basedirs:
|
||||||
|
print "This script should be run from the Django SVN tree or your project or app tree, or with the settings module specified."
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if locale is not None:
|
for basedir in basedirs:
|
||||||
basedir = os.path.join(basedir, locale, 'LC_MESSAGES')
|
if locale:
|
||||||
|
basedir = os.path.join(basedir, locale, 'LC_MESSAGES')
|
||||||
|
compile_messages_in_dir(basedir)
|
||||||
|
|
||||||
|
def compile_messages_in_dir(basedir):
|
||||||
for dirpath, dirnames, filenames in os.walk(basedir):
|
for dirpath, dirnames, filenames in os.walk(basedir):
|
||||||
for f in filenames:
|
for f in filenames:
|
||||||
if f.endswith('.po'):
|
if f.endswith('.po'):
|
||||||
@ -40,9 +51,13 @@ def main():
|
|||||||
parser = optparse.OptionParser()
|
parser = optparse.OptionParser()
|
||||||
parser.add_option('-l', '--locale', dest='locale',
|
parser.add_option('-l', '--locale', dest='locale',
|
||||||
help="The locale to process. Default is to process all.")
|
help="The locale to process. Default is to process all.")
|
||||||
|
parser.add_option('--settings',
|
||||||
|
help='Python path to settings module, e.g. "myproject.settings". If provided, all LOCALE_PATHS will be processed. If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be checked as well.')
|
||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
if len(args):
|
if len(args):
|
||||||
parser.error("This program takes no arguments")
|
parser.error("This program takes no arguments")
|
||||||
|
if options.settings:
|
||||||
|
os.environ['DJANGO_SETTINGS_MODULE'] = options.settings
|
||||||
compile_messages(options.locale)
|
compile_messages(options.locale)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -112,6 +112,7 @@ class Settings(object):
|
|||||||
# Move the time zone info into os.environ. See ticket #2315 for why
|
# Move the time zone info into os.environ. See ticket #2315 for why
|
||||||
# we don't do this unconditionally (breaks Windows).
|
# we don't do this unconditionally (breaks Windows).
|
||||||
os.environ['TZ'] = self.TIME_ZONE
|
os.environ['TZ'] = self.TIME_ZONE
|
||||||
|
time.tzset()
|
||||||
|
|
||||||
def get_all_members(self):
|
def get_all_members(self):
|
||||||
return dir(self)
|
return dir(self)
|
||||||
|
@ -51,6 +51,7 @@ LANGUAGES = (
|
|||||||
('fa', gettext_noop('Persian')),
|
('fa', gettext_noop('Persian')),
|
||||||
('fi', gettext_noop('Finnish')),
|
('fi', gettext_noop('Finnish')),
|
||||||
('fr', gettext_noop('French')),
|
('fr', gettext_noop('French')),
|
||||||
|
('ga', gettext_noop('Gaeilge')),
|
||||||
('gl', gettext_noop('Galician')),
|
('gl', gettext_noop('Galician')),
|
||||||
('hu', gettext_noop('Hungarian')),
|
('hu', gettext_noop('Hungarian')),
|
||||||
('he', gettext_noop('Hebrew')),
|
('he', gettext_noop('Hebrew')),
|
||||||
@ -59,6 +60,7 @@ LANGUAGES = (
|
|||||||
('it', gettext_noop('Italian')),
|
('it', gettext_noop('Italian')),
|
||||||
('ja', gettext_noop('Japanese')),
|
('ja', gettext_noop('Japanese')),
|
||||||
('ko', gettext_noop('Korean')),
|
('ko', gettext_noop('Korean')),
|
||||||
|
('km', gettext_noop('Khmer')),
|
||||||
('kn', gettext_noop('Kannada')),
|
('kn', gettext_noop('Kannada')),
|
||||||
('lv', gettext_noop('Latvian')),
|
('lv', gettext_noop('Latvian')),
|
||||||
('mk', gettext_noop('Macedonian')),
|
('mk', gettext_noop('Macedonian')),
|
||||||
@ -269,12 +271,14 @@ MIDDLEWARE_CLASSES = (
|
|||||||
# SESSIONS #
|
# SESSIONS #
|
||||||
############
|
############
|
||||||
|
|
||||||
SESSION_COOKIE_NAME = 'sessionid' # Cookie name. This can be whatever you want.
|
SESSION_COOKIE_NAME = 'sessionid' # Cookie name. This can be whatever you want.
|
||||||
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # Age of cookie, in seconds (default: 2 weeks).
|
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # Age of cookie, in seconds (default: 2 weeks).
|
||||||
SESSION_COOKIE_DOMAIN = None # A string like ".lawrence.com", or None for standard domain cookie.
|
SESSION_COOKIE_DOMAIN = None # A string like ".lawrence.com", or None for standard domain cookie.
|
||||||
SESSION_COOKIE_SECURE = False # Whether the session cookie should be secure (https:// only).
|
SESSION_COOKIE_SECURE = False # Whether the session cookie should be secure (https:// only).
|
||||||
SESSION_SAVE_EVERY_REQUEST = False # Whether to save the session data on every request.
|
SESSION_SAVE_EVERY_REQUEST = False # Whether to save the session data on every request.
|
||||||
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Whether sessions expire when a user closes his browser.
|
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # Whether sessions expire when a user closes his browser.
|
||||||
|
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # The module to store session data
|
||||||
|
SESSION_FILE_PATH = '/tmp/' # Directory to store session files if using the file session module
|
||||||
|
|
||||||
#########
|
#########
|
||||||
# CACHE #
|
# CACHE #
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/ga/LC_MESSAGES/django.mo
Normal file
BIN
django/conf/locale/ga/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
3443
django/conf/locale/ga/LC_MESSAGES/django.po
Normal file
3443
django/conf/locale/ga/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/ga/LC_MESSAGES/djangojs.mo
Normal file
BIN
django/conf/locale/ga/LC_MESSAGES/djangojs.mo
Normal file
Binary file not shown.
116
django/conf/locale/ga/LC_MESSAGES/djangojs.po
Normal file
116
django/conf/locale/ga/LC_MESSAGES/djangojs.po
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: django 1.0\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2007-09-14 12:33+0100\n"
|
||||||
|
"PO-Revision-Date: 2007-09-14 14:19+0100\n"
|
||||||
|
"Last-Translator: Michael Thornhill <michael.thornhill@gmail.com>\n"
|
||||||
|
"Language-Team: Gaeilge <ga@li.org>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/calendar.js:24
|
||||||
|
#: contrib/admin/media/js/dateparse.js:32
|
||||||
|
msgid "January February March April May June July August September October November December"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/calendar.js:25
|
||||||
|
msgid "S M T W T F S"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/dateparse.js:33
|
||||||
|
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||||
|
#, perl-format
|
||||||
|
msgid "Available %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||||
|
msgid "Choose all"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||||
|
msgid "Add"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||||
|
#, perl-format
|
||||||
|
msgid "Chosen %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||||
|
msgid "Select your choice(s) and click "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||||
|
msgid "Clear all"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||||
|
msgid "Now"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||||
|
msgid "Clock"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||||
|
msgid "Choose a time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||||
|
msgid "Midnight"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||||
|
msgid "6 a.m."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||||
|
msgid "Noon"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
|
||||||
|
msgid "Today"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||||
|
msgid "Calendar"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||||
|
msgid "Yesterday"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||||
|
msgid "Tomorrow"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||||
|
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||||
|
msgid "Show"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||||
|
msgid "Hide"
|
||||||
|
msgstr ""
|
||||||
|
|
Binary file not shown.
@ -205,7 +205,7 @@ msgstr "פברואר"
|
|||||||
|
|
||||||
#: utils/dates.py:14 utils/dates.py:27
|
#: utils/dates.py:14 utils/dates.py:27
|
||||||
msgid "March"
|
msgid "March"
|
||||||
msgstr "מרץ"
|
msgstr "מרס"
|
||||||
|
|
||||||
#: utils/dates.py:14 utils/dates.py:27
|
#: utils/dates.py:14 utils/dates.py:27
|
||||||
msgid "April"
|
msgid "April"
|
||||||
@ -241,11 +241,11 @@ msgstr "נובמבר"
|
|||||||
|
|
||||||
#: utils/dates.py:16
|
#: utils/dates.py:16
|
||||||
msgid "December"
|
msgid "December"
|
||||||
msgstr "תצבר"
|
msgstr "דצמבר"
|
||||||
|
|
||||||
#: utils/dates.py:19
|
#: utils/dates.py:19
|
||||||
msgid "jan"
|
msgid "jan"
|
||||||
msgstr "יאנ"
|
msgstr "ינו"
|
||||||
|
|
||||||
#: utils/dates.py:19
|
#: utils/dates.py:19
|
||||||
msgid "feb"
|
msgid "feb"
|
||||||
@ -253,7 +253,7 @@ msgstr "פבר"
|
|||||||
|
|
||||||
#: utils/dates.py:19
|
#: utils/dates.py:19
|
||||||
msgid "mar"
|
msgid "mar"
|
||||||
msgstr "מרץ"
|
msgstr "מרס"
|
||||||
|
|
||||||
#: utils/dates.py:19
|
#: utils/dates.py:19
|
||||||
msgid "apr"
|
msgid "apr"
|
||||||
@ -293,7 +293,7 @@ msgstr "דצמ"
|
|||||||
|
|
||||||
#: utils/dates.py:27
|
#: utils/dates.py:27
|
||||||
msgid "Jan."
|
msgid "Jan."
|
||||||
msgstr "יאנ'"
|
msgstr "ינו'"
|
||||||
|
|
||||||
#: utils/dates.py:27
|
#: utils/dates.py:27
|
||||||
msgid "Feb."
|
msgid "Feb."
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,20 +1,21 @@
|
|||||||
# translation of djangojs.po to
|
# translation of djangojs.po to Hungarian
|
||||||
|
# translation of djangojs.po to
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER.
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER.
|
||||||
# Nagy Károly <charlie@rendszergazda.com>, 2006.
|
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: djangojs\n"
|
"Project-Id-Version: djangojs\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||||
"PO-Revision-Date: 2006-05-10 11:59+0200\n"
|
"PO-Revision-Date: 2007-09-13 13:30+0200\n"
|
||||||
"Last-Translator: Nagy Károly <charlie@rendszergazda.com>\n"
|
"Last-Translator: Szilveszter Farkas <szilveszter.farkas@gmail.com>\n"
|
||||||
"Language-Team: <hu@li.org>\n"
|
"Language-Team: Hungarian <hu@li.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Generator: KBabel 1.9.1\n"
|
"X-Generator: KBabel 1.11.4\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||||
#, perl-format
|
#, perl-format
|
||||||
@ -23,15 +24,15 @@ msgstr "Elérhető %s"
|
|||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||||
msgid "Choose all"
|
msgid "Choose all"
|
||||||
msgstr "Mindent kijelöl"
|
msgstr "Mindet kijelölni"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||||
msgid "Add"
|
msgid "Add"
|
||||||
msgstr "Hozzáad"
|
msgstr "Hozzáadás"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||||
msgid "Remove"
|
msgid "Remove"
|
||||||
msgstr "Eltávolít"
|
msgstr "Eltávolítás"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||||
#, perl-format
|
#, perl-format
|
||||||
@ -40,7 +41,7 @@ msgstr "%s kiválasztva"
|
|||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||||
msgid "Select your choice(s) and click "
|
msgid "Select your choice(s) and click "
|
||||||
msgstr "Válaszd ki a kért elemeket és kattints"
|
msgstr "Válassza ki a kért elemeket és kattintson"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||||
msgid "Clear all"
|
msgid "Clear all"
|
||||||
@ -51,11 +52,11 @@ msgstr "Összes törlése"
|
|||||||
msgid ""
|
msgid ""
|
||||||
"January February March April May June July August September October November "
|
"January February March April May June July August September October November "
|
||||||
"December"
|
"December"
|
||||||
msgstr "Január Február Március Április Május Június Július Szeptember Október November December"
|
msgstr "január február március április május június július augusztus szeptember október november december"
|
||||||
|
|
||||||
#: contrib/admin/media/js/dateparse.js:27
|
#: contrib/admin/media/js/dateparse.js:27
|
||||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||||
msgstr "Vasárnap Hétfő Kedd Szerda Csütörtök Péntek Szombat"
|
msgstr "vasárnap hétfő kedd szerda csütörtök péntek szombat"
|
||||||
|
|
||||||
#: contrib/admin/media/js/calendar.js:25
|
#: contrib/admin/media/js/calendar.js:25
|
||||||
msgid "S M T W T F S"
|
msgid "S M T W T F S"
|
||||||
@ -72,7 +73,7 @@ msgstr "Óra"
|
|||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||||
msgid "Choose a time"
|
msgid "Choose a time"
|
||||||
msgstr "Válaszd ki az időt"
|
msgstr "Válassza ki az időt"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||||
msgid "Midnight"
|
msgid "Midnight"
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/km/LC_MESSAGES/django.mo
Normal file
BIN
django/conf/locale/km/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
2508
django/conf/locale/km/LC_MESSAGES/django.po
Normal file
2508
django/conf/locale/km/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/km/LC_MESSAGES/djangojs.mo
Normal file
BIN
django/conf/locale/km/LC_MESSAGES/djangojs.mo
Normal file
Binary file not shown.
108
django/conf/locale/km/LC_MESSAGES/djangojs.po
Normal file
108
django/conf/locale/km/LC_MESSAGES/djangojs.po
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||||
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: 01\n"
|
||||||
|
"Report-Msgid-Bugs-To: sengtha@e-khmer.com\n"
|
||||||
|
"POT-Creation-Date: 2007-01-15 15:43+0200\n"
|
||||||
|
"PO-Revision-Date: 2007-01-21 01:25+0900\n"
|
||||||
|
"Last-Translator: Chay Sengtha <sengtha@e-khmer.com>\n"
|
||||||
|
"Language-Team: Chay Sengtha <sengtha@e-khmer.com>\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||||
|
#, perl-format
|
||||||
|
msgid "Available %s"
|
||||||
|
msgstr "%s ដែលអាចជ្រើសរើសបាន"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||||
|
msgid "Choose all"
|
||||||
|
msgstr "ជ្រើសរើសទាំងអស់"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||||
|
msgid "Add"
|
||||||
|
msgstr "បន្ថែម"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "លប់ចេញ"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||||
|
#, perl-format
|
||||||
|
msgid "Chosen %s"
|
||||||
|
msgstr "%s ដែលបានជ្រើសរើស"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||||
|
msgid "Select your choice(s) and click "
|
||||||
|
msgstr "សូមជ្រើសរើសយក"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||||
|
msgid "Clear all"
|
||||||
|
msgstr "លប់ចេញទាំងអស់"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/dateparse.js:26
|
||||||
|
#: contrib/admin/media/js/calendar.js:24
|
||||||
|
msgid "January February March April May June July August September October November December"
|
||||||
|
msgstr "January February March April May June July August September October November December"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/dateparse.js:27
|
||||||
|
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||||
|
msgstr "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/calendar.js:25
|
||||||
|
msgid "S M T W T F S"
|
||||||
|
msgstr "S M T W T F S"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
||||||
|
msgid "Now"
|
||||||
|
msgstr "ឥឡូវនេះ"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||||
|
msgid "Clock"
|
||||||
|
msgstr "នាឡិការ"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||||
|
msgid "Choose a time"
|
||||||
|
msgstr "ជ្រើសរើសម៉ោង"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||||
|
msgid "Midnight"
|
||||||
|
msgstr "អធ្រាត្រ"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||||
|
msgid "6 a.m."
|
||||||
|
msgstr "ម៉ោង ៦ ព្រឹក"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||||
|
msgid "Noon"
|
||||||
|
msgstr "ពេលថ្ងែត្រង់"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "លប់ចោល"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
||||||
|
msgid "Today"
|
||||||
|
msgstr "ថ្ងៃនេះ"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
|
||||||
|
msgid "Calendar"
|
||||||
|
msgstr "ប្រក្រតិទិន"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
||||||
|
msgid "Yesterday"
|
||||||
|
msgstr "ម្សិលមិញ"
|
||||||
|
|
||||||
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||||
|
msgid "Tomorrow"
|
||||||
|
msgstr "ថ្ងៃស្អែក"
|
||||||
|
|
Binary file not shown.
@ -825,12 +825,12 @@ msgstr "%d 자 이상 입력해 주세요."
|
|||||||
#: newforms/fields.py:130
|
#: newforms/fields.py:130
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Ensure this value is less than or equal to %s."
|
msgid "Ensure this value is less than or equal to %s."
|
||||||
msgstr "%s 자 이하로 입력해 주세요."
|
msgstr "%s 이하의 값을 입력해 주세요."
|
||||||
|
|
||||||
#: newforms/fields.py:132
|
#: newforms/fields.py:132
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Ensure this value is greater than or equal to %s."
|
msgid "Ensure this value is greater than or equal to %s."
|
||||||
msgstr "%s 자 이상 입력해 주세요."
|
msgstr "%s 이상의 값을 입력해 주세요."
|
||||||
|
|
||||||
#: newforms/fields.py:165
|
#: newforms/fields.py:165
|
||||||
msgid "Enter a valid date."
|
msgid "Enter a valid date."
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
# translation of djangojs.po to
|
# translation of djangojs.po to norwegian
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2005 and beyond
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the Django package.
|
||||||
# Espen Grindhaug <espen.grindhaug@mail.com>, 2006.
|
# Espen Grindhaug <espen.grindhaug@mail.com>, 2006.
|
||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -8,16 +8,14 @@ msgstr ""
|
|||||||
"Project-Id-Version: djangojs\n"
|
"Project-Id-Version: djangojs\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||||
"PO-Revision-Date: 2007-04-27 06:51+0200\n"
|
"PO-Revision-Date: 2007-08-29 18:22+0200\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: jonklo\n"
|
||||||
"Language-Team: <en@li.org>\n"
|
"Language-Team: Norsk <no@li.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Generator: KBabel 1.11.4\n"
|
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||||
#, perl-format
|
|
||||||
msgid "Available %s"
|
msgid "Available %s"
|
||||||
msgstr "%s er tilgjengelige"
|
msgstr "%s er tilgjengelige"
|
||||||
|
|
||||||
@ -34,13 +32,12 @@ msgid "Remove"
|
|||||||
msgstr "Slett"
|
msgstr "Slett"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||||
#, perl-format
|
|
||||||
msgid "Chosen %s"
|
msgid "Chosen %s"
|
||||||
msgstr "%s er valgt"
|
msgstr "%s er valgt"
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||||
msgid "Select your choice(s) and click "
|
msgid "Select your choice(s) and click "
|
||||||
msgstr "Velg ditt svaralternativ(er) og klikk"
|
msgstr "Velg ditt svaralternativ(er) og klikk "
|
||||||
|
|
||||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||||
msgid "Clear all"
|
msgid "Clear all"
|
||||||
@ -85,15 +82,15 @@ msgstr "Velg et klokkeslett"
|
|||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||||
msgid "Midnight"
|
msgid "Midnight"
|
||||||
msgstr "24.00"
|
msgstr "Midnatt"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||||
msgid "6 a.m."
|
msgid "6 a.m."
|
||||||
msgstr "06.00"
|
msgstr "06:00"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||||
msgid "Noon"
|
msgid "Noon"
|
||||||
msgstr "12.00"
|
msgstr "12:00"
|
||||||
|
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||||
|
Binary file not shown.
@ -14,7 +14,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"X-Generator: KBabel 1.11.4\n"
|
"X-Generator: KBabel 1.11.4\n"
|
||||||
"Plural-Forms: nplurals=2; nplurals=n>1;"
|
"Plural-Forms: nplurals=2; plural=n>1;"
|
||||||
|
|
||||||
#: contrib/comments/models.py:67 contrib/comments/models.py:166
|
#: contrib/comments/models.py:67 contrib/comments/models.py:166
|
||||||
msgid "object ID"
|
msgid "object ID"
|
||||||
|
Binary file not shown.
@ -107,3 +107,9 @@ msgstr "Dün"
|
|||||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||||
msgid "Tomorrow"
|
msgid "Tomorrow"
|
||||||
msgstr "Yarın"
|
msgstr "Yarın"
|
||||||
|
|
||||||
|
msgid "Show"
|
||||||
|
msgstr "Göster"
|
||||||
|
|
||||||
|
msgid "Hide"
|
||||||
|
msgstr "Gizle"
|
||||||
|
@ -24,7 +24,7 @@ DATABASE_PORT = '' # Set to empty string for default. Not used with
|
|||||||
TIME_ZONE = 'America/Chicago'
|
TIME_ZONE = 'America/Chicago'
|
||||||
|
|
||||||
# Language code for this installation. All choices can be found here:
|
# Language code for this installation. All choices can be found here:
|
||||||
# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
|
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
SITE_ID = 1
|
SITE_ID = 1
|
||||||
|
1
django/contrib/admin/media/css/null.css
Normal file
1
django/contrib/admin/media/css/null.css
Normal file
@ -0,0 +1 @@
|
|||||||
|
/* Nothing to see here. Dummy file to feed to the high pass filter which hides CSS from IE5/win. Details: http://tantek.com/CSS/Examples/highpass.html */
|
@ -43,7 +43,7 @@ p.file-upload { line-height:20px; margin:0; padding:0; color:#666; font-size:11p
|
|||||||
|
|
||||||
/* CALENDARS & CLOCKS */
|
/* CALENDARS & CLOCKS */
|
||||||
.calendarbox, .clockbox { margin:5px auto; font-size:11px; width:16em; text-align:center; background:white; position:relative; }
|
.calendarbox, .clockbox { margin:5px auto; font-size:11px; width:16em; text-align:center; background:white; position:relative; }
|
||||||
.clockbox { width:9em; }
|
.clockbox { width:auto; }
|
||||||
.calendar { margin:0; padding: 0; }
|
.calendar { margin:0; padding: 0; }
|
||||||
.calendar table { margin:0; padding:0; border-collapse:collapse; background:white; width:99%; }
|
.calendar table { margin:0; padding:0; border-collapse:collapse; background:white; width:99%; }
|
||||||
.calendar caption, .calendarbox h2 { margin: 0; font-size:11px; text-align:center; border-top:none; }
|
.calendar caption, .calendarbox h2 { margin: 0; font-size:11px; text-align:center; border-top:none; }
|
||||||
|
@ -58,7 +58,7 @@ var SelectFilter = {
|
|||||||
quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name]));
|
quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s'), [field_name]));
|
||||||
var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click '));
|
var selector_filter = quickElement('p', selector_chosen, gettext('Select your choice(s) and click '));
|
||||||
selector_filter.className = 'selector-filter';
|
selector_filter.className = 'selector-filter';
|
||||||
quickElement('img', selector_filter, '', 'src', admin_media_prefix + 'img/admin/selector-add.gif', 'alt', 'Add');
|
quickElement('img', selector_filter, '', 'src', admin_media_prefix + (is_stacked ? 'img/admin/selector_stacked-add.gif':'img/admin/selector-add.gif'), 'alt', 'Add');
|
||||||
var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
|
var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));
|
||||||
to_box.className = 'filtered';
|
to_box.className = 'filtered';
|
||||||
var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');
|
var clear_all = quickElement('a', selector_chosen, gettext('Clear all'), 'href', 'javascript: (function() { SelectBox.move_all("' + field_id + '_to", "' + field_id + '_from");})()');
|
||||||
|
@ -195,6 +195,19 @@ var DateTimeShortcuts = {
|
|||||||
openCalendar: function(num) {
|
openCalendar: function(num) {
|
||||||
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
|
var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1+num)
|
||||||
var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num)
|
var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName+num)
|
||||||
|
var inp = DateTimeShortcuts.calendarInputs[num];
|
||||||
|
|
||||||
|
// Determine if the current value in the input has a valid date.
|
||||||
|
// If so, draw the calendar with that date's year and month.
|
||||||
|
if (inp.value) {
|
||||||
|
var date_parts = inp.value.split('-');
|
||||||
|
var year = date_parts[0];
|
||||||
|
var month = parseFloat(date_parts[1]);
|
||||||
|
if (year.match(/\d\d\d\d/) && month >= 1 && month <= 12) {
|
||||||
|
DateTimeShortcuts.calendars[num].drawDate(month, year);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Recalculate the clockbox position
|
// Recalculate the clockbox position
|
||||||
// is it left-to-right or right-to-left layout ?
|
// is it left-to-right or right-to-left layout ?
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
// Core javascript helper functions
|
// Core javascript helper functions
|
||||||
|
|
||||||
|
// basic browser identification & version
|
||||||
|
var isOpera = (navigator.userAgent.indexOf("Opera")>=0) && parseFloat(navigator.appVersion);
|
||||||
|
var isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split("MSIE ")[1].split(";")[0]);
|
||||||
|
|
||||||
// Cross-browser event handlers.
|
// Cross-browser event handlers.
|
||||||
function addEvent(obj, evType, fn) {
|
function addEvent(obj, evType, fn) {
|
||||||
if (obj.addEventListener) {
|
if (obj.addEventListener) {
|
||||||
@ -71,9 +75,13 @@ function findPosX(obj) {
|
|||||||
var curleft = 0;
|
var curleft = 0;
|
||||||
if (obj.offsetParent) {
|
if (obj.offsetParent) {
|
||||||
while (obj.offsetParent) {
|
while (obj.offsetParent) {
|
||||||
curleft += obj.offsetLeft;
|
curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft);
|
||||||
obj = obj.offsetParent;
|
obj = obj.offsetParent;
|
||||||
}
|
}
|
||||||
|
// IE offsetParent does not include the top-level
|
||||||
|
if (isIE && obj.parentElement){
|
||||||
|
curleft += obj.offsetLeft - obj.scrollLeft;
|
||||||
|
}
|
||||||
} else if (obj.x) {
|
} else if (obj.x) {
|
||||||
curleft += obj.x;
|
curleft += obj.x;
|
||||||
}
|
}
|
||||||
@ -84,9 +92,13 @@ function findPosY(obj) {
|
|||||||
var curtop = 0;
|
var curtop = 0;
|
||||||
if (obj.offsetParent) {
|
if (obj.offsetParent) {
|
||||||
while (obj.offsetParent) {
|
while (obj.offsetParent) {
|
||||||
curtop += obj.offsetTop;
|
curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop);
|
||||||
obj = obj.offsetParent;
|
obj = obj.offsetParent;
|
||||||
}
|
}
|
||||||
|
// IE offsetParent does not include the top-level
|
||||||
|
if (isIE && obj.parentElement){
|
||||||
|
curtop += obj.offsetTop - obj.scrollTop;
|
||||||
|
}
|
||||||
} else if (obj.y) {
|
} else if (obj.y) {
|
||||||
curtop += obj.y;
|
curtop += obj.y;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,9 @@ var RUSSIAN_MAP = {
|
|||||||
'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
|
'Ч':'Ch', 'Ш':'Sh', 'Щ':'Sh', 'Ъ':'', 'Ы':'Y', 'Ь':'', 'Э':'E', 'Ю':'Yu',
|
||||||
'Я':'Ya'
|
'Я':'Ya'
|
||||||
}
|
}
|
||||||
|
var UKRAINIAN_MAP = {
|
||||||
|
'Є':'Ye', 'І':'I', 'Ї':'Yi', 'Ґ':'G', 'є':'ye', 'і':'i', 'ї':'yi', 'ґ':'g'
|
||||||
|
}
|
||||||
var CZECH_MAP = {
|
var CZECH_MAP = {
|
||||||
'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
|
'č':'c', 'ď':'d', 'ě':'e', 'ň': 'n', 'ř':'r', 'š':'s', 'ť':'t', 'ů':'u',
|
||||||
'ž':'z'
|
'ž':'z'
|
||||||
@ -51,7 +54,8 @@ ALL_DOWNCODE_MAPS[1]=LATIN_SYMBOLS_MAP
|
|||||||
ALL_DOWNCODE_MAPS[2]=GREEK_MAP
|
ALL_DOWNCODE_MAPS[2]=GREEK_MAP
|
||||||
ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
|
ALL_DOWNCODE_MAPS[3]=TURKISH_MAP
|
||||||
ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
|
ALL_DOWNCODE_MAPS[4]=RUSSIAN_MAP
|
||||||
ALL_DOWNCODE_MAPS[5]=CZECH_MAP
|
ALL_DOWNCODE_MAPS[5]=UKRAINIAN_MAP
|
||||||
|
ALL_DOWNCODE_MAPS[6]=CZECH_MAP
|
||||||
|
|
||||||
var Downcoder = new Object();
|
var Downcoder = new Object();
|
||||||
Downcoder.Initialize = function()
|
Downcoder.Initialize = function()
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block stylesheet %}{% admin_media_prefix %}css/forms.css{% endblock %}
|
{% block stylesheet %}{% admin_media_prefix %}css/forms.css{% endblock %}
|
||||||
{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
|
{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
|
||||||
{% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block breadcrumbs %}{% if not is_popup %}
|
{% block breadcrumbs %}{% if not is_popup %}
|
||||||
<div class="breadcrumbs">
|
<div class="breadcrumbs">
|
||||||
<a href="../../../../">{% trans "Home" %}</a> ›
|
<a href="../../../../">{% trans "Home" %}</a> ›
|
||||||
|
@ -22,7 +22,14 @@
|
|||||||
{% block branding %}{% endblock %}
|
{% block branding %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
{% if user.is_authenticated and user.is_staff %}
|
{% if user.is_authenticated and user.is_staff %}
|
||||||
<div id="user-tools">{% trans 'Welcome,' %} <strong>{% if user.first_name %}{{ user.first_name|escape }}{% else %}{{ user.username }}{% endif %}</strong>. {% block userlinks %}<a href="doc/">{% trans 'Documentation' %}</a> / <a href="password_change/">{% trans 'Change password' %}</a> / <a href="logout/">{% trans 'Log out' %}</a>{% endblock %}</div>
|
<div id="user-tools">
|
||||||
|
{% trans 'Welcome,' %} <strong>{% if user.first_name %}{{ user.first_name|escape }}{% else %}{{ user.username }}{% endif %}</strong>.
|
||||||
|
{% block userlinks %}
|
||||||
|
<a href="{% url django.contrib.admin.views.doc.doc_index %}">{% trans 'Documentation' %}</a>
|
||||||
|
/ <a href="{% url django.contrib.auth.views.password_change %}">{% trans 'Change password' %}</a>
|
||||||
|
/ <a href="{% url django.contrib.auth.views.logout %}">{% trans 'Log out' %}</a>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% block nav-global %}{% endblock %}
|
{% block nav-global %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
{% block stylesheet %}{% admin_media_prefix %}css/forms.css{% endblock %}
|
{% block stylesheet %}{% admin_media_prefix %}css/forms.css{% endblock %}
|
||||||
{% block coltype %}{% if ordered_objects %}colMS{% else %}colM{% endif %}{% endblock %}
|
{% block coltype %}{% if ordered_objects %}colMS{% else %}colM{% endif %}{% endblock %}
|
||||||
{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
|
{% block bodyclass %}{{ opts.app_label }}-{{ opts.object_name.lower }} change-form{% endblock %}
|
||||||
{% block userlinks %}<a href="../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block breadcrumbs %}{% if not is_popup %}
|
{% block breadcrumbs %}{% if not is_popup %}
|
||||||
<div class="breadcrumbs">
|
<div class="breadcrumbs">
|
||||||
<a href="../../../">{% trans "Home" %}</a> ›
|
<a href="../../../">{% trans "Home" %}</a> ›
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
{% load adminmedia admin_list i18n %}
|
{% load adminmedia admin_list i18n %}
|
||||||
{% block stylesheet %}{% admin_media_prefix %}css/changelists.css{% endblock %}
|
{% block stylesheet %}{% admin_media_prefix %}css/changelists.css{% endblock %}
|
||||||
{% block bodyclass %}change-list{% endblock %}
|
{% block bodyclass %}change-list{% endblock %}
|
||||||
{% block userlinks %}<a href="../../doc/">{% trans 'Documentation' %}</a> / <a href="../../password_change/">{% trans 'Change password' %}</a> / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% if not is_popup %}{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> › {{ cl.opts.verbose_name_plural|capfirst|escape }}</div>{% endblock %}{% endif %}
|
{% if not is_popup %}{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> › {{ cl.opts.verbose_name_plural|capfirst|escape }}</div>{% endblock %}{% endif %}
|
||||||
{% block coltype %}flex{% endblock %}
|
{% block coltype %}flex{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for result in results %}
|
{% for result in results %}
|
||||||
<tr class="{% cycle row1,row2 %}">{% for item in result %}{{ item }}{% endfor %}</tr>
|
<tr class="{% cycle 'row1' 'row2' %}">{% for item in result %}{{ item }}{% endfor %}</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<div class="breadcrumbs">
|
<div class="breadcrumbs">
|
||||||
<a href="../../../../">{% trans "Home" %}</a> ›
|
<a href="../../../../">{% trans "Home" %}</a> ›
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block userlinks %}<a href="../../../../doc/">{% trans 'Documentation' %}</a> / <a href="../../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block breadcrumbs %}
|
{% block breadcrumbs %}
|
||||||
<div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> › <a href="../../">{{ module_name|escape }}</a> › <a href="../">{{ object|escape|truncatewords:"18" }}</a> › {% trans 'History' %}</div>
|
<div class="breadcrumbs"><a href="../../../../">{% trans 'Home' %}</a> › <a href="../../">{{ module_name|escape }}</a> › <a href="../">{{ object|escape|truncatewords:"18" }}</a> › {% trans 'History' %}</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
|
|
||||||
{% block breadcrumbs %}{% load i18n %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> › <a href="../">{% trans "Documentation" %}</a> › {% trans "Bookmarklets" %}</div>{% endblock %}
|
{% block breadcrumbs %}{% load i18n %}<div class="breadcrumbs"><a href="../../">{% trans "Home" %}</a> › <a href="../">{% trans "Documentation" %}</a> › {% trans "Bookmarklets" %}</div>{% endblock %}
|
||||||
{% block userlinks %}<a href="../../password_change/">{% trans 'Change password' %}</a> / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block title %}{% trans "Documentation bookmarklets" %}{% endblock %}
|
{% block title %}{% trans "Documentation bookmarklets" %}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">Home</a> › Documentation</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">Home</a> › Documentation</div>{% endblock %}
|
||||||
{% block userlinks %}<a href="../password_change/">{% trans 'Change password' %}</a> / <a href="../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block title %}Documentation{% endblock %}
|
{% block title %}Documentation{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">Home</a> › Documentation</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">Home</a> › Documentation</div>{% endblock %}
|
||||||
{% block userlinks %}<a href="../password_change/">{% trans 'Change password' %}</a> / <a href="../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block title %}Please install docutils{% endblock %}
|
{% block title %}Please install docutils{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block userlinks %}<a href="../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block extrahead %}
|
{% block extrahead %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block coltype %}colSM{% endblock %}
|
{% block coltype %}colSM{% endblock %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › Models</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › Models</div>{% endblock %}
|
||||||
{% block userlinks %}<a href="../../password_change/">{% trans 'Change password' %}</a> / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
|
|
||||||
{% block title %}Models{% endblock %}
|
{% block title %}Models{% endblock %}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> › <a href="../../">Documentation</a> › Templates › {{ name|escape }}</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> › <a href="../../">Documentation</a> › Templates › {{ name|escape }}</div>{% endblock %}
|
||||||
{% block userlinks %}<a href="../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
|
|
||||||
{% block title %}Template: {{ name|escape }}{% endblock %}
|
{% block title %}Template: {{ name|escape }}{% endblock %}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block coltype %}colSM{% endblock %}
|
{% block coltype %}colSM{% endblock %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › filters</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › filters</div>{% endblock %}
|
||||||
{% block userlinks %}<a href="../../password_change/">{% trans 'Change password' %}</a> / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block title %}Template filters{% endblock %}
|
{% block title %}Template filters{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block coltype %}colSM{% endblock %}
|
{% block coltype %}colSM{% endblock %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › Tags</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › Tags</div>{% endblock %}
|
||||||
{% block userlinks %}<a href="../../password_change/">{% trans 'Change password' %}</a> / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block title %}Template tags{% endblock %}
|
{% block title %}Template tags{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> › <a href="../../">Documentation</a> › <a href="../">Views</a> › {{ name }}</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../../">Home</a> › <a href="../../">Documentation</a> › <a href="../">Views</a> › {{ name }}</div>{% endblock %}
|
||||||
{% block userlinks %}<a href="../../../password_change/">{% trans 'Change password' %}</a> / <a href="../../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block title %}View: {{ name }}{% endblock %}
|
{% block title %}View: {{ name }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block coltype %}colSM{% endblock %}
|
{% block coltype %}colSM{% endblock %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › Views</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › Views</div>{% endblock %}
|
||||||
{% block userlinks %}<a href="../../password_change/">{% trans 'Change password' %}</a> / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block title %}Views{% endblock %}
|
{% block title %}Views{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block userlinks %}<a href="../../doc/">{% trans 'Documentation' %}</a> / {% trans 'Change password' %} / <a href="../../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> › {% trans 'Password change' %}</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">{% trans 'Home' %}</a> › {% trans 'Password change' %}</div>{% endblock %}
|
||||||
|
|
||||||
{% block title %}{% trans 'Password change successful' %}{% endblock %}
|
{% block title %}{% trans 'Password change successful' %}{% endblock %}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block userlinks %}<a href="../doc/">{% trans 'Documentation' %}</a> / {% trans 'Change password' %} / <a href="../logout/">{% trans 'Log out' %}</a>{% endblock %}
|
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> › {% trans 'Password change' %}</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">{% trans 'Home' %}</a> › {% trans 'Password change' %}</div>{% endblock %}
|
||||||
|
|
||||||
{% block title %}{% trans 'Password change' %}{% endblock %}
|
{% block title %}{% trans 'Password change' %}{% endblock %}
|
||||||
|
@ -5,7 +5,7 @@ from django.contrib.admin.views.decorators import staff_member_required
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
|
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
|
||||||
from django.http import Http404, get_host
|
from django.http import Http404
|
||||||
from django.core import urlresolvers
|
from django.core import urlresolvers
|
||||||
from django.contrib.admin import utils
|
from django.contrib.admin import utils
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
@ -29,7 +29,7 @@ def bookmarklets(request):
|
|||||||
# Hack! This couples this view to the URL it lives at.
|
# Hack! This couples this view to the URL it lives at.
|
||||||
admin_root = request.path[:-len('doc/bookmarklets/')]
|
admin_root = request.path[:-len('doc/bookmarklets/')]
|
||||||
return render_to_response('admin_doc/bookmarklets.html', {
|
return render_to_response('admin_doc/bookmarklets.html', {
|
||||||
'admin_url': "%s://%s%s" % (request.is_secure() and 'https' or 'http', get_host(request), admin_root),
|
'admin_url': "%s://%s%s" % (request.is_secure() and 'https' or 'http', request.get_host(), admin_root),
|
||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request))
|
||||||
bookmarklets = staff_member_required(bookmarklets)
|
bookmarklets = staff_member_required(bookmarklets)
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ class AdminBoundField(object):
|
|||||||
|
|
||||||
def original_value(self):
|
def original_value(self):
|
||||||
if self.original:
|
if self.original:
|
||||||
return self.original.__dict__[self.field.column]
|
return self.original.__dict__[self.field.attname]
|
||||||
|
|
||||||
def existing_display(self):
|
def existing_display(self):
|
||||||
try:
|
try:
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from django.db import connection
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
class ModelBackend:
|
class ModelBackend:
|
||||||
@ -14,6 +15,49 @@ class ModelBackend:
|
|||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_group_permissions(self, user_obj):
|
||||||
|
"Returns a list of permission strings that this user has through his/her groups."
|
||||||
|
if not hasattr(user_obj, '_group_perm_cache'):
|
||||||
|
cursor = connection.cursor()
|
||||||
|
# The SQL below works out to the following, after DB quoting:
|
||||||
|
# cursor.execute("""
|
||||||
|
# SELECT ct."app_label", p."codename"
|
||||||
|
# FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct
|
||||||
|
# WHERE p."id" = gp."permission_id"
|
||||||
|
# AND gp."group_id" = ug."group_id"
|
||||||
|
# AND ct."id" = p."content_type_id"
|
||||||
|
# AND ug."user_id" = %s, [self.id])
|
||||||
|
qn = connection.ops.quote_name
|
||||||
|
sql = """
|
||||||
|
SELECT ct.%s, p.%s
|
||||||
|
FROM %s p, %s gp, %s ug, %s ct
|
||||||
|
WHERE p.%s = gp.%s
|
||||||
|
AND gp.%s = ug.%s
|
||||||
|
AND ct.%s = p.%s
|
||||||
|
AND ug.%s = %%s""" % (
|
||||||
|
qn('app_label'), qn('codename'),
|
||||||
|
qn('auth_permission'), qn('auth_group_permissions'),
|
||||||
|
qn('auth_user_groups'), qn('django_content_type'),
|
||||||
|
qn('id'), qn('permission_id'),
|
||||||
|
qn('group_id'), qn('group_id'),
|
||||||
|
qn('id'), qn('content_type_id'),
|
||||||
|
qn('user_id'),)
|
||||||
|
cursor.execute(sql, [user_obj.id])
|
||||||
|
user_obj._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
|
||||||
|
return user_obj._group_perm_cache
|
||||||
|
|
||||||
|
def get_all_permissions(self, user_obj):
|
||||||
|
if not hasattr(user_obj, '_perm_cache'):
|
||||||
|
user_obj._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in user_obj.user_permissions.select_related()])
|
||||||
|
user_obj._perm_cache.update(self.get_group_permissions(user_obj))
|
||||||
|
return user_obj._perm_cache
|
||||||
|
|
||||||
|
def has_perm(self, user_obj, perm):
|
||||||
|
return perm in self.get_all_permissions(user_obj)
|
||||||
|
|
||||||
|
def has_module_perms(self, user_obj, app_label):
|
||||||
|
return bool(len([p for p in self.get_all_permissions(user_obj) if p[:p.index('.')] == app_label]))
|
||||||
|
|
||||||
def get_user(self, user_id):
|
def get_user(self, user_id):
|
||||||
try:
|
try:
|
||||||
return User.objects.get(pk=user_id)
|
return User.objects.get(pk=user_id)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from urllib import quote
|
from django.utils.http import urlquote
|
||||||
|
|
||||||
def user_passes_test(test_func, login_url=None):
|
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
|
||||||
"""
|
"""
|
||||||
Decorator for views that checks that the user passes the given test,
|
Decorator for views that checks that the user passes the given test,
|
||||||
redirecting to the log-in page if necessary. The test should be a callable
|
redirecting to the log-in page if necessary. The test should be a callable
|
||||||
@ -15,20 +15,25 @@ def user_passes_test(test_func, login_url=None):
|
|||||||
def _checklogin(request, *args, **kwargs):
|
def _checklogin(request, *args, **kwargs):
|
||||||
if test_func(request.user):
|
if test_func(request.user):
|
||||||
return view_func(request, *args, **kwargs)
|
return view_func(request, *args, **kwargs)
|
||||||
return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, quote(request.get_full_path())))
|
return HttpResponseRedirect('%s?%s=%s' % (login_url, redirect_field_name, urlquote(request.get_full_path())))
|
||||||
_checklogin.__doc__ = view_func.__doc__
|
_checklogin.__doc__ = view_func.__doc__
|
||||||
_checklogin.__dict__ = view_func.__dict__
|
_checklogin.__dict__ = view_func.__dict__
|
||||||
|
|
||||||
return _checklogin
|
return _checklogin
|
||||||
return _dec
|
return _dec
|
||||||
|
|
||||||
login_required = user_passes_test(lambda u: u.is_authenticated())
|
def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME):
|
||||||
login_required.__doc__ = (
|
|
||||||
"""
|
"""
|
||||||
Decorator for views that checks that the user is logged in, redirecting
|
Decorator for views that checks that the user is logged in, redirecting
|
||||||
to the log-in page if necessary.
|
to the log-in page if necessary.
|
||||||
"""
|
"""
|
||||||
|
actual_decorator = user_passes_test(
|
||||||
|
lambda u: u.is_authenticated(),
|
||||||
|
redirect_field_name=redirect_field_name
|
||||||
)
|
)
|
||||||
|
if function:
|
||||||
|
return actual_decorator(function)
|
||||||
|
return actual_decorator
|
||||||
|
|
||||||
def permission_required(perm, login_url=None):
|
def permission_required(perm, login_url=None):
|
||||||
"""
|
"""
|
||||||
|
@ -10,6 +10,10 @@ def authenhandler(req, **kwargs):
|
|||||||
# that so that the following import works
|
# that so that the following import works
|
||||||
os.environ.update(req.subprocess_env)
|
os.environ.update(req.subprocess_env)
|
||||||
|
|
||||||
|
# apache 2.2 requires a call to req.get_basic_auth_pw() before
|
||||||
|
# req.user and friends are available.
|
||||||
|
req.get_basic_auth_pw()
|
||||||
|
|
||||||
# check for PythonOptions
|
# check for PythonOptions
|
||||||
_str_to_bool = lambda s: s.lower() in ('1', 'true', 'on', 'yes')
|
_str_to_bool = lambda s: s.lower() in ('1', 'true', 'on', 'yes')
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
from django.contrib import auth
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import connection, models
|
from django.db import models
|
||||||
|
from django.db.models.manager import EmptyManager
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
@ -14,25 +16,43 @@ try:
|
|||||||
except NameError:
|
except NameError:
|
||||||
from sets import Set as set # Python 2.3 fallback
|
from sets import Set as set # Python 2.3 fallback
|
||||||
|
|
||||||
|
def get_hexdigest(algorithm, salt, raw_password):
|
||||||
|
"""
|
||||||
|
Returns a string of the hexdigest of the given plaintext password and salt
|
||||||
|
using the given algorithm ('md5', 'sha1' or 'crypt').
|
||||||
|
"""
|
||||||
|
raw_password, salt = smart_str(raw_password), smart_str(salt)
|
||||||
|
if algorithm == 'crypt':
|
||||||
|
try:
|
||||||
|
import crypt
|
||||||
|
except ImportError:
|
||||||
|
raise ValueError('"crypt" password algorithm not supported in this environment')
|
||||||
|
return crypt.crypt(raw_password, salt)
|
||||||
|
# The rest of the supported algorithms are supported by hashlib, but
|
||||||
|
# hashlib is only available in Python 2.5.
|
||||||
|
try:
|
||||||
|
import hashlib
|
||||||
|
except ImportError:
|
||||||
|
if algorithm == 'md5':
|
||||||
|
import md5
|
||||||
|
return md5.new(salt + raw_password).hexdigest()
|
||||||
|
elif algorithm == 'sha1':
|
||||||
|
import sha
|
||||||
|
return sha.new(salt + raw_password).hexdigest()
|
||||||
|
else:
|
||||||
|
if algorithm == 'md5':
|
||||||
|
return hashlib.md5(salt + raw_password).hexdigest()
|
||||||
|
elif algorithm == 'sha1':
|
||||||
|
return hashlib.sha1(salt + raw_password).hexdigest()
|
||||||
|
raise ValueError("Got unknown password algorithm type in password.")
|
||||||
|
|
||||||
def check_password(raw_password, enc_password):
|
def check_password(raw_password, enc_password):
|
||||||
"""
|
"""
|
||||||
Returns a boolean of whether the raw_password was correct. Handles
|
Returns a boolean of whether the raw_password was correct. Handles
|
||||||
encryption formats behind the scenes.
|
encryption formats behind the scenes.
|
||||||
"""
|
"""
|
||||||
algo, salt, hsh = enc_password.split('$')
|
algo, salt, hsh = enc_password.split('$')
|
||||||
if algo == 'md5':
|
return hsh == get_hexdigest(algo, salt, raw_password)
|
||||||
import md5
|
|
||||||
return hsh == md5.new(smart_str(salt + raw_password)).hexdigest()
|
|
||||||
elif algo == 'sha1':
|
|
||||||
import sha
|
|
||||||
return hsh == sha.new(smart_str(salt + raw_password)).hexdigest()
|
|
||||||
elif algo == 'crypt':
|
|
||||||
try:
|
|
||||||
import crypt
|
|
||||||
except ImportError:
|
|
||||||
raise ValueError, "Crypt password algorithm not supported in this environment."
|
|
||||||
return hsh == crypt.crypt(smart_str(raw_password), smart_str(salt))
|
|
||||||
raise ValueError, "Got unknown password algorithm type in password."
|
|
||||||
|
|
||||||
class SiteProfileNotAvailable(Exception):
|
class SiteProfileNotAvailable(Exception):
|
||||||
pass
|
pass
|
||||||
@ -161,10 +181,10 @@ class User(models.Model):
|
|||||||
return full_name.strip()
|
return full_name.strip()
|
||||||
|
|
||||||
def set_password(self, raw_password):
|
def set_password(self, raw_password):
|
||||||
import sha, random
|
import random
|
||||||
algo = 'sha1'
|
algo = 'sha1'
|
||||||
salt = sha.new(str(random.random())).hexdigest()[:5]
|
salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
|
||||||
hsh = sha.new(salt + smart_str(raw_password)).hexdigest()
|
hsh = get_hexdigest(algo, salt, raw_password)
|
||||||
self.password = '%s$%s$%s' % (algo, salt, hsh)
|
self.password = '%s$%s$%s' % (algo, salt, hsh)
|
||||||
|
|
||||||
def check_password(self, raw_password):
|
def check_password(self, raw_password):
|
||||||
@ -175,8 +195,7 @@ class User(models.Model):
|
|||||||
# Backwards-compatibility check. Older passwords won't include the
|
# Backwards-compatibility check. Older passwords won't include the
|
||||||
# algorithm or salt.
|
# algorithm or salt.
|
||||||
if '$' not in self.password:
|
if '$' not in self.password:
|
||||||
import md5
|
is_correct = (self.password == get_hexdigest('md5', '', raw_password))
|
||||||
is_correct = (self.password == md5.new(smart_str(raw_password)).hexdigest())
|
|
||||||
if is_correct:
|
if is_correct:
|
||||||
# Convert the password to the new, more secure format.
|
# Convert the password to the new, more secure format.
|
||||||
self.set_password(raw_password)
|
self.set_password(raw_password)
|
||||||
@ -192,64 +211,68 @@ class User(models.Model):
|
|||||||
return self.password != UNUSABLE_PASSWORD
|
return self.password != UNUSABLE_PASSWORD
|
||||||
|
|
||||||
def get_group_permissions(self):
|
def get_group_permissions(self):
|
||||||
"Returns a list of permission strings that this user has through his/her groups."
|
"""
|
||||||
if not hasattr(self, '_group_perm_cache'):
|
Returns a list of permission strings that this user has through
|
||||||
cursor = connection.cursor()
|
his/her groups. This method queries all available auth backends.
|
||||||
# The SQL below works out to the following, after DB quoting:
|
"""
|
||||||
# cursor.execute("""
|
permissions = set()
|
||||||
# SELECT ct."app_label", p."codename"
|
for backend in auth.get_backends():
|
||||||
# FROM "auth_permission" p, "auth_group_permissions" gp, "auth_user_groups" ug, "django_content_type" ct
|
if hasattr(backend, "get_group_permissions"):
|
||||||
# WHERE p."id" = gp."permission_id"
|
permissions.update(backend.get_group_permissions(self))
|
||||||
# AND gp."group_id" = ug."group_id"
|
return permissions
|
||||||
# AND ct."id" = p."content_type_id"
|
|
||||||
# AND ug."user_id" = %s, [self.id])
|
|
||||||
qn = connection.ops.quote_name
|
|
||||||
sql = """
|
|
||||||
SELECT ct.%s, p.%s
|
|
||||||
FROM %s p, %s gp, %s ug, %s ct
|
|
||||||
WHERE p.%s = gp.%s
|
|
||||||
AND gp.%s = ug.%s
|
|
||||||
AND ct.%s = p.%s
|
|
||||||
AND ug.%s = %%s""" % (
|
|
||||||
qn('app_label'), qn('codename'),
|
|
||||||
qn('auth_permission'), qn('auth_group_permissions'),
|
|
||||||
qn('auth_user_groups'), qn('django_content_type'),
|
|
||||||
qn('id'), qn('permission_id'),
|
|
||||||
qn('group_id'), qn('group_id'),
|
|
||||||
qn('id'), qn('content_type_id'),
|
|
||||||
qn('user_id'),)
|
|
||||||
cursor.execute(sql, [self.id])
|
|
||||||
self._group_perm_cache = set(["%s.%s" % (row[0], row[1]) for row in cursor.fetchall()])
|
|
||||||
return self._group_perm_cache
|
|
||||||
|
|
||||||
def get_all_permissions(self):
|
def get_all_permissions(self):
|
||||||
if not hasattr(self, '_perm_cache'):
|
permissions = set()
|
||||||
self._perm_cache = set([u"%s.%s" % (p.content_type.app_label, p.codename) for p in self.user_permissions.select_related()])
|
for backend in auth.get_backends():
|
||||||
self._perm_cache.update(self.get_group_permissions())
|
if hasattr(backend, "get_all_permissions"):
|
||||||
return self._perm_cache
|
permissions.update(backend.get_all_permissions(self))
|
||||||
|
return permissions
|
||||||
|
|
||||||
def has_perm(self, perm):
|
def has_perm(self, perm):
|
||||||
"Returns True if the user has the specified permission."
|
"""
|
||||||
|
Returns True if the user has the specified permission. This method
|
||||||
|
queries all available auth backends, but returns immediately if any
|
||||||
|
backend returns True. Thus, a user who has permission from a single
|
||||||
|
auth backend is assumed to have permission in general.
|
||||||
|
"""
|
||||||
|
# Inactive users have no permissions.
|
||||||
if not self.is_active:
|
if not self.is_active:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Superusers have all permissions.
|
||||||
if self.is_superuser:
|
if self.is_superuser:
|
||||||
return True
|
return True
|
||||||
return perm in self.get_all_permissions()
|
|
||||||
|
# Otherwise we need to check the backends.
|
||||||
|
for backend in auth.get_backends():
|
||||||
|
if hasattr(backend, "has_perm"):
|
||||||
|
if backend.has_perm(self, perm):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def has_perms(self, perm_list):
|
def has_perms(self, perm_list):
|
||||||
"Returns True if the user has each of the specified permissions."
|
"""Returns True if the user has each of the specified permissions."""
|
||||||
for perm in perm_list:
|
for perm in perm_list:
|
||||||
if not self.has_perm(perm):
|
if not self.has_perm(perm):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def has_module_perms(self, app_label):
|
def has_module_perms(self, app_label):
|
||||||
"Returns True if the user has any permissions in the given app label."
|
"""
|
||||||
|
Returns True if the user has any permissions in the given app
|
||||||
|
label. Uses pretty much the same logic as has_perm, above.
|
||||||
|
"""
|
||||||
if not self.is_active:
|
if not self.is_active:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.is_superuser:
|
if self.is_superuser:
|
||||||
return True
|
return True
|
||||||
return bool(len([p for p in self.get_all_permissions() if p[:p.index('.')] == app_label]))
|
|
||||||
|
for backend in auth.get_backends():
|
||||||
|
if hasattr(backend, "has_module_perms"):
|
||||||
|
if backend.has_module_perms(self, app_label):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def get_and_delete_messages(self):
|
def get_and_delete_messages(self):
|
||||||
messages = []
|
messages = []
|
||||||
@ -282,7 +305,12 @@ class User(models.Model):
|
|||||||
|
|
||||||
class Message(models.Model):
|
class Message(models.Model):
|
||||||
"""
|
"""
|
||||||
The message system is a lightweight way to queue messages for given users. A message is associated with a User instance (so it is only applicable for registered users). There's no concept of expiration or timestamps. Messages are created by the Django admin after successful actions. For example, "The poll Foo was created successfully." is a message.
|
The message system is a lightweight way to queue messages for given
|
||||||
|
users. A message is associated with a User instance (so it is only
|
||||||
|
applicable for registered users). There's no concept of expiration or
|
||||||
|
timestamps. Messages are created by the Django admin after successful
|
||||||
|
actions. For example, "The poll Foo was created successfully." is a
|
||||||
|
message.
|
||||||
"""
|
"""
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
message = models.TextField(_('message'))
|
message = models.TextField(_('message'))
|
||||||
@ -293,6 +321,11 @@ class Message(models.Model):
|
|||||||
class AnonymousUser(object):
|
class AnonymousUser(object):
|
||||||
id = None
|
id = None
|
||||||
username = ''
|
username = ''
|
||||||
|
is_staff = False
|
||||||
|
is_active = True
|
||||||
|
is_superuser = False
|
||||||
|
_groups = EmptyManager()
|
||||||
|
_user_permissions = EmptyManager()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
@ -325,11 +358,11 @@ class AnonymousUser(object):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def _get_groups(self):
|
def _get_groups(self):
|
||||||
raise NotImplementedError
|
return self._groups
|
||||||
groups = property(_get_groups)
|
groups = property(_get_groups)
|
||||||
|
|
||||||
def _get_user_permissions(self):
|
def _get_user_permissions(self):
|
||||||
raise NotImplementedError
|
return self._user_permissions
|
||||||
user_permissions = property(_get_user_permissions)
|
user_permissions = property(_get_user_permissions)
|
||||||
|
|
||||||
def has_perm(self, perm):
|
def has_perm(self, perm):
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
>>> from models import User
|
>>> from models import User, AnonymousUser
|
||||||
>>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw')
|
>>> u = User.objects.create_user('testuser', 'test@example.com', 'testpw')
|
||||||
>>> u.has_usable_password()
|
>>> u.has_usable_password()
|
||||||
True
|
True
|
||||||
@ -16,4 +16,11 @@ False
|
|||||||
>>> u2 = User.objects.create_user('testuser2', 'test2@example.com')
|
>>> u2 = User.objects.create_user('testuser2', 'test2@example.com')
|
||||||
>>> u2.has_usable_password()
|
>>> u2.has_usable_password()
|
||||||
False
|
False
|
||||||
|
>>> a = AnonymousUser()
|
||||||
|
>>> a.is_staff
|
||||||
|
False
|
||||||
|
>>> a.groups.all()
|
||||||
|
[]
|
||||||
|
>>> a.user_permissions.all()
|
||||||
|
[]
|
||||||
"""
|
"""
|
@ -9,10 +9,10 @@ from django.contrib.auth.decorators import login_required
|
|||||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
def login(request, template_name='registration/login.html'):
|
def login(request, template_name='registration/login.html', redirect_field_name=REDIRECT_FIELD_NAME):
|
||||||
"Displays the login form and handles the login action."
|
"Displays the login form and handles the login action."
|
||||||
manipulator = AuthenticationForm(request)
|
manipulator = AuthenticationForm(request)
|
||||||
redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, '')
|
redirect_to = request.REQUEST.get(redirect_field_name, '')
|
||||||
if request.POST:
|
if request.POST:
|
||||||
errors = manipulator.get_validation_errors(request.POST)
|
errors = manipulator.get_validation_errors(request.POST)
|
||||||
if not errors:
|
if not errors:
|
||||||
@ -35,7 +35,7 @@ def login(request, template_name='registration/login.html'):
|
|||||||
|
|
||||||
return render_to_response(template_name, {
|
return render_to_response(template_name, {
|
||||||
'form': oldforms.FormWrapper(manipulator, request.POST, errors),
|
'form': oldforms.FormWrapper(manipulator, request.POST, errors),
|
||||||
REDIRECT_FIELD_NAME: redirect_to,
|
redirect_field_name: redirect_to,
|
||||||
'site_name': current_site.name,
|
'site_name': current_site.name,
|
||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request))
|
||||||
|
|
||||||
@ -56,12 +56,12 @@ def logout_then_login(request, login_url=None):
|
|||||||
login_url = settings.LOGIN_URL
|
login_url = settings.LOGIN_URL
|
||||||
return logout(request, login_url)
|
return logout(request, login_url)
|
||||||
|
|
||||||
def redirect_to_login(next, login_url=None):
|
def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
|
||||||
"Redirects the user to the login page, passing the given 'next' page"
|
"Redirects the user to the login page, passing the given 'next' page"
|
||||||
if not login_url:
|
if not login_url:
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
login_url = settings.LOGIN_URL
|
login_url = settings.LOGIN_URL
|
||||||
return HttpResponseRedirect('%s?%s=%s' % (login_url, REDIRECT_FIELD_NAME, next))
|
return HttpResponseRedirect('%s?%s=%s' % (login_url, redirect_field_name, next))
|
||||||
|
|
||||||
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
|
def password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html',
|
||||||
email_template_name='registration/password_reset_email.html'):
|
email_template_name='registration/password_reset_email.html'):
|
||||||
|
@ -155,7 +155,7 @@ class PublicFreeCommentManipulator(oldforms.Manipulator):
|
|||||||
c.save()
|
c.save()
|
||||||
return c
|
return c
|
||||||
|
|
||||||
def post_comment(request):
|
def post_comment(request, extra_context=None, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Post a comment
|
Post a comment
|
||||||
|
|
||||||
@ -185,6 +185,7 @@ def post_comment(request):
|
|||||||
rating_choices
|
rating_choices
|
||||||
choice of ratings
|
choice of ratings
|
||||||
"""
|
"""
|
||||||
|
if extra_context is None: extra_context = {}
|
||||||
if not request.POST:
|
if not request.POST:
|
||||||
raise Http404, _("Only POSTs are allowed")
|
raise Http404, _("Only POSTs are allowed")
|
||||||
try:
|
try:
|
||||||
@ -244,7 +245,7 @@ def post_comment(request):
|
|||||||
'ratings_required': RATINGS_REQUIRED in option_list,
|
'ratings_required': RATINGS_REQUIRED in option_list,
|
||||||
'rating_range': rating_range,
|
'rating_range': rating_range,
|
||||||
'rating_choices': rating_choices,
|
'rating_choices': rating_choices,
|
||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request, extra_context, context_processors))
|
||||||
elif 'post' in request.POST:
|
elif 'post' in request.POST:
|
||||||
# If the IP is banned, mail the admins, do NOT save the comment, and
|
# If the IP is banned, mail the admins, do NOT save the comment, and
|
||||||
# serve up the "Thanks for posting" page as if the comment WAS posted.
|
# serve up the "Thanks for posting" page as if the comment WAS posted.
|
||||||
@ -257,7 +258,7 @@ def post_comment(request):
|
|||||||
else:
|
else:
|
||||||
raise Http404, _("The comment form didn't provide either 'preview' or 'post'")
|
raise Http404, _("The comment form didn't provide either 'preview' or 'post'")
|
||||||
|
|
||||||
def post_free_comment(request):
|
def post_free_comment(request, extra_context=None, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Post a free comment (not requiring a log in)
|
Post a free comment (not requiring a log in)
|
||||||
|
|
||||||
@ -277,6 +278,7 @@ def post_free_comment(request):
|
|||||||
security hash (must be included in a posted form to succesfully
|
security hash (must be included in a posted form to succesfully
|
||||||
post a comment).
|
post a comment).
|
||||||
"""
|
"""
|
||||||
|
if extra_context is None: extra_context = {}
|
||||||
if not request.POST:
|
if not request.POST:
|
||||||
raise Http404, _("Only POSTs are allowed")
|
raise Http404, _("Only POSTs are allowed")
|
||||||
try:
|
try:
|
||||||
@ -307,7 +309,7 @@ def post_free_comment(request):
|
|||||||
'options': options,
|
'options': options,
|
||||||
'target': target,
|
'target': target,
|
||||||
'hash': security_hash,
|
'hash': security_hash,
|
||||||
}, context_instance=RequestContext(request))
|
}, context_instance=RequestContext(request, extra_context, context_processors))
|
||||||
elif 'post' in request.POST:
|
elif 'post' in request.POST:
|
||||||
# If the IP is banned, mail the admins, do NOT save the comment, and
|
# If the IP is banned, mail the admins, do NOT save the comment, and
|
||||||
# serve up the "Thanks for posting" page as if the comment WAS posted.
|
# serve up the "Thanks for posting" page as if the comment WAS posted.
|
||||||
@ -321,7 +323,7 @@ def post_free_comment(request):
|
|||||||
else:
|
else:
|
||||||
raise Http404, _("The comment form didn't provide either 'preview' or 'post'")
|
raise Http404, _("The comment form didn't provide either 'preview' or 'post'")
|
||||||
|
|
||||||
def comment_was_posted(request):
|
def comment_was_posted(request, extra_context=None, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Display "comment was posted" success page
|
Display "comment was posted" success page
|
||||||
|
|
||||||
@ -330,6 +332,7 @@ def comment_was_posted(request):
|
|||||||
object
|
object
|
||||||
The object the comment was posted on
|
The object the comment was posted on
|
||||||
"""
|
"""
|
||||||
|
if extra_context is None: extra_context = {}
|
||||||
obj = None
|
obj = None
|
||||||
if 'c' in request.GET:
|
if 'c' in request.GET:
|
||||||
content_type_id, object_id = request.GET['c'].split(':')
|
content_type_id, object_id = request.GET['c'].split(':')
|
||||||
@ -338,4 +341,5 @@ def comment_was_posted(request):
|
|||||||
obj = content_type.get_object_for_this_type(pk=object_id)
|
obj = content_type.get_object_for_this_type(pk=object_id)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
pass
|
pass
|
||||||
return render_to_response('comments/posted.html', {'object': obj}, context_instance=RequestContext(request))
|
return render_to_response('comments/posted.html', {'object': obj},
|
||||||
|
context_instance=RequestContext(request, extra_context, context_processors))
|
||||||
|
@ -4,7 +4,7 @@ from django.template import RequestContext
|
|||||||
from django.contrib.comments.models import Comment, KarmaScore
|
from django.contrib.comments.models import Comment, KarmaScore
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
def vote(request, comment_id, vote):
|
def vote(request, comment_id, vote, extra_context=None, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Rate a comment (+1 or -1)
|
Rate a comment (+1 or -1)
|
||||||
|
|
||||||
@ -13,6 +13,7 @@ def vote(request, comment_id, vote):
|
|||||||
comment
|
comment
|
||||||
`comments.comments` object being rated
|
`comments.comments` object being rated
|
||||||
"""
|
"""
|
||||||
|
if extra_context is None: extra_context = {}
|
||||||
rating = {'up': 1, 'down': -1}.get(vote, False)
|
rating = {'up': 1, 'down': -1}.get(vote, False)
|
||||||
if not rating:
|
if not rating:
|
||||||
raise Http404, "Invalid vote"
|
raise Http404, "Invalid vote"
|
||||||
@ -27,4 +28,5 @@ def vote(request, comment_id, vote):
|
|||||||
KarmaScore.objects.vote(request.user.id, comment_id, rating)
|
KarmaScore.objects.vote(request.user.id, comment_id, rating)
|
||||||
# Reload comment to ensure we have up to date karma count
|
# Reload comment to ensure we have up to date karma count
|
||||||
comment = Comment.objects.get(pk=comment_id)
|
comment = Comment.objects.get(pk=comment_id)
|
||||||
return render_to_response('comments/karma_vote_accepted.html', {'comment': comment}, context_instance=RequestContext(request))
|
return render_to_response('comments/karma_vote_accepted.html', {'comment': comment},
|
||||||
|
context_instance=RequestContext(request, extra_context, context_processors))
|
||||||
|
@ -6,7 +6,7 @@ from django.contrib.auth.decorators import login_required
|
|||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
def flag(request, comment_id):
|
def flag(request, comment_id, extra_context=None, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Flags a comment. Confirmation on GET, action on POST.
|
Flags a comment. Confirmation on GET, action on POST.
|
||||||
|
|
||||||
@ -15,18 +15,22 @@ def flag(request, comment_id):
|
|||||||
comment
|
comment
|
||||||
the flagged `comments.comments` object
|
the flagged `comments.comments` object
|
||||||
"""
|
"""
|
||||||
|
if extra_context is None: extra_context = {}
|
||||||
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
|
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
|
||||||
if request.POST:
|
if request.POST:
|
||||||
UserFlag.objects.flag(comment, request.user)
|
UserFlag.objects.flag(comment, request.user)
|
||||||
return HttpResponseRedirect('%sdone/' % request.path)
|
return HttpResponseRedirect('%sdone/' % request.path)
|
||||||
return render_to_response('comments/flag_verify.html', {'comment': comment}, context_instance=RequestContext(request))
|
return render_to_response('comments/flag_verify.html', {'comment': comment},
|
||||||
|
context_instance=RequestContext(request, extra_context, context_processors))
|
||||||
flag = login_required(flag)
|
flag = login_required(flag)
|
||||||
|
|
||||||
def flag_done(request, comment_id):
|
def flag_done(request, comment_id, extra_context=None, context_processors=None):
|
||||||
|
if extra_context is None: extra_context = {}
|
||||||
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
|
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
|
||||||
return render_to_response('comments/flag_done.html', {'comment': comment}, context_instance=RequestContext(request))
|
return render_to_response('comments/flag_done.html', {'comment': comment},
|
||||||
|
context_instance=RequestContext(request, extra_context, context_processors))
|
||||||
|
|
||||||
def delete(request, comment_id):
|
def delete(request, comment_id, extra_context=None, context_processors=None):
|
||||||
"""
|
"""
|
||||||
Deletes a comment. Confirmation on GET, action on POST.
|
Deletes a comment. Confirmation on GET, action on POST.
|
||||||
|
|
||||||
@ -35,6 +39,7 @@ def delete(request, comment_id):
|
|||||||
comment
|
comment
|
||||||
the flagged `comments.comments` object
|
the flagged `comments.comments` object
|
||||||
"""
|
"""
|
||||||
|
if extra_context is None: extra_context = {}
|
||||||
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
|
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
|
||||||
if not Comment.objects.user_is_moderator(request.user):
|
if not Comment.objects.user_is_moderator(request.user):
|
||||||
raise Http404
|
raise Http404
|
||||||
@ -46,9 +51,12 @@ def delete(request, comment_id):
|
|||||||
m = ModeratorDeletion(None, request.user.id, comment.id, None)
|
m = ModeratorDeletion(None, request.user.id, comment.id, None)
|
||||||
m.save()
|
m.save()
|
||||||
return HttpResponseRedirect('%sdone/' % request.path)
|
return HttpResponseRedirect('%sdone/' % request.path)
|
||||||
return render_to_response('comments/delete_verify.html', {'comment': comment}, context_instance=RequestContext(request))
|
return render_to_response('comments/delete_verify.html', {'comment': comment},
|
||||||
|
context_instance=RequestContext(request, extra_context, context_processors))
|
||||||
delete = login_required(delete)
|
delete = login_required(delete)
|
||||||
|
|
||||||
def delete_done(request, comment_id):
|
def delete_done(request, comment_id, extra_context=None, context_processors=None):
|
||||||
|
if extra_context is None: extra_context = {}
|
||||||
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
|
comment = get_object_or_404(Comment,pk=comment_id, site__id__exact=settings.SITE_ID)
|
||||||
return render_to_response('comments/delete_done.html', {'comment': comment}, context_instance=RequestContext(request))
|
return render_to_response('comments/delete_done.html', {'comment': comment},
|
||||||
|
context_instance=RequestContext(request, extra_context, context_processors))
|
||||||
|
@ -1,34 +1,43 @@
|
|||||||
"""
|
from django.contrib.contenttypes.models import ContentType
|
||||||
Creates content types for all installed models.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from django.dispatch import dispatcher
|
from django.dispatch import dispatcher
|
||||||
from django.db.models import get_apps, get_models, signals
|
from django.db.models import get_apps, get_models, signals
|
||||||
from django.utils.encoding import smart_unicode
|
from django.utils.encoding import smart_unicode
|
||||||
|
|
||||||
def create_contenttypes(app, created_models, verbosity=2):
|
def update_contenttypes(app, created_models, verbosity=2):
|
||||||
from django.contrib.contenttypes.models import ContentType
|
"""
|
||||||
|
Creates content types for models in the given app, removing any model
|
||||||
|
entries that no longer have a matching model class.
|
||||||
|
"""
|
||||||
ContentType.objects.clear_cache()
|
ContentType.objects.clear_cache()
|
||||||
|
content_types = list(ContentType.objects.filter(app_label=app.__name__.split('.')[-2]))
|
||||||
app_models = get_models(app)
|
app_models = get_models(app)
|
||||||
if not app_models:
|
if not app_models:
|
||||||
return
|
return
|
||||||
for klass in app_models:
|
for klass in app_models:
|
||||||
opts = klass._meta
|
opts = klass._meta
|
||||||
try:
|
try:
|
||||||
ContentType.objects.get(app_label=opts.app_label,
|
ct = ContentType.objects.get(app_label=opts.app_label,
|
||||||
model=opts.object_name.lower())
|
model=opts.object_name.lower())
|
||||||
|
content_types.remove(ct)
|
||||||
except ContentType.DoesNotExist:
|
except ContentType.DoesNotExist:
|
||||||
ct = ContentType(name=smart_unicode(opts.verbose_name_raw),
|
ct = ContentType(name=smart_unicode(opts.verbose_name_raw),
|
||||||
app_label=opts.app_label, model=opts.object_name.lower())
|
app_label=opts.app_label, model=opts.object_name.lower())
|
||||||
ct.save()
|
ct.save()
|
||||||
if verbosity >= 2:
|
if verbosity >= 2:
|
||||||
print "Adding content type '%s | %s'" % (ct.app_label, ct.model)
|
print "Adding content type '%s | %s'" % (ct.app_label, ct.model)
|
||||||
|
# The presence of any remaining content types means the supplied app has an
|
||||||
|
# undefined model and can safely be removed, which cascades to also remove
|
||||||
|
# related permissions.
|
||||||
|
for ct in content_types:
|
||||||
|
if verbosity >= 2:
|
||||||
|
print "Deleting stale content type '%s | %s'" % (ct.app_label, ct.model)
|
||||||
|
ct.delete()
|
||||||
|
|
||||||
def create_all_contenttypes(verbosity=2):
|
def update_all_contenttypes(verbosity=2):
|
||||||
for app in get_apps():
|
for app in get_apps():
|
||||||
create_contenttypes(app, None, verbosity)
|
update_contenttypes(app, None, verbosity)
|
||||||
|
|
||||||
dispatcher.connect(create_contenttypes, signal=signals.post_syncdb)
|
dispatcher.connect(update_contenttypes, signal=signals.post_syncdb)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
create_all_contenttypes()
|
update_all_contenttypes()
|
||||||
|
@ -25,7 +25,7 @@ class ContentTypeManager(models.Manager):
|
|||||||
"""
|
"""
|
||||||
Clear out the content-type cache. This needs to happen during database
|
Clear out the content-type cache. This needs to happen during database
|
||||||
flushes to prevent caching of "stale" content type IDs (see
|
flushes to prevent caching of "stale" content type IDs (see
|
||||||
django.contrib.contenttypes.management.create_contenttypes for where
|
django.contrib.contenttypes.management.update_contenttypes for where
|
||||||
this gets called).
|
this gets called).
|
||||||
"""
|
"""
|
||||||
global CONTENT_TYPE_CACHE
|
global CONTENT_TYPE_CACHE
|
||||||
|
@ -40,7 +40,7 @@ class CsrfMiddleware(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def process_request(self, request):
|
def process_request(self, request):
|
||||||
if request.POST:
|
if request.method == 'POST':
|
||||||
try:
|
try:
|
||||||
session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
|
session_id = request.COOKIES[settings.SESSION_COOKIE_NAME]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for object in object_list %}
|
{% for object in object_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for field in field_list %}
|
{% for field in field_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for year in date_list %}
|
{% for year in date_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for object in object_list %}
|
{% for object in object_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for month in date_list %}
|
{% for month in date_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for object in object_list %}
|
{% for object in object_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for choice in field.choices %}
|
{% for choice in field.choices %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ choice.url }}">{{ choice.label|escape }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for object in object_list %}
|
{% for object in object_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for field in field_list %}
|
{% for field in field_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ field.name }}/">{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for object in object_list %}
|
{% for object in object_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object|iriencode }}/">{{ object|escape }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
{% for model in model_list %}
|
{% for model in model_list %}
|
||||||
<div class="modelgroup {% cycle even,odd %}">
|
<div class="modelgroup {% cycle 'even' 'odd' %}">
|
||||||
<h2><a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a></h2>
|
<h2><a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a></h2>
|
||||||
<p>
|
<p>
|
||||||
{% for object in model.sample_objects %}
|
{% for object in model.sample_objects %}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for object in model.objects %}
|
{% for object in model.objects %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<table class="objectinfo">
|
<table class="objectinfo">
|
||||||
{% for field in object.fields %}
|
{% for field in object.fields %}
|
||||||
<tr class="{% cycle odd,even %}">
|
<tr class="{% cycle 'odd' 'even' %}">
|
||||||
<th>{{ field.field.verbose_name|capfirst }}</th>
|
<th>{{ field.field.verbose_name|capfirst }}</th>
|
||||||
<td>
|
<td>
|
||||||
{% if field.urls %}
|
{% if field.urls %}
|
||||||
@ -29,7 +29,7 @@
|
|||||||
{% if related_object.object_list %}
|
{% if related_object.object_list %}
|
||||||
<ul class="objectlist">
|
<ul class="objectlist">
|
||||||
{% for object in related_object.object_list %}
|
{% for object in related_object.object_list %}
|
||||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
<li class="{% cycle 'odd' 'even' %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -1,47 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Formtools Preview application.
|
Formtools Preview application.
|
||||||
|
|
||||||
This is an abstraction of the following workflow:
|
|
||||||
|
|
||||||
"Display an HTML form, force a preview, then do something with the submission."
|
|
||||||
|
|
||||||
Given a django.newforms.Form object that you define, this takes care of the
|
|
||||||
following:
|
|
||||||
|
|
||||||
* Displays the form as HTML on a Web page.
|
|
||||||
* Validates the form data once it's submitted via POST.
|
|
||||||
* If it's valid, displays a preview page.
|
|
||||||
* If it's not valid, redisplays the form with error messages.
|
|
||||||
* At the preview page, if the preview confirmation button is pressed, calls
|
|
||||||
a hook that you define -- a done() method.
|
|
||||||
|
|
||||||
The framework enforces the required preview by passing a shared-secret hash to
|
|
||||||
the preview page. If somebody tweaks the form parameters on the preview page,
|
|
||||||
the form submission will fail the hash comparison test.
|
|
||||||
|
|
||||||
Usage
|
|
||||||
=====
|
|
||||||
|
|
||||||
Subclass FormPreview and define a done() method:
|
|
||||||
|
|
||||||
def done(self, request, cleaned_data):
|
|
||||||
# ...
|
|
||||||
|
|
||||||
This method takes an HttpRequest object and a dictionary of the form data after
|
|
||||||
it has been validated and cleaned. It should return an HttpResponseRedirect.
|
|
||||||
|
|
||||||
Then, just instantiate your FormPreview subclass by passing it a Form class,
|
|
||||||
and pass that to your URLconf, like so:
|
|
||||||
|
|
||||||
(r'^post/$', MyFormPreview(MyForm)),
|
|
||||||
|
|
||||||
The FormPreview class has a few other hooks. See the docstrings in the source
|
|
||||||
code below.
|
|
||||||
|
|
||||||
The framework also uses two templates: 'formtools/preview.html' and
|
|
||||||
'formtools/form.html'. You can override these by setting 'preview_template' and
|
|
||||||
'form_template' attributes on your FormPreview subclass. See
|
|
||||||
django/contrib/formtools/templates for the default templates.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
0
django/contrib/localflavor/ar/__init__.py
Normal file
0
django/contrib/localflavor/ar/__init__.py
Normal file
36
django/contrib/localflavor/ar/ar_provinces.py
Normal file
36
django/contrib/localflavor/ar/ar_provinces.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
A list of Argentinean provinces and autonomous cities as `choices` in a
|
||||||
|
formfield. From
|
||||||
|
http://www.argentina.gov.ar/argentina/portal/paginas.dhtml?pagina=425
|
||||||
|
|
||||||
|
This exists in this standalone file so that it's only imported into memory
|
||||||
|
when explicitly needed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
PROVINCE_CHOICES = (
|
||||||
|
('B', u'Buenos Aires'),
|
||||||
|
('K', u'Catamarca'),
|
||||||
|
('H', u'Chaco'),
|
||||||
|
('U', u'Chubut'),
|
||||||
|
('C', u'Ciudad Autónoma de Buenos Aires'),
|
||||||
|
('X', u'Córdoba'),
|
||||||
|
('W', u'Corrientes'),
|
||||||
|
('E', u'Entre Ríos'),
|
||||||
|
('P', u'Formosa'),
|
||||||
|
('Y', u'Jujuy'),
|
||||||
|
('L', u'La Pampa'),
|
||||||
|
('F', u'La Rioja'),
|
||||||
|
('M', u'Mendoza'),
|
||||||
|
('N', u'Misiones'),
|
||||||
|
('Q', u'Neuquén'),
|
||||||
|
('R', u'Río Negro'),
|
||||||
|
('A', u'Salta'),
|
||||||
|
('J', u'San Juan'),
|
||||||
|
('D', u'San Luis'),
|
||||||
|
('Z', u'Santa Cruz'),
|
||||||
|
('S', u'Santa Fe'),
|
||||||
|
('G', u'Santiago del Estero'),
|
||||||
|
('V', u'Tierra del Fuego, Antártida e Islas del Atlántico Sur'),
|
||||||
|
('T', u'Tucumán'),
|
||||||
|
)
|
105
django/contrib/localflavor/ar/forms.py
Normal file
105
django/contrib/localflavor/ar/forms.py
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
AR-specific Form helpers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.newforms import ValidationError
|
||||||
|
from django.newforms.fields import RegexField, CharField, Select, EMPTY_VALUES
|
||||||
|
from django.utils.encoding import smart_unicode
|
||||||
|
from django.utils.translation import ugettext
|
||||||
|
import re
|
||||||
|
|
||||||
|
class ARProvinceSelect(Select):
|
||||||
|
"""
|
||||||
|
A Select widget that uses a list of Argentinean provinces/autonomous cities
|
||||||
|
as its choices.
|
||||||
|
"""
|
||||||
|
def __init__(self, attrs=None):
|
||||||
|
from ar_provinces import PROVINCE_CHOICES
|
||||||
|
super(ARProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
|
||||||
|
|
||||||
|
class ARPostalCodeField(RegexField):
|
||||||
|
"""
|
||||||
|
A field that accepts a `classic´ NNNN Postal Code or a CPA.
|
||||||
|
|
||||||
|
See http://www.correoargentino.com.ar/consulta_cpa/home.php
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(ARPostalCodeField, self).__init__(r'^\d{4}$|^[A-HJ-NP-Za-hj-np-z]\d{4}\D{3}$',
|
||||||
|
min_length=4, max_length=8,
|
||||||
|
error_message=ugettext("Enter a postal code in the format NNNN or ANNNNAAA."),
|
||||||
|
*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
value = super(ARPostalCodeField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
if len(value) not in (4, 8):
|
||||||
|
raise ValidationError(ugettext("Enter a postal code in the format NNNN or ANNNNAAA."))
|
||||||
|
if len(value) == 8:
|
||||||
|
return u'%s%s%s' % (value[0].upper(), value[1:5], value[5:].upper())
|
||||||
|
return value
|
||||||
|
|
||||||
|
class ARDNIField(CharField):
|
||||||
|
"""
|
||||||
|
A field that validates `Documento Nacional de Identidad´ (DNI) numbers.
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(ARDNIField, self).__init__(max_length=10, min_length=7, *args,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
"""
|
||||||
|
Value can be a string either in the [X]X.XXX.XXX or [X]XXXXXXX formats.
|
||||||
|
"""
|
||||||
|
value = super(ARDNIField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
if not value.isdigit():
|
||||||
|
value = value.replace('.', '')
|
||||||
|
if not value.isdigit():
|
||||||
|
raise ValidationError(ugettext("This field requires only numbers."))
|
||||||
|
if len(value) not in (7, 8):
|
||||||
|
raise ValidationError(
|
||||||
|
ugettext("This field requires 7 or 8 digits."))
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
class ARCUITField(RegexField):
|
||||||
|
"""
|
||||||
|
This field validates a CUIT (Código Único de Identificación Tributaria). A
|
||||||
|
CUIT is of the form XX-XXXXXXXX-V. The last digit is a check digit.
|
||||||
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(ARCUITField, self).__init__(r'^\d{2}-?\d{8}-?\d$',
|
||||||
|
error_message=ugettext('Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.'),
|
||||||
|
*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
"""
|
||||||
|
Value can be either a string in the format XX-XXXXXXXX-X or an
|
||||||
|
11-digit number.
|
||||||
|
"""
|
||||||
|
value = super(ARCUITField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
value, cd = self._canon(value)
|
||||||
|
if self._calc_cd(value) != cd:
|
||||||
|
raise ValidationError(ugettext("Invalid CUIT."))
|
||||||
|
return self._format(value, cd)
|
||||||
|
|
||||||
|
def _canon(self, cuit):
|
||||||
|
cuit = cuit.replace('-', '')
|
||||||
|
return cuit[:-1], cuit[-1]
|
||||||
|
|
||||||
|
def _calc_cd(self, cuit):
|
||||||
|
mults = (5, 4, 3, 2, 7, 6, 5, 4, 3, 2)
|
||||||
|
tmp = sum([m * int(cuit[idx]) for idx, m in enumerate(mults)])
|
||||||
|
return str(11 - tmp % 11)
|
||||||
|
|
||||||
|
def _format(self, cuit, check_digit=None):
|
||||||
|
if check_digit == None:
|
||||||
|
check_digit = cuit[-1]
|
||||||
|
cuit = cuit[:-1]
|
||||||
|
return u'%s-%s-%s' % (cuit[:2], cuit[2:], check_digit)
|
||||||
|
|
@ -6,16 +6,21 @@ BR-specific Form helpers
|
|||||||
from django.newforms import ValidationError
|
from django.newforms import ValidationError
|
||||||
from django.newforms.fields import Field, RegexField, CharField, Select, EMPTY_VALUES
|
from django.newforms.fields import Field, RegexField, CharField, Select, EMPTY_VALUES
|
||||||
from django.utils.encoding import smart_unicode
|
from django.utils.encoding import smart_unicode
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import ugettext as _
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
try:
|
||||||
|
set
|
||||||
|
except NameError:
|
||||||
|
from sets import Set as set # For Python 2.3
|
||||||
|
|
||||||
phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$')
|
phone_digits_re = re.compile(r'^(\d{2})[-\.]?(\d{4})[-\.]?(\d{4})$')
|
||||||
|
|
||||||
class BRZipCodeField(RegexField):
|
class BRZipCodeField(RegexField):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
|
super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
|
||||||
max_length=None, min_length=None,
|
max_length=None, min_length=None,
|
||||||
error_message=ugettext('Enter a zip code in the format XXXXX-XXX.'),
|
error_message=_('Enter a zip code in the format XXXXX-XXX.'),
|
||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
|
|
||||||
class BRPhoneNumberField(Field):
|
class BRPhoneNumberField(Field):
|
||||||
@ -27,7 +32,7 @@ class BRPhoneNumberField(Field):
|
|||||||
m = phone_digits_re.search(value)
|
m = phone_digits_re.search(value)
|
||||||
if m:
|
if m:
|
||||||
return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
|
return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
|
||||||
raise ValidationError(ugettext('Phone numbers must be in XX-XXXX-XXXX format.'))
|
raise ValidationError(_('Phone numbers must be in XX-XXXX-XXXX format.'))
|
||||||
|
|
||||||
class BRStateSelect(Select):
|
class BRStateSelect(Select):
|
||||||
"""
|
"""
|
||||||
@ -38,6 +43,32 @@ class BRStateSelect(Select):
|
|||||||
from br_states import STATE_CHOICES
|
from br_states import STATE_CHOICES
|
||||||
super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
|
super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
|
||||||
|
|
||||||
|
class BRStateChoiceField(Field):
|
||||||
|
"""
|
||||||
|
A choice field that uses a list of Brazilian states as its choices.
|
||||||
|
"""
|
||||||
|
widget = Select
|
||||||
|
|
||||||
|
def __init__(self, required=True, widget=None, label=None,
|
||||||
|
initial=None, help_text=None):
|
||||||
|
super(BRStateChoiceField, self).__init__(required, widget, label,
|
||||||
|
initial, help_text)
|
||||||
|
from br_states import STATE_CHOICES
|
||||||
|
self.widget.choices = STATE_CHOICES
|
||||||
|
|
||||||
|
def clean(self, value):
|
||||||
|
value = super(BRStateChoiceField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
value = u''
|
||||||
|
value = smart_unicode(value)
|
||||||
|
if value == u'':
|
||||||
|
return value
|
||||||
|
valid_values = set([smart_unicode(k) for k, v in self.widget.choices])
|
||||||
|
if value not in valid_values:
|
||||||
|
raise ValidationError(_(u'Select a valid brazilian state.'
|
||||||
|
u' That state is not one'
|
||||||
|
u' of the available states.'))
|
||||||
|
return value
|
||||||
|
|
||||||
def DV_maker(v):
|
def DV_maker(v):
|
||||||
if v >= 2:
|
if v >= 2:
|
||||||
@ -69,9 +100,9 @@ class BRCPFField(CharField):
|
|||||||
try:
|
try:
|
||||||
int(value)
|
int(value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ValidationError(ugettext("This field requires only numbers."))
|
raise ValidationError(_("This field requires only numbers."))
|
||||||
if len(value) != 11:
|
if len(value) != 11:
|
||||||
raise ValidationError(ugettext("This field requires at most 11 digits or 14 characters."))
|
raise ValidationError(_("This field requires at most 11 digits or 14 characters."))
|
||||||
orig_dv = value[-2:]
|
orig_dv = value[-2:]
|
||||||
|
|
||||||
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
|
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
|
||||||
@ -81,7 +112,7 @@ class BRCPFField(CharField):
|
|||||||
new_2dv = DV_maker(new_2dv % 11)
|
new_2dv = DV_maker(new_2dv % 11)
|
||||||
value = value[:-1] + str(new_2dv)
|
value = value[:-1] + str(new_2dv)
|
||||||
if value[-2:] != orig_dv:
|
if value[-2:] != orig_dv:
|
||||||
raise ValidationError(ugettext("Invalid CPF number."))
|
raise ValidationError(_("Invalid CPF number."))
|
||||||
|
|
||||||
return orig_value
|
return orig_value
|
||||||
|
|
||||||
@ -103,7 +134,7 @@ class BRCNPJField(Field):
|
|||||||
raise ValidationError("This field requires only numbers.")
|
raise ValidationError("This field requires only numbers.")
|
||||||
if len(value) != 14:
|
if len(value) != 14:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
ugettext("This field requires at least 14 digits"))
|
_("This field requires at least 14 digits"))
|
||||||
orig_dv = value[-2:]
|
orig_dv = value[-2:]
|
||||||
|
|
||||||
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))])
|
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(5, 1, -1) + range(9, 1, -1))])
|
||||||
@ -113,7 +144,7 @@ class BRCNPJField(Field):
|
|||||||
new_2dv = DV_maker(new_2dv % 11)
|
new_2dv = DV_maker(new_2dv % 11)
|
||||||
value = value[:-1] + str(new_2dv)
|
value = value[:-1] + str(new_2dv)
|
||||||
if value[-2:] != orig_dv:
|
if value[-2:] != orig_dv:
|
||||||
raise ValidationError(ugettext("Invalid CNPJ number."))
|
raise ValidationError(_("Invalid CNPJ number."))
|
||||||
|
|
||||||
return orig_value
|
return orig_value
|
||||||
|
|
||||||
|
0
django/contrib/localflavor/ca/__init__.py
Normal file
0
django/contrib/localflavor/ca/__init__.py
Normal file
57
django/contrib/localflavor/ca/ca_provinces.py
Normal file
57
django/contrib/localflavor/ca/ca_provinces.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
"""
|
||||||
|
An alphabetical list of provinces and territories for use as `choices`
|
||||||
|
in a formfield., and a mapping of province misspellings/abbreviations to
|
||||||
|
normalized abbreviations
|
||||||
|
|
||||||
|
Source: http://www.canada.gc.ca/othergov/prov_e.html
|
||||||
|
|
||||||
|
This exists in this standalone file so that it's only imported into memory
|
||||||
|
when explicitly needed.
|
||||||
|
"""
|
||||||
|
|
||||||
|
PROVINCE_CHOICES = (
|
||||||
|
('AB', 'Alberta'),
|
||||||
|
('BC', 'British Columbia'),
|
||||||
|
('MB', 'Manitoba'),
|
||||||
|
('NB', 'New Brunswick'),
|
||||||
|
('NF', 'Newfoundland and Labrador'),
|
||||||
|
('NT', 'Northwest Territories'),
|
||||||
|
('NS', 'Nova Scotia'),
|
||||||
|
('NU', 'Nunavut'),
|
||||||
|
('ON', 'Ontario'),
|
||||||
|
('PE', 'Prince Edward Island'),
|
||||||
|
('QC', 'Quebec'),
|
||||||
|
('SK', 'Saskatchewan'),
|
||||||
|
('YK', 'Yukon')
|
||||||
|
)
|
||||||
|
|
||||||
|
PROVINCES_NORMALIZED = {
|
||||||
|
'ab': 'AB',
|
||||||
|
'alberta': 'AB',
|
||||||
|
'bc': 'BC',
|
||||||
|
'b.c.': 'BC',
|
||||||
|
'british columbia': 'BC',
|
||||||
|
'mb': 'MB',
|
||||||
|
'manitoba': 'MB',
|
||||||
|
'nf': 'NF',
|
||||||
|
'newfoundland': 'NF',
|
||||||
|
'newfoundland and labrador': 'NF',
|
||||||
|
'nt': 'NT',
|
||||||
|
'northwest territories': 'NT',
|
||||||
|
'ns': 'NS',
|
||||||
|
'nova scotia': 'NS',
|
||||||
|
'nu': 'NU',
|
||||||
|
'nunavut': 'NU',
|
||||||
|
'on': 'ON',
|
||||||
|
'ontario': 'ON',
|
||||||
|
'pe': 'PE',
|
||||||
|
'pei': 'PE',
|
||||||
|
'p.e.i.': 'PE',
|
||||||
|
'prince edward island': 'PE',
|
||||||
|
'qc': 'QC',
|
||||||
|
'quebec': 'QC',
|
||||||
|
'sk': 'SK',
|
||||||
|
'saskatchewan': 'SK',
|
||||||
|
'yk': 'YK',
|
||||||
|
'yukon': 'YK',
|
||||||
|
}
|
112
django/contrib/localflavor/ca/forms.py
Normal file
112
django/contrib/localflavor/ca/forms.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
"""
|
||||||
|
Canada-specific Form helpers
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.newforms import ValidationError
|
||||||
|
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
|
||||||
|
from django.newforms.util import smart_unicode
|
||||||
|
from django.utils.translation import gettext, ugettext
|
||||||
|
import re
|
||||||
|
|
||||||
|
phone_digits_re = re.compile(r'^(?:1-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$')
|
||||||
|
sin_re = re.compile(r"^(\d{3})-(\d{3})-(\d{3})$")
|
||||||
|
|
||||||
|
class CAPostalCodeField(RegexField):
|
||||||
|
"""Canadian postal code field."""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(CAPostalCodeField, self).__init__(r'^[ABCEGHJKLMNPRSTVXYZ]\d[A-Z] \d[A-Z]\d$',
|
||||||
|
max_length=None, min_length=None,
|
||||||
|
error_message=gettext(u'Enter a postal code in the format XXX XXX.'),
|
||||||
|
*args, **kwargs)
|
||||||
|
|
||||||
|
class CAPhoneNumberField(Field):
|
||||||
|
"""Canadian phone number field."""
|
||||||
|
def clean(self, value):
|
||||||
|
"""Validate a phone number.
|
||||||
|
"""
|
||||||
|
super(CAPhoneNumberField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
value = re.sub('(\(|\)|\s+)', '', smart_unicode(value))
|
||||||
|
m = phone_digits_re.search(value)
|
||||||
|
if m:
|
||||||
|
return u'%s-%s-%s' % (m.group(1), m.group(2), m.group(3))
|
||||||
|
raise ValidationError(u'Phone numbers must be in XXX-XXX-XXXX format.')
|
||||||
|
|
||||||
|
class CAProvinceField(Field):
|
||||||
|
"""
|
||||||
|
A form field that validates its input is a Canadian province name or abbreviation.
|
||||||
|
It normalizes the input to the standard two-leter postal service
|
||||||
|
abbreviation for the given province.
|
||||||
|
"""
|
||||||
|
def clean(self, value):
|
||||||
|
from ca_provinces import PROVINCES_NORMALIZED
|
||||||
|
super(CAProvinceField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
try:
|
||||||
|
value = value.strip().lower()
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return PROVINCES_NORMALIZED[value.strip().lower()].decode('ascii')
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
raise ValidationError(u'Enter a Canadian province or territory.')
|
||||||
|
|
||||||
|
class CAProvinceSelect(Select):
|
||||||
|
"""
|
||||||
|
A Select widget that uses a list of Canadian provinces and
|
||||||
|
territories as its choices.
|
||||||
|
"""
|
||||||
|
def __init__(self, attrs=None):
|
||||||
|
from ca_provinces import PROVINCE_CHOICES # relative import
|
||||||
|
super(CAProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
|
||||||
|
|
||||||
|
class CASocialInsuranceNumberField(Field):
|
||||||
|
"""
|
||||||
|
A Canadian Social Insurance Number (SIN).
|
||||||
|
|
||||||
|
Checks the following rules to determine whether the number is valid:
|
||||||
|
|
||||||
|
* Conforms to the XXX-XXX-XXXX format.
|
||||||
|
* Passes the check digit process "Luhn Algorithm"
|
||||||
|
See: http://en.wikipedia.org/wiki/Social_Insurance_Number
|
||||||
|
"""
|
||||||
|
def clean(self, value):
|
||||||
|
super(CASocialInsuranceNumberField, self).clean(value)
|
||||||
|
if value in EMPTY_VALUES:
|
||||||
|
return u''
|
||||||
|
msg = ugettext('Enter a valid Canadian Social Insurance number in XXX-XXX-XXXX format.')
|
||||||
|
match = re.match(sin_re, value)
|
||||||
|
if not match:
|
||||||
|
raise ValidationError(msg)
|
||||||
|
|
||||||
|
number = u'%s-%s-%s' % (match.group(1), match.group(2), match.group(3))
|
||||||
|
check_number = u'%s%s%s' % (match.group(1), match.group(2), match.group(3))
|
||||||
|
if not self.luhn_checksum_is_valid(check_number):
|
||||||
|
raise ValidationError(msg)
|
||||||
|
return number
|
||||||
|
|
||||||
|
def luhn_checksum_is_valid(self, number):
|
||||||
|
"""
|
||||||
|
Checks to make sure that the SIN passes a luhn mod-10 checksum
|
||||||
|
See: http://en.wikipedia.org/wiki/Luhn_algorithm
|
||||||
|
"""
|
||||||
|
|
||||||
|
sum = 0
|
||||||
|
num_digits = len(number)
|
||||||
|
oddeven = num_digits & 1
|
||||||
|
|
||||||
|
for count in range(0, num_digits):
|
||||||
|
digit = int(number[count])
|
||||||
|
|
||||||
|
if not (( count & 1 ) ^ oddeven ):
|
||||||
|
digit = digit * 2
|
||||||
|
if digit > 9:
|
||||||
|
digit = digit - 9
|
||||||
|
|
||||||
|
sum = sum + digit
|
||||||
|
|
||||||
|
return ( (sum % 10) == 0 )
|
0
django/contrib/localflavor/generic/__init__.py
Normal file
0
django/contrib/localflavor/generic/__init__.py
Normal file
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user