root/trunk/config.py

Revision 3201, 21.4 kB (checked in by jukka, 5 days ago)

Fixed #2048. Vocational education added to vocabulary.

Line 
1 # Copyright 2006 by the LeMill Team (see AUTHORS)
2 #
3 # This file is part of LeMill.
4 #
5 # LeMill is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # LeMill is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with LeMill; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19 try:
20     from Products.CMFPlone.migrations import v2_5
21 except ImportError:
22     PLONE25 = 0
23     PLONE21 = 1 # This is ok since we've never supported anything below Plone 2.1
24 else:
25     PLONE25 = 1
26     PLONE21 = 0
27
28 from Products.CMFCore import permissions
29 from types import UnicodeType
30 from Products.ATContentTypes import permission as atpermissions
31 import os
32 from os import path, environ
33 from Globals import package_home
34 from Acquisition import ImplicitAcquisitionWrapper, aq_base
35
36 try:
37     from Products.FileSystemStorage.FileSystemStorage import FileSystemStorage
38     FS_STORAGE=True   
39 except ImportError:
40     FS_STORAGE=False   
41
42
43 import sys
44
45 # Load zope instance specific LeMill configuration from zope.conf:
46 from App import config as zconfig
47 product_config=getattr(zconfig.getConfiguration(),'product_config', {})
48 lemill_config = product_config.get('lemill', {})
49
50 # Load recaptcha keys from zope.conf:
51 RECAPTCHA_PUBLIC_KEY=lemill_config.get('recaptcha_public_key','')
52 RECAPTCHA_PRIVATE_KEY=lemill_config.get('recaptcha_private_key','')
53
54
55 AVAILABLE_TRANSLATIONS = ['cs','de','en','es','et','fi','fr','hu','ka','lt','pl','pt-br','ru','se']
56
57
58 SLIDESHARE_API_KEY=lemill_config.get('slideshare_api_key','')
59 SLIDESHARE_SECRET_KEY=lemill_config.get('slideshare_secret_key','')
60
61
62 # Load google maps api key:
63 GOOGLE_MAPS_API_KEY=lemill_config.get('google_maps_api_key','')
64
65 #TODO: Other configuration directives should also go to zope.conf and loaded as above.
66
67 ADD_TOPICS = atpermissions.AddTopics
68 ADD_CONTENT_PERMISSION = permissions.AddPortalContent
69 LIST_FOLDER_CONTENTS = permissions.ListFolderContents
70 MODIFY_CONTENT = permissions.ModifyPortalContent
71 DELETE_CONTENT = permissions.DeleteObjects
72 MANAGE_PORTAL = permissions.ManagePortal
73 VIEW = permissions.View
74
75 # Must match the folder in Products/ where this product is installed
76 PROJECTNAME = "LeMill"
77    
78
79 # With LaTeX you can write complex math notation to pages,
80 # Local LaTeX support requires that
81 # 1. LaTeX-typesetting is installed to your computer
82 # 2. Zope Product 'LocalFS' v1.7-> is installed to your Products-folder.
83
84 # External latex support doesn't require anything on your server,
85 # but it depends on external service to compile images from latex code,
86 # which can result in missing or slowly loading images, depending on your network.
87 # If both are enabled, first the local solution is tried, then external
88
89 # Default for local latex is
90 # /zope-instance/var/latex_images
91 LATEX_IMAGES_STORAGE_PATH='latex_images' # this will be a directory under your zope instances var/
92
93 # Forkosh service seems to be closed for us now.
94 #EXTERNAL_LATEX_SERVICE='http://www.forkosh.dreamhost.com/mimetex.cgi?'
95 EXTERNAL_LATEX_SERVICE='http://chart.apis.google.com/chart?cht=tx&chl='
96
97 # To disable local latex, uncomment line below:
98 #LATEX_IMAGES_STORAGE_PATH=''
99
100 # To disable external latex service, uncomment line below:
101 #EXTERNAL_LATEX_SERVICE=''
102
103 # If you want to enable Flickr-search for pieces, you must have a flickr api key.
104 # You can get one from http://www.flickr.com/services/
105 #FLICKR_API_KEY = "774a1f64011ec6166e85def00ec641f6"
106 #FLICKR_API_KEY = ""
107
108 SCORE_THRESHOLD=5 # Resource needs to have score>N to get to front page
109
110 #
111 REMOTE_SERVERS = ["http://lemill.net"]
112
113 MATERIAL_TYPES = ('PresentationMaterial', 'MultimediaMaterial', 'PILOTMaterial', 'ExerciseMaterial','LessonPlan', 'SchoolProjectMaterial', 'LeMillReference')
114 CONTENT_TYPES = ('Piece','LeMillPrintResource') + MATERIAL_TYPES
115 ACTIVITY_TYPES = ('Activity',)
116 TOOLS_TYPES = ('Tool',)
117 COMMUNITY_MAIN_TYPES = ('GroupBlog','MemberFolder',)
118 COMMUNITY_FEATURED_TYPES = ('MemberFolder',)
119 COMMUNITY_TYPES = ('BlogPost',) + COMMUNITY_MAIN_TYPES
120 FEATURED_TYPES = MATERIAL_TYPES + ACTIVITY_TYPES + TOOLS_TYPES + COMMUNITY_FEATURED_TYPES
121 ALL_CONTENT_TYPES = CONTENT_TYPES + ACTIVITY_TYPES + TOOLS_TYPES + COMMUNITY_TYPES
122 SEARCHABLE_TYPES = ALL_CONTENT_TYPES + ('Collection',)
123 STATISTICS_TYPES = COMMUNITY_MAIN_TYPES + CONTENT_TYPES + ACTIVITY_TYPES + TOOLS_TYPES
124 l = list(ALL_CONTENT_TYPES)
125 l.remove('MemberFolder')
126 CREATED_RESOURCES = tuple(l)
127
128 TYPE_NAMES = {'Piece':('Media piece','Media pieces'),
129  'Material':('Content', 'Content'),
130  'Learning resource':('Learning resource', 'Learning resources'),
131  'Content': ('Content', 'Content'),
132  'Activity': ('Method', 'Methods'),
133  'Tool': ('Tool', 'Tools'),
134  'MemberFolder': ('Member', 'People'),
135  'GroupBlog': ('Group', 'Groups'),
136  'BlogPost': ('Forum post', 'Forum posts'),
137  'LeMillReference': ('Reference', 'References'),
138  'MultimediaMaterial': ('Web page', 'Web pages'),
139  'PILOTMaterial': ('PILOT', 'PILOTs'),
140  'PresentationMaterial': ('Presentation', 'Presentations'), 
141  'ExerciseMaterial': ('Exercise', 'Exercises'),   
142  'Collection': ('Collection', 'Collections'),
143  'LessonPlan': ('Lesson plan', 'Lesson plans'),
144  'SchoolProjectMaterial': ('School project', 'School projects'),
145  'LeMillPrintResource': ('Print resource', 'Print resources'),
146 }
147
148
149 SUBJECT_AREAS = ["Natural sciences",
150         "Geography",
151         "Chemistry",
152         "Physics",
153         "Biology",
154         "Environmental education",
155         "Language and literature",
156         "Foreign languages",
157         "Mathematics",
158         "Informatics or ICT",
159         "Art",
160         "Music",
161         "History",
162         "Religion",
163         "Philosophy",
164         "Ethics",
165         "Psychology",
166         "Social sciences",
167         "Culture",
168         "Citizenship",
169         "Politics",
170         "Economics",
171         "Media education",
172         "Physical education",
173         "School-community relationship",
174         "Educational administration",
175         "Cross-curricular education"]
176 SUBJECT_AREAS_DICT= dict([(sa.split()[0].lower(),sa) for sa in SUBJECT_AREAS])
177 SUBJECT_AREAS_INVERSE_DICT= dict([(sa, sa.split()[0].lower()) for sa in SUBJECT_AREAS])
178
179 TARGET_GROUPS= ["pre-school education",
180             "1st grade",
181             "2nd grade",
182             "3rd grade",
183             "4th grade",
184             "5th grade",
185             "6th grade",
186             "7th grade",
187             "8th grade",
188             "9th grade",
189             "10th grade",
190             "11th grade",
191             "12th grade",
192             "vocational education",
193             "higher education",
194             "adult education",
195             "teachers",
196             "special education"]
197
198 TARGET_GROUPS_DICT= dict([(tg.split()[0].lower(),tg) for tg in TARGET_GROUPS])
199 TARGET_GROUPS_INVERSE_DICT = dict([(tg, tg.split()[0].lower()) for tg in TARGET_GROUPS])
200
201
202
203 TYPE_ABBREVIATIONS={'Piece':'MP',
204             'MultimediaMaterial':'LR',
205             'PresentationMaterial':'LR',
206             'PILOTMaterial':'LR',
207             'ExerciseMaterial':'LR',
208             'SchoolProjectMaterial':'LR',
209             'LeMillReference':'R',
210             'Activity':'LM',
211             'Tool':'T',
212             'MemberFolder':'M',
213             'GroupBlog':'G',
214             'BlogPost':'FP',
215             'Collection':'C',
216             'LessonPlan':'LR',
217             'LeMillPrintResource':'PR'}
218            
219
220 # Subdirectory of this product folder which contains our skin folders
221 SKINS_DIR = 'skins'
222 SKIN_NAME='lemill'
223 # The skin from which to build our own skin
224 BASE_SKIN = 'Plone Default'
225
226 # application/octet-stream have to be in white list, because the browser recognize FLV as octet stream
227 MIMETYPE_WHITELIST = ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png',
228                       'application/x-shockwave-flash', 'audio/mpeg', 'application/octet-stream',
229                       'text/plain', 'application/earthviewer', 'text/xml', 'application/xml', 'application/x-xml']
230
231 #list of shown metadata fields, if 'all' is in array then all fields are shown
232 SHOW_METADATA_FIELDS = {'Piece':['description', 'tags'],
233                         'PresentationMaterial':['all',],
234                         'MultimediaMaterial':['all',],
235                         'ExerciseMaterial':['all',],
236                         'Tool':['all',],
237                         'Activity':['all',],
238                         'GroupBlog':['all',],
239                         'LeMillReference' : ['all',],
240                         'PILOTMaterial' : ['all',],
241                         'LessonPlan' : ['all',],
242                         'SchoolProjectMaterial' : ['all',],
243                         'LeMillPrintResource' : ['all',]
244                        }
245
246 # Main sections of the site
247 SECTIONS = {'Content':['Pieces','References','Presentations','PILOTs','WebPages','Exercises','LessonPlans','SchoolProjects','PrintResources'],'Methods':[],'Tools':[],'Community':['People','Groups']}
248
249
250 SECTION_FOLDER_TYPES = {
251     'Methods':'LargeActivityFolder',   
252     'Tools':'LargeToolFolder',
253     'Content':'LargeContentFolder',
254     'Pieces':'LargeContentFolder',
255     'References':'LargeContentFolder',
256     'Presentations':'LargeContentFolder',
257     'PILOTs':'LargeContentFolder',
258     'WebPages':'LargeContentFolder',
259     'Exercises':'LargeContentFolder',
260     'Community':'LargeCommunityFolder',
261     'People':'LargeCommunityFolder',
262     'Groups':'LargeCommunityFolder',
263     'LessonPlans':'LargeContentFolder',
264     'SchoolProjects':'LargeContentFolder',
265     'PrintResources':'LargeContentFolder'
266 }
267
268 SECTION_TOPLISTS={
269     'content':['top3languages','top3subject_areas','top3target_groups','top3tags'],
270     'methods':['top3languages','top3tags'],
271     'tools':['top3languages','top3tags'],
272     'community':['top3language_skills','top3locations','top3skills','top3interests','top3subject_areas',
273         'top3group_languages','top3group_tags','top3group_subject_areas']
274 }
275
276    
277 DEFAULT_PORTRAIT = 'default_member.png'
278
279 INSTANT_MESSENGERS = ('AIM','Gadu-Gadu','Google Talk','ICQ','MSN','Skype','Yahoo')
280
281 # search terms travel all over the place in urls, often without any
282 # (easy) access to types that have these fields. Still they need to be displayed in some nice way.
283 FIELD_METHODS_DISPLAY_STRINGS={
284     'getSubject_area':('subject area','subject areas'),
285     'getTarget_group':('target group','target groups'),
286     'sortable_title':('title', 'titles'),
287     'Language':('language', 'languages'),
288     'getTags' : ('tag', 'tags'),
289     'getState':('status', 'status'),
290     'getLanguage_skills':('language skill', 'language skills'),
291     'sortable_title':('title', 'titles'),
292     'getLocation_country':('country', 'countries'),
293     'getLocation_area':('area', 'areas'),
294     'getSkills':('skill', 'skills'),
295     'getInterests':('interest', 'interests'),
296     'Creator':('creator', 'creators'),
297     }
298
299
300
301 TEMPLATES = {
302     'multimediapage' : {
303         'title'  : 'Web page',
304         'fields' : ['title', 'bodyText'],
305         'meta_type' : 'MultimediaMaterial',
306         'icon' : 'images/default_multimedia_page.png',
307         'order' : 'A',
308         },
309     'exercisepage' : {
310         'title'  : 'Exercise',
311         'fields' : ['title', 'bodyText'],
312         'meta_type' : 'ExerciseMaterial',
313         'icon' : 'images/default_exercise.png',
314         'order' : 'C',
315         },
316     'presentation' : {
317         'title'  : 'Presentation',
318         'fields' : ['title', 'bodyText', 'audio'],
319         'meta_type' : 'PresentationMaterial',
320         'icon' : 'images/default_presentation.png',
321         'order' : 'B',
322         },
323     'PILOTMaterial' : {
324         'title' : 'PILOT',
325         'fields' : ['title', 'shortDescription', 'description', 'bodyText'],
326         'meta_type' : 'PILOTMaterial',
327         'icon' : 'images/default_pilot.png',
328         'order' : 'F',
329         },
330     'lessonplan' : {
331         'title' : 'Lesson plan',
332         'fields' : ['title', 'lessonTopic', 'subject_area', 'target_group', 'goalsAndObjectives', 'lessonDescription', 'contentLinks', 'methodsLinks', 'toolsLinks', 'evaluationAssessment', 'teacherReflections'],
333         'meta_type' : 'LessonPlan',
334         'icon' : 'images/default_lesson_plan.png',
335         'order' : 'D',
336         },
337     'schoolproject' : {
338         'title' : 'School project',
339         'fields' : ['title', 'aims', 'outcomes', 'subject_area', 'target_group', 'prerequisite', 'duration', 'activities', 'contentLinks', 'methodsLinks', 'toolsLinks', 'evaluation'],
340         'meta_type' : 'SchoolProjectMaterial',
341         'icon' : 'images/default_school_project.png',
342         'order' : 'E',
343         }
344     }
345
346 ALL_LICENSES = (('CreativeCommons', '''Creative Commons Attribution-ShareAlike License'''), ('CreativeCommonsAttribution', 'Creative Commons Attribution License'), ('FreeDocumentationLicense', 'Free Documentation License'), ('PublicDomain', 'Public Domain'))
347 LICENSES = ALL_LICENSES[0:1]
348
349        
350 GLOBALS = globals()
351
352 def to_unicode(s,encoding='utf-8'):
353     """Convenience method for converting strings to unicode."""
354     if not s:
355         return u''
356     while type(s)==ImplicitAcquisitionWrapper:
357         s=s()
358     if type(s)==UnicodeType:
359         return s       
360     return unicode(s,encoding)
361
362 def _genUID():
363     import time, random
364     import sys
365     t = str(int(time.time()))
366     d = "%010d" % random.randint(0, sys.maxint-1)
367     return "%s_%s" % (t, d)
368
369        
370 DEFAULT_ICONS = {
371         'Piece':'images/default_media_piece.png', # shouldn't be called this way
372         'PresentationMaterial':'images/default_presentation.png',
373         'PILOTMaterial':'images/default_pilot.png',
374         'MultimediaMaterial':'images/default_multimedia_page.png',
375         'ExerciseMaterial':'images/default_exercise.png',
376         'LeMillReference':'images/default_reference.png',
377         'LeMillPrintResource':'images/default_printresource.png',
378         'LessonPlan':'images/default_lesson_plan.png',
379         'SchoolProjectMaterial':'images/default_school_project.png',
380         'Tool':'images/default_tool.png',
381         'Activity':'images/default_activity.png',
382         'GroupBlog':'images/default_group.png',
383         'MemberFolder':'images/default_member.png',
384         'Collection':'images/default_collection.png', # doesn't exist
385         'BlogPost':'images/default_member.png', # shouldn't be called this way
386         'Discussion Item': 'images/default_group.png'
387         }
388        
389
390 # Front-page shows only resources that already have stories, no random combinations.
391 GOOD_STORIES_ONLY = True
392
393 TARGET_GROUP = ["pre-school education", "1st grade", "2nd grade", "3rd grade", "4th grade", "5th grade", "6th grade", "7th grade", "8th grade", "9th grade", "10th grade", "11th grade", "12th grade","vocational education", "higher education", "adult education","teachers", "special education", "", None]
394 REPOSITORY = path.join(package_home(globals()), 'Repository/')
395 # path to fonts
396 TTF_FONTS = path.join(package_home(globals()), 'skins/lemill/fonts/')
397
398
399 TARGET_GROUP_TO_LRE_MAPPING = { 'pre-school education': ('U-6', 'LOMv1.0', 'learner', 'LREv3.0', 'pre-school'),
400     '1st grade' : ('6-8', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
401     '2nd grade' : ('7-9', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
402     '3rd grade' : ('8-10', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
403     '4th grade' : ('9-11', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
404     '5th grade' : ('10-12', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
405     '6th grade' : ('11-13', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
406     '7th grade' : ('12-14', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
407     '8th grade' : ('13-15', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
408     '9th grade' : ('14-16', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
409     '10th grade' : ('15-17', 'LOMv1.0', 'learner', 'LREv3.0', 'compulsory education'),
410     '11th grade' : ('16-18', 'LOMv1.0', 'learner', None, None),
411     '12th grade' : ('17-19', 'LOMv1.0', 'learner', None, None),
412     'vocational education' : ('18-U', 'LOMv1.0', 'learner', 'LREv3.0', 'vocational education'),
413     'higher education' : ('18-U', 'LOMv1.0', 'learner', 'LOMv1.0', 'higher education'),
414     'adult education' : ('18-U', 'LOMv1.0', 'learner', 'LREv3.0', 'continuing education'),
415     'teachers' : ('21-U', 'LOMv1.0', 'teacher', None, None),
416     'special education' : ('6-19', 'LOMv1.0', 'learner', 'LREv3.0', 'special education')
417     }
418
419 SUBJECT_AREA_TO_LRE_MAPPING = {'Natural sciences': (875, 'natural sciences'),
420     'Geography': (540, 'geography'),
421     'Chemistry': (195, 'chemistry'),
422     'Physics': (978, 'physics'),
423     'Biology': (144, 'biology'),
424     'Environmental education': (431, 'environmental education'),
425     'Language and literature': (707, 'language and literature'),
426     'Foreign languages': (508, 'foreign language'),
427     'Mathematics': (790, 'mathematics'),
428     'Informatics or ICT': (650, 'informatics'),
429     'Art': (91, 'art'),
430     'Music': (856, 'music'),
431     'History': (590, 'history'),
432     'Religion': (1085, 'religion'),
433     'Philosophy': (968, 'philosophy'),
434     'Ethics': (441, 'ethics'),
435     'Psychology': (1040, 'psychology'),
436     'Social sciences': (1204, 'social sciences'),
437     'Culture': (303, 'culture'),
438     'Citizenship': (209, 'citizenship'),
439     'Politics': (1001, 'politics'),
440     'Economics': (383, 'economics'),
441     'Media education': (798, 'media education'),
442     'Physical education': (974, 'physical education'),
443     'School-community relationship': (1139, 'school-community relationship'),
444     'Educational administration': (186, 'central administration'),
445     'Cross-curricular education': (292, 'cross-curricular education'),
446     }
447
448 PORTAL_TYPE_TO_LRE_MAPPING = {'PresentationMaterial':'presentation',
449     'MultimediaMaterial':'text',
450     'PILOTMaterial':'video',
451     'ExerciseMaterial':'educational game',
452     'LessonPlan':'lesson plan',
453     'SchoolProjectMaterial':'project'
454     }
455
456
457 LANGUAGES=[('aa', 'Afar'),
458     ('ab', 'Abkhazian'),
459     ('af', 'Afrikaans'),
460     ('am', 'Amharic'),
461     ('ar', 'Arabic'),
462     ('as', 'Assamese'),
463     ('ay', 'Aymara'),
464     ('az', 'Azerbaijani'),
465     ('ba', 'Bashkir'),
466     ('be', 'Byelorussian (Belarussian)'),
467     ('bg', 'Bulgarian'),
468     ('bh', 'Bihari'),
469     ('bi', 'Bislama'),
470     ('bn', 'Bengali'),
471     ('bo', 'Tibetan'),
472     ('br', 'Breton'),
473     ('ca', 'Catalan'),
474     ('co', 'Corsican'),
475     ('cs', 'Czech'),
476     ('cy', 'Welsh'),
477     ('da', 'Danish'),
478     ('de', 'German'),
479     ('dz', 'Bhutani'),
480     ('el', 'Greek'),
481     ('en', 'English'),
482     ('eo', 'Esperanto'),
483     ('es', 'Spanish'),
484     ('et', 'Estonian'),
485     ('eu', 'Basque'),
486     ('fa', 'Persian'),
487     ('fi', 'Finnish'),
488     ('fj', 'Fiji'),
489     ('fo', 'Faroese'),
490     ('fr', 'French'),
491     ('fy', 'Frisian'),
492     ('ga', 'Irish (Irish Gaelic)'),
493     ('gd', 'Scots Gaelic (Scottish Gaelic)'),
494     ('gl', 'Galician'),
495     ('gn', 'Guarani'),
496     ('gu', 'Gujarati'),
497     ('gv', 'Manx Gaelic'),
498     ('ha', 'Hausa'),
499     ('he', 'Hebrew'),
500     ('hi', 'Hindi'),
501     ('hr', 'Croatian'),
502     ('hu', 'Hungarian'),
503     ('hy', 'Armenian'),
504     ('ia', 'Interlingua'),
505     ('id', 'Indonesian'),
506     ('ie', 'Interlingue'),
507     ('ik', 'Inupiak'),
508     ('is', 'Icelandic'),
509     ('it', 'Italian'),
510     ('iu', 'Inuktitut'),
511     ('ja', 'Japanese'),
512     ('jw', 'Javanese'),
513     ('ka', 'Georgian'),
514     ('kk', 'Kazakh'),
515     ('kl', 'Greenlandic'),
516     ('km', 'Cambodian'),
517     ('kn', 'Kannada'),
518     ('ko', 'Korean'),
519     ('ks', 'Kashmiri'),
520     ('ku', 'Kurdish'),
521     ('kw', 'Cornish'),
522     ('ky', 'Kirghiz'),
523     ('la', 'Latin'),
524     ('lb', 'Luxemburgish'),
525     ('ln', 'Lingala'),
526     ('lo', 'Laotian'),
527     ('lt', 'Lithuanian'),
528     ('lv', 'Latvian Lettish'),
529     ('mg', 'Malagasy'),
530     ('mi', 'Maori'),
531     ('mk', 'Macedonian'),
532     ('ml', 'Malayalam'),
533     ('mn', 'Mongolian'),
534     ('mo', 'Moldavian'),
535     ('mr', 'Marathi'),
536     ('ms', 'Malay'),
537     ('mt', 'Maltese'),
538     ('my', 'Burmese'),
539     ('na', 'Nauru'),
540     ('ne', 'Nepali'),
541     ('nl', 'Dutch'),
542     ('no', 'Norwegian'),
543     ('oc', 'Occitan'),
544     ('om', 'Oromo'),
545     ('or', 'Oriya'),
546     ('pa', 'Punjabi'),
547     ('pl', 'Polish'),
548     ('ps', 'Pashto'),
549     ('pt', 'Portuguese'),
550     ('pt-br', 'Brazilian Portuguese'),
551     ('qu', 'Quechua'),
552     ('rm', 'Rhaeto-Romance'),
553     ('rn', 'Kirundi'),
554     ('ro', 'Romanian'),
555     ('ru', 'Russian'),
556     ('rw', 'Kiyarwanda'),
557     ('sa', 'Sanskrit'),
558     ('sd', 'Sindhi'),
559     ('se', 'Northern Sami'),
560     ('sg', 'Sangho'),
561     ('sh', 'Serbo-Croatian'),
562     ('si', 'Singhalese'),
563     ('sk', 'Slovak'),
564     ('sl', 'Slovenian'),
565     ('sm', 'Samoan'),
566     ('sn', 'Shona'),
567     ('so', 'Somali'),
568     ('sq', 'Albanian'),
569     ('sr', 'Serbian'),
570     ('ss', 'Siswati'),
571     ('st', 'Sesotho'),
572     ('su', 'Sudanese'),
573     ('sv', 'Swedish'),
574     ('sw', 'Swahili'),
575     ('ta', 'Tamil'),
576     ('te', 'Telugu'),
577     ('tg', 'Tajik'),
578     ('th', 'Thai'),
579     ('ti', 'Tigrinya'),
580     ('tk', 'Turkmen'),
581     ('tl', 'Tagalog'),
582     ('tn', 'Setswana'),
583     ('to', 'Tonga'),
584     ('tr', 'Turkish'),
585     ('ts', 'Tsonga'),
586     ('tt', 'Tatar'),
587     ('tw', 'Twi'),
588     ('ug', 'Uigur'),
589     ('uk', 'Ukrainian'),
590     ('ur', 'Urdu'),
591     ('uz', 'Uzbek'),
592     ('vi', 'Vietnamese'),
593     ('vo', 'Volapuk'),
594     ('wo', 'Wolof'),
595     ('xh', 'Xhosa'),
596     ('yi', 'Yiddish'),
597     ('yo', 'Yorouba'),
598     ('za', 'Zhuang'),
599     ('zh', 'Chinese'),
600     ('zu', 'Zulu')
601 ]
602 LANGUAGES.sort(lambda x,y:cmp(x[1], y[1]))
603 # Put language neutral at the top.
604 LANGUAGES.insert(0,('',u'Language neutral (site default)'))
605 LANGUAGES_DICT=dict(LANGUAGES)
606  
Note: See TracBrowser for help on using the browser.