mirror of
https://github.com/django/django.git
synced 2025-07-03 09:19:16 +00:00
newforms-admin: Merged to [5194]
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@5195 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
4938c8ea6d
commit
415e84ad53
26
AUTHORS
26
AUTHORS
@ -42,13 +42,17 @@ people who have submitted patches, reported bugs, added translations, helped
|
||||
answer newbie questions, and generally made Django that much better:
|
||||
|
||||
adurdin@gmail.com
|
||||
alang@bright-green.com
|
||||
Marty Alchin <gulopine@gamemusic.org>
|
||||
Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
|
||||
Andreas
|
||||
andy@jadedplanet.net
|
||||
Fabrice Aneche <akh@nobugware.com>
|
||||
ant9000@netwise.it
|
||||
David Ascher <http://ascher.ca/>
|
||||
david@kazserve.org
|
||||
Arthur <avandorp@gmail.com>
|
||||
axiak@mit.edu
|
||||
Jiri Barton
|
||||
Ned Batchelder <http://www.nedbatchelder.com/>
|
||||
Shannon -jj Behrens <http://jjinux.blogspot.com/>
|
||||
@ -66,6 +70,8 @@ answer newbie questions, and generally made Django that much better:
|
||||
Amit Chakradeo <http://amit.chakradeo.net/>
|
||||
ChaosKCW
|
||||
ivan.chelubeev@gmail.com
|
||||
Bryan Chow <bryan at verdjn dot com>
|
||||
Michal Chruszcz <troll@pld-linux.org>
|
||||
Ian Clelland <clelland@gmail.com>
|
||||
crankycoder@gmail.com
|
||||
Matt Croydon <http://www.postneo.com/>
|
||||
@ -78,22 +84,26 @@ answer newbie questions, and generally made Django that much better:
|
||||
Jason Davies (Esaj) <http://www.jasondavies.com/>
|
||||
Alex Dedul
|
||||
deric@monowerks.com
|
||||
Max Derkachev <mderk@yandex.ru>
|
||||
dne@mayonnaise.net
|
||||
Maximillian Dornseif <md@hudora.de>
|
||||
Jeremy Dunck <http://dunck.us/>
|
||||
Andy Dustman <farcepest@gmail.com>
|
||||
Clint Ecker
|
||||
enlight
|
||||
Enrico <rico.bl@gmail.com>
|
||||
Ludvig Ericson <ludvig.ericson@gmail.com>
|
||||
Dirk Eschler <dirk.eschler@gmx.net>
|
||||
Marc Fargas <telenieko@telenieko.com>
|
||||
favo@exoweb.net
|
||||
Bill Fenner <fenner@gmail.com>
|
||||
Matthew Flanagan <http://wadofstuff.blogspot.com>
|
||||
Eric Floehr <eric@intellovations.com>
|
||||
Jorge Gajon <gajon@gajon.org>
|
||||
gandalf@owca.info
|
||||
Baishampayan Ghose
|
||||
martin.glueck@gmail.com
|
||||
GomoX <gomo@datafull.com>
|
||||
Simon Greenhill <dev@simon.net.nz>
|
||||
Owen Griffiths
|
||||
Espen Grindhaug <http://grindhaug.org/>
|
||||
@ -105,11 +115,14 @@ answer newbie questions, and generally made Django that much better:
|
||||
hipertracker@gmail.com
|
||||
Ian Holsman <http://feh.holsman.net/>
|
||||
Kieran Holland <http://www.kieranholland.com>
|
||||
Sung-Jin Hong <serialx.net@gmail.com>
|
||||
Robert Rock Howard <http://djangomojo.com/>
|
||||
Jason Huggins <http://www.jrandolph.com/blog/>
|
||||
Hyun Mi Ae
|
||||
Tom Insam
|
||||
Baurzhan Ismagulov <ibr@radix50.net>
|
||||
jcrasta@gmail.com
|
||||
Zak Johnson <zakj@nox.cx>
|
||||
Michael Josephson <http://www.sdjournal.com/>
|
||||
jpellerin@gmail.com
|
||||
junzhang.jn@gmail.com
|
||||
@ -120,6 +133,8 @@ answer newbie questions, and generally made Django that much better:
|
||||
Sune Kirkeby <http://ibofobi.dk/>
|
||||
Bastian Kleineidam <calvin@debian.org>
|
||||
Cameron Knight (ckknight)
|
||||
Gasper Koren
|
||||
Martin Kosír <martin@martinkosir.net>
|
||||
Meir Kriheli <http://mksoft.co.il/>
|
||||
Bruce Kroeze <http://coderseye.com/>
|
||||
Joseph Kocherhans
|
||||
@ -134,12 +149,13 @@ answer newbie questions, and generally made Django that much better:
|
||||
lerouxb@gmail.com
|
||||
Waylan Limberg <waylan@gmail.com>
|
||||
limodou
|
||||
mattmcc
|
||||
Matt McClanahan <http://mmcc.cx/>
|
||||
Martin Maney <http://www.chipy.org/Martin_Maney>
|
||||
masonsimon+django@gmail.com
|
||||
Manuzhai
|
||||
Petar Marić <http://www.petarmaric.com/>
|
||||
Nuno Mariz <nmariz@gmail.com>
|
||||
marijn@metronomo.cl
|
||||
mark@junklight.com
|
||||
Yasushi Masuda <whosaysni@gmail.com>
|
||||
mattycakes@gmail.com
|
||||
@ -153,6 +169,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
Robin Munn <http://www.geekforgod.com/>
|
||||
Robert Myers <myer0052@gmail.com>
|
||||
Nebojša Dorđević
|
||||
Gopal Narayanan <gopastro@gmail.com>
|
||||
Fraser Nevett <mail@nevett.org>
|
||||
Sam Newman <http://www.magpiebrain.com/>
|
||||
Neal Norwitz <nnorwitz@google.com>
|
||||
@ -168,14 +185,19 @@ answer newbie questions, and generally made Django that much better:
|
||||
Luke Plant <http://lukeplant.me.uk/>
|
||||
plisk
|
||||
Daniel Poelzleithner <http://poelzi.org/>
|
||||
polpak@yahoo.com
|
||||
J. Rademaker
|
||||
Michael Radziej <mir@noris.de>
|
||||
ramiro
|
||||
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
|
||||
Brian Ray <http://brianray.chipy.org/>
|
||||
remco@diji.biz
|
||||
rhettg@gmail.com
|
||||
Henrique Romano <onaiort@gmail.com>
|
||||
Armin Ronacher
|
||||
Oliver Rutherfurd <http://rutherfurd.net/>
|
||||
Ivan Sagalaev (Maniac) <http://www.softwaremaniacs.org/>
|
||||
Vinay Sajip <vinay_sajip@yahoo.co.uk>
|
||||
David Schein
|
||||
scott@staplefish.com
|
||||
serbaut@gmail.com
|
||||
@ -199,6 +221,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
torne-django@wolfpuppy.org.uk
|
||||
Karen Tracey <graybark@bellsouth.net>
|
||||
Makoto Tsuyuki <mtsuyuki@gmail.com>
|
||||
tt@gurgle.no
|
||||
Amit Upadhyay
|
||||
Geert Vanderkelen
|
||||
viestards.lists@gmail.com
|
||||
@ -206,6 +229,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
wam-djangobug@wamber.net
|
||||
Dan Watson <http://theidioteque.net/>
|
||||
Chris Wesseling <Chris.Wesseling@cwi.nl>
|
||||
charly.wilhelm@gmail.com
|
||||
Rachel Willmer <http://www.willmer.com/kb/>
|
||||
Gary Wilson <gary.wilson@gmail.com>
|
||||
wojtek
|
||||
|
@ -11,4 +11,5 @@ recursive-include django/conf/locale *
|
||||
recursive-include django/contrib/admin/templates *
|
||||
recursive-include django/contrib/admin/media *
|
||||
recursive-include django/contrib/comments/templates *
|
||||
recursive-include django/contrib/databrowse/templates *
|
||||
recursive-include django/contrib/sitemaps/templates *
|
||||
|
@ -81,7 +81,7 @@ def make_messages():
|
||||
src = pythonize_re.sub('\n#', src)
|
||||
open(os.path.join(dirpath, '%s.py' % file), "wb").write(src)
|
||||
thefile = '%s.py' % file
|
||||
cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy --from-code UTF-8 -o - "%s"' % (
|
||||
cmd = 'xgettext %s -d %s -L Perl --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
|
||||
os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
|
||||
(stdin, stdout, stderr) = os.popen3(cmd, 'b')
|
||||
msgs = stdout.read()
|
||||
@ -103,7 +103,7 @@ def make_messages():
|
||||
open(os.path.join(dirpath, '%s.py' % file), "wb").write(templatize(src))
|
||||
thefile = '%s.py' % file
|
||||
if verbose: sys.stdout.write('processing file %s in %s\n' % (file, dirpath))
|
||||
cmd = 'xgettext %s -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy --from-code UTF-8 -o - "%s"' % (
|
||||
cmd = 'xgettext %s -d %s -L Python --keyword=gettext_noop --keyword=gettext_lazy --keyword=ngettext_lazy:1,2 --from-code UTF-8 -o - "%s"' % (
|
||||
os.path.exists(potfile) and '--omit-header' or '', domain, os.path.join(dirpath, thefile))
|
||||
(stdin, stdout, stderr) = os.popen3(cmd, 'b')
|
||||
msgs = stdout.read()
|
||||
|
@ -22,7 +22,7 @@ def gather_stats(p):
|
||||
else:
|
||||
continue
|
||||
print "Processing %s" % f
|
||||
if profiles.has_key(path):
|
||||
if path in profiles:
|
||||
profiles[path].add(prof)
|
||||
else:
|
||||
profiles[path] = prof
|
||||
|
@ -55,6 +55,7 @@ LANGUAGES = (
|
||||
('is', gettext_noop('Icelandic')),
|
||||
('it', gettext_noop('Italian')),
|
||||
('ja', gettext_noop('Japanese')),
|
||||
('ko', gettext_noop('Korean')),
|
||||
('kn', gettext_noop('Kannada')),
|
||||
('lv', gettext_noop('Latvian')),
|
||||
('mk', gettext_noop('Macedonian')),
|
||||
@ -118,6 +119,7 @@ EMAIL_PORT = 25
|
||||
# Optional SMTP authentication information for EMAIL_HOST.
|
||||
EMAIL_HOST_USER = ''
|
||||
EMAIL_HOST_PASSWORD = ''
|
||||
EMAIL_USE_TLS = False
|
||||
|
||||
# List of strings representing installed apps.
|
||||
INSTALLED_APPS = ()
|
||||
@ -311,6 +313,12 @@ BANNED_IPS = ()
|
||||
|
||||
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
|
||||
|
||||
LOGIN_URL = '/accounts/login/'
|
||||
|
||||
LOGOUT_URL = '/accounts/logout/'
|
||||
|
||||
LOGIN_REDIRECT_URL = '/accounts/profile/'
|
||||
|
||||
###########
|
||||
# TESTING #
|
||||
###########
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -10,7 +10,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-05-16 10:13+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: panos laganakos <panos.laganakos@gmail.com>\n"
|
||||
"Last-Translator: Orestis Markou <orestis@orestis.gr>\n"
|
||||
"Language-Team: Greek\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
@ -164,9 +164,9 @@ msgid ""
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr ""
|
||||
"Αυτο το σχόλιο σημειώθηκε απο %(χρήστη)ες\n"
|
||||
"Αυτο το σχόλιο σημειώθηκε απο %(user)s\n"
|
||||
"\n"
|
||||
"%(κείμενο)α"
|
||||
"%(text)s"
|
||||
|
||||
#: contrib/comments/models.py:265
|
||||
msgid "flag date"
|
||||
|
Binary file not shown.
@ -305,7 +305,7 @@ msgstr "Japon
|
||||
|
||||
#: conf/global_settings.py:58
|
||||
msgid "Latvian"
|
||||
msgstr ""
|
||||
msgstr "Latvio"
|
||||
|
||||
#: conf/global_settings.py:59
|
||||
msgid "Macedonian"
|
||||
@ -611,7 +611,7 @@ msgstr "La URL %s no apunta a una imagen v
|
||||
#, python-format
|
||||
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
|
||||
msgstr ""
|
||||
"Los números de teléfono deben guardar el formato XXX-XXX-XXXX format. \"%s\" "
|
||||
"Los números de teléfono deben guardar el formato XXX-XXX-XXXX. \"%s\" "
|
||||
"no es válido."
|
||||
|
||||
#: core/validators.py:196
|
||||
@ -726,10 +726,10 @@ msgid "Please enter a valid decimal number with a whole part of at most %s digit
|
||||
msgid_plural "Please enter a valid decimal number with a whole part of at most %s digits."
|
||||
msgstr[0] ""
|
||||
"Por favor, introduzca un número decimal válido con a lo más %s dígito en "
|
||||
"total."
|
||||
"su parte entera."
|
||||
msgstr[1] ""
|
||||
"Por favor, introduzca un número decimal válido con a lo más %s dígitos en "
|
||||
"total."
|
||||
"su parte entera."
|
||||
|
||||
#: core/validators.py:426
|
||||
#, python-format
|
||||
@ -958,7 +958,7 @@ msgid ""
|
||||
"digits and underscores)."
|
||||
msgstr ""
|
||||
"Requerido. 30 caracteres o menos. Sólo caracteres alfanuméricos (letras, "
|
||||
"dígutos y guiones bajos)."
|
||||
"dígitos y guiones bajos)."
|
||||
|
||||
#: contrib/auth/models.py:91
|
||||
msgid "first name"
|
||||
@ -1107,7 +1107,7 @@ msgstr "Las contrase
|
||||
#: contrib/auth/forms.py:124
|
||||
msgid "Your old password was entered incorrectly. Please enter it again."
|
||||
msgstr ""
|
||||
"Tu contraseña antígua es incorrecta. Por favor, vuelve a introducirla "
|
||||
"Tu contraseña antigua es incorrecta. Por favor, vuelve a introducirla "
|
||||
"correctamente."
|
||||
|
||||
#: contrib/comments/models.py:67 contrib/comments/models.py:166
|
||||
@ -1707,7 +1707,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Ha ocurrido un error. Se ha informado a los administradores del sitio "
|
||||
"mediante correo electrónico y debería arreglarse en breve. Gracias por su "
|
||||
"paciencia"
|
||||
"paciencia."
|
||||
|
||||
#: contrib/admin/templates/admin/search_form.html:8
|
||||
msgid "Go"
|
||||
@ -1899,7 +1899,7 @@ msgid ""
|
||||
"the appropriate user."
|
||||
msgstr ""
|
||||
"Algo va mal con la instalación de la base de datos. Asegúrate que las tablas "
|
||||
"necesarias han sido creadas, y que la base de datos puede ser leida por el "
|
||||
"necesarias han sido creadas, y que la base de datos puede ser leída por el "
|
||||
"usuario apropiado."
|
||||
|
||||
#: contrib/admin/templates/admin/filter.html:2
|
||||
@ -1912,7 +1912,7 @@ msgid ""
|
||||
"First, enter a username and password. Then, you'll be able to edit more user "
|
||||
"options."
|
||||
msgstr ""
|
||||
"Primero, introduzca un nombre de usuario y una contraseña. Luego, podrá "
|
||||
"Primero introduzca un nombre de usuario y una contraseña. Luego podrá "
|
||||
"editar el resto de opciones del usuario."
|
||||
|
||||
#: contrib/admin/templates/admin/auth/user/add_form.html:12
|
||||
@ -2105,7 +2105,7 @@ msgstr "vista:"
|
||||
#: contrib/admin/views/doc.py:164
|
||||
#, python-format
|
||||
msgid "App %r not found"
|
||||
msgstr "Applicación %r no encontrada"
|
||||
msgstr "Aplicación %r no encontrada"
|
||||
|
||||
#: contrib/admin/views/doc.py:171
|
||||
#, python-format
|
||||
@ -2326,12 +2326,12 @@ msgstr "Cambiar clave: %s"
|
||||
|
||||
#: contrib/localflavor/usa/forms.py:17
|
||||
msgid "Enter a zip code in the format XXXXX or XXXXX-XXXX."
|
||||
msgstr "Introduzca un código zip en el formato XXXXX o XXXX-XXXX."
|
||||
msgstr "Introduzca un código postal en el formato XXXXX o XXXX-XXXX."
|
||||
|
||||
#: contrib/localflavor/uk/forms.py:18
|
||||
msgid "Enter a postcode. A space is required between the two postcode parts."
|
||||
msgstr ""
|
||||
"Introduzca in código postal. Se necesita un espacio entre las dos partes del "
|
||||
"Introduzca un código postal. Se necesita un espacio entre las dos partes del "
|
||||
"código."
|
||||
|
||||
#: contrib/sessions/models.py:51
|
||||
|
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.
@ -8,26 +8,14 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: djangojs 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-03-30 13:28+0200\n"
|
||||
"PO-Revision-Date: 2006-03-30 13:35+0200\n"
|
||||
"POT-Creation-Date: 2007-05-06 13:08+0300\n"
|
||||
"PO-Revision-Date: 2007-05-06 13:08+0300\n"
|
||||
"Last-Translator: Meir Kriheli <meir@mksoft.co.il>\n"
|
||||
"Language-Team: Hebrew\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:32
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
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"
|
||||
@ -58,54 +46,75 @@ msgstr "יש לסמן את ההרשאות המבוקשות וללחוץ על "
|
||||
msgid "Clear all"
|
||||
msgstr "איפוס הכל"
|
||||
|
||||
#: 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/admin/DateTimeShortcuts.js:45
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
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 "הסתר"
|
||||
|
||||
#: 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:48
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||
msgid "Clock"
|
||||
msgstr "שעון"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||
msgid "Choose a time"
|
||||
msgstr "בחירת שעה"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "Midnight"
|
||||
msgstr "חצות"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "6 a.m."
|
||||
msgstr "6 בבוקר"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr "צהריים"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||
#: 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:111
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
||||
#: 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:114
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||
msgid "Calendar"
|
||||
msgstr "לוח שנה"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||
msgid "Yesterday"
|
||||
msgstr "אתמול"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr "מחר"
|
||||
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/ko/LC_MESSAGES/django.mo
Normal file
BIN
django/conf/locale/ko/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
2797
django/conf/locale/ko/LC_MESSAGES/django.po
Normal file
2797
django/conf/locale/ko/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
django/conf/locale/ko/LC_MESSAGES/djangojs.mo
Normal file
BIN
django/conf/locale/ko/LC_MESSAGES/djangojs.mo
Normal file
Binary file not shown.
118
django/conf/locale/ko/LC_MESSAGES/djangojs.po
Normal file
118
django/conf/locale/ko/LC_MESSAGES/djangojs.po
Normal file
@ -0,0 +1,118 @@
|
||||
# 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.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-04-06 11:10+0900\n"
|
||||
"PO-Revision-Date: 2007-04-06 11:15+0900\n"
|
||||
"Last-Translator: Hyun Mi Ae <happyhyun@gmail.com>\n"
|
||||
"Language-Team: Korean\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 "1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월"
|
||||
|
||||
#: 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 "이용 가능한 %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/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 "감추기"
|
||||
|
||||
#: 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 "오전 6시"
|
||||
|
||||
#: 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 "내일"
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -10,7 +10,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2007-02-15 10:46+1100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Last-Translator: Gatis Tomsons <gatis.tomsons@gmail.com>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
@ -19,64 +19,65 @@ msgstr ""
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr ""
|
||||
msgstr "Pieejams %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
msgstr ""
|
||||
msgstr "Izvēlēties visu"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
msgstr "Pievienot"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
msgstr "Izņemt"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr ""
|
||||
msgstr "Izvēlies %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr ""
|
||||
msgstr "Izvēlies un klikšķini"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
msgstr ""
|
||||
msgstr "Attīrīt visu"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:32
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
"December"
|
||||
msgstr ""
|
||||
msgstr "Janvāris Februāris Marts Aprīlis Maijs Jūnijs Jūlijs Augusts Septembris Oktobris Novembris"
|
||||
"Decembris"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr ""
|
||||
msgstr "Svētdiena Pirmdiena Otrdiena Trešdiena Ceturtdiena Piektdiena Sestdiena"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr ""
|
||||
msgstr "S M T W T F S"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Now"
|
||||
msgstr ""
|
||||
msgstr "Tagad"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||
msgid "Clock"
|
||||
msgstr ""
|
||||
msgstr "Pulkstens"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||
msgid "Choose a time"
|
||||
msgstr ""
|
||||
msgstr "Izvēlieties laiku"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "Midnight"
|
||||
msgstr ""
|
||||
msgstr "Pusnakts"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "6 a.m."
|
||||
@ -84,35 +85,35 @@ msgstr ""
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr ""
|
||||
msgstr "Pusdienas laiks"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
msgstr "Atcelt"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
|
||||
msgid "Today"
|
||||
msgstr ""
|
||||
msgstr "Šodien"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||
msgid "Calendar"
|
||||
msgstr ""
|
||||
msgstr "Kalendārs"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||
msgid "Yesterday"
|
||||
msgstr ""
|
||||
msgstr "Vakar"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr ""
|
||||
msgstr "Rīt"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
msgstr "Parādīt"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr ""
|
||||
msgstr "Slēpt"
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# translation of django.po to
|
||||
# Copyright (C) 2005 and beyond
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Espen Grindhaug <espen@grindhaug.org>, Nov 2005.
|
||||
@ -6,74 +6,73 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Project-Id-Version: django\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-05-16 10:12+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Espen Grndhaug <espen@grindhaug.org>\n"
|
||||
"Language-Team: Norwegian\n"
|
||||
"PO-Revision-Date: 2007-04-27 06:48+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: <en@li.org>\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"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#: contrib/comments/models.py:67 contrib/comments/models.py:166
|
||||
#, fuzzy
|
||||
msgid "object ID"
|
||||
msgstr "Vis objekt ID"
|
||||
msgstr "objekt ID"
|
||||
|
||||
#: contrib/comments/models.py:68
|
||||
msgid "headline"
|
||||
msgstr ""
|
||||
msgstr "overskrift"
|
||||
|
||||
#: contrib/comments/models.py:69 contrib/comments/models.py:90
|
||||
#: contrib/comments/models.py:167
|
||||
#, fuzzy
|
||||
msgid "comment"
|
||||
msgstr "innhold"
|
||||
msgstr "kommentar"
|
||||
|
||||
#: contrib/comments/models.py:70
|
||||
msgid "rating #1"
|
||||
msgstr ""
|
||||
msgstr "rangering #1 "
|
||||
|
||||
#: contrib/comments/models.py:71
|
||||
msgid "rating #2"
|
||||
msgstr ""
|
||||
msgstr "rangering #2"
|
||||
|
||||
#: contrib/comments/models.py:72
|
||||
msgid "rating #3"
|
||||
msgstr ""
|
||||
msgstr "rangering #3"
|
||||
|
||||
#: contrib/comments/models.py:73
|
||||
msgid "rating #4"
|
||||
msgstr ""
|
||||
msgstr "rangering #4"
|
||||
|
||||
#: contrib/comments/models.py:74
|
||||
msgid "rating #5"
|
||||
msgstr ""
|
||||
msgstr "rangering #5"
|
||||
|
||||
#: contrib/comments/models.py:75
|
||||
msgid "rating #6"
|
||||
msgstr ""
|
||||
msgstr "rangering #6"
|
||||
|
||||
#: contrib/comments/models.py:76
|
||||
msgid "rating #7"
|
||||
msgstr ""
|
||||
msgstr "rangering #7"
|
||||
|
||||
#: contrib/comments/models.py:77
|
||||
msgid "rating #8"
|
||||
msgstr ""
|
||||
msgstr "rangering #8"
|
||||
|
||||
#: contrib/comments/models.py:82
|
||||
msgid "is valid rating"
|
||||
msgstr ""
|
||||
msgstr "er gyldig rangering"
|
||||
|
||||
#: contrib/comments/models.py:83 contrib/comments/models.py:169
|
||||
msgid "date/time submitted"
|
||||
msgstr ""
|
||||
msgstr "dato/tid for innsendelse"
|
||||
|
||||
#: contrib/comments/models.py:84 contrib/comments/models.py:170
|
||||
msgid "is public"
|
||||
msgstr ""
|
||||
msgstr "er tilgjengelig for alle"
|
||||
|
||||
#: contrib/comments/models.py:85 contrib/admin/views/doc.py:289
|
||||
msgid "IP address"
|
||||
@ -81,23 +80,21 @@ msgstr "IP adresse"
|
||||
|
||||
#: contrib/comments/models.py:86
|
||||
msgid "is removed"
|
||||
msgstr ""
|
||||
msgstr "er fjernet"
|
||||
|
||||
#: contrib/comments/models.py:86
|
||||
msgid ""
|
||||
"Check this box if the comment is inappropriate. A \"This comment has been "
|
||||
"removed\" message will be displayed instead."
|
||||
msgstr ""
|
||||
msgstr "Aktiver denne avkryssningsboksen hvis kommentaren er upasende. Beskjeden \"Denne kommentaren er blitt fjernet\" vil bli vist istedet."
|
||||
|
||||
#: contrib/comments/models.py:91
|
||||
#, fuzzy
|
||||
msgid "comments"
|
||||
msgstr "innhold"
|
||||
msgstr "kommentarer"
|
||||
|
||||
#: contrib/comments/models.py:131 contrib/comments/models.py:207
|
||||
#, fuzzy
|
||||
msgid "Content object"
|
||||
msgstr "innholds type"
|
||||
msgstr "innholdsobjekt"
|
||||
|
||||
#: contrib/comments/models.py:159
|
||||
#, python-format
|
||||
@ -108,101 +105,97 @@ msgid ""
|
||||
"\n"
|
||||
"http://%(domain)s%(url)s"
|
||||
msgstr ""
|
||||
"Sendt av %(user)s på %(date)s\n"
|
||||
"\n"
|
||||
"%(comment)s\n"
|
||||
"\n"
|
||||
"http://%(domain)s%(url)s"
|
||||
|
||||
#: contrib/comments/models.py:168
|
||||
#, fuzzy
|
||||
msgid "person's name"
|
||||
msgstr "fornavn"
|
||||
msgstr "personens navn"
|
||||
|
||||
#: contrib/comments/models.py:171
|
||||
#, fuzzy
|
||||
msgid "ip address"
|
||||
msgstr "IP adresse"
|
||||
|
||||
#: contrib/comments/models.py:173
|
||||
msgid "approved by staff"
|
||||
msgstr ""
|
||||
msgstr "godkjent av moderator"
|
||||
|
||||
#: contrib/comments/models.py:176
|
||||
#, fuzzy
|
||||
msgid "free comment"
|
||||
msgstr "tillat kommentarer"
|
||||
msgstr "åpen kommentar"
|
||||
|
||||
#: contrib/comments/models.py:177
|
||||
#, fuzzy
|
||||
msgid "free comments"
|
||||
msgstr "tillat kommentarer"
|
||||
msgstr "åpne kommentarer"
|
||||
|
||||
#: contrib/comments/models.py:233
|
||||
msgid "score"
|
||||
msgstr ""
|
||||
msgstr "poeng"
|
||||
|
||||
#: contrib/comments/models.py:234
|
||||
#, fuzzy
|
||||
msgid "score date"
|
||||
msgstr "utløpsdato"
|
||||
msgstr "poeng dato"
|
||||
|
||||
#: contrib/comments/models.py:237
|
||||
msgid "karma score"
|
||||
msgstr ""
|
||||
msgstr "karma poeng"
|
||||
|
||||
#: contrib/comments/models.py:238
|
||||
msgid "karma scores"
|
||||
msgstr ""
|
||||
msgstr "karma poeng"
|
||||
|
||||
#: contrib/comments/models.py:242
|
||||
#, python-format
|
||||
msgid "%(score)d rating by %(user)s"
|
||||
msgstr ""
|
||||
msgstr "%(score)d rangering av %(user)s"
|
||||
|
||||
#: contrib/comments/models.py:258
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This comment was flagged by %(user)s:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr ""
|
||||
"Denne kommentaren er skrevet med lite omtanke:\n"
|
||||
"Denne kommentaren er flagget av %(user)s:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
|
||||
#: contrib/comments/models.py:265
|
||||
#, fuzzy
|
||||
msgid "flag date"
|
||||
msgstr "flatside"
|
||||
msgstr "flagg dato"
|
||||
|
||||
#: contrib/comments/models.py:268
|
||||
#, fuzzy
|
||||
msgid "user flag"
|
||||
msgstr "Bruker"
|
||||
msgstr "brukerflag"
|
||||
|
||||
#: contrib/comments/models.py:269
|
||||
#, fuzzy
|
||||
msgid "user flags"
|
||||
msgstr "Brukere"
|
||||
msgstr "brukerflag"
|
||||
|
||||
#: contrib/comments/models.py:273
|
||||
#, python-format
|
||||
msgid "Flag by %r"
|
||||
msgstr ""
|
||||
msgstr "Flagg med %r"
|
||||
|
||||
#: contrib/comments/models.py:278
|
||||
#, fuzzy
|
||||
msgid "deletion date"
|
||||
msgstr "sesjon data"
|
||||
msgstr "fjernet dato"
|
||||
|
||||
#: contrib/comments/models.py:280
|
||||
msgid "moderator deletion"
|
||||
msgstr ""
|
||||
msgstr "fjernet av moderator"
|
||||
|
||||
#: contrib/comments/models.py:281
|
||||
msgid "moderator deletions"
|
||||
msgstr ""
|
||||
msgstr "fjernet av moderator"
|
||||
|
||||
#: contrib/comments/models.py:285
|
||||
#, python-format
|
||||
msgid "Moderator deletion by %r"
|
||||
msgstr ""
|
||||
msgstr "Fjernet av moderator med %r"
|
||||
|
||||
#: contrib/comments/views/karma.py:19
|
||||
msgid "Anonymous users cannot vote"
|
||||
@ -214,16 +207,14 @@ msgstr "Ikke gyldig kommentar ID"
|
||||
|
||||
#: contrib/comments/views/karma.py:25
|
||||
msgid "No voting for yourself"
|
||||
msgstr "Du kan ikke stemme selv"
|
||||
msgstr "Du kan ikke stemme på deg selv"
|
||||
|
||||
#: contrib/comments/views/comments.py:28
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"This rating is required because you've entered at least one other rating."
|
||||
msgstr "Denne bla bla.."
|
||||
msgid "This rating is required because you've entered at least one other rating."
|
||||
msgstr "Denne rangeringen er påkrevd fordi du har rangert en eller flere ting fra før "
|
||||
|
||||
#: contrib/comments/views/comments.py:112
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This comment was posted by a user who has posted fewer than %(count)s "
|
||||
"comment:\n"
|
||||
@ -246,13 +237,13 @@ msgstr[1] ""
|
||||
"%(text)s"
|
||||
|
||||
#: contrib/comments/views/comments.py:117
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This comment was posted by a sketchy user:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
msgstr ""
|
||||
"Denne kommentaren er skrevet med lite omtanke:\n"
|
||||
"Denne kommentaren er skrevet av en upålitelig bruker:\n"
|
||||
"\n"
|
||||
"%(text)s"
|
||||
|
||||
@ -281,8 +272,7 @@ msgstr "Skjemaet hadde en ugyldig verdi - objekt IDen var ugyldig"
|
||||
#: contrib/comments/views/comments.py:257
|
||||
#: contrib/comments/views/comments.py:321
|
||||
msgid "The comment form didn't provide either 'preview' or 'post'"
|
||||
msgstr ""
|
||||
"Kommentar skjemaet returnerte ikke et 'forhåndsvisning' eller 'post' objekt"
|
||||
msgstr "Kommentar skjemaet returnerte ikke et 'forhåndsvisning' eller 'post' objekt"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:6
|
||||
#: contrib/comments/templates/comments/form.html:8
|
||||
@ -296,9 +286,8 @@ msgid "Password:"
|
||||
msgstr "Passord:"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:6
|
||||
#, fuzzy
|
||||
msgid "Forgotten your password?"
|
||||
msgstr "Endre passord"
|
||||
msgstr "Har du glemt passordet ditt ?"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:8
|
||||
#: contrib/admin/templates/admin/object_history.html:3
|
||||
@ -323,38 +312,35 @@ msgstr "Log ut"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:12
|
||||
msgid "Ratings"
|
||||
msgstr ""
|
||||
msgstr "Rangeringer"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:12
|
||||
#: contrib/comments/templates/comments/form.html:23
|
||||
msgid "Required"
|
||||
msgstr ""
|
||||
msgstr "Påkrevd"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:12
|
||||
#: contrib/comments/templates/comments/form.html:23
|
||||
msgid "Optional"
|
||||
msgstr ""
|
||||
msgstr "Valgfri"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:23
|
||||
msgid "Post a photo"
|
||||
msgstr ""
|
||||
msgstr "Send et foto"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:27
|
||||
#: contrib/comments/templates/comments/freeform.html:5
|
||||
#, fuzzy
|
||||
msgid "Comment:"
|
||||
msgstr "tillat kommentarer"
|
||||
msgstr "Kommentar:"
|
||||
|
||||
#: contrib/comments/templates/comments/form.html:32
|
||||
#: contrib/comments/templates/comments/freeform.html:9
|
||||
#, fuzzy
|
||||
msgid "Preview comment"
|
||||
msgstr "tillat kommentarer"
|
||||
msgstr "Forhåndvis kommentar"
|
||||
|
||||
#: contrib/comments/templates/comments/freeform.html:4
|
||||
#, fuzzy
|
||||
msgid "Your name:"
|
||||
msgstr "brukernavn"
|
||||
msgstr "Ditt navn:"
|
||||
|
||||
#: contrib/admin/filterspecs.py:40
|
||||
#, python-format
|
||||
@ -416,7 +402,7 @@ msgstr "objekt repr"
|
||||
|
||||
#: contrib/admin/models.py:21
|
||||
msgid "action flag"
|
||||
msgstr "handlings flagg"
|
||||
msgstr "handlingsflagg"
|
||||
|
||||
#: contrib/admin/models.py:22
|
||||
msgid "change message"
|
||||
@ -424,11 +410,11 @@ msgstr "endre melding"
|
||||
|
||||
#: contrib/admin/models.py:25
|
||||
msgid "log entry"
|
||||
msgstr "logg notis"
|
||||
msgstr "logg post"
|
||||
|
||||
#: contrib/admin/models.py:26
|
||||
msgid "log entries"
|
||||
msgstr "logg innlegg"
|
||||
msgstr "logg poster"
|
||||
|
||||
#: contrib/admin/templatetags/admin_list.py:228
|
||||
msgid "All dates"
|
||||
@ -440,8 +426,8 @@ msgid ""
|
||||
"Please enter a correct username and password. Note that both fields are case-"
|
||||
"sensitive."
|
||||
msgstr ""
|
||||
"Vær snill å angi korrekt brukernavn og passord. La merke til at små og "
|
||||
"store bokstaver er betraktet ulik."
|
||||
"Vennligst angi korrekt brukernavn og passord. Merk at små og "
|
||||
"store bokstaver er betraktet ulikt."
|
||||
|
||||
#: contrib/admin/views/decorators.py:23
|
||||
#: contrib/admin/templates/admin/login.html:25
|
||||
@ -452,18 +438,15 @@ msgstr "Logg inn"
|
||||
msgid ""
|
||||
"Please log in again, because your session has expired. Don't worry: Your "
|
||||
"submission has been saved."
|
||||
msgstr ""
|
||||
"Du må logge inn igjen, fordi sesjonen din har gått ut på dato, men ikke ikke "
|
||||
"bekjymr deg informasjonen du sendte ble lagret."
|
||||
msgstr "Du må logge inn igjen, fordi økten din har gått ut, men innlegget ditt ble lagret."
|
||||
|
||||
#: contrib/admin/views/decorators.py:68
|
||||
msgid ""
|
||||
"Looks like your browser isn't configured to accept cookies. Please enable "
|
||||
"cookies, reload this page, and try again."
|
||||
msgstr ""
|
||||
"Det ser ut som om nettleseren din ikke vill ta i mot informasjonskapsler "
|
||||
"('cookies'). Vennligst omkonfigurer nettleseren din, last siden på ny og "
|
||||
"prøv igjen."
|
||||
"Det ser ut som om nettleseren din ikke støtter informasjonskapsler "
|
||||
"('cookies'). Vennligst konfigurer nettleseren din, og prøv igjen."
|
||||
|
||||
#: contrib/admin/views/decorators.py:82
|
||||
msgid "Usernames cannot contain the '@' character."
|
||||
@ -500,7 +483,7 @@ msgstr "Ny %s"
|
||||
#: contrib/admin/views/main.py:336
|
||||
#, python-format
|
||||
msgid "Added %s."
|
||||
msgstr "Lagt til %s"
|
||||
msgstr "La til %s"
|
||||
|
||||
#: contrib/admin/views/main.py:336 contrib/admin/views/main.py:338
|
||||
#: contrib/admin/views/main.py:340
|
||||
@ -528,8 +511,7 @@ msgstr "%(name)s \"%(obj)s\" ble endret."
|
||||
|
||||
#: contrib/admin/views/main.py:354
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgid "The %(name)s \"%(obj)s\" was added successfully. You may edit it again below."
|
||||
msgstr "%(name)s \"%(obj)s\" ble endret. Du kan endre det igjen under."
|
||||
|
||||
#: contrib/admin/views/main.py:392
|
||||
@ -742,8 +724,8 @@ msgid ""
|
||||
"There's been an error. It's been reported to the site administrators via e-"
|
||||
"mail and should be fixed shortly. Thanks for your patience."
|
||||
msgstr ""
|
||||
"Det har vært en feil. Feilen er blitt rapportert til administrator via e-"
|
||||
"mail, og vill bli fikset snart. Takk for din tålmodighet."
|
||||
"Det har oppstått en feil. Feilen er blitt rapportert til administrator via e-"
|
||||
"post, og vil bli fikset snart. Takk for din tålmodighet."
|
||||
|
||||
#: contrib/admin/templates/admin/404.html:4
|
||||
#: contrib/admin/templates/admin/404.html:8
|
||||
@ -909,7 +891,7 @@ msgstr "Tilbakestill mitt passord"
|
||||
|
||||
#: contrib/admin/templates/registration/logged_out.html:8
|
||||
msgid "Thanks for spending some quality time with the Web site today."
|
||||
msgstr "Takk for å bruke tid på internett siden i dag."
|
||||
msgstr "Takk for at du valgte å bruke kvalitetstid på nettstedet idag."
|
||||
|
||||
#: contrib/admin/templates/registration/logged_out.html:10
|
||||
msgid "Log in again"
|
||||
@ -954,8 +936,7 @@ msgstr "Endre passord"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:2
|
||||
msgid "You're receiving this e-mail because you requested a password reset"
|
||||
msgstr ""
|
||||
"Du har mottatt denne e-posten fordi du ba om å tilbakestille passordet ditt"
|
||||
msgstr "Du har mottatt denne e-posten fordi du ba om å tilbakestille passordet ditt"
|
||||
|
||||
#: contrib/admin/templates/registration/password_reset_email.html:3
|
||||
#, python-format
|
||||
@ -1002,6 +983,12 @@ msgid ""
|
||||
"as \"internal\" (talk to your system administrator if you aren't sure if\n"
|
||||
"your computer is \"internal\").</p>\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"<p class=\"help\">For å installere bokmerker, dra linken til verktøylinja\n"
|
||||
"for bokmerker, eller høyreklikk og legg til i bokmerker. Nå kan du du velge\n"
|
||||
"bokmerket fra hvilken som helst side på nettstedet. Noen av disse\n"
|
||||
"bokmerkene krever at datamaskinen du bruker er markert som \"intern\"\n"
|
||||
"(kontakt din systemadministrator hvis du er usikker på om maskinen din er \"intern\").</p>\n"
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:19
|
||||
msgid "Documentation for this page"
|
||||
@ -1033,8 +1020,7 @@ msgstr "Endre dette objektet (åpnes i dette vinduet)"
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:26
|
||||
msgid "Jumps to the admin page for pages that represent a single object."
|
||||
msgstr ""
|
||||
"Hopp til administrasjonsiden for sidene som representerer et enkelt objekt."
|
||||
msgstr "Hopp til administrasjonsiden for sidene som representerer et enkelt objekt."
|
||||
|
||||
#: contrib/admin/templates/admin_doc/bookmarklets.html:28
|
||||
msgid "Edit this object (new window)"
|
||||
@ -1069,7 +1055,7 @@ msgid ""
|
||||
"This should be an absolute path, excluding the domain name. Example: '/"
|
||||
"events/search/'."
|
||||
msgstr ""
|
||||
"Denne burde vær en fullstendig sti, uten domene navnet. Foreksempel: '/"
|
||||
"Dette burde vært en fullstendig sti, uten domene navnet. Foreksempel: '/"
|
||||
"nyheter/les/"
|
||||
|
||||
#: contrib/redirects/models.py:9
|
||||
@ -1081,7 +1067,7 @@ msgid ""
|
||||
"This can be either an absolute path (as above) or a full URL starting with "
|
||||
"'http://'."
|
||||
msgstr ""
|
||||
"Denne kan enten være en fullstendig sti (som over), eller en hel "
|
||||
"Dette kan enten være en fullstendig sti (som over), eller en hel "
|
||||
"internettadresse som starter med 'http://'"
|
||||
|
||||
#: contrib/redirects/models.py:12
|
||||
@ -1093,10 +1079,8 @@ msgid "redirects"
|
||||
msgstr "omadresserelser"
|
||||
|
||||
#: contrib/flatpages/models.py:8
|
||||
msgid ""
|
||||
"Example: '/about/contact/'. Make sure to have leading and trailing slashes."
|
||||
msgstr ""
|
||||
"Eksempel: '/om/kontakt/'. Vær sikker på at du har en skråstrek forran og bak."
|
||||
msgid "Example: '/about/contact/'. Make sure to have leading and trailing slashes."
|
||||
msgstr "Eksempel: '/om/kontakt/'. Vær sikker på at du har en skråstrek forran og bak."
|
||||
|
||||
#: contrib/flatpages/models.py:9
|
||||
msgid "title"
|
||||
@ -1186,7 +1170,7 @@ msgstr "passord"
|
||||
|
||||
#: contrib/auth/models.py:59
|
||||
msgid "Use '[algo]$[salt]$[hexdigest]'"
|
||||
msgstr ""
|
||||
msgstr "Bruk '[algo]$[salt]$[hexdigest]'"
|
||||
|
||||
#: contrib/auth/models.py:60
|
||||
msgid "staff status"
|
||||
@ -1256,7 +1240,7 @@ msgstr "Melding"
|
||||
msgid ""
|
||||
"Your Web browser doesn't appear to have cookies enabled. Cookies are "
|
||||
"required for logging in."
|
||||
msgstr ""
|
||||
msgstr "Din nettleser ser ikkeut til å støtte informasjonskapsler (cookies). Informasjonskapsler er påkrevd for å logge inn."
|
||||
|
||||
#: contrib/contenttypes/models.py:25
|
||||
msgid "python model class name"
|
||||
@ -1698,8 +1682,7 @@ msgstr "Internettadressen %s peker ikke til et godkjent bilde."
|
||||
#: core/validators.py:159
|
||||
#, python-format
|
||||
msgid "Phone numbers must be in XXX-XXX-XXXX format. \"%s\" is invalid."
|
||||
msgstr ""
|
||||
"Telefon nummeret må være i XXX-XXX-XXXX format. \"%s\" er ikke godkjent."
|
||||
msgstr "Telefon nummeret må være i XXX-XXX-XXXX format. \"%s\" er ikke godkjent."
|
||||
|
||||
#: core/validators.py:167
|
||||
#, python-format
|
||||
@ -1732,7 +1715,7 @@ msgstr "Ikke godkjent URL: %s"
|
||||
#: core/validators.py:206 core/validators.py:208
|
||||
#, python-format
|
||||
msgid "The URL %s is a broken link."
|
||||
msgstr "Internettadresse fører til en side som ikke virker."
|
||||
msgstr "Internettadresse %s fører til en side som ikke virker."
|
||||
|
||||
#: core/validators.py:214
|
||||
msgid "Enter a valid U.S. state abbreviation."
|
||||
@ -1784,30 +1767,26 @@ msgstr "Vennligst skriv inn et godkjent desimal tall."
|
||||
#: core/validators.py:349
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with at most %s total digit."
|
||||
msgid_plural ""
|
||||
"Please enter a valid decimal number with at most %s total digits."
|
||||
msgid_plural "Please enter a valid decimal number with at most %s total digits."
|
||||
msgstr[0] "Skriv inn et desimal tall med maksimum %s total antall tall."
|
||||
msgstr[1] "Skriv inn et desimal tall med maksimum %s total antall tall."
|
||||
|
||||
#: core/validators.py:352
|
||||
#, python-format
|
||||
msgid "Please enter a valid decimal number with at most %s decimal place."
|
||||
msgid_plural ""
|
||||
"Please enter a valid decimal number with at most %s decimal places."
|
||||
msgid_plural "Please enter a valid decimal number with at most %s decimal places."
|
||||
msgstr[0] "Skriv inn et desimal tall med maksimum %s tall bak komma. "
|
||||
msgstr[1] "Skriv inn et desimal tall med maksimum %s tall bak komma. "
|
||||
|
||||
#: core/validators.py:362
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at least %s bytes big."
|
||||
msgstr ""
|
||||
"Vær sikker på at fila du prøver å laste opp er minimum %s bytes stor."
|
||||
msgstr "Vær sikker på at fila du prøver å laste opp er minimum %s bytes stor."
|
||||
|
||||
#: core/validators.py:363
|
||||
#, python-format
|
||||
msgid "Make sure your uploaded file is at most %s bytes big."
|
||||
msgstr ""
|
||||
"Vær sikker på at fila du prøver å laste opp er maksimum %s bytes stor."
|
||||
msgstr "Vær sikker på at fila du prøver å laste opp er maksimum %s bytes stor."
|
||||
|
||||
#: core/validators.py:376
|
||||
msgid "The format for this field is wrong."
|
||||
@ -1824,8 +1803,7 @@ msgstr "Klarte ikke å motta noe fra %s."
|
||||
|
||||
#: core/validators.py:429
|
||||
#, python-format
|
||||
msgid ""
|
||||
"The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
|
||||
msgid "The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'."
|
||||
msgstr ""
|
||||
"Internettadressen %(url)s returnerte en ikke godkjent Content-Type '%"
|
||||
"(contenttype)s'."
|
||||
@ -1881,7 +1859,7 @@ msgid ""
|
||||
"The \"%(attr)s\" attribute on line %(line)s has an invalid value. (Line "
|
||||
"starts with \"%(start)s\".)"
|
||||
msgstr ""
|
||||
"\"%(attr)s\" tillegg på linje $(line)s har en ikke godkjent verdi. (Linjen "
|
||||
"\"%(attr)s\" tillegg på linje %(line)s har en ikke godkjent verdi. (Linjen "
|
||||
"starter med \"%(start)s\".)"
|
||||
|
||||
#: db/models/manipulators.py:302
|
||||
@ -1892,7 +1870,7 @@ msgstr "%(object)s med %(type)s finnes allerede for angitt %(field)s."
|
||||
#: db/models/fields/__init__.py:40
|
||||
#, python-format
|
||||
msgid "%(optname)s with this %(fieldname)s already exists."
|
||||
msgstr "$(optname)s med %(fieldname)s finnes allerede."
|
||||
msgstr "%(optname)s med %(fieldname)s finnes allerede."
|
||||
|
||||
#: db/models/fields/__init__.py:114 db/models/fields/__init__.py:265
|
||||
#: db/models/fields/__init__.py:542 db/models/fields/__init__.py:553
|
||||
@ -1926,16 +1904,13 @@ msgid "Separate multiple IDs with commas."
|
||||
msgstr "Separer Id-ene med kommaer."
|
||||
|
||||
#: db/models/fields/related.py:581
|
||||
msgid ""
|
||||
"Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr ""
|
||||
"Hold nede \"Control\", eller \"Command\" på en Mac, for å velge mere enn en."
|
||||
msgid "Hold down \"Control\", or \"Command\" on a Mac, to select more than one."
|
||||
msgstr "Hold nede \"Control\", eller \"Command\" på en Mac, for å velge mere enn en."
|
||||
|
||||
#: db/models/fields/related.py:625
|
||||
#, python-format
|
||||
msgid "Please enter valid %(self)s IDs. The value %(value)r is invalid."
|
||||
msgid_plural ""
|
||||
"Please enter valid %(self)s IDs. The values %(value)r are invalid."
|
||||
msgid_plural "Please enter valid %(self)s IDs. The values %(value)r are invalid."
|
||||
msgstr[0] "Skriv inn gyldige %(self)s ID-er. Verdien %(value)r er ikke gyldig."
|
||||
msgstr[1] "Skriv inn gyldige %(self)s ID-er. Verdiene %(value)r er ikke gyldige."
|
||||
|
||||
|
Binary file not shown.
@ -1,19 +1,20 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# translation of djangojs.po to
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# Espen Grindhaug <espen.grindhaug@mail.com>, 2006.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Project-Id-Version: djangojs\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Espen Grindhaug <espen.grindhaug@gmail.com>\n"
|
||||
"Language-Team: no\n"
|
||||
"PO-Revision-Date: 2007-04-27 06:51+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: <en@li.org>\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"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
@ -21,7 +22,6 @@ msgid "Available %s"
|
||||
msgstr "%s er tilgjengelige"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
#, fuzzy
|
||||
msgid "Choose all"
|
||||
msgstr "Velg alle"
|
||||
|
||||
@ -116,3 +116,4 @@ msgstr "I går"
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
msgid "Tomorrow"
|
||||
msgstr "I morgen"
|
||||
|
||||
|
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.
@ -1,20 +1,15 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# VLADO LABATH <vlado@labath.org>, 2005.
|
||||
#
|
||||
#, fuzzy
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Project-Id-Version: Django 1.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-18 19:38-0500\n"
|
||||
"PO-Revision-Date: 2005-12-18 19:26-0500\n"
|
||||
"Last-Translator: VLADO LABATH <vlado@labath.org>\n"
|
||||
"Language-Team: LANGUAGE <sk@li.org>\n"
|
||||
"POT-Creation-Date: 2007-04-01 19:21+0200\n"
|
||||
"PO-Revision-Date: 2007-04-03 21:48+0200\n"
|
||||
"Last-Translator: <>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
@ -23,15 +18,15 @@ msgstr "Možný %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
msgstr "Vyber všetko"
|
||||
msgstr "Vybrať všetko"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
msgstr "Pridaj"
|
||||
msgstr "Pridať"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
msgstr "Vymaž"
|
||||
msgstr "Vymazať"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
@ -40,13 +35,13 @@ msgstr "Vybrané %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr "Vyber si svoju voľbu a klikni"
|
||||
msgstr "Vyberte položku a kliknite"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
msgstr "Vyčisti všetko"
|
||||
msgstr "Odstrániť vybrané"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:26
|
||||
#: contrib/admin/media/js/dateparse.js:32
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
msgid ""
|
||||
"January February March April May June July August September October November "
|
||||
@ -55,7 +50,7 @@ msgstr ""
|
||||
"Január Február Marec Apríl Máj Jún Júl August September Október November "
|
||||
"December"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:27
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Nedeľa Pondelok Utorok Streda Štvrtok Piatok Sobota"
|
||||
|
||||
@ -63,49 +58,59 @@ msgstr "Nedeľa Pondelok Utorok Streda Štvrtok Piatok Sobota"
|
||||
msgid "S M T W T F S"
|
||||
msgstr "N P U S Š P S"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
msgstr "Zobraziť"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr "Skryť"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:47
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Now"
|
||||
msgstr "Práve teraz"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:51
|
||||
msgid "Clock"
|
||||
msgstr "Hodiny"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:78
|
||||
msgid "Choose a time"
|
||||
msgstr "Vyber čas"
|
||||
msgstr "Vybrať čas"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "Midnight"
|
||||
msgstr "Polnoc"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "6 a.m."
|
||||
msgstr "6 ráno"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:84
|
||||
msgid "Noon"
|
||||
msgstr "Poludnie"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:88
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:183
|
||||
msgid "Cancel"
|
||||
msgstr "Zruš"
|
||||
msgstr "Zrušiť"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:128
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:177
|
||||
msgid "Today"
|
||||
msgstr "Dnes"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:132
|
||||
msgid "Calendar"
|
||||
msgstr "Kalendár"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:175
|
||||
msgid "Yesterday"
|
||||
msgstr "Včera"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:179
|
||||
msgid "Tomorrow"
|
||||
msgstr "Zajtra"
|
||||
|
||||
|
BIN
django/conf/locale/sl/LC_MESSAGES/djangojs.mo
Normal file
BIN
django/conf/locale/sl/LC_MESSAGES/djangojs.mo
Normal file
Binary file not shown.
107
django/conf/locale/sl/LC_MESSAGES/djangojs.po
Normal file
107
django/conf/locale/sl/LC_MESSAGES/djangojs.po
Normal file
@ -0,0 +1,107 @@
|
||||
# Copyright (C) 2007
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: DJANGO-JS\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2005-12-09 11:51+0100\n"
|
||||
"PO-Revision-Date: 2007-03-31 21:29+0100\n"
|
||||
"Last-Translator: Gasper Koren <skrat@owca.info>\n"
|
||||
"Language-Team: SLOVENIAN <lugos-slo@lugos.si>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Slovenian\n"
|
||||
"X-Poedit-Country: SLOVENIA\n"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:33
|
||||
#, perl-format
|
||||
msgid "Available %s"
|
||||
msgstr "Možne %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:41
|
||||
msgid "Choose all"
|
||||
msgstr "Izberi vse"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:46
|
||||
msgid "Add"
|
||||
msgstr "Dodaj"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:48
|
||||
msgid "Remove"
|
||||
msgstr "Odstrani"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:53
|
||||
#, perl-format
|
||||
msgid "Chosen %s"
|
||||
msgstr "Izberite %s"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:54
|
||||
msgid "Select your choice(s) and click "
|
||||
msgstr "Izberite in kliknite"
|
||||
|
||||
#: contrib/admin/media/js/SelectFilter2.js:59
|
||||
msgid "Clear all"
|
||||
msgstr "Izbriši vse"
|
||||
|
||||
#: 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 "Januar Februar Marec April Maj Junij Julij Avgust September Oktober November December"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:27
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
msgstr "Nedelja Ponedeljek Torek Sreda Četrtek Petek Sobota"
|
||||
|
||||
#: contrib/admin/media/js/calendar.js:25
|
||||
msgid "S M T W T F S"
|
||||
msgstr "N P T S Č P S"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:45
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:80
|
||||
msgid "Now"
|
||||
msgstr "Sedaj"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:48
|
||||
msgid "Clock"
|
||||
msgstr "URA"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:77
|
||||
msgid "Choose a time"
|
||||
msgstr "Izberite čas"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:81
|
||||
msgid "Midnight"
|
||||
msgstr "Polnoč"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:82
|
||||
msgid "6 a.m."
|
||||
msgstr "Ob 6h"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:83
|
||||
msgid "Noon"
|
||||
msgstr "Opoldne"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:87
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:168
|
||||
msgid "Cancel"
|
||||
msgstr "Prekliči"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:111
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:162
|
||||
msgid "Today"
|
||||
msgstr "Danes"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:114
|
||||
msgid "Calendar"
|
||||
msgstr "Koledar"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:160
|
||||
msgid "Yesterday"
|
||||
msgstr "Včeraj"
|
||||
|
||||
#: contrib/admin/media/js/admin/DateTimeShortcuts.js:164
|
||||
msgid "Tomorrow"
|
||||
msgstr "Jutri"
|
||||
|
Binary file not shown.
@ -1344,7 +1344,7 @@ msgstr "四月"
|
||||
|
||||
#: utils/dates.py:19
|
||||
msgid "may"
|
||||
msgstr "三月"
|
||||
msgstr "五月"
|
||||
|
||||
#: utils/dates.py:19
|
||||
msgid "jun"
|
||||
|
Binary file not shown.
@ -46,7 +46,7 @@ msgstr "清除全部"
|
||||
#: contrib/admin/media/js/dateparse.js:32
|
||||
#: contrib/admin/media/js/calendar.js:24
|
||||
msgid "January February March April May June July August September October November December"
|
||||
msgstr "一月 二月 三月 四月 五月 六月 六月 七月 八月 九月 十月 十一月 十二月"
|
||||
msgstr "一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 十二月"
|
||||
|
||||
#: contrib/admin/media/js/dateparse.js:33
|
||||
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"
|
||||
|
@ -11,9 +11,10 @@ def patterns(prefix, *args):
|
||||
pattern_list = []
|
||||
for t in args:
|
||||
if isinstance(t, (list, tuple)):
|
||||
pattern_list.append(url(prefix=prefix, *t))
|
||||
else:
|
||||
pattern_list.append(t)
|
||||
t = url(prefix=prefix, *t)
|
||||
elif isinstance(t, RegexURLPattern):
|
||||
t.add_prefix(prefix)
|
||||
pattern_list.append(t)
|
||||
return pattern_list
|
||||
|
||||
def url(regex, view, kwargs=None, name=None, prefix=''):
|
||||
@ -21,5 +22,7 @@ def url(regex, view, kwargs=None, name=None, prefix=''):
|
||||
# For include(...) processing.
|
||||
return RegexURLResolver(regex, view[0], kwargs)
|
||||
else:
|
||||
return RegexURLPattern(regex, prefix and (prefix + '.' + view) or view, kwargs, name)
|
||||
if prefix and isinstance(view, basestring):
|
||||
view = prefix + '.' + view
|
||||
return RegexURLPattern(regex, view, kwargs, name)
|
||||
|
||||
|
@ -26,7 +26,7 @@ form .aligned p, form .aligned ul { margin-left:7em; padding-left:30px; }
|
||||
form .aligned table p { margin-left:0; padding-left:0; }
|
||||
form .aligned p.help { padding-left:38px; }
|
||||
.aligned .vCheckboxLabel { float:none !important; display:inline; padding-left:4px; }
|
||||
.colM .aligned .vLargeTextField, colM .aligned .vXMLLargeTextField { width:610px; }
|
||||
.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { width:610px; }
|
||||
.checkbox-row p.help { margin-left:0; padding-left:0 !important; }
|
||||
|
||||
/* WIDE FIELDSETS */
|
||||
|
@ -42,7 +42,7 @@ class FieldWidgetNode(template.Node):
|
||||
self.bound_field_var = bound_field_var
|
||||
|
||||
def get_nodelist(cls, klass):
|
||||
if not cls.nodelists.has_key(klass):
|
||||
if klass not in cls.nodelists:
|
||||
try:
|
||||
field_class_name = klass.__name__
|
||||
template_name = "widget/%s.html" % class_name_to_underscored(field_class_name)
|
||||
|
@ -11,9 +11,12 @@ class AdminLogNode(template.Node):
|
||||
return "<GetAdminLog Node>"
|
||||
|
||||
def render(self, context):
|
||||
if self.user is not None and not self.user.isdigit():
|
||||
self.user = context[self.user].id
|
||||
context[self.varname] = LogEntry.objects.filter(user__id__exact=self.user).select_related()[:self.limit]
|
||||
if self.user is None:
|
||||
context[self.varname] = LogEntry.objects.all().select_related()[:self.limit]
|
||||
else:
|
||||
if not self.user.isdigit():
|
||||
self.user = context[self.user].id
|
||||
context[self.varname] = LogEntry.objects.filter(user__id__exact=self.user).select_related()[:self.limit]
|
||||
return ''
|
||||
|
||||
class DoGetAdminLog:
|
||||
|
@ -17,7 +17,7 @@ def user_add_stage(request):
|
||||
if not errors:
|
||||
new_user = manipulator.save(new_data)
|
||||
msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user}
|
||||
if request.POST.has_key("_addanother"):
|
||||
if "_addanother" in request.POST:
|
||||
request.user.message_set.create(message=msg)
|
||||
return HttpResponseRedirect(request.path)
|
||||
else:
|
||||
@ -29,7 +29,7 @@ def user_add_stage(request):
|
||||
return render_to_response('admin/auth/user/add_form.html', {
|
||||
'title': _('Add user'),
|
||||
'form': form,
|
||||
'is_popup': request.REQUEST.has_key('_popup'),
|
||||
'is_popup': '_popup' in request.REQUEST,
|
||||
'add': True,
|
||||
'change': False,
|
||||
'has_delete_permission': False,
|
||||
@ -61,7 +61,7 @@ def user_change_password(request, id):
|
||||
return render_to_response('admin/auth/user/change_password.html', {
|
||||
'title': _('Change password: %s') % escape(user.username),
|
||||
'form': form,
|
||||
'is_popup': request.REQUEST.has_key('_popup'),
|
||||
'is_popup': '_popup' in request.REQUEST,
|
||||
'add': True,
|
||||
'change': False,
|
||||
'has_delete_permission': False,
|
||||
|
@ -12,7 +12,7 @@ LOGIN_FORM_KEY = 'this_is_the_login_form'
|
||||
|
||||
def _display_login_form(request, error_message=''):
|
||||
request.session.set_test_cookie()
|
||||
if request.POST and request.POST.has_key('post_data'):
|
||||
if request.POST and 'post_data' in request.POST:
|
||||
# User has failed login BUT has previously saved post data.
|
||||
post_data = request.POST['post_data']
|
||||
elif request.POST:
|
||||
@ -48,7 +48,7 @@ def staff_member_required(view_func):
|
||||
def _checklogin(request, *args, **kwargs):
|
||||
if request.user.is_authenticated() and request.user.is_staff:
|
||||
# The user is valid. Continue to the admin page.
|
||||
if request.POST.has_key('post_data'):
|
||||
if 'post_data' in request.POST:
|
||||
# User must have re-authenticated through a different window
|
||||
# or tab.
|
||||
request.POST = _decode_post_data(request.POST['post_data'])
|
||||
@ -57,7 +57,7 @@ def staff_member_required(view_func):
|
||||
assert hasattr(request, 'session'), "The Django admin requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."
|
||||
|
||||
# If this isn't already the login page, display it.
|
||||
if not request.POST.has_key(LOGIN_FORM_KEY):
|
||||
if LOGIN_FORM_KEY not in request.POST:
|
||||
if request.POST:
|
||||
message = _("Please log in again, because your session has expired. Don't worry: Your submission has been saved.")
|
||||
else:
|
||||
@ -90,11 +90,9 @@ def staff_member_required(view_func):
|
||||
if user.is_active and user.is_staff:
|
||||
login(request, user)
|
||||
# TODO: set last_login with an event.
|
||||
user.last_login = datetime.datetime.now()
|
||||
user.save()
|
||||
if request.POST.has_key('post_data'):
|
||||
if 'post_data' in request.POST:
|
||||
post_data = _decode_post_data(request.POST['post_data'])
|
||||
if post_data and not post_data.has_key(LOGIN_FORM_KEY):
|
||||
if post_data and LOGIN_FORM_KEY not in post_data:
|
||||
# overwrite request.POST with the saved post_data, and continue
|
||||
request.POST = post_data
|
||||
request.user = user
|
||||
|
@ -200,7 +200,7 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
|
||||
opts_seen.append(related.opts)
|
||||
rel_opts_name = related.get_accessor_name()
|
||||
has_related_objs = False
|
||||
|
||||
|
||||
# related.get_accessor_name() could return None for symmetrical relationships
|
||||
if rel_opts_name:
|
||||
rel_objs = getattr(obj, rel_opts_name, None)
|
||||
@ -247,12 +247,12 @@ class ChangeList(object):
|
||||
self.page_num = int(request.GET.get(PAGE_VAR, 0))
|
||||
except ValueError:
|
||||
self.page_num = 0
|
||||
self.show_all = request.GET.has_key(ALL_VAR)
|
||||
self.is_popup = request.GET.has_key(IS_POPUP_VAR)
|
||||
self.show_all = ALL_VAR in request.GET
|
||||
self.is_popup = IS_POPUP_VAR in request.GET
|
||||
self.params = dict(request.GET.items())
|
||||
if self.params.has_key(PAGE_VAR):
|
||||
if PAGE_VAR in self.params:
|
||||
del self.params[PAGE_VAR]
|
||||
if self.params.has_key(ERROR_FLAG):
|
||||
if ERROR_FLAG in self.params:
|
||||
del self.params[ERROR_FLAG]
|
||||
|
||||
self.order_field, self.order_type = self.get_ordering()
|
||||
@ -282,7 +282,7 @@ class ChangeList(object):
|
||||
if k.startswith(r):
|
||||
del p[k]
|
||||
for k, v in new_params.items():
|
||||
if p.has_key(k) and v is None:
|
||||
if k in p and v is None:
|
||||
del p[k]
|
||||
elif v is not None:
|
||||
p[k] = v
|
||||
@ -344,7 +344,7 @@ class ChangeList(object):
|
||||
order_field, order_type = ordering[0][1:], 'desc'
|
||||
else:
|
||||
order_field, order_type = ordering[0], 'asc'
|
||||
if params.has_key(ORDER_VAR):
|
||||
if ORDER_VAR in params:
|
||||
try:
|
||||
field_name = self.list_display[int(params[ORDER_VAR])]
|
||||
try:
|
||||
@ -362,7 +362,7 @@ class ChangeList(object):
|
||||
order_field = f.name
|
||||
except (IndexError, ValueError):
|
||||
pass # Invalid ordering specified. Just use the default.
|
||||
if params.has_key(ORDER_TYPE_VAR) and params[ORDER_TYPE_VAR] in ('asc', 'desc'):
|
||||
if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'):
|
||||
order_type = params[ORDER_TYPE_VAR]
|
||||
return order_field, order_type
|
||||
|
||||
@ -370,7 +370,7 @@ class ChangeList(object):
|
||||
qs = self.root_query_set
|
||||
lookup_params = self.params.copy() # a dictionary of the query string
|
||||
for i in (ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR):
|
||||
if lookup_params.has_key(i):
|
||||
if i in lookup_params:
|
||||
del lookup_params[i]
|
||||
|
||||
# Apply lookup parameters from the query string.
|
||||
|
@ -1,8 +1,8 @@
|
||||
import datetime
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
SESSION_KEY = '_auth_user_id'
|
||||
BACKEND_SESSION_KEY = '_auth_user_backend'
|
||||
LOGIN_URL = '/accounts/login/'
|
||||
REDIRECT_FIELD_NAME = 'next'
|
||||
|
||||
def load_backend(path):
|
||||
@ -49,6 +49,8 @@ def login(request, user):
|
||||
if user is None:
|
||||
user = request.user
|
||||
# TODO: It would be nice to support different login methods, like signed cookies.
|
||||
user.last_login = datetime.datetime.now()
|
||||
user.save()
|
||||
request.session[SESSION_KEY] = user.id
|
||||
request.session[BACKEND_SESSION_KEY] = user.backend
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||
from django.http import HttpResponseRedirect
|
||||
from urllib import quote
|
||||
|
||||
def user_passes_test(test_func, login_url=LOGIN_URL):
|
||||
def user_passes_test(test_func, login_url=None):
|
||||
"""
|
||||
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
|
||||
that takes the user object and returns True if the user passes.
|
||||
"""
|
||||
if not login_url:
|
||||
from django.conf import settings
|
||||
login_url = settings.LOGIN_URL
|
||||
def _dec(view_func):
|
||||
def _checklogin(request, *args, **kwargs):
|
||||
if test_func(request.user):
|
||||
@ -27,7 +30,7 @@ login_required.__doc__ = (
|
||||
"""
|
||||
)
|
||||
|
||||
def permission_required(perm, login_url=LOGIN_URL):
|
||||
def permission_required(perm, login_url=None):
|
||||
"""
|
||||
Decorator for views that checks whether a user has a particular permission
|
||||
enabled, redirecting to the log-in page if necessary.
|
||||
|
@ -17,6 +17,12 @@ def check_password(raw_password, enc_password):
|
||||
elif algo == 'sha1':
|
||||
import sha
|
||||
return hsh == sha.new(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(raw_password, salt)
|
||||
raise ValueError, "Got unknown password algorithm type in password."
|
||||
|
||||
class SiteProfileNotAvailable(Exception):
|
||||
@ -95,8 +101,8 @@ class User(models.Model):
|
||||
is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site."))
|
||||
is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user can log into the Django admin. Unselect this instead of deleting accounts."))
|
||||
is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them."))
|
||||
last_login = models.DateTimeField(_('last login'), default=models.LazyDate())
|
||||
date_joined = models.DateTimeField(_('date joined'), default=models.LazyDate())
|
||||
last_login = models.DateTimeField(_('last login'), default=datetime.datetime.now)
|
||||
date_joined = models.DateTimeField(_('date joined'), default=datetime.datetime.now)
|
||||
groups = models.ManyToManyField(Group, verbose_name=_('groups'), blank=True,
|
||||
help_text=_("In addition to the permissions manually assigned, this user will also get all permissions granted to each group he/she is in."))
|
||||
user_permissions = models.ManyToManyField(Permission, verbose_name=_('user permissions'), blank=True)
|
||||
@ -258,7 +264,7 @@ class AnonymousUser(object):
|
||||
pass
|
||||
|
||||
def __str__(self):
|
||||
return 'AnonymousUser'
|
||||
return _('AnonymousUser')
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, self.__class__)
|
||||
|
@ -6,7 +6,7 @@ from django.template import RequestContext
|
||||
from django.contrib.sites.models import Site
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth import LOGIN_URL, REDIRECT_FIELD_NAME
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||
|
||||
def login(request, template_name='registration/login.html'):
|
||||
"Displays the login form and handles the login action."
|
||||
@ -17,7 +17,8 @@ def login(request, template_name='registration/login.html'):
|
||||
if not errors:
|
||||
# Light security check -- make sure redirect_to isn't garbage.
|
||||
if not redirect_to or '://' in redirect_to or ' ' in redirect_to:
|
||||
redirect_to = '/accounts/profile/'
|
||||
from django.conf import settings
|
||||
redirect_to = settings.LOGIN_REDIRECT_URL
|
||||
from django.contrib.auth import login
|
||||
login(request, manipulator.get_user())
|
||||
request.session.delete_test_cookie()
|
||||
@ -41,12 +42,18 @@ def logout(request, next_page=None, template_name='registration/logged_out.html'
|
||||
# Redirect to this page until the session has been cleared.
|
||||
return HttpResponseRedirect(next_page or request.path)
|
||||
|
||||
def logout_then_login(request, login_url=LOGIN_URL):
|
||||
def logout_then_login(request, login_url=None):
|
||||
"Logs out the user if he is logged in. Then redirects to the log-in page."
|
||||
if not login_url:
|
||||
from django.conf import settings
|
||||
login_url = settings.LOGIN_URL
|
||||
return logout(request, login_url)
|
||||
|
||||
def redirect_to_login(next, login_url=LOGIN_URL):
|
||||
def redirect_to_login(next, login_url=None):
|
||||
"Redirects the user to the login page, passing the given 'next' page"
|
||||
if not login_url:
|
||||
from django.conf import settings
|
||||
login_url = settings.LOGIN_URL
|
||||
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',
|
||||
|
@ -3,7 +3,7 @@
|
||||
<form {% if photos_optional or photos_required %}enctype="multipart/form-data" {% endif %}action="/comments/post/" method="post">
|
||||
|
||||
{% if user.is_authenticated %}
|
||||
<p>{% trans "Username:" %} <strong>{{ user.username }}</strong> (<a href="/accounts/logout/">{% trans "Log out" %}</a>)</p>
|
||||
<p>{% trans "Username:" %} <strong>{{ user.username }}</strong> (<a href="{{ logout_url }}">{% trans "Log out" %}</a>)</p>
|
||||
{% else %}
|
||||
<p><label for="id_username">{% trans "Username:" %}</label> <input type="text" name="username" id="id_username" /><br />{% trans "Password:" %} <input type="password" name="password" id="id_password" /> (<a href="/accounts/password_reset/">{% trans "Forgotten your password?" %}</a>)</p>
|
||||
{% endif %}
|
||||
|
@ -25,6 +25,7 @@ class CommentFormNode(template.Node):
|
||||
self.is_public = is_public
|
||||
|
||||
def render(self, context):
|
||||
from django.conf import settings
|
||||
from django.utils.text import normalize_newlines
|
||||
import base64
|
||||
context.push()
|
||||
@ -64,6 +65,7 @@ class CommentFormNode(template.Node):
|
||||
if self.rating_options:
|
||||
context['rating_range'], context['rating_choices'] = Comment.objects.get_rating_options(self.rating_options)
|
||||
context['hash'] = Comment.objects.get_security_hash(context['options'], context['photo_options'], context['rating_options'], context['target'])
|
||||
context['logout_url'] = settings.LOGOUT_URL
|
||||
default_form = loader.get_template(COMMENT_FORM)
|
||||
output = default_form.render(context)
|
||||
context.pop()
|
||||
@ -114,7 +116,7 @@ class CommentListNode(template.Node):
|
||||
comment_list = get_list_function(**kwargs).order_by(self.ordering + 'submit_date').select_related()
|
||||
|
||||
if not self.free:
|
||||
if context.has_key('user') and context['user'].is_authenticated():
|
||||
if 'user' in context and context['user'].is_authenticated():
|
||||
user_id = context['user'].id
|
||||
context['user_can_moderate_comments'] = Comment.objects.user_is_moderator(context['user'])
|
||||
else:
|
||||
|
@ -217,10 +217,10 @@ def post_comment(request):
|
||||
errors = manipulator.get_validation_errors(new_data)
|
||||
# If user gave correct username/password and wasn't already logged in, log them in
|
||||
# so they don't have to enter a username/password again.
|
||||
if manipulator.get_user() and not manipulator.get_user().is_authenticated() and new_data.has_key('password') and manipulator.get_user().check_password(new_data['password']):
|
||||
if manipulator.get_user() and not manipulator.get_user().is_authenticated() and 'password' in new_data and manipulator.get_user().check_password(new_data['password']):
|
||||
from django.contrib.auth import login
|
||||
login(request, manipulator.get_user())
|
||||
if errors or request.POST.has_key('preview'):
|
||||
if errors or 'preview' in request.POST:
|
||||
class CommentFormWrapper(oldforms.FormWrapper):
|
||||
def __init__(self, manipulator, new_data, errors, rating_choices):
|
||||
oldforms.FormWrapper.__init__(self, manipulator, new_data, errors)
|
||||
@ -244,7 +244,7 @@ def post_comment(request):
|
||||
'rating_range': rating_range,
|
||||
'rating_choices': rating_choices,
|
||||
}, context_instance=RequestContext(request))
|
||||
elif request.POST.has_key('post'):
|
||||
elif 'post' in request.POST:
|
||||
# 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.
|
||||
if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
|
||||
@ -298,7 +298,7 @@ def post_free_comment(request):
|
||||
new_data['is_public'] = IS_PUBLIC in option_list
|
||||
manipulator = PublicFreeCommentManipulator()
|
||||
errors = manipulator.get_validation_errors(new_data)
|
||||
if errors or request.POST.has_key('preview'):
|
||||
if errors or 'preview' in request.POST:
|
||||
comment = errors and '' or manipulator.get_comment(new_data)
|
||||
return render_to_response('comments/free_preview.html', {
|
||||
'comment': comment,
|
||||
@ -307,7 +307,7 @@ def post_free_comment(request):
|
||||
'target': target,
|
||||
'hash': security_hash,
|
||||
}, context_instance=RequestContext(request))
|
||||
elif request.POST.has_key('post'):
|
||||
elif 'post' in request.POST:
|
||||
# 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.
|
||||
if request.META['REMOTE_ADDR'] in settings.BANNED_IPS:
|
||||
@ -330,7 +330,7 @@ def comment_was_posted(request):
|
||||
The object the comment was posted on
|
||||
"""
|
||||
obj = None
|
||||
if request.GET.has_key('c'):
|
||||
if 'c' in request.GET:
|
||||
content_type_id, object_id = request.GET['c'].split(':')
|
||||
try:
|
||||
content_type = ContentType.objects.get(pk=content_type_id)
|
||||
|
@ -16,18 +16,18 @@ class GenericForeignKey(object):
|
||||
Provides a generic relation to any object through content-type/object-id
|
||||
fields.
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, ct_field="content_type", fk_field="object_id"):
|
||||
self.ct_field = ct_field
|
||||
self.fk_field = fk_field
|
||||
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
# Make sure the fields exist (these raise FieldDoesNotExist,
|
||||
# Make sure the fields exist (these raise FieldDoesNotExist,
|
||||
# which is a fine error to raise here)
|
||||
self.name = name
|
||||
self.model = cls
|
||||
self.cache_attr = "_%s_cache" % name
|
||||
|
||||
|
||||
# For some reason I don't totally understand, using weakrefs here doesn't work.
|
||||
dispatcher.connect(self.instance_pre_init, signal=signals.pre_init, sender=cls, weak=False)
|
||||
|
||||
@ -35,18 +35,18 @@ class GenericForeignKey(object):
|
||||
setattr(cls, name, self)
|
||||
|
||||
def instance_pre_init(self, signal, sender, args, kwargs):
|
||||
# Handle initalizing an object with the generic FK instaed of
|
||||
# content-type/object-id fields.
|
||||
if kwargs.has_key(self.name):
|
||||
# Handle initalizing an object with the generic FK instaed of
|
||||
# content-type/object-id fields.
|
||||
if self.name in kwargs:
|
||||
value = kwargs.pop(self.name)
|
||||
kwargs[self.ct_field] = self.get_content_type(value)
|
||||
kwargs[self.fk_field] = value._get_pk_val()
|
||||
|
||||
|
||||
def get_content_type(self, obj):
|
||||
# Convenience function using get_model avoids a circular import when using this model
|
||||
ContentType = get_model("contenttypes", "contenttype")
|
||||
return ContentType.objects.get_for_model(obj)
|
||||
|
||||
|
||||
def __get__(self, instance, instance_type=None):
|
||||
if instance is None:
|
||||
raise AttributeError, "%s must be accessed via instance" % self.name
|
||||
@ -77,21 +77,21 @@ class GenericForeignKey(object):
|
||||
setattr(instance, self.ct_field, ct)
|
||||
setattr(instance, self.fk_field, fk)
|
||||
setattr(instance, self.cache_attr, value)
|
||||
|
||||
|
||||
class GenericRelation(RelatedField, Field):
|
||||
"""Provides an accessor to generic related objects (i.e. comments)"""
|
||||
|
||||
def __init__(self, to, **kwargs):
|
||||
kwargs['verbose_name'] = kwargs.get('verbose_name', None)
|
||||
kwargs['rel'] = GenericRel(to,
|
||||
kwargs['rel'] = GenericRel(to,
|
||||
related_name=kwargs.pop('related_name', None),
|
||||
limit_choices_to=kwargs.pop('limit_choices_to', None),
|
||||
symmetrical=kwargs.pop('symmetrical', True))
|
||||
|
||||
|
||||
# Override content-type/object-id field names on the related class
|
||||
self.object_id_field_name = kwargs.pop("object_id_field", "object_id")
|
||||
self.content_type_field_name = kwargs.pop("content_type_field", "content_type")
|
||||
|
||||
self.content_type_field_name = kwargs.pop("content_type_field", "content_type")
|
||||
|
||||
kwargs['blank'] = True
|
||||
kwargs['editable'] = False
|
||||
kwargs['serialize'] = False
|
||||
@ -116,7 +116,7 @@ class GenericRelation(RelatedField, Field):
|
||||
|
||||
def m2m_column_name(self):
|
||||
return self.object_id_field_name
|
||||
|
||||
|
||||
def m2m_reverse_name(self):
|
||||
return self.object_id_field_name
|
||||
|
||||
@ -131,13 +131,13 @@ class GenericRelation(RelatedField, Field):
|
||||
|
||||
def contribute_to_related_class(self, cls, related):
|
||||
pass
|
||||
|
||||
|
||||
def set_attributes_from_rel(self):
|
||||
pass
|
||||
|
||||
def get_internal_type(self):
|
||||
return "ManyToManyField"
|
||||
|
||||
|
||||
class ReverseGenericRelatedObjectsDescriptor(object):
|
||||
"""
|
||||
This class provides the functionality that makes the related-object
|
||||
@ -191,12 +191,12 @@ def create_generic_related_manager(superclass):
|
||||
Factory function for a manager that subclasses 'superclass' (which is a
|
||||
Manager) and adds behavior for generic related objects.
|
||||
"""
|
||||
|
||||
|
||||
class GenericRelatedObjectManager(superclass):
|
||||
def __init__(self, model=None, core_filters=None, instance=None, symmetrical=None,
|
||||
join_table=None, source_col_name=None, target_col_name=None, content_type=None,
|
||||
content_type_field_name=None, object_id_field_name=None):
|
||||
|
||||
|
||||
super(GenericRelatedObjectManager, self).__init__()
|
||||
self.core_filters = core_filters or {}
|
||||
self.model = model
|
||||
@ -210,10 +210,10 @@ def create_generic_related_manager(superclass):
|
||||
self.content_type_field_name = content_type_field_name
|
||||
self.object_id_field_name = object_id_field_name
|
||||
self.pk_val = self.instance._get_pk_val()
|
||||
|
||||
|
||||
def get_query_set(self):
|
||||
query = {
|
||||
'%s__pk' % self.content_type_field_name : self.content_type.id,
|
||||
'%s__pk' % self.content_type_field_name : self.content_type.id,
|
||||
'%s__exact' % self.object_id_field_name : self.pk_val,
|
||||
}
|
||||
return superclass.get_query_set(self).filter(**query)
|
||||
@ -250,7 +250,11 @@ class GenericRel(ManyToManyRel):
|
||||
self.to = to
|
||||
self.num_in_admin = 0
|
||||
self.related_name = related_name
|
||||
self.filter_interface = None
|
||||
self.limit_choices_to = limit_choices_to or {}
|
||||
self.edit_inline = False
|
||||
self.raw_id_admin = False
|
||||
self.symmetrical = symmetrical
|
||||
self.multiple = True
|
||||
assert not (self.raw_id_admin and self.filter_interface), \
|
||||
"Generic relations may not use both raw_id_admin and filter_interface"
|
1
django/contrib/databrowse/__init__.py
Normal file
1
django/contrib/databrowse/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from django.contrib.databrowse.sites import DatabrowsePlugin, ModelDatabrowse, DatabrowseSite, site
|
192
django/contrib/databrowse/datastructures.py
Normal file
192
django/contrib/databrowse/datastructures.py
Normal file
@ -0,0 +1,192 @@
|
||||
"""
|
||||
These classes are light wrappers around Django's database API that provide
|
||||
convenience functionality and permalink functions for the databrowse app.
|
||||
"""
|
||||
|
||||
from django.db import models
|
||||
from django.utils import dateformat
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import get_date_formats
|
||||
|
||||
EMPTY_VALUE = '(None)'
|
||||
|
||||
class EasyModel(object):
|
||||
def __init__(self, site, model):
|
||||
self.site = site
|
||||
self.model = model
|
||||
self.model_list = site.registry.keys()
|
||||
self.verbose_name = model._meta.verbose_name
|
||||
self.verbose_name_plural = model._meta.verbose_name_plural
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyModel for %s>' % self.model._meta.object_name
|
||||
|
||||
def model_databrowse(self):
|
||||
"Returns the ModelDatabrowse class for this model."
|
||||
return self.site.registry[self.model]
|
||||
|
||||
def url(self):
|
||||
return '%s%s/%s/' % (self.site.root_url, self.model._meta.app_label, self.model._meta.module_name)
|
||||
|
||||
def objects(self, **kwargs):
|
||||
for obj in self.model._default_manager.filter(**kwargs):
|
||||
yield EasyInstance(self, obj)
|
||||
|
||||
def object_by_pk(self, pk):
|
||||
return EasyInstance(self, self.model._default_manager.get(pk=pk))
|
||||
|
||||
def sample_objects(self):
|
||||
for obj in self.model._default_manager.all()[:3]:
|
||||
yield EasyInstance(self, obj)
|
||||
|
||||
def field(self, name):
|
||||
try:
|
||||
f = self.model._meta.get_field(name)
|
||||
except models.FieldDoesNotExist:
|
||||
return None
|
||||
return EasyField(self, f)
|
||||
|
||||
def fields(self):
|
||||
return [EasyField(self, f) for f in (self.model._meta.fields + self.model._meta.many_to_many)]
|
||||
|
||||
class EasyField(object):
|
||||
def __init__(self, easy_model, field):
|
||||
self.model, self.field = easy_model, field
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)
|
||||
|
||||
def choices(self):
|
||||
for value, label in self.field.choices:
|
||||
yield EasyChoice(self.model, self, value, label)
|
||||
|
||||
def url(self):
|
||||
if self.field.choices:
|
||||
return '%s%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name)
|
||||
elif self.field.rel:
|
||||
return '%s%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name)
|
||||
|
||||
class EasyChoice(object):
|
||||
def __init__(self, easy_model, field, value, label):
|
||||
self.model, self.field = easy_model, field
|
||||
self.value, self.label = value, label
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyChoice for %s.%s>' % (self.model.model._meta.object_name, self.field.name)
|
||||
|
||||
def url(self):
|
||||
return '%s%s/%s/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.field.name, self.value)
|
||||
|
||||
class EasyInstance(object):
|
||||
def __init__(self, easy_model, instance):
|
||||
self.model, self.instance = easy_model, instance
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyInstance for %s (%s)>' % (self.model.model._meta.object_name, self.instance._get_pk_val())
|
||||
|
||||
def __str__(self):
|
||||
val = str(self.instance)
|
||||
if len(val) > 30:
|
||||
return val[:30] + '...'
|
||||
return val
|
||||
|
||||
def pk(self):
|
||||
return self.instance._get_pk_val()
|
||||
|
||||
def url(self):
|
||||
return '%s%s/%s/objects/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.pk())
|
||||
|
||||
def fields(self):
|
||||
"""
|
||||
Generator that yields EasyInstanceFields for each field in this
|
||||
EasyInstance's model.
|
||||
"""
|
||||
for f in self.model.model._meta.fields + self.model.model._meta.many_to_many:
|
||||
yield EasyInstanceField(self.model, self, f)
|
||||
|
||||
def related_objects(self):
|
||||
"""
|
||||
Generator that yields dictionaries of all models that have this
|
||||
EasyInstance's model as a ForeignKey or ManyToManyField, along with
|
||||
lists of related objects.
|
||||
"""
|
||||
for rel_object in self.model.model._meta.get_all_related_objects() + self.model.model._meta.get_all_related_many_to_many_objects():
|
||||
if rel_object.model not in self.model.model_list:
|
||||
continue # Skip models that aren't in the model_list
|
||||
em = EasyModel(self.model.site, rel_object.model)
|
||||
yield {
|
||||
'model': em,
|
||||
'related_field': rel_object.field.verbose_name,
|
||||
'object_list': [EasyInstance(em, i) for i in getattr(self.instance, rel_object.get_accessor_name()).all()],
|
||||
}
|
||||
|
||||
class EasyInstanceField(object):
|
||||
def __init__(self, easy_model, instance, field):
|
||||
self.model, self.field, self.instance = easy_model, field, instance
|
||||
self.raw_value = getattr(instance.instance, field.name)
|
||||
|
||||
def __repr__(self):
|
||||
return '<EasyInstanceField for %s.%s>' % (self.model.model._meta.object_name, self.field.name)
|
||||
|
||||
def values(self):
|
||||
"""
|
||||
Returns a list of values for this field for this instance. It's a list
|
||||
so we can accomodate many-to-many fields.
|
||||
"""
|
||||
# This import is deliberately inside the function because it causes
|
||||
# some settings to be imported, and we don't want to do that at the
|
||||
# module level.
|
||||
if self.field.rel:
|
||||
if isinstance(self.field.rel, models.ManyToOneRel):
|
||||
objs = getattr(self.instance.instance, self.field.name)
|
||||
elif isinstance(self.field.rel, models.ManyToManyRel): # ManyToManyRel
|
||||
return list(getattr(self.instance.instance, self.field.name).all())
|
||||
elif self.field.choices:
|
||||
objs = dict(self.field.choices).get(self.raw_value, EMPTY_VALUE)
|
||||
elif isinstance(self.field, models.DateField) or isinstance(self.field, models.TimeField):
|
||||
if self.raw_value:
|
||||
date_format, datetime_format, time_format = get_date_formats()
|
||||
if isinstance(self.field, models.DateTimeField):
|
||||
objs = capfirst(dateformat.format(self.raw_value, datetime_format))
|
||||
elif isinstance(self.field, models.TimeField):
|
||||
objs = capfirst(dateformat.time_format(self.raw_value, time_format))
|
||||
else:
|
||||
objs = capfirst(dateformat.format(self.raw_value, date_format))
|
||||
else:
|
||||
objs = EMPTY_VALUE
|
||||
elif isinstance(self.field, models.BooleanField) or isinstance(self.field, models.NullBooleanField):
|
||||
objs = {True: 'Yes', False: 'No', None: 'Unknown'}[self.raw_value]
|
||||
else:
|
||||
objs = self.raw_value
|
||||
return [objs]
|
||||
|
||||
def urls(self):
|
||||
"Returns a list of (value, URL) tuples."
|
||||
# First, check the urls() method for each plugin.
|
||||
plugin_urls = []
|
||||
for plugin_name, plugin in self.model.model_databrowse().plugins.items():
|
||||
urls = plugin.urls(plugin_name, self)
|
||||
if urls is not None:
|
||||
#plugin_urls.append(urls)
|
||||
values = self.values()
|
||||
return zip(self.values(), urls)
|
||||
if self.field.rel:
|
||||
m = EasyModel(self.model.site, self.field.rel.to)
|
||||
if self.field.rel.to in self.model.model_list:
|
||||
lst = []
|
||||
for value in self.values():
|
||||
url = '%s%s/%s/objects/%s/' % (self.model.site.root_url, m.model._meta.app_label, m.model._meta.module_name, value._get_pk_val())
|
||||
lst.append((str(value), url))
|
||||
else:
|
||||
lst = [(value, None) for value in self.values()]
|
||||
elif self.field.choices:
|
||||
lst = []
|
||||
for value in self.values():
|
||||
url = '%s%s/%s/fields/%s/%s/' % (self.model.site.root_url, self.model.model._meta.app_label, self.model.model._meta.module_name, self.field.name, self.raw_value)
|
||||
lst.append((value, url))
|
||||
elif isinstance(self.field, models.URLField):
|
||||
val = self.values()[0]
|
||||
lst = [(val, val)]
|
||||
else:
|
||||
lst = [(self.values()[0], None)]
|
||||
return lst
|
0
django/contrib/databrowse/plugins/__init__.py
Normal file
0
django/contrib/databrowse/plugins/__init__.py
Normal file
84
django/contrib/databrowse/plugins/calendars.py
Normal file
84
django/contrib/databrowse/plugins/calendars.py
Normal file
@ -0,0 +1,84 @@
|
||||
from django import http
|
||||
from django.db import models
|
||||
from django.contrib.databrowse.datastructures import EasyModel
|
||||
from django.contrib.databrowse.sites import DatabrowsePlugin
|
||||
from django.shortcuts import render_to_response
|
||||
from django.utils.text import capfirst
|
||||
from django.utils.translation import get_date_formats
|
||||
from django.views.generic import date_based
|
||||
import datetime
|
||||
import time
|
||||
|
||||
class CalendarPlugin(DatabrowsePlugin):
|
||||
def __init__(self, field_names=None):
|
||||
self.field_names = field_names
|
||||
|
||||
def field_dict(self, model):
|
||||
"""
|
||||
Helper function that returns a dictionary of all DateFields or
|
||||
DateTimeFields in the given model. If self.field_names is set, it takes
|
||||
take that into account when building the dictionary.
|
||||
"""
|
||||
if self.field_names is None:
|
||||
return dict([(f.name, f) for f in model._meta.fields if isinstance(f, models.DateField)])
|
||||
else:
|
||||
return dict([(f.name, f) for f in model._meta.fields if isinstance(f, models.DateField) and f.name in self.field_names])
|
||||
|
||||
def model_index_html(self, request, model, site):
|
||||
fields = self.field_dict(model)
|
||||
if not fields:
|
||||
return ''
|
||||
return '<p class="filter"><strong>View calendar by:</strong> %s</p>' % \
|
||||
', '.join(['<a href="calendars/%s/">%s</a>' % (f.name, capfirst(f.verbose_name)) for f in fields.values()])
|
||||
|
||||
def urls(self, plugin_name, easy_instance_field):
|
||||
if isinstance(easy_instance_field.field, models.DateField):
|
||||
return ['%s%s/%s/%s/%s/%s/' % (easy_instance_field.model.url(),
|
||||
plugin_name, easy_instance_field.field.name,
|
||||
easy_instance_field.raw_value.year,
|
||||
easy_instance_field.raw_value.strftime('%b').lower(),
|
||||
easy_instance_field.raw_value.day)]
|
||||
|
||||
def model_view(self, request, model_databrowse, url):
|
||||
self.model, self.site = model_databrowse.model, model_databrowse.site
|
||||
self.fields = self.field_dict(self.model)
|
||||
|
||||
# If the model has no DateFields, there's no point in going further.
|
||||
if not self.fields:
|
||||
raise http.Http404('The requested model has no calendars.')
|
||||
|
||||
if url is None:
|
||||
return self.homepage_view(request)
|
||||
url_bits = url.split('/')
|
||||
if self.fields.has_key(url_bits[0]):
|
||||
return self.calendar_view(request, self.fields[url_bits[0]], *url_bits[1:])
|
||||
|
||||
raise http.Http404('The requested page does not exist.')
|
||||
|
||||
def homepage_view(self, request):
|
||||
easy_model = EasyModel(self.site, self.model)
|
||||
field_list = self.fields.values()
|
||||
field_list.sort(lambda x, y: cmp(x.verbose_name, y.verbose_name))
|
||||
return render_to_response('databrowse/calendar_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list})
|
||||
|
||||
def calendar_view(self, request, field, year=None, month=None, day=None):
|
||||
easy_model = EasyModel(self.site, self.model)
|
||||
extra_context = {'root_url': self.site.root_url, 'model': easy_model, 'field': field}
|
||||
if day is not None:
|
||||
# TODO: The objects in this template should be EasyInstances
|
||||
return date_based.archive_day(request, year, month, day, self.model.objects.all(), field.name,
|
||||
template_name='databrowse/calendar_day.html', allow_empty=False, allow_future=True,
|
||||
extra_context=extra_context)
|
||||
elif month is not None:
|
||||
return date_based.archive_month(request, year, month, self.model.objects.all(), field.name,
|
||||
template_name='databrowse/calendar_month.html', allow_empty=False, allow_future=True,
|
||||
extra_context=extra_context)
|
||||
elif year is not None:
|
||||
return date_based.archive_year(request, year, self.model.objects.all(), field.name,
|
||||
template_name='databrowse/calendar_year.html', allow_empty=False, allow_future=True,
|
||||
extra_context=extra_context)
|
||||
else:
|
||||
return date_based.archive_index(request, self.model.objects.all(), field.name,
|
||||
template_name='databrowse/calendar_main.html', allow_empty=True, allow_future=True,
|
||||
extra_context=extra_context)
|
||||
assert False, ('%s, %s, %s, %s' % (field, year, month, day))
|
72
django/contrib/databrowse/plugins/fieldchoices.py
Normal file
72
django/contrib/databrowse/plugins/fieldchoices.py
Normal file
@ -0,0 +1,72 @@
|
||||
from django import http
|
||||
from django.db import models
|
||||
from django.contrib.databrowse.datastructures import EasyModel
|
||||
from django.contrib.databrowse.sites import DatabrowsePlugin
|
||||
from django.shortcuts import render_to_response
|
||||
from django.utils.text import capfirst
|
||||
from django.views.generic import date_based
|
||||
import datetime
|
||||
import time
|
||||
|
||||
class FieldChoicePlugin(DatabrowsePlugin):
|
||||
def __init__(self, field_filter=None):
|
||||
# If field_filter is given, it should be a callable that takes a
|
||||
# Django database Field instance and returns True if that field should
|
||||
# be included. If field_filter is None, that all fields will be used.
|
||||
self.field_filter = field_filter
|
||||
|
||||
def field_dict(self, model):
|
||||
"""
|
||||
Helper function that returns a dictionary of all fields in the given
|
||||
model. If self.field_filter is set, it only includes the fields that
|
||||
match the filter.
|
||||
"""
|
||||
if self.field_filter:
|
||||
return dict([(f.name, f) for f in model._meta.fields if self.field_filter(f)])
|
||||
else:
|
||||
return dict([(f.name, f) for f in model._meta.fields if not f.rel and not f.primary_key and not f.unique and not isinstance(f, (models.AutoField, models.TextField))])
|
||||
|
||||
def model_index_html(self, request, model, site):
|
||||
fields = self.field_dict(model)
|
||||
if not fields:
|
||||
return ''
|
||||
return '<p class="filter"><strong>View by:</strong> %s</p>' % \
|
||||
', '.join(['<a href="fields/%s/">%s</a>' % (f.name, capfirst(f.verbose_name)) for f in fields.values()])
|
||||
|
||||
def urls(self, plugin_name, easy_instance_field):
|
||||
if easy_instance_field.field in self.field_dict(easy_instance_field.model.model).values():
|
||||
return ['%s%s/%s/%s/' % (easy_instance_field.model.url(),
|
||||
plugin_name, easy_instance_field.field.name,
|
||||
easy_instance_field.raw_value)]
|
||||
|
||||
def model_view(self, request, model_databrowse, url):
|
||||
self.model, self.site = model_databrowse.model, model_databrowse.site
|
||||
self.fields = self.field_dict(self.model)
|
||||
|
||||
# If the model has no fields with choices, there's no point in going
|
||||
# further.
|
||||
if not self.fields:
|
||||
raise http.Http404('The requested model has no fields.')
|
||||
|
||||
if url is None:
|
||||
return self.homepage_view(request)
|
||||
url_bits = url.split('/', 1)
|
||||
if self.fields.has_key(url_bits[0]):
|
||||
return self.field_view(request, self.fields[url_bits[0]], *url_bits[1:])
|
||||
|
||||
raise http.Http404('The requested page does not exist.')
|
||||
|
||||
def homepage_view(self, request):
|
||||
easy_model = EasyModel(self.site, self.model)
|
||||
field_list = self.fields.values()
|
||||
field_list.sort(lambda x, y: cmp(x.verbose_name, y.verbose_name))
|
||||
return render_to_response('databrowse/fieldchoice_homepage.html', {'root_url': self.site.root_url, 'model': easy_model, 'field_list': field_list})
|
||||
|
||||
def field_view(self, request, field, value=None):
|
||||
easy_model = EasyModel(self.site, self.model)
|
||||
easy_field = easy_model.field(field.name)
|
||||
if value is not None:
|
||||
obj_list = easy_model.objects(**{field.name: value})
|
||||
return render_to_response('databrowse/fieldchoice_detail.html', {'root_url': self.site.root_url, 'model': easy_model, 'field': easy_field, 'value': value, 'object_list': obj_list})
|
||||
obj_list = [v[field.name] for v in self.model._default_manager.distinct().order_by(field.name).values(field.name)]
|
||||
return render_to_response('databrowse/fieldchoice_list.html', {'root_url': self.site.root_url, 'model': easy_model, 'field': easy_field, 'object_list': obj_list})
|
14
django/contrib/databrowse/plugins/objects.py
Normal file
14
django/contrib/databrowse/plugins/objects.py
Normal file
@ -0,0 +1,14 @@
|
||||
from django import http
|
||||
from django.contrib.databrowse.datastructures import EasyModel
|
||||
from django.contrib.databrowse.sites import DatabrowsePlugin
|
||||
from django.shortcuts import render_to_response
|
||||
import urlparse
|
||||
|
||||
class ObjectDetailPlugin(DatabrowsePlugin):
|
||||
def model_view(self, request, model_databrowse, url):
|
||||
# If the object ID wasn't provided, redirect to the model page, which is one level up.
|
||||
if url is None:
|
||||
return http.HttpResponseRedirect(urlparse.urljoin(request.path, '../'))
|
||||
easy_model = EasyModel(model_databrowse.site, model_databrowse.model)
|
||||
obj = easy_model.object_by_pk(url)
|
||||
return render_to_response('databrowse/object_detail.html', {'object': obj, 'root_url': model_databrowse.site.root_url})
|
148
django/contrib/databrowse/sites.py
Normal file
148
django/contrib/databrowse/sites.py
Normal file
@ -0,0 +1,148 @@
|
||||
from django import http
|
||||
from django.db import models
|
||||
from django.contrib.databrowse.datastructures import EasyModel, EasyChoice
|
||||
from django.shortcuts import render_to_response
|
||||
|
||||
class AlreadyRegistered(Exception):
|
||||
pass
|
||||
|
||||
class NotRegistered(Exception):
|
||||
pass
|
||||
|
||||
class DatabrowsePlugin(object):
|
||||
def urls(self, plugin_name, easy_instance_field):
|
||||
"""
|
||||
Given an EasyInstanceField object, returns a list of URLs for this
|
||||
plugin's views of this object. These URLs should be absolute.
|
||||
|
||||
Returns None if the EasyInstanceField object doesn't get a
|
||||
list of plugin-specific URLs.
|
||||
"""
|
||||
return None
|
||||
|
||||
def model_index_html(self, request, model, site):
|
||||
"""
|
||||
Returns a snippet of HTML to include on the model index page.
|
||||
"""
|
||||
return ''
|
||||
|
||||
def model_view(self, request, model_databrowse, url):
|
||||
"""
|
||||
Handles main URL routing for a plugin's model-specific pages.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
class ModelDatabrowse(object):
|
||||
plugins = {}
|
||||
|
||||
def __init__(self, model, site):
|
||||
self.model = model
|
||||
self.site = site
|
||||
|
||||
def root(self, request, url):
|
||||
"""
|
||||
Handles main URL routing for the databrowse app.
|
||||
|
||||
`url` is the remainder of the URL -- e.g. 'objects/3'.
|
||||
"""
|
||||
# Delegate to the appropriate method, based on the URL.
|
||||
if url is None:
|
||||
return self.main_view(request)
|
||||
try:
|
||||
plugin_name, rest_of_url = url.split('/', 1)
|
||||
except ValueError: # need more than 1 value to unpack
|
||||
plugin_name, rest_of_url = url, None
|
||||
try:
|
||||
plugin = self.plugins[plugin_name]
|
||||
except KeyError:
|
||||
raise http.Http404('A plugin with the requested name does not exist.')
|
||||
return plugin.model_view(request, self, rest_of_url)
|
||||
|
||||
def main_view(self, request):
|
||||
easy_model = EasyModel(self.site, self.model)
|
||||
html_snippets = '\n'.join([p.model_index_html(request, self.model, self.site) for p in self.plugins.values()])
|
||||
return render_to_response('databrowse/model_detail.html', {
|
||||
'model': easy_model,
|
||||
'root_url': self.site.root_url,
|
||||
'plugin_html': html_snippets,
|
||||
})
|
||||
|
||||
class DatabrowseSite(object):
|
||||
def __init__(self):
|
||||
self.registry = {} # model_class -> databrowse_class
|
||||
self.root_url = None
|
||||
|
||||
def register(self, model_or_iterable, databrowse_class=None, **options):
|
||||
"""
|
||||
Registers the given model(s) with the given databrowse site.
|
||||
|
||||
The model(s) should be Model classes, not instances.
|
||||
|
||||
If a databrowse class isn't given, it will use DefaultModelDatabrowse
|
||||
(the default databrowse options).
|
||||
|
||||
If a model is already registered, this will raise AlreadyRegistered.
|
||||
"""
|
||||
databrowse_class = databrowse_class or DefaultModelDatabrowse
|
||||
if issubclass(model_or_iterable, models.Model):
|
||||
model_or_iterable = [model_or_iterable]
|
||||
for model in model_or_iterable:
|
||||
if model in self.registry:
|
||||
raise AlreadyRegistered('The model %s is already registered' % model.__class__.__name__)
|
||||
self.registry[model] = databrowse_class
|
||||
|
||||
def unregister(self, model_or_iterable):
|
||||
"""
|
||||
Unregisters the given model(s).
|
||||
|
||||
If a model isn't already registered, this will raise NotRegistered.
|
||||
"""
|
||||
if issubclass(model_or_iterable, models.Model):
|
||||
model_or_iterable = [model_or_iterable]
|
||||
for model in model_or_iterable:
|
||||
if model not in self.registry:
|
||||
raise NotRegistered('The model %s is not registered' % model.__class__.__name__)
|
||||
del self.registry[model]
|
||||
|
||||
def root(self, request, url):
|
||||
"""
|
||||
Handles main URL routing for the databrowse app.
|
||||
|
||||
`url` is the remainder of the URL -- e.g. 'comments/comment/'.
|
||||
"""
|
||||
self.root_url = request.path[:len(request.path) - len(url)]
|
||||
url = url.rstrip('/') # Trim trailing slash, if it exists.
|
||||
|
||||
if url == '':
|
||||
return self.index(request)
|
||||
elif '/' in url:
|
||||
return self.model_page(request, *url.split('/', 2))
|
||||
|
||||
raise http.Http404('The requested databrowse page does not exist.')
|
||||
|
||||
def index(self, request):
|
||||
m_list = [EasyModel(self, m) for m in self.registry.keys()]
|
||||
return render_to_response('databrowse/homepage.html', {'model_list': m_list, 'root_url': self.root_url})
|
||||
|
||||
def model_page(self, request, app_label, model_name, rest_of_url=None):
|
||||
"""
|
||||
Handles the model-specific functionality of the databrowse site, delegating
|
||||
to the appropriate ModelDatabrowse class.
|
||||
"""
|
||||
model = models.get_model(app_label, model_name)
|
||||
if model is None:
|
||||
raise http.Http404("App %r, model %r, not found." % (app_label, model_name))
|
||||
try:
|
||||
databrowse_class = self.registry[model]
|
||||
except KeyError:
|
||||
raise http.Http404("This model exists but has not been registered with databrowse.")
|
||||
return databrowse_class(model, self).root(request, rest_of_url)
|
||||
|
||||
site = DatabrowseSite()
|
||||
|
||||
from django.contrib.databrowse.plugins.calendars import CalendarPlugin
|
||||
from django.contrib.databrowse.plugins.objects import ObjectDetailPlugin
|
||||
from django.contrib.databrowse.plugins.fieldchoices import FieldChoicePlugin
|
||||
|
||||
class DefaultModelDatabrowse(ModelDatabrowse):
|
||||
plugins = {'objects': ObjectDetailPlugin(), 'calendars': CalendarPlugin(), 'fields': FieldChoicePlugin()}
|
58
django/contrib/databrowse/templates/databrowse/base.html
Normal file
58
django/contrib/databrowse/templates/databrowse/base.html
Normal file
@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ LANGUAGE_CODE }}" xml:lang="{{ LANGUAGE_CODE }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
|
||||
<head>
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
<style type="text/css">
|
||||
* { margin:0; padding:0; }
|
||||
body { background:#eee; color:#333; font:76%/1.6 "Lucida Grande","Bitstream Vera Sans",Verdana,sans-serif; }
|
||||
a { color: #5b80b2; text-decoration:none; }
|
||||
a:hover { text-decoration:underline; }
|
||||
a img { border:none; }
|
||||
h1 { font-size:1.8em; color:#666; margin:0.4em 0 0.2em 0; }
|
||||
h2 { font-size:1.5em; color:#666; margin:1em 0 0.2em 0; }
|
||||
p { margin:0.5em 0 1em 0; }
|
||||
.odd { background-color:#EDF3FE; }
|
||||
.quiet { color:#666; }
|
||||
/* FILTERS */
|
||||
.filter { color:#999; font-size:0.9em; float:left; margin-bottom:10px; margin-right:20px; }
|
||||
.filter strong { color:#666; }
|
||||
/* OBJECT LISTS */
|
||||
.objectlist { clear:both; margin:0 -20px; color:#666; }
|
||||
.objectlist li a { display:block; padding:1em 20px; }
|
||||
.objectlist li a:hover { background:#5b80b2; color:#3B5572; color:#fff; text-decoration:none; }
|
||||
.related h2 { font-size: 1em; margin-bottom: 0.6em; }
|
||||
.related .objectlist li a { padding: 0.6em 20px; }
|
||||
.related .objectlist li.odd { background:#eee; }
|
||||
/* OBJECT DETAIL */
|
||||
.objectinfo { border-collapse:collapse; color:#666; margin:0 -20px; }
|
||||
.objectinfo td, .objectinfo th { padding:1em 20px; vertical-align:top; }
|
||||
.objectinfo td { width:100%; }
|
||||
.objectinfo th { text-align:left; white-space:nowrap; }
|
||||
/* MODEL GROUPS */
|
||||
.modelgroup { color:#999; font-size:0.9em; margin:0 -20px; }
|
||||
.modelgroup h2 { font-size:1.2em; margin:0; }
|
||||
.modelgroup h2 a { display: block; padding: 0.83em 20px; }
|
||||
.modelgroup h2 a:hover { text-decoration: none; color: #fff; }
|
||||
.modelgroup p { float:left; margin:-2.65em 0 0 14em; position:relative; }
|
||||
.modelgroup p a { white-space:nowrap; }
|
||||
.modelgroup a.more { color:#999; }
|
||||
.modelgroup:hover { background:#5b80b2; color:#becfe5; }
|
||||
.modelgroup:hover p a { color:#becfe5; }
|
||||
.modelgroup:hover a { color:#fff; }
|
||||
.modelgroup:hover a.more { color:#fff; }
|
||||
/* BREADCRUMBS */
|
||||
#breadcrumbs { padding:10px 0; color:#999; font-size:0.9em; }
|
||||
/* HEADER */
|
||||
#header a { display:block; background:#eee; color:#676868; padding:10px 20px; font-weight:bold; font-size:1em; text-decoration:none; border-bottom:1px solid #ddd; }
|
||||
#header a:hover { text-decoration:underline; }
|
||||
/* CONTENT */
|
||||
#content { background:#fff; border-bottom:1px solid #ddd; padding:0 20px; }
|
||||
</style>
|
||||
</head>
|
||||
<body id="{% block bodyid %}page{% endblock %}">
|
||||
<div id="header"><a href="{{ root_url }}">Databrowse</a></div>
|
||||
<div id="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} {{ day|date:"F j, Y" }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="../../../../">Calendars</a> / <a href="../../../">By {{ field.verbose_name }}</a> / <a href="../../">{{ day.year }}</a> / <a href="../">{{ day|date:"F" }}</a> / {{ day.day }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} on {{ day|date:"F j, Y" }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}Calendars{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / Calendars</div>
|
||||
|
||||
<h1>Calendars</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% 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>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ field.verbose_name|capfirst }} calendar{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="../">Calendars</a> / By {{ field.verbose_name }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }} by {{ field.verbose_name }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for year in date_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ year.year }}/">{{ year.year }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} in {{ month|date:"F Y" }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="../../../">Calendars</a> / <a href="../../">By {{ field.verbose_name }}</a> / <a href="../">{{ month.year }}</a> / {{ month|date:"F" }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} in {{ month|date:"F Y" }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} in {{ year }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="../../">Calendars</a> / <a href="../">By {{ field.verbose_name }}</a> / {{ year }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }} with {{ field.verbose_name }} in {{ year }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for month in date_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ month|date:"M"|lower }}/">{{ month|date:"F" }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} by {{ field.field.verbose_name }}: {{ value|escape }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="{{ field.url }}">By {{ field.field.verbose_name }}</a> / {{ value|escape }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }} by {{ field.field.verbose_name }}: {{ value|escape }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }} by {{ field.field.verbose_name }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / By {{ field.field.verbose_name }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }} by {{ field.field.verbose_name }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for choice in field.choices %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ choice.url }}">{{ choice.label }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst|escape }} with {{ field.field.verbose_name|escape }} {{ value|escape }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="../../">Fields</a> / <a href="../">By {{ field.field.verbose_name|escape }}</a> / {{ value|escape }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst|escape }} with {{ field.field.verbose_name|escape }} {{ value|escape }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}Browsable fields in {{ model.verbose_name_plural|escape }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / Fields</div>
|
||||
|
||||
<h1>Browsable fields in {{ model.verbose_name_plural }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% 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>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,17 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst|escape }} by {{ field.field.verbose_name|escape }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a> / <a href="../">Fields</a> / By {{ field.field.verbose_name|escape }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst|escape }} by {{ field.field.verbose_name|escape }}</h1>
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object }}/">{{ object|escape }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
21
django/contrib/databrowse/templates/databrowse/homepage.html
Normal file
21
django/contrib/databrowse/templates/databrowse/homepage.html
Normal file
@ -0,0 +1,21 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}Databrowse{% endblock %}
|
||||
|
||||
{% block bodyid %}homepage{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% for model in model_list %}
|
||||
<div class="modelgroup {% cycle even,odd %}">
|
||||
<h2><a href="{{ model.url }}">{{ model.verbose_name_plural|capfirst }}</a></h2>
|
||||
<p>
|
||||
{% for object in model.sample_objects %}
|
||||
<a href="{{ object.url }}">{{ object }}</a>,
|
||||
{% endfor %}
|
||||
<a class="more" href="{{ model.url }}">More →</a>
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,19 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ model.verbose_name_plural|capfirst }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / {{ model.verbose_name_plural|capfirst }}</div>
|
||||
|
||||
<h1>{{ model.verbose_name_plural|capfirst }}</h1>
|
||||
|
||||
{{ plugin_html }}
|
||||
|
||||
<ul class="objectlist">
|
||||
{% for object in model.objects %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,41 @@
|
||||
{% extends "databrowse/base.html" %}
|
||||
|
||||
{% block title %}{{ object.model.verbose_name|capfirst }}: {{ object }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="breadcrumbs"><a href="{{ root_url }}">Home</a> / <a href="{{ object.model.url }}">{{ object.model.verbose_name_plural|capfirst }}</a> / {{ object }}</div>
|
||||
|
||||
<h1>{{ object.model.verbose_name|capfirst }}: {{ object }}</h1>
|
||||
|
||||
<table class="objectinfo">
|
||||
{% for field in object.fields %}
|
||||
<tr class="{% cycle odd,even %}">
|
||||
<th>{{ field.field.verbose_name|capfirst }}</th>
|
||||
<td>
|
||||
{% if field.urls %}
|
||||
{% for urlvalue in field.urls %}
|
||||
{% if urlvalue.1 %}<a href="{{ urlvalue.1 }}">{% endif %}{{ urlvalue.0 }}{% if urlvalue.1 %}</a>{% endif %}{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% else %}None{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% for related_object in object.related_objects %}
|
||||
<div class="related">
|
||||
<h2>Appears in "{{ related_object.related_field }}" in the following {{ related_object.model.verbose_name_plural }}:</h2>
|
||||
{% if related_object.object_list %}
|
||||
<ul class="objectlist">
|
||||
{% for object in related_object.object_list %}
|
||||
<li class="{% cycle odd,even %}"><a href="{{ object.url }}">{{ object }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="quiet">(None)</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
20
django/contrib/databrowse/urls.py
Normal file
20
django/contrib/databrowse/urls.py
Normal file
@ -0,0 +1,20 @@
|
||||
from django.conf.urls.defaults import *
|
||||
from django.contrib.databrowse import views
|
||||
|
||||
# Note: The views in this URLconf all require a 'models' argument,
|
||||
# which is a list of model classes (*not* instances).
|
||||
|
||||
urlpatterns = patterns('',
|
||||
#(r'^$', views.homepage),
|
||||
#(r'^([^/]+)/([^/]+)/$', views.model_detail),
|
||||
|
||||
(r'^([^/]+)/([^/]+)/fields/(\w+)/$', views.choice_list),
|
||||
(r'^([^/]+)/([^/]+)/fields/(\w+)/(.*)/$', views.choice_detail),
|
||||
|
||||
#(r'^([^/]+)/([^/]+)/calendars/(\w+)/$', views.calendar_main),
|
||||
#(r'^([^/]+)/([^/]+)/calendars/(\w+)/(\d{4})/$', views.calendar_year),
|
||||
#(r'^([^/]+)/([^/]+)/calendars/(\w+)/(\d{4})/(\w{3})/$', views.calendar_month),
|
||||
#(r'^([^/]+)/([^/]+)/calendars/(\w+)/(\d{4})/(\w{3})/(\d{1,2})/$', views.calendar_day),
|
||||
|
||||
#(r'^([^/]+)/([^/]+)/objects/(.*)/$', views.object_detail),
|
||||
)
|
23
django/contrib/databrowse/views.py
Normal file
23
django/contrib/databrowse/views.py
Normal file
@ -0,0 +1,23 @@
|
||||
from django.db.models import FieldDoesNotExist, DateTimeField
|
||||
from django.http import Http404
|
||||
from django.shortcuts import render_to_response
|
||||
from django.contrib.databrowse.datastructures import EasyModel, EasyChoice
|
||||
import datetime
|
||||
import time
|
||||
|
||||
###########
|
||||
# CHOICES #
|
||||
###########
|
||||
|
||||
def choice_list(request, app_label, module_name, field_name, models):
|
||||
m, f = lookup_field(app_label, module_name, field_name, models)
|
||||
return render_to_response('databrowse/choice_list.html', {'model': m, 'field': f})
|
||||
|
||||
def choice_detail(request, app_label, module_name, field_name, field_val, models):
|
||||
m, f = lookup_field(app_label, module_name, field_name, models)
|
||||
try:
|
||||
label = dict(f.field.choices)[field_val]
|
||||
except KeyError:
|
||||
raise Http404('Invalid choice value given')
|
||||
obj_list = m.objects(**{f.field.name: field_val})
|
||||
return render_to_response('databrowse/choice_detail.html', {'model': m, 'field': f, 'value': label, 'object_list': obj_list})
|
@ -1,11 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
A brazilian mapping of state misspellings/abbreviations to normalized
|
||||
abbreviations, and an alphabetical list of states for use as `choices
|
||||
in a formfield.
|
||||
An alphabetical list of Brazilian states for use as `choices` in a formfield.
|
||||
|
||||
This exists in this standalone file so that it's only imported into
|
||||
memory when explicitly needed.
|
||||
This exists in this standalone file so that it's only imported into memory
|
||||
when explicitly needed.
|
||||
"""
|
||||
|
||||
STATE_CHOICES = (
|
||||
|
@ -4,7 +4,7 @@ BR-specific Form helpers
|
||||
"""
|
||||
|
||||
from django.newforms import ValidationError
|
||||
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
|
||||
from django.newforms.fields import Field, RegexField, CharField, Select, EMPTY_VALUES
|
||||
from django.utils.encoding import smart_unicode
|
||||
from django.utils.translation import gettext
|
||||
import re
|
||||
@ -15,7 +15,7 @@ class BRZipCodeField(RegexField):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BRZipCodeField, self).__init__(r'^\d{5}-\d{3}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=gettext(u'Enter a zip code in the format XXXXX-XXX.'),
|
||||
error_message=gettext('Enter a zip code in the format XXXXX-XXX.'),
|
||||
*args, **kwargs)
|
||||
|
||||
class BRPhoneNumberField(Field):
|
||||
@ -31,9 +31,89 @@ class BRPhoneNumberField(Field):
|
||||
|
||||
class BRStateSelect(Select):
|
||||
"""
|
||||
A Select widget that uses a list of brazilian states/territories
|
||||
A Select widget that uses a list of Brazilian states/territories
|
||||
as its choices.
|
||||
"""
|
||||
def __init__(self, attrs=None):
|
||||
from br_states import STATE_CHOICES # relative import
|
||||
super(BRStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
|
||||
|
||||
|
||||
def DV_maker(v):
|
||||
if v >= 2:
|
||||
return 11 - v
|
||||
return 0
|
||||
|
||||
class BRCPFField(CharField):
|
||||
"""
|
||||
This field validate a CPF number or a CPF string. A CPF number is
|
||||
compounded by XXX.XXX.XXX-VD. The two last digits are check digits.
|
||||
|
||||
More information:
|
||||
http://en.wikipedia.org/wiki/Cadastro_de_Pessoas_F%C3%ADsicas
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BRCPFField, self).__init__(max_length=14, min_length=11, *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
"""
|
||||
Value can be either a string in the format XXX.XXX.XXX-XX or an
|
||||
11-digit number.
|
||||
"""
|
||||
value = super(BRCPFField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
orig_value = value[:]
|
||||
if not value.isdigit():
|
||||
value = re.sub("[-\.]", "", value)
|
||||
try:
|
||||
int(value)
|
||||
except ValueError:
|
||||
raise ValidationError(gettext("This field requires only numbers."))
|
||||
if len(value) != 11:
|
||||
raise ValidationError(gettext("This field requires at most 11 digits or 14 characters."))
|
||||
orig_dv = value[-2:]
|
||||
|
||||
new_1dv = sum([i * int(value[idx]) for idx, i in enumerate(range(10, 1, -1))])
|
||||
new_1dv = DV_maker(new_1dv % 11)
|
||||
value = value[:-2] + str(new_1dv) + value[-1]
|
||||
new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(11, 1, -1))])
|
||||
new_2dv = DV_maker(new_2dv % 11)
|
||||
value = value[:-1] + str(new_2dv)
|
||||
if value[-2:] != orig_dv:
|
||||
raise ValidationError(gettext("Invalid CPF number."))
|
||||
|
||||
return orig_value
|
||||
|
||||
class BRCNPJField(Field):
|
||||
def clean(self, value):
|
||||
"""
|
||||
Value can be either a string in the format XX.XXX.XXX/XXXX-XX or a
|
||||
group of 14 characters.
|
||||
"""
|
||||
value = super(BRCNPJField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
orig_value = value[:]
|
||||
if not value.isdigit():
|
||||
value = re.sub("[-/\.]", "", value)
|
||||
try:
|
||||
int(value)
|
||||
except ValueError:
|
||||
raise ValidationError("This field requires only numbers.")
|
||||
if len(value) != 14:
|
||||
raise ValidationError(
|
||||
gettext("This field requires at least 14 digits"))
|
||||
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 = DV_maker(new_1dv % 11)
|
||||
value = value[:-2] + str(new_1dv) + value[-1]
|
||||
new_2dv = sum([i * int(value[idx]) for idx, i in enumerate(range(6, 1, -1) + range(9, 1, -1))])
|
||||
new_2dv = DV_maker(new_2dv % 11)
|
||||
value = value[:-1] + str(new_2dv)
|
||||
if value[-2:] != orig_dv:
|
||||
raise ValidationError(gettext("Invalid CNPJ number."))
|
||||
|
||||
return orig_value
|
||||
|
||||
|
0
django/contrib/localflavor/ch/__init__.py
Normal file
0
django/contrib/localflavor/ch/__init__.py
Normal file
31
django/contrib/localflavor/ch/ch_states.py
Normal file
31
django/contrib/localflavor/ch/ch_states.py
Normal file
@ -0,0 +1,31 @@
|
||||
# -*- coding: utf-8 -*
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
STATE_CHOICES = (
|
||||
('AG', _('Aargau')),
|
||||
('AI', _('Appenzell Innerrhoden')),
|
||||
('AR', _('Appenzell Ausserrhoden')),
|
||||
('BS', _('Basel-Stadt')),
|
||||
('BL', _('Basel-Land')),
|
||||
('BE', _('Berne')),
|
||||
('FR', _('Fribourg')),
|
||||
('GE', _('Geneva')),
|
||||
('GL', _('Glarus')),
|
||||
('GR', _('Graubuenden')),
|
||||
('JU', _('Jura')),
|
||||
('LU', _('Lucerne')),
|
||||
('NE', _('Neuchatel')),
|
||||
('NW', _('Nidwalden')),
|
||||
('OW', _('Obwalden')),
|
||||
('SH', _('Schaffhausen')),
|
||||
('SZ', _('Schwyz')),
|
||||
('SO', _('Solothurn')),
|
||||
('SG', _('St. Gallen')),
|
||||
('TG', _('Thurgau')),
|
||||
('TI', _('Ticino')),
|
||||
('UR', _('Uri')),
|
||||
('VS', _('Valais')),
|
||||
('VD', _('Vaud')),
|
||||
('ZG', _('Zug')),
|
||||
('ZH', _('Zurich'))
|
||||
)
|
109
django/contrib/localflavor/ch/forms.py
Normal file
109
django/contrib/localflavor/ch/forms.py
Normal file
@ -0,0 +1,109 @@
|
||||
"""
|
||||
Swiss-specific Form helpers
|
||||
"""
|
||||
|
||||
from django.newforms import ValidationError
|
||||
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
|
||||
from django.utils.encoding import smart_unicode
|
||||
from django.utils.translation import gettext
|
||||
import re
|
||||
|
||||
id_re = re.compile(r"^(?P<idnumber>\w{8})(?P<pos9>(\d{1}|<))(?P<checksum>\d{1})$")
|
||||
phone_digits_re = re.compile(r'^0([1-9]{1})\d{8}$')
|
||||
|
||||
class CHZipCodeField(RegexField):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CHZipCodeField, self).__init__(r'^\d{4}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=gettext('Enter a zip code in the format XXXX.'),
|
||||
*args, **kwargs)
|
||||
|
||||
class CHPhoneNumberField(Field):
|
||||
"""
|
||||
Validate local Swiss phone number (not international ones)
|
||||
The correct format is '0XX XXX XX XX'.
|
||||
'0XX.XXX.XX.XX' and '0XXXXXXXXX' validate but are corrected to
|
||||
'0XX XXX XX XX'.
|
||||
"""
|
||||
def clean(self, value):
|
||||
super(CHPhoneNumberField, 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 %s' % (value[0:3], value[3:6], value[6:8], value[8:10])
|
||||
raise ValidationError('Phone numbers must be in 0XX XXX XX XX format.')
|
||||
|
||||
class CHStateSelect(Select):
|
||||
"""
|
||||
A Select widget that uses a list of CH states as its choices.
|
||||
"""
|
||||
def __init__(self, attrs=None):
|
||||
from ch_states import STATE_CHOICES # relative import
|
||||
super(CHStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
|
||||
|
||||
class CHIdentityCardNumberField(Field):
|
||||
"""
|
||||
A Swiss identity card number.
|
||||
|
||||
Checks the following rules to determine whether the number is valid:
|
||||
|
||||
* Conforms to the X1234567<0 or 1234567890 format.
|
||||
* Included checksums match calculated checksums
|
||||
|
||||
Algorithm is documented at http://adi.kousz.ch/artikel/IDCHE.htm
|
||||
"""
|
||||
def has_valid_checksum(self, number):
|
||||
given_number, given_checksum = number[:-1], number[-1]
|
||||
new_number = given_number
|
||||
calculated_checksum = 0
|
||||
fragment = ""
|
||||
parameter = 7
|
||||
|
||||
first = str(number[:1])
|
||||
if first.isalpha():
|
||||
num = ord(first.upper()) - 65
|
||||
if num < 0 or num > 8:
|
||||
return False
|
||||
new_number = str(num) + new_number[1:]
|
||||
new_number = new_number[:8] + '0'
|
||||
|
||||
if not new_number.isdigit():
|
||||
return False
|
||||
|
||||
for i in range(len(new_number)):
|
||||
fragment = int(new_number[i])*parameter
|
||||
calculated_checksum += fragment
|
||||
|
||||
if parameter == 1:
|
||||
parameter = 7
|
||||
elif parameter == 3:
|
||||
parameter = 1
|
||||
elif parameter ==7:
|
||||
parameter = 3
|
||||
|
||||
return str(calculated_checksum)[-1] == given_checksum
|
||||
|
||||
def clean(self, value):
|
||||
super(CHIdentityCardNumberField, self).clean(value)
|
||||
error_msg = gettext('Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format.')
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
|
||||
match = re.match(id_re, value)
|
||||
if not match:
|
||||
raise ValidationError(error_msg)
|
||||
|
||||
idnumber, pos9, checksum = match.groupdict()['idnumber'], match.groupdict()['pos9'], match.groupdict()['checksum']
|
||||
|
||||
if idnumber == '00000000' or \
|
||||
idnumber == 'A0000000':
|
||||
raise ValidationError(error_msg)
|
||||
|
||||
all_digits = "%s%s%s" % (idnumber, pos9, checksum)
|
||||
if not self.has_valid_checksum(all_digits):
|
||||
raise ValidationError(error_msg)
|
||||
|
||||
return u'%s%s%s' % (idnumber, pos9, checksum)
|
||||
|
0
django/contrib/localflavor/cl/__init__.py
Normal file
0
django/contrib/localflavor/cl/__init__.py
Normal file
78
django/contrib/localflavor/cl/forms.py
Normal file
78
django/contrib/localflavor/cl/forms.py
Normal file
@ -0,0 +1,78 @@
|
||||
"""
|
||||
Chile specific form helpers.
|
||||
"""
|
||||
|
||||
from django.newforms import ValidationError
|
||||
from django.newforms.fields import RegexField, EMPTY_VALUES
|
||||
from django.utils.translation import gettext
|
||||
|
||||
class CLRutField(RegexField):
|
||||
"""
|
||||
Chilean "Rol Unico Tributario" (RUT) field. This is the Chilean national
|
||||
identification number.
|
||||
|
||||
Samples for testing are available from
|
||||
https://palena.sii.cl/cvc/dte/ee_empresas_emisoras.html
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
if 'strict' in kwargs:
|
||||
del kwargs['strict']
|
||||
super(CLRutField, self).__init__(r'^(\d{1,2}\.)?\d{3}\.\d{3}-[\dkK]$',
|
||||
error_message=gettext('Enter valid a Chilean RUT. The format is XX.XXX.XXX-X.'),
|
||||
*args, **kwargs)
|
||||
else:
|
||||
# In non-strict mode, accept RUTs that validate but do not exist in
|
||||
# the real world.
|
||||
super(CLRutField, self).__init__(r'^[\d\.]{1,11}-?[\dkK]$', error_message=gettext(u'Enter valid a Chilean RUT'), *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
"""
|
||||
Check and clean the Chilean RUT.
|
||||
"""
|
||||
super(CLRutField, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
rut, verificador = self._canonify(value)
|
||||
if self._algorithm(rut) == verificador:
|
||||
return self._format(rut, verificador)
|
||||
else:
|
||||
raise ValidationError(u'The Chilean RUT is not valid.')
|
||||
|
||||
def _algorithm(self, rut):
|
||||
"""
|
||||
Takes RUT in pure canonical form, calculates the verifier digit.
|
||||
"""
|
||||
suma = 0
|
||||
multi = 2
|
||||
for r in rut[::-1]:
|
||||
suma += int(r) * multi
|
||||
multi += 1
|
||||
if multi == 8:
|
||||
multi = 2
|
||||
return '0123456789K0'[11 - suma % 11]
|
||||
|
||||
def _canonify(self, rut):
|
||||
"""
|
||||
Turns the RUT into one normalized format. Returns a (rut, verifier)
|
||||
tuple.
|
||||
"""
|
||||
rut = str(rut).replace(' ', '').replace('.', '').replace('-', '')
|
||||
return rut[:-1], rut[-1]
|
||||
|
||||
def _format(self, code, verifier=None):
|
||||
"""
|
||||
Formats the RUT from canonical form to the common string representation.
|
||||
If verifier=None, then the last digit in 'code' is the verifier.
|
||||
"""
|
||||
if verifier is None:
|
||||
verifier = code[-1]
|
||||
code = code[:-1]
|
||||
while len(code) > 3 and '.' not in code[:3]:
|
||||
pos = code.find('.')
|
||||
if pos == -1:
|
||||
new_dot = -3
|
||||
else:
|
||||
new_dot = pos - 3
|
||||
code = code[:new_dot] + '.' + code[new_dot:]
|
||||
return '%s-%s' % (code, verifier)
|
||||
|
@ -26,8 +26,8 @@ class FISocialSecurityNumber(Field):
|
||||
def clean(self, value):
|
||||
super(FISocialSecurityNumber, self).clean(value)
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
|
||||
return u''
|
||||
|
||||
checkmarks = "0123456789ABCDEFHJKLMNPRSTUVWXY"
|
||||
result = re.match(r"""^
|
||||
(?P<date>([0-2]\d|3[01])
|
||||
@ -35,13 +35,11 @@ class FISocialSecurityNumber(Field):
|
||||
(\d{2}))
|
||||
[A+-]
|
||||
(?P<serial>(\d{3}))
|
||||
(?P<chechsum>[%s])$""" % checkmarks, value, re.VERBOSE | re.IGNORECASE)
|
||||
(?P<checksum>[%s])$""" % checkmarks, value, re.VERBOSE | re.IGNORECASE)
|
||||
if not result:
|
||||
raise ValidationError(gettext(u'Enter a valid Finnish social security number.'))
|
||||
checksum = int(result.groupdict()['date'] + result.groupdict()['serial'])
|
||||
|
||||
if checkmarks[checksum % len(checkmarks)] == result.groupdict()['chechsum'].upper():
|
||||
gd = result.groupdict()
|
||||
checksum = int(gd['date'] + gd['serial'])
|
||||
if checkmarks[checksum % len(checkmarks)] == gd['checksum'].upper():
|
||||
return u'%s' % value.upper()
|
||||
|
||||
raise ValidationError(gettext(u'Enter a valid Finnish social security number.'))
|
||||
|
||||
|
0
django/contrib/localflavor/is_/__init__.py
Normal file
0
django/contrib/localflavor/is_/__init__.py
Normal file
77
django/contrib/localflavor/is_/forms.py
Normal file
77
django/contrib/localflavor/is_/forms.py
Normal file
@ -0,0 +1,77 @@
|
||||
"""
|
||||
Iceland specific form helpers.
|
||||
"""
|
||||
|
||||
from django.newforms import ValidationError
|
||||
from django.newforms.fields import RegexField, EMPTY_VALUES
|
||||
from django.newforms.widgets import Select
|
||||
from django.utils.translation import gettext
|
||||
|
||||
class ISIdNumberField(RegexField):
|
||||
"""
|
||||
Icelandic identification number (kennitala). This is a number every citizen
|
||||
of Iceland has.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
error_msg = gettext(u'Enter a valid Icelandic identification number. The format is XXXXXX-XXXX.')
|
||||
kwargs['min_length'],kwargs['max_length'] = 10,11
|
||||
super(ISIdNumberField, self).__init__(r'^\d{6}(-| )?\d{4}$', error_message=error_msg, *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
value = super(ISIdNumberField, self).clean(value)
|
||||
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
|
||||
value = self._canonify(value)
|
||||
if self._validate(value):
|
||||
return self._format(value)
|
||||
else:
|
||||
raise ValidationError(gettext(u'The Icelandic identification number is not valid.'))
|
||||
|
||||
def _canonify(self, value):
|
||||
"""
|
||||
Returns the value as only digits.
|
||||
"""
|
||||
return value.replace('-', '').replace(' ', '')
|
||||
|
||||
def _validate(self, value):
|
||||
"""
|
||||
Takes in the value in canonical form and checks the verifier digit. The
|
||||
method is modulo 11.
|
||||
"""
|
||||
check = [3, 2, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||
return sum(int(value[i]) * check[i] for i in range(10)) % 11 == 0
|
||||
|
||||
def _format(self, value):
|
||||
"""
|
||||
Takes in the value in canonical form and returns it in the common
|
||||
display format.
|
||||
"""
|
||||
return value[:6]+'-'+value[6:]
|
||||
|
||||
class ISPhoneNumberField(RegexField):
|
||||
"""
|
||||
Icelandic phone number. Seven digits with an optional hyphen or space after
|
||||
the first three digits.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['min_length'], kwargs['max_length'] = 7,8
|
||||
super(ISPhoneNumberField, self).__init__(r'^\d{3}(-| )?\d{4}$', *args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
value = super(ISPhoneNumberField, self).clean(value)
|
||||
|
||||
if value in EMPTY_VALUES:
|
||||
return u''
|
||||
|
||||
return value.replace('-', '').replace(' ', '')
|
||||
|
||||
class ISPostalCodeSelect(Select):
|
||||
"""
|
||||
A Select widget that uses a list of Icelandic postal codes as its choices.
|
||||
"""
|
||||
def __init__(self, attrs=None):
|
||||
from is_postalcodes import IS_POSTALCODES
|
||||
super(ISPostalCodeSelect, self).__init__(attrs, choices=IS_POSTALCODES)
|
||||
|
151
django/contrib/localflavor/is_/is_postalcodes.py
Normal file
151
django/contrib/localflavor/is_/is_postalcodes.py
Normal file
@ -0,0 +1,151 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
IS_POSTALCODES = (
|
||||
('101', u'101 Reykjavík'),
|
||||
('103', u'103 Reykjavík'),
|
||||
('104', u'104 Reykjavík'),
|
||||
('105', u'105 Reykjavík'),
|
||||
('107', u'107 Reykjavík'),
|
||||
('108', u'108 Reykjavík'),
|
||||
('109', u'109 Reykjavík'),
|
||||
('110', u'110 Reykjavík'),
|
||||
('111', u'111 Reykjavík'),
|
||||
('112', u'112 Reykjavík'),
|
||||
('113', u'113 Reykjavík'),
|
||||
('116', u'116 Kjalarnes'),
|
||||
('121', u'121 Reykjavík'),
|
||||
('123', u'123 Reykjavík'),
|
||||
('124', u'124 Reykjavík'),
|
||||
('125', u'125 Reykjavík'),
|
||||
('127', u'127 Reykjavík'),
|
||||
('128', u'128 Reykjavík'),
|
||||
('129', u'129 Reykjavík'),
|
||||
('130', u'130 Reykjavík'),
|
||||
('132', u'132 Reykjavík'),
|
||||
('150', u'150 Reykjavík'),
|
||||
('155', u'155 Reykjavík'),
|
||||
('170', u'170 Seltjarnarnes'),
|
||||
('172', u'172 Seltjarnarnes'),
|
||||
('190', u'190 Vogar'),
|
||||
('200', u'200 Kópavogur'),
|
||||
('201', u'201 Kópavogur'),
|
||||
('202', u'202 Kópavogur'),
|
||||
('203', u'203 Kópavogur'),
|
||||
('210', u'210 Garðabær'),
|
||||
('212', u'212 Garðabær'),
|
||||
('220', u'220 Hafnarfjörður'),
|
||||
('221', u'221 Hafnarfjörður'),
|
||||
('222', u'222 Hafnarfjörður'),
|
||||
('225', u'225 Álftanes'),
|
||||
('230', u'230 Reykjanesbær'),
|
||||
('232', u'232 Reykjanesbær'),
|
||||
('233', u'233 Reykjanesbær'),
|
||||
('235', u'235 Keflavíkurflugvöllur'),
|
||||
('240', u'240 Grindavík'),
|
||||
('245', u'245 Sandgerði'),
|
||||
('250', u'250 Garður'),
|
||||
('260', u'260 Reykjanesbær'),
|
||||
('270', u'270 Mosfellsbær'),
|
||||
('300', u'300 Akranes'),
|
||||
('301', u'301 Akranes'),
|
||||
('302', u'302 Akranes'),
|
||||
('310', u'310 Borgarnes'),
|
||||
('311', u'311 Borgarnes'),
|
||||
('320', u'320 Reykholt í Borgarfirði'),
|
||||
('340', u'340 Stykkishólmur'),
|
||||
('345', u'345 Flatey á Breiðafirði'),
|
||||
('350', u'350 Grundarfjörður'),
|
||||
('355', u'355 Ólafsvík'),
|
||||
('356', u'356 Snæfellsbær'),
|
||||
('360', u'360 Hellissandur'),
|
||||
('370', u'370 Búðardalur'),
|
||||
('371', u'371 Búðardalur'),
|
||||
('380', u'380 Reykhólahreppur'),
|
||||
('400', u'400 Ísafjörður'),
|
||||
('401', u'401 Ísafjörður'),
|
||||
('410', u'410 Hnífsdalur'),
|
||||
('415', u'415 Bolungarvík'),
|
||||
('420', u'420 Súðavík'),
|
||||
('425', u'425 Flateyri'),
|
||||
('430', u'430 Suðureyri'),
|
||||
('450', u'450 Patreksfjörður'),
|
||||
('451', u'451 Patreksfjörður'),
|
||||
('460', u'460 Tálknafjörður'),
|
||||
('465', u'465 Bíldudalur'),
|
||||
('470', u'470 Þingeyri'),
|
||||
('471', u'471 Þingeyri'),
|
||||
('500', u'500 Staður'),
|
||||
('510', u'510 Hólmavík'),
|
||||
('512', u'512 Hólmavík'),
|
||||
('520', u'520 Drangsnes'),
|
||||
('522', u'522 Kjörvogur'),
|
||||
('523', u'523 Bær'),
|
||||
('524', u'524 Norðurfjörður'),
|
||||
('530', u'530 Hvammstangi'),
|
||||
('531', u'531 Hvammstangi'),
|
||||
('540', u'540 Blönduós'),
|
||||
('541', u'541 Blönduós'),
|
||||
('545', u'545 Skagaströnd'),
|
||||
('550', u'550 Sauðárkrókur'),
|
||||
('551', u'551 Sauðárkrókur'),
|
||||
('560', u'560 Varmahlíð'),
|
||||
('565', u'565 Hofsós'),
|
||||
('566', u'566 Hofsós'),
|
||||
('570', u'570 Fljót'),
|
||||
('580', u'580 Siglufjörður'),
|
||||
('600', u'600 Akureyri'),
|
||||
('601', u'601 Akureyri'),
|
||||
('602', u'602 Akureyri'),
|
||||
('603', u'603 Akureyri'),
|
||||
('610', u'610 Grenivík'),
|
||||
('611', u'611 Grímsey'),
|
||||
('620', u'620 Dalvík'),
|
||||
('621', u'621 Dalvík'),
|
||||
('625', u'625 Ólafsfjörður'),
|
||||
('630', u'630 Hrísey'),
|
||||
('640', u'640 Húsavík'),
|
||||
('641', u'641 Húsavík'),
|
||||
('645', u'645 Fosshóll'),
|
||||
('650', u'650 Laugar'),
|
||||
('660', u'660 Mývatn'),
|
||||
('670', u'670 Kópasker'),
|
||||
('671', u'671 Kópasker'),
|
||||
('675', u'675 Raufarhöfn'),
|
||||
('680', u'680 Þórshöfn'),
|
||||
('681', u'681 Þórshöfn'),
|
||||
('685', u'685 Bakkafjörður'),
|
||||
('690', u'690 Vopnafjörður'),
|
||||
('700', u'700 Egilsstaðir'),
|
||||
('701', u'701 Egilsstaðir'),
|
||||
('710', u'710 Seyðisfjörður'),
|
||||
('715', u'715 Mjóifjörður'),
|
||||
('720', u'720 Borgarfjörður eystri'),
|
||||
('730', u'730 Reyðarfjörður'),
|
||||
('735', u'735 Eskifjörður'),
|
||||
('740', u'740 Neskaupstaður'),
|
||||
('750', u'750 Fáskrúðsfjörður'),
|
||||
('755', u'755 Stöðvarfjörður'),
|
||||
('760', u'760 Breiðdalsvík'),
|
||||
('765', u'765 Djúpivogur'),
|
||||
('780', u'780 Höfn í Hornafirði'),
|
||||
('781', u'781 Höfn í Hornafirði'),
|
||||
('785', u'785 Öræfi'),
|
||||
('800', u'800 Selfoss'),
|
||||
('801', u'801 Selfoss'),
|
||||
('802', u'802 Selfoss'),
|
||||
('810', u'810 Hveragerði'),
|
||||
('815', u'815 Þorlákshöfn'),
|
||||
('820', u'820 Eyrarbakki'),
|
||||
('825', u'825 Stokkseyri'),
|
||||
('840', u'840 Laugarvatn'),
|
||||
('845', u'845 Flúðir'),
|
||||
('850', u'850 Hella'),
|
||||
('851', u'851 Hella'),
|
||||
('860', u'860 Hvolsvöllur'),
|
||||
('861', u'861 Hvolsvöllur'),
|
||||
('870', u'870 Vík'),
|
||||
('871', u'871 Vík'),
|
||||
('880', u'880 Kirkjubæjarklaustur'),
|
||||
('900', u'900 Vestmannaeyjar'),
|
||||
('902', u'902 Vestmannaeyjar')
|
||||
)
|
@ -5,13 +5,15 @@ IT-specific Form helpers
|
||||
from django.newforms import ValidationError
|
||||
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
|
||||
from django.utils.translation import gettext
|
||||
from django.utils.encoding import smart_unicode
|
||||
from django.contrib.localflavor.it.util import ssn_check_digit, vat_number_check_digit
|
||||
import re
|
||||
|
||||
class ITZipCodeField(RegexField):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ITZipCodeField, self).__init__(r'^\d{5}$',
|
||||
max_length=None, min_length=None,
|
||||
error_message=gettext(u'Enter a zip code in the format XXXXX.'),
|
||||
error_message=gettext(u'Enter a valid zip code.'),
|
||||
*args, **kwargs)
|
||||
|
||||
class ITRegionSelect(Select):
|
||||
@ -29,3 +31,47 @@ class ITProvinceSelect(Select):
|
||||
def __init__(self, attrs=None):
|
||||
from it_province import PROVINCE_CHOICES # relative import
|
||||
super(ITProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
|
||||
|
||||
class ITSocialSecurityNumberField(RegexField):
|
||||
"""
|
||||
A form field that validates Italian Social Security numbers (codice fiscale).
|
||||
For reference see http://www.agenziaentrate.it/ and search for
|
||||
'Informazioni sulla codificazione delle persone fisiche'.
|
||||
"""
|
||||
err_msg = gettext(u'Enter a valid Social Security number.')
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ITSocialSecurityNumberField, self).__init__(r'^\w{3}\s*\w{3}\s*\w{5}\s*\w{5}$',
|
||||
max_length=None, min_length=None, error_message=self.err_msg,
|
||||
*args, **kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
value = super(ITSocialSecurityNumberField, self).clean(value)
|
||||
if value == u'':
|
||||
return value
|
||||
value = re.sub('\s', u'', value).upper()
|
||||
try:
|
||||
check_digit = ssn_check_digit(value)
|
||||
except ValueError:
|
||||
raise ValidationError(self.err_msg)
|
||||
if not value[15] == check_digit:
|
||||
raise ValidationError(self.err_msg)
|
||||
return value
|
||||
|
||||
class ITVatNumberField(Field):
|
||||
"""
|
||||
A form field that validates Italian VAT numbers (partita IVA).
|
||||
"""
|
||||
def clean(self, value):
|
||||
value = super(ITVatNumberField, self).clean(value)
|
||||
if value == u'':
|
||||
return value
|
||||
err_msg = gettext(u'Enter a valid VAT number.')
|
||||
try:
|
||||
vat_number = int(value)
|
||||
except ValueError:
|
||||
raise ValidationError(err_msg)
|
||||
vat_number = str(vat_number).zfill(11)
|
||||
check_digit = vat_number_check_digit(vat_number[0:10])
|
||||
if not vat_number[10] == check_digit:
|
||||
raise ValidationError(err_msg)
|
||||
return smart_unicode(vat_number)
|
||||
|
40
django/contrib/localflavor/it/util.py
Normal file
40
django/contrib/localflavor/it/util.py
Normal file
@ -0,0 +1,40 @@
|
||||
def ssn_check_digit(value):
|
||||
"Calculate Italian social security number check digit."
|
||||
ssn_even_chars = {
|
||||
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
|
||||
'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9,
|
||||
'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18,
|
||||
'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25
|
||||
}
|
||||
ssn_odd_chars = {
|
||||
'0': 1, '1': 0, '2': 5, '3': 7, '4': 9, '5': 13, '6': 15, '7': 17, '8': 19, '9': 21,
|
||||
'A': 1, 'B': 0, 'C': 5, 'D': 7, 'E': 9, 'F': 13, 'G': 15, 'H': 17, 'I': 19, 'J': 21,
|
||||
'K': 2, 'L': 4, 'M': 18, 'N': 20, 'O': 11, 'P': 3, 'Q': 6, 'R': 8, 'S': 12,
|
||||
'T': 14, 'U': 16, 'V': 10, 'W': 22, 'X': 25, 'Y': 24, 'Z': 23
|
||||
}
|
||||
# Chars from 'A' to 'Z'
|
||||
ssn_check_digits = [chr(x) for x in range(65, 91)]
|
||||
|
||||
ssn = value.upper()
|
||||
total = 0
|
||||
for i in range(0,15):
|
||||
try:
|
||||
if i % 2 == 0:
|
||||
total += ssn_odd_chars[ssn[i]]
|
||||
else:
|
||||
total += ssn_even_chars[ssn[i]]
|
||||
except KeyError:
|
||||
msg = "Character '%(char)s' is not allowed." % {'char': ssn[i]}
|
||||
raise ValueError(msg)
|
||||
return ssn_check_digits[total % 26]
|
||||
|
||||
def vat_number_check_digit(vat_number):
|
||||
"Calculate Italian VAT number check digit."
|
||||
normalized_vat_number = str(vat_number).zfill(10)
|
||||
total = 0
|
||||
for i in range(0, 10, 2):
|
||||
total += int(normalized_vat_number[i])
|
||||
for i in range(1, 11, 2):
|
||||
quotient , remainder = divmod(int(normalized_vat_number[i]) * 2, 10)
|
||||
total += quotient + remainder
|
||||
return str((10 - total % 10) % 10)
|
@ -15,7 +15,7 @@ STATE_CHOICES = (
|
||||
('CA', 'California'),
|
||||
('CO', 'Colorado'),
|
||||
('CT', 'Connecticut'),
|
||||
('DE', 'Deleware'),
|
||||
('DE', 'Delaware'),
|
||||
('DC', 'District of Columbia'),
|
||||
('FM', 'Federated States of Micronesia'),
|
||||
('FL', 'Florida'),
|
||||
@ -97,6 +97,7 @@ STATES_NORMALIZED = {
|
||||
'de': 'DE',
|
||||
'del': 'DE',
|
||||
'delaware': 'DE',
|
||||
'deleware': 'DE',
|
||||
'district of columbia': 'DC',
|
||||
'federated states of micronesia': 'FM',
|
||||
'fl': 'FL',
|
||||
|
@ -16,7 +16,7 @@ def index(request, sitemaps):
|
||||
def sitemap(request, sitemaps, section=None):
|
||||
maps, urls = [], []
|
||||
if section is not None:
|
||||
if not sitemaps.has_key(section):
|
||||
if section not in sitemaps:
|
||||
raise Http404("No sitemap available for section: %r" % section)
|
||||
maps.append(sitemaps[section])
|
||||
else:
|
||||
|
@ -70,6 +70,7 @@ class Feed(object):
|
||||
|
||||
feed = self.feed_type(
|
||||
title = self.__get_dynamic_attr('title', obj),
|
||||
subtitle = self.__get_dynamic_attr('subtitle', obj),
|
||||
link = link,
|
||||
description = self.__get_dynamic_attr('description', obj),
|
||||
language = settings.LANGUAGE_CODE.decode(),
|
||||
|
@ -1,66 +1,69 @@
|
||||
"""
|
||||
Utility functions for generating "lorem ipsum" Latin text.
|
||||
"""
|
||||
|
||||
import random
|
||||
|
||||
COMMON_P = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
|
||||
WORDS = ('exercitationem', 'perferendis', 'perspiciatis', 'laborum', 'eveniet', 'sunt', 'iure', 'nam', 'nobis', 'eum', 'cum', 'officiis', 'excepturi', 'odio', 'consectetur', 'quasi', 'aut', 'quisquam', 'vel', 'eligendi', 'itaque', 'non', 'odit', 'tempore', 'quaerat', 'dignissimos', 'facilis', 'neque', 'nihil', 'expedita', 'vitae', 'vero', 'ipsum', 'nisi', 'animi', 'cumque', 'pariatur', 'velit', 'modi', 'natus', 'iusto', 'eaque', 'sequi', 'illo', 'sed', 'ex', 'et', 'voluptatibus', 'tempora', 'veritatis', 'ratione', 'assumenda', 'incidunt', 'nostrum', 'placeat', 'aliquid', 'fuga', 'provident', 'praesentium', 'rem', 'necessitatibus', 'suscipit', 'adipisci', 'quidem', 'possimus', 'voluptas', 'debitis', 'sint', 'accusantium', 'unde', 'sapiente', 'voluptate', 'qui', 'aspernatur', 'laudantium', 'soluta', 'amet', 'quo', 'aliquam', 'saepe', 'culpa', 'libero', 'ipsa', 'dicta', 'reiciendis', 'nesciunt', 'doloribus', 'autem', 'impedit', 'minima', 'maiores', 'repudiandae', 'ipsam', 'obcaecati', 'ullam', 'enim', 'totam', 'delectus', 'ducimus', 'quis', 'voluptates', 'dolores', 'molestiae', 'harum', 'dolorem', 'quia', 'voluptatem', 'molestias', 'magni', 'distinctio', 'omnis', 'illum', 'dolorum', 'voluptatum', 'ea', 'quas', 'quam', 'corporis', 'quae', 'blanditiis', 'atque', 'deserunt', 'laboriosam', 'earum', 'consequuntur', 'hic', 'cupiditate', 'quibusdam', 'accusamus', 'ut', 'rerum', 'error', 'minus', 'eius', 'ab', 'ad', 'nemo', 'fugit', 'officia', 'at', 'in', 'id', 'quos', 'reprehenderit', 'numquam', 'iste', 'fugiat', 'sit', 'inventore', 'beatae', 'repellendus', 'magnam', 'recusandae', 'quod', 'explicabo', 'doloremque', 'aperiam', 'consequatur', 'asperiores', 'commodi', 'optio', 'dolor', 'labore', 'temporibus', 'repellat', 'veniam', 'architecto', 'est', 'esse', 'mollitia', 'nulla', 'a', 'similique', 'eos', 'alias', 'dolore', 'tenetur', 'deleniti', 'porro', 'facere', 'maxime', 'corrupti')
|
||||
COMMON_WORDS = ('lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipisicing', 'elit', 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore', 'magna', 'aliqua')
|
||||
|
||||
def sentence():
|
||||
"""
|
||||
Returns a randomly generated sentence of lorem ipsum text.
|
||||
|
||||
The first word is capitalized, and the sentence ends in either a period or
|
||||
question mark. Commas are added at random.
|
||||
"""
|
||||
# Determine the number of comma-separated sections and number of words in
|
||||
# each section for this sentence.
|
||||
sections = [' '.join(random.sample(WORDS, random.randint(3, 12))) for i in range(random.randint(1, 5))]
|
||||
s = ', '.join(sections)
|
||||
# Convert to sentence case and add end punctuation.
|
||||
return '%s%s%s' % (s[0].upper(), s[1:], random.choice('?.'))
|
||||
|
||||
def paragraph():
|
||||
"""
|
||||
Returns a randomly generated paragraph of lorem ipsum text.
|
||||
|
||||
The paragraph consists of between 1 and 4 sentences, inclusive.
|
||||
"""
|
||||
return ' '.join([sentence() for i in range(random.randint(1, 4))])
|
||||
|
||||
def paragraphs(count, common=True):
|
||||
"""
|
||||
Returns a list of paragraphs as returned by paragraph().
|
||||
|
||||
If `common` is True, then the first paragraph will be the standard
|
||||
'lorem ipsum' paragraph. Otherwise, the first paragraph will be random
|
||||
Latin text. Either way, subsequent paragraphs will be random Latin text.
|
||||
"""
|
||||
paras = []
|
||||
for i in range(count):
|
||||
if common and i == 0:
|
||||
paras.append(COMMON_P)
|
||||
else:
|
||||
paras.append(paragraph())
|
||||
return paras
|
||||
|
||||
def words(count, common=True):
|
||||
"""
|
||||
Returns a string of `count` lorem ipsum words separated by a single space.
|
||||
|
||||
If `common` is True, then the first 19 words will be the standard
|
||||
'lorem ipsum' words. Otherwise, all words will be selected randomly.
|
||||
"""
|
||||
if common:
|
||||
word_list = list(COMMON_WORDS)
|
||||
else:
|
||||
word_list = []
|
||||
c = len(word_list)
|
||||
if count > c:
|
||||
count = min(count - c, len(WORDS))
|
||||
word_list += random.sample(WORDS, count - c)
|
||||
else:
|
||||
word_list = word_list[:count]
|
||||
return ' '.join(word_list)
|
||||
"""
|
||||
Utility functions for generating "lorem ipsum" Latin text.
|
||||
"""
|
||||
|
||||
import random
|
||||
|
||||
COMMON_P = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
|
||||
WORDS = ('exercitationem', 'perferendis', 'perspiciatis', 'laborum', 'eveniet', 'sunt', 'iure', 'nam', 'nobis', 'eum', 'cum', 'officiis', 'excepturi', 'odio', 'consectetur', 'quasi', 'aut', 'quisquam', 'vel', 'eligendi', 'itaque', 'non', 'odit', 'tempore', 'quaerat', 'dignissimos', 'facilis', 'neque', 'nihil', 'expedita', 'vitae', 'vero', 'ipsum', 'nisi', 'animi', 'cumque', 'pariatur', 'velit', 'modi', 'natus', 'iusto', 'eaque', 'sequi', 'illo', 'sed', 'ex', 'et', 'voluptatibus', 'tempora', 'veritatis', 'ratione', 'assumenda', 'incidunt', 'nostrum', 'placeat', 'aliquid', 'fuga', 'provident', 'praesentium', 'rem', 'necessitatibus', 'suscipit', 'adipisci', 'quidem', 'possimus', 'voluptas', 'debitis', 'sint', 'accusantium', 'unde', 'sapiente', 'voluptate', 'qui', 'aspernatur', 'laudantium', 'soluta', 'amet', 'quo', 'aliquam', 'saepe', 'culpa', 'libero', 'ipsa', 'dicta', 'reiciendis', 'nesciunt', 'doloribus', 'autem', 'impedit', 'minima', 'maiores', 'repudiandae', 'ipsam', 'obcaecati', 'ullam', 'enim', 'totam', 'delectus', 'ducimus', 'quis', 'voluptates', 'dolores', 'molestiae', 'harum', 'dolorem', 'quia', 'voluptatem', 'molestias', 'magni', 'distinctio', 'omnis', 'illum', 'dolorum', 'voluptatum', 'ea', 'quas', 'quam', 'corporis', 'quae', 'blanditiis', 'atque', 'deserunt', 'laboriosam', 'earum', 'consequuntur', 'hic', 'cupiditate', 'quibusdam', 'accusamus', 'ut', 'rerum', 'error', 'minus', 'eius', 'ab', 'ad', 'nemo', 'fugit', 'officia', 'at', 'in', 'id', 'quos', 'reprehenderit', 'numquam', 'iste', 'fugiat', 'sit', 'inventore', 'beatae', 'repellendus', 'magnam', 'recusandae', 'quod', 'explicabo', 'doloremque', 'aperiam', 'consequatur', 'asperiores', 'commodi', 'optio', 'dolor', 'labore', 'temporibus', 'repellat', 'veniam', 'architecto', 'est', 'esse', 'mollitia', 'nulla', 'a', 'similique', 'eos', 'alias', 'dolore', 'tenetur', 'deleniti', 'porro', 'facere', 'maxime', 'corrupti')
|
||||
COMMON_WORDS = ('lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipisicing', 'elit', 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore', 'magna', 'aliqua')
|
||||
|
||||
def sentence():
|
||||
"""
|
||||
Returns a randomly generated sentence of lorem ipsum text.
|
||||
|
||||
The first word is capitalized, and the sentence ends in either a period or
|
||||
question mark. Commas are added at random.
|
||||
"""
|
||||
# Determine the number of comma-separated sections and number of words in
|
||||
# each section for this sentence.
|
||||
sections = [' '.join(random.sample(WORDS, random.randint(3, 12))) for i in range(random.randint(1, 5))]
|
||||
s = ', '.join(sections)
|
||||
# Convert to sentence case and add end punctuation.
|
||||
return '%s%s%s' % (s[0].upper(), s[1:], random.choice('?.'))
|
||||
|
||||
def paragraph():
|
||||
"""
|
||||
Returns a randomly generated paragraph of lorem ipsum text.
|
||||
|
||||
The paragraph consists of between 1 and 4 sentences, inclusive.
|
||||
"""
|
||||
return ' '.join([sentence() for i in range(random.randint(1, 4))])
|
||||
|
||||
def paragraphs(count, common=True):
|
||||
"""
|
||||
Returns a list of paragraphs as returned by paragraph().
|
||||
|
||||
If `common` is True, then the first paragraph will be the standard
|
||||
'lorem ipsum' paragraph. Otherwise, the first paragraph will be random
|
||||
Latin text. Either way, subsequent paragraphs will be random Latin text.
|
||||
"""
|
||||
paras = []
|
||||
for i in range(count):
|
||||
if common and i == 0:
|
||||
paras.append(COMMON_P)
|
||||
else:
|
||||
paras.append(paragraph())
|
||||
return paras
|
||||
|
||||
def words(count, common=True):
|
||||
"""
|
||||
Returns a string of `count` lorem ipsum words separated by a single space.
|
||||
|
||||
If `common` is True, then the first 19 words will be the standard
|
||||
'lorem ipsum' words. Otherwise, all words will be selected randomly.
|
||||
"""
|
||||
if common:
|
||||
word_list = list(COMMON_WORDS)
|
||||
else:
|
||||
word_list = []
|
||||
c = len(word_list)
|
||||
if count > c:
|
||||
count -= c
|
||||
while count > 0:
|
||||
c = min(count, len(WORDS))
|
||||
count -= c
|
||||
word_list += random.sample(WORDS, c)
|
||||
else:
|
||||
word_list = word_list[:count]
|
||||
return ' '.join(word_list)
|
||||
|
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