PageRenderTime 60ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/askbot/const/__init__.py

https://github.com/sagarun/askbot-devel
Python | 304 lines | 248 code | 25 blank | 31 comment | 5 complexity | aff2b4437477a26075910febbd2fe5ad MD5 | raw file
  1. # encoding:utf-8
  2. """
  3. All constants could be used in other modules
  4. For reasons that models, views can't have unicode
  5. text in this project, all unicode text go here.
  6. """
  7. from django.utils.translation import ugettext as _
  8. import re
  9. CLOSE_REASONS = (
  10. (1, _('duplicate question')),
  11. (2, _('question is off-topic or not relevant')),
  12. (3, _('too subjective and argumentative')),
  13. (4, _('not a real question')),
  14. (5, _('the question is answered, right answer was accepted')),
  15. (6, _('question is not relevant or outdated')),
  16. (7, _('question contains offensive or malicious remarks')),
  17. (8, _('spam or advertising')),
  18. (9, _('too localized')),
  19. )
  20. TYPE_REPUTATION = (
  21. (1, 'gain_by_upvoted'),
  22. (2, 'gain_by_answer_accepted'),
  23. (3, 'gain_by_accepting_answer'),
  24. (4, 'gain_by_downvote_canceled'),
  25. (5, 'gain_by_canceling_downvote'),
  26. (-1, 'lose_by_canceling_accepted_answer'),
  27. (-2, 'lose_by_accepted_answer_cancled'),
  28. (-3, 'lose_by_downvoted'),
  29. (-4, 'lose_by_flagged'),
  30. (-5, 'lose_by_downvoting'),
  31. (-6, 'lose_by_flagged_lastrevision_3_times'),
  32. (-7, 'lose_by_flagged_lastrevision_5_times'),
  33. (-8, 'lose_by_upvote_canceled'),
  34. #for reputation type 10 Repute.comment field is required
  35. (10, 'assigned_by_moderator'),
  36. )
  37. #do not translate keys
  38. POST_SORT_METHODS = (
  39. ('age-desc', _('newest')),
  40. ('age-asc', _('oldest')),
  41. ('activity-desc', _('active')),
  42. ('activity-asc', _('inactive')),
  43. ('answers-desc', _('hottest')),
  44. ('answers-asc', _('coldest')),
  45. ('votes-desc', _('most voted')),
  46. ('votes-asc', _('least voted')),
  47. ('relevance-desc', _('relevance')),
  48. )
  49. #todo: add assertion here that all sort methods are unique
  50. #because they are keys to the hash used in implementations
  51. #of Q.run_advanced_search
  52. DEFAULT_POST_SORT_METHOD = 'activity-desc'
  53. POST_SCOPE_LIST = (
  54. ('all', _('all')),
  55. ('unanswered', _('unanswered')),
  56. ('favorite', _('favorite')),
  57. )
  58. DEFAULT_POST_SCOPE = 'all'
  59. TAG_LIST_FORMAT_CHOICES = (
  60. ('list', _('list')),
  61. ('cloud', _('cloud')),
  62. )
  63. PAGE_SIZE_CHOICES = (('10', '10',), ('30', '30',), ('50', '50',),)
  64. ANSWERS_PAGE_SIZE = 10
  65. #todo: remove this duplication
  66. QUESTIONS_PER_PAGE_USER_CHOICES = (
  67. (10, u'10'),
  68. (30, u'30'),
  69. (50, u'50'),
  70. )
  71. UNANSWERED_QUESTION_MEANING_CHOICES = (
  72. ('NO_ANSWERS', _('Question has no answers')),
  73. ('NO_ACCEPTED_ANSWERS', _('Question has no accepted answers')),
  74. )
  75. #todo: implement this
  76. # ('NO_UPVOTED_ANSWERS',),
  77. #)
  78. #todo:
  79. #this probably needs to be language-specific
  80. #and selectable/changeable from the admin interface
  81. #however it will be hard to expect that people will type
  82. #correct regexes - plus this must be an anchored regex
  83. #to do full string match
  84. TAG_CHARS = '\w\+\.\-#'
  85. TAG_REGEX = r'^[%s]+$' % TAG_CHARS
  86. TAG_SPLIT_REGEX = r'[ ,]+'
  87. EMAIL_REGEX = re.compile(r'\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b', re.I)
  88. TYPE_ACTIVITY_ASK_QUESTION = 1
  89. TYPE_ACTIVITY_ANSWER = 2
  90. TYPE_ACTIVITY_COMMENT_QUESTION = 3
  91. TYPE_ACTIVITY_COMMENT_ANSWER = 4
  92. TYPE_ACTIVITY_UPDATE_QUESTION = 5
  93. TYPE_ACTIVITY_UPDATE_ANSWER = 6
  94. TYPE_ACTIVITY_PRIZE = 7
  95. TYPE_ACTIVITY_MARK_ANSWER = 8
  96. TYPE_ACTIVITY_VOTE_UP = 9
  97. TYPE_ACTIVITY_VOTE_DOWN = 10
  98. TYPE_ACTIVITY_CANCEL_VOTE = 11
  99. TYPE_ACTIVITY_DELETE_QUESTION = 12
  100. TYPE_ACTIVITY_DELETE_ANSWER = 13
  101. TYPE_ACTIVITY_MARK_OFFENSIVE = 14
  102. TYPE_ACTIVITY_UPDATE_TAGS = 15
  103. TYPE_ACTIVITY_FAVORITE = 16
  104. TYPE_ACTIVITY_USER_FULL_UPDATED = 17
  105. TYPE_ACTIVITY_EMAIL_UPDATE_SENT = 18
  106. TYPE_ACTIVITY_MENTION = 19
  107. TYPE_ACTIVITY_UNANSWERED_REMINDER_SENT = 20
  108. TYPE_ACTIVITY_ACCEPT_ANSWER_REMINDER_SENT = 21
  109. #TYPE_ACTIVITY_EDIT_QUESTION = 17
  110. #TYPE_ACTIVITY_EDIT_ANSWER = 18
  111. #todo: rename this to TYPE_ACTIVITY_CHOICES
  112. TYPE_ACTIVITY = (
  113. (TYPE_ACTIVITY_ASK_QUESTION, _('asked a question')),
  114. (TYPE_ACTIVITY_ANSWER, _('answered a question')),
  115. (TYPE_ACTIVITY_COMMENT_QUESTION, _('commented question')),
  116. (TYPE_ACTIVITY_COMMENT_ANSWER, _('commented answer')),
  117. (TYPE_ACTIVITY_UPDATE_QUESTION, _('edited question')),
  118. (TYPE_ACTIVITY_UPDATE_ANSWER, _('edited answer')),
  119. (TYPE_ACTIVITY_PRIZE, _('received award')),
  120. (TYPE_ACTIVITY_MARK_ANSWER, _('marked best answer')),
  121. (TYPE_ACTIVITY_VOTE_UP, _('upvoted')),
  122. (TYPE_ACTIVITY_VOTE_DOWN, _('downvoted')),
  123. (TYPE_ACTIVITY_CANCEL_VOTE, _('canceled vote')),
  124. (TYPE_ACTIVITY_DELETE_QUESTION, _('deleted question')),
  125. (TYPE_ACTIVITY_DELETE_ANSWER, _('deleted answer')),
  126. (TYPE_ACTIVITY_MARK_OFFENSIVE, _('marked offensive')),
  127. (TYPE_ACTIVITY_UPDATE_TAGS, _('updated tags')),
  128. (TYPE_ACTIVITY_FAVORITE, _('selected favorite')),
  129. (TYPE_ACTIVITY_USER_FULL_UPDATED, _('completed user profile')),
  130. (TYPE_ACTIVITY_EMAIL_UPDATE_SENT, _('email update sent to user')),
  131. (
  132. TYPE_ACTIVITY_UNANSWERED_REMINDER_SENT,
  133. _('reminder about unanswered questions sent'),
  134. ),
  135. (
  136. TYPE_ACTIVITY_ACCEPT_ANSWER_REMINDER_SENT,
  137. _('reminder about accepting the best answer sent'),
  138. ),
  139. (TYPE_ACTIVITY_MENTION, _('mentioned in the post')),
  140. )
  141. #MENTION activity is added implicitly, unfortunately
  142. RESPONSE_ACTIVITY_TYPES_FOR_INSTANT_NOTIFICATIONS = (
  143. TYPE_ACTIVITY_COMMENT_QUESTION,
  144. TYPE_ACTIVITY_COMMENT_ANSWER,
  145. TYPE_ACTIVITY_UPDATE_ANSWER,
  146. TYPE_ACTIVITY_UPDATE_QUESTION,
  147. TYPE_ACTIVITY_ANSWER,
  148. TYPE_ACTIVITY_ASK_QUESTION,
  149. )
  150. #the same as for instant notifications for now
  151. #MENTION activity is added implicitly, unfortunately
  152. RESPONSE_ACTIVITY_TYPES_FOR_DISPLAY = (
  153. TYPE_ACTIVITY_ANSWER,
  154. TYPE_ACTIVITY_ASK_QUESTION,
  155. TYPE_ACTIVITY_COMMENT_QUESTION,
  156. TYPE_ACTIVITY_COMMENT_ANSWER,
  157. TYPE_ACTIVITY_UPDATE_ANSWER,
  158. TYPE_ACTIVITY_UPDATE_QUESTION,
  159. # TYPE_ACTIVITY_PRIZE,
  160. # TYPE_ACTIVITY_MARK_ANSWER,
  161. # TYPE_ACTIVITY_VOTE_UP,
  162. # TYPE_ACTIVITY_VOTE_DOWN,
  163. # TYPE_ACTIVITY_CANCEL_VOTE,
  164. # TYPE_ACTIVITY_DELETE_QUESTION,
  165. # TYPE_ACTIVITY_DELETE_ANSWER,
  166. # TYPE_ACTIVITY_MARK_OFFENSIVE,
  167. # TYPE_ACTIVITY_FAVORITE,
  168. )
  169. RESPONSE_ACTIVITY_TYPE_MAP_FOR_TEMPLATES = {
  170. TYPE_ACTIVITY_COMMENT_QUESTION: 'question_comment',
  171. TYPE_ACTIVITY_COMMENT_ANSWER: 'answer_comment',
  172. TYPE_ACTIVITY_UPDATE_ANSWER: 'answer_update',
  173. TYPE_ACTIVITY_UPDATE_QUESTION: 'question_update',
  174. TYPE_ACTIVITY_ANSWER: 'new_answer',
  175. TYPE_ACTIVITY_ASK_QUESTION: 'new_question',
  176. }
  177. assert(
  178. set(RESPONSE_ACTIVITY_TYPES_FOR_INSTANT_NOTIFICATIONS) \
  179. == set(RESPONSE_ACTIVITY_TYPE_MAP_FOR_TEMPLATES.keys())
  180. )
  181. TYPE_RESPONSE = {
  182. 'QUESTION_ANSWERED' : _('question_answered'),
  183. 'QUESTION_COMMENTED': _('question_commented'),
  184. 'ANSWER_COMMENTED' : _('answer_commented'),
  185. 'ANSWER_ACCEPTED' : _('answer_accepted'),
  186. }
  187. POST_STATUS = {
  188. 'closed' : _('[closed]'),
  189. 'deleted' : _('[deleted]'),
  190. 'default_version' : _('initial version'),
  191. 'retagged' : _('retagged'),
  192. }
  193. #choices used in email and display filters
  194. INCLUDE_ALL = 0
  195. EXCLUDE_IGNORED = 1
  196. INCLUDE_INTERESTING = 2
  197. TAG_FILTER_STRATEGY_CHOICES = (
  198. (INCLUDE_ALL, _('off')),
  199. (EXCLUDE_IGNORED, _('exclude ignored')),
  200. (INCLUDE_INTERESTING, _('only selected')),
  201. )
  202. NOTIFICATION_DELIVERY_SCHEDULE_CHOICES = (
  203. ('i',_('instantly')),
  204. ('d',_('daily')),
  205. ('w',_('weekly')),
  206. ('n',_('no email')),
  207. )
  208. USERS_PAGE_SIZE = 28#todo: move it to settings?
  209. USERNAME_REGEX_STRING = r'^[\w \-.@+\']+$'
  210. GRAVATAR_TYPE_CHOICES = (
  211. ('identicon',_('identicon')),
  212. ('mm',_('mystery-man')),
  213. ('monsterid',_('monsterid')),
  214. ('wavatar',_('wavatar')),
  215. ('retro',_('retro')),
  216. )
  217. #chars that can go before or after @mention
  218. TWITTER_STYLE_MENTION_TERMINATION_CHARS = '\n ;:,.!?<>"\''
  219. COMMENT_HARD_MAX_LENGTH = 2048
  220. #user status ch
  221. USER_STATUS_CHOICES = (
  222. #in addition to these there is administrator
  223. #admin status is determined by the User.is_superuser() call
  224. ('m', _('moderator')), #user with moderation privilege
  225. ('a', _('approved')), #regular user
  226. ('w', _('watched')), #regular user placed on the moderation watch
  227. ('s', _('suspended')), #suspended user who cannot post new stuff
  228. ('b', _('blocked')), #blocked
  229. )
  230. DEFAULT_USER_STATUS = 'w'
  231. #number of items to show in user views
  232. USER_VIEW_DATA_SIZE = 50
  233. #not really dependency, but external links, which it would
  234. #be nice to test for correctness from time to time
  235. DEPENDENCY_URLS = {
  236. 'akismet': 'https://akismet.com/signup/',
  237. 'cc-by-sa': 'http://creativecommons.org/licenses/by-sa/3.0/legalcode',
  238. 'embedding-video': \
  239. 'http://askbot.org/doc/optional-modules.html#embedding-video',
  240. 'favicon': 'http://en.wikipedia.org/wiki/Favicon',
  241. 'facebook-apps': 'http://www.facebook.com/developers/createapp.php',
  242. 'google-webmaster-tools': 'https://www.google.com/webmasters/tools/home',
  243. 'identica-apps': 'http://identi.ca/settings/oauthapps',
  244. 'noscript': 'https://www.google.com/support/bin/answer.py?answer=23852',
  245. 'linkedin-apps': 'https://www.linkedin.com/secure/developer',
  246. 'mathjax': 'http://www.mathjax.org/resources/docs/?installation.html',
  247. 'recaptcha': 'http://google.com/recaptcha',
  248. 'twitter-apps': 'http://dev.twitter.com/apps/',
  249. }
  250. PASSWORD_MIN_LENGTH = 8
  251. GOLD_BADGE = 1
  252. SILVER_BADGE = 2
  253. BRONZE_BADGE = 3
  254. BADGE_TYPE_CHOICES = (
  255. (GOLD_BADGE, _('gold')),
  256. (SILVER_BADGE, _('silver')),
  257. (BRONZE_BADGE, _('bronze')),
  258. )
  259. BADGE_CSS_CLASSES = {
  260. GOLD_BADGE: 'badge1',
  261. SILVER_BADGE: 'badge2',
  262. BRONZE_BADGE: 'badge3',
  263. }
  264. BADGE_DISPLAY_SYMBOL = '&#9679;'
  265. MIN_REPUTATION = 1
  266. AVATAR_STATUS_CHOICE = (
  267. ('n', _('None')),
  268. ('g', _('Gravatar')),#only if user has real uploaded gravatar
  269. ('a', _('Uploaded Avatar')),#avatar uploaded locally - with django-avatar app
  270. )
  271. #an exception import * because that file has only strings
  272. from askbot.const.message_keys import *