summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdolfo Fitoria <fitoria@fitoria-laptop.(none)>2010-02-15 23:18:02 -0600
committerAdolfo Fitoria <fitoria@fitoria-laptop.(none)>2010-02-15 23:18:02 -0600
commit1e7bd132df5f56f397b555c7481a635c9d66a56a (patch)
tree54aac7789eb445d3d01eaea36f2956e386bb0086
parentd276802efa5899ccb568de1b4c445d54ea72c42d (diff)
parent89131389eb631456a0bdaa3a705488d43d0ced9b (diff)
downloadaskbot-1e7bd132df5f56f397b555c7481a635c9d66a56a.tar.gz
askbot-1e7bd132df5f56f397b555c7481a635c9d66a56a.tar.bz2
askbot-1e7bd132df5f56f397b555c7481a635c9d66a56a.zip
Merge commit 'osqa/master'
Conflicts: forum/skins/default/media/js/wmd/wmd.js forum/skins/default/templates/base.html forum/skins/default/templates/base_content.html forum/views.py locale/en/LC_MESSAGES/django.mo locale/en/LC_MESSAGES/django.po settings_local.py.dist
-rw-r--r--.gitignore1
-rw-r--r--INSTALL78
-rw-r--r--PENDING32
-rw-r--r--TODO3
-rw-r--r--WISH_LIST10
-rw-r--r--context.py1
-rwxr-xr-xfbconnect/fb.py9
-rwxr-xr-xfbconnect/urls.py5
-rwxr-xr-xfbconnect/views.py33
-rw-r--r--forum/__init__.py1
-rw-r--r--forum/forms.py.orig352
-rw-r--r--forum/models.py112
-rw-r--r--forum/skins/README23
-rw-r--r--forum/skins/__init__.py57
-rw-r--r--forum/skins/common/media/README1
-rw-r--r--forum/skins/default/media/images/blue-up-arrow-h18px.png (renamed from templates/content/images/blue-up-arrow-h18px.png)bin593 -> 593 bytes
-rw-r--r--forum/skins/default/media/images/box-arrow.gif (renamed from templates/content/images/box-arrow.gif)bin69 -> 69 bytes
-rw-r--r--forum/skins/default/media/images/bullet_green.gif (renamed from templates/content/images/bullet_green.gif)bin64 -> 64 bytes
-rw-r--r--forum/skins/default/media/images/cc-88x31.png (renamed from templates/content/images/cc-88x31.png)bin5460 -> 5460 bytes
-rw-r--r--forum/skins/default/media/images/cc-wiki.png (renamed from templates/content/images/cc-wiki.png)bin2333 -> 2333 bytes
-rw-r--r--forum/skins/default/media/images/close-small-dark.png (renamed from templates/content/images/close-small-dark.png)bin226 -> 226 bytes
-rw-r--r--forum/skins/default/media/images/close-small-hover.png (renamed from templates/content/images/close-small-hover.png)bin337 -> 337 bytes
-rw-r--r--forum/skins/default/media/images/close-small.png (renamed from templates/content/images/close-small.png)bin293 -> 293 bytes
-rw-r--r--forum/skins/default/media/images/dash.gif (renamed from templates/content/images/dash.gif)bin44 -> 44 bytes
-rw-r--r--forum/skins/default/media/images/djangomade124x25_grey.gif (renamed from templates/content/images/djangomade124x25_grey.gif)bin2035 -> 2035 bytes
-rw-r--r--forum/skins/default/media/images/dot-g.gif (renamed from templates/content/images/dot-g.gif)bin61 -> 61 bytes
-rw-r--r--forum/skins/default/media/images/dot-list.gif (renamed from templates/content/images/dot-list.gif)bin56 -> 56 bytes
-rw-r--r--forum/skins/default/media/images/edit.png (renamed from templates/content/images/edit.png)bin758 -> 758 bytes
-rw-r--r--forum/skins/default/media/images/expander-arrow-hide.gif (renamed from templates/content/images/expander-arrow-hide.gif)bin126 -> 126 bytes
-rw-r--r--forum/skins/default/media/images/expander-arrow-show.gif (renamed from templates/content/images/expander-arrow-show.gif)bin135 -> 135 bytes
-rw-r--r--forum/skins/default/media/images/favicon.gif (renamed from templates/content/images/favicon.gif)bin3918 -> 3918 bytes
-rw-r--r--forum/skins/default/media/images/feed-icon-small.png (renamed from templates/content/images/feed-icon-small.png)bin689 -> 689 bytes
-rw-r--r--forum/skins/default/media/images/gray-up-arrow-h18px.png (renamed from templates/content/images/gray-up-arrow-h18px.png)bin383 -> 383 bytes
-rw-r--r--forum/skins/default/media/images/grippie.png (renamed from templates/content/images/grippie.png)bin162 -> 162 bytes
-rw-r--r--forum/skins/default/media/images/indicator.gif (renamed from templates/content/images/indicator.gif)bin2545 -> 2545 bytes
-rw-r--r--forum/skins/default/media/images/logo.gif (renamed from templates/content/images/logo.gif)bin2114 -> 2114 bytes
-rw-r--r--forum/skins/default/media/images/logo.png (renamed from templates/content/images/logo.png)bin2081 -> 2081 bytes
-rw-r--r--forum/skins/default/media/images/logo1.png (renamed from templates/content/images/logo1.png)bin2752 -> 2752 bytes
-rw-r--r--forum/skins/default/media/images/logo2.png (renamed from templates/content/images/logo2.png)bin2124 -> 2124 bytes
-rw-r--r--forum/skins/default/media/images/medala.gif (renamed from templates/content/images/medala.gif)bin801 -> 801 bytes
-rw-r--r--forum/skins/default/media/images/medala_on.gif (renamed from templates/content/images/medala_on.gif)bin957 -> 957 bytes
-rw-r--r--forum/skins/default/media/images/new.gif (renamed from templates/content/images/new.gif)bin635 -> 635 bytes
-rw-r--r--forum/skins/default/media/images/nophoto.png (renamed from templates/content/images/nophoto.png)bin696 -> 696 bytes
-rw-r--r--forum/skins/default/media/images/openid.gif (renamed from templates/content/images/openid.gif)bin910 -> 910 bytes
-rw-r--r--forum/skins/default/media/images/openid/aol.gif (renamed from templates/content/images/openid/aol.gif)bin2205 -> 2205 bytes
-rw-r--r--forum/skins/default/media/images/openid/blogger.ico (renamed from templates/content/images/openid/blogger.ico)bin3638 -> 3638 bytes
-rw-r--r--forum/skins/default/media/images/openid/claimid.ico (renamed from templates/content/images/openid/claimid.ico)bin3638 -> 3638 bytes
-rw-r--r--forum/skins/default/media/images/openid/facebook.gif (renamed from templates/content/images/openid/facebook.gif)bin2075 -> 2075 bytes
-rw-r--r--forum/skins/default/media/images/openid/flickr.ico (renamed from templates/content/images/openid/flickr.ico)bin1150 -> 1150 bytes
-rw-r--r--forum/skins/default/media/images/openid/google.gif (renamed from templates/content/images/openid/google.gif)bin1596 -> 1596 bytes
-rw-r--r--forum/skins/default/media/images/openid/livejournal.ico (renamed from templates/content/images/openid/livejournal.ico)bin5222 -> 5222 bytes
-rw-r--r--forum/skins/default/media/images/openid/myopenid.ico (renamed from templates/content/images/openid/myopenid.ico)bin2862 -> 2862 bytes
-rw-r--r--forum/skins/default/media/images/openid/openid-inputicon.gif (renamed from templates/content/images/openid/openid-inputicon.gif)bin237 -> 237 bytes
-rw-r--r--forum/skins/default/media/images/openid/openid.gif (renamed from templates/content/images/openid/openid.gif)bin740 -> 740 bytes
-rw-r--r--forum/skins/default/media/images/openid/technorati.ico (renamed from templates/content/images/openid/technorati.ico)bin2294 -> 2294 bytes
-rw-r--r--forum/skins/default/media/images/openid/verisign.ico (renamed from templates/content/images/openid/verisign.ico)bin4710 -> 4710 bytes
-rw-r--r--forum/skins/default/media/images/openid/vidoop.ico (renamed from templates/content/images/openid/vidoop.ico)bin1406 -> 1406 bytes
-rw-r--r--forum/skins/default/media/images/openid/wordpress.ico (renamed from templates/content/images/openid/wordpress.ico)bin1150 -> 1150 bytes
-rw-r--r--forum/skins/default/media/images/openid/yahoo.gif (renamed from templates/content/images/openid/yahoo.gif)bin1682 -> 1682 bytes
-rw-r--r--forum/skins/default/media/images/quest-bg.gif (renamed from templates/content/images/quest-bg.gif)bin294 -> 294 bytes
-rw-r--r--forum/skins/default/media/images/vote-accepted-on.png (renamed from templates/content/images/vote-accepted-on.png)bin1124 -> 1124 bytes
-rw-r--r--forum/skins/default/media/images/vote-accepted.png (renamed from templates/content/images/vote-accepted.png)bin1058 -> 1058 bytes
-rw-r--r--forum/skins/default/media/images/vote-arrow-down-on.png (renamed from templates/content/images/vote-arrow-down-on.png)bin905 -> 905 bytes
-rw-r--r--forum/skins/default/media/images/vote-arrow-down.png (renamed from templates/content/images/vote-arrow-down.png)bin876 -> 876 bytes
-rw-r--r--forum/skins/default/media/images/vote-arrow-up-on.png (renamed from templates/content/images/vote-arrow-up-on.png)bin906 -> 906 bytes
-rw-r--r--forum/skins/default/media/images/vote-arrow-up.png (renamed from templates/content/images/vote-arrow-up.png)bin843 -> 843 bytes
-rw-r--r--forum/skins/default/media/images/vote-favorite-off.png (renamed from templates/content/images/vote-favorite-off.png)bin930 -> 930 bytes
-rw-r--r--forum/skins/default/media/images/vote-favorite-on.png (renamed from templates/content/images/vote-favorite-on.png)bin1023 -> 1023 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/aol.gif (renamed from templates/content/jquery-openid/images/aol.gif)bin2205 -> 2205 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/blogger-1.png (renamed from templates/content/jquery-openid/images/blogger-1.png)bin432 -> 432 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/blogger.ico (renamed from templates/content/jquery-openid/images/blogger.ico)bin3638 -> 3638 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/claimid-0.png (renamed from templates/content/jquery-openid/images/claimid-0.png)bin629 -> 629 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/claimid.ico (renamed from templates/content/jquery-openid/images/claimid.ico)bin3638 -> 3638 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/facebook.gif (renamed from templates/content/jquery-openid/images/facebook.gif)bin2075 -> 2075 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/flickr.ico (renamed from templates/content/jquery-openid/images/flickr.ico)bin1150 -> 1150 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/flickr.png (renamed from templates/content/jquery-openid/images/flickr.png)bin426 -> 426 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/google.gif (renamed from templates/content/jquery-openid/images/google.gif)bin1596 -> 1596 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/livejournal-1.png (renamed from templates/content/jquery-openid/images/livejournal-1.png)bin713 -> 713 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/livejournal.ico (renamed from templates/content/jquery-openid/images/livejournal.ico)bin5222 -> 5222 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/myopenid-2.png (renamed from templates/content/jquery-openid/images/myopenid-2.png)bin511 -> 511 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/myopenid.ico (renamed from templates/content/jquery-openid/images/myopenid.ico)bin2862 -> 2862 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/openid-inputicon.gif (renamed from templates/content/jquery-openid/images/openid-inputicon.gif)bin237 -> 237 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/openid.gif (renamed from templates/content/jquery-openid/images/openid.gif)bin740 -> 740 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/openidico.png (renamed from templates/content/jquery-openid/images/openidico.png)bin654 -> 654 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/openidico16.png (renamed from templates/content/jquery-openid/images/openidico16.png)bin554 -> 554 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/technorati-1.png (renamed from templates/content/jquery-openid/images/technorati-1.png)bin606 -> 606 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/technorati.ico (renamed from templates/content/jquery-openid/images/technorati.ico)bin2294 -> 2294 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/verisign-2.png (renamed from templates/content/jquery-openid/images/verisign-2.png)bin859 -> 859 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/verisign.ico (renamed from templates/content/jquery-openid/images/verisign.ico)bin4710 -> 4710 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/vidoop.ico (renamed from templates/content/jquery-openid/images/vidoop.ico)bin1406 -> 1406 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/vidoop.png (renamed from templates/content/jquery-openid/images/vidoop.png)bin499 -> 499 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/wordpress.ico (renamed from templates/content/jquery-openid/images/wordpress.ico)bin1150 -> 1150 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/wordpress.png (renamed from templates/content/jquery-openid/images/wordpress.png)bin566 -> 566 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/images/yahoo.gif (renamed from templates/content/jquery-openid/images/yahoo.gif)bin1682 -> 1682 bytes
-rw-r--r--forum/skins/default/media/jquery-openid/jquery.openid.js (renamed from templates/content/jquery-openid/jquery.openid.js)0
-rw-r--r--forum/skins/default/media/jquery-openid/openid.css (renamed from templates/content/jquery-openid/openid.css)0
-rw-r--r--forum/skins/default/media/js/com.cnprog.admin.js (renamed from templates/content/js/com.cnprog.admin.js)0
-rw-r--r--forum/skins/default/media/js/com.cnprog.editor.js (renamed from templates/content/js/com.cnprog.editor.js)0
-rw-r--r--forum/skins/default/media/js/com.cnprog.i18n.js (renamed from templates/content/js/com.cnprog.i18n.js)0
-rw-r--r--forum/skins/default/media/js/com.cnprog.post.js (renamed from templates/content/js/com.cnprog.post.js)28
-rw-r--r--forum/skins/default/media/js/com.cnprog.tag_selector.js (renamed from templates/content/js/com.cnprog.tag_selector.js)6
-rw-r--r--forum/skins/default/media/js/com.cnprog.utils.js (renamed from templates/content/js/com.cnprog.utils.js)18
-rw-r--r--forum/skins/default/media/js/compress.bat (renamed from templates/content/js/compress.bat)0
-rw-r--r--forum/skins/default/media/js/excanvas.pack.js (renamed from templates/content/js/excanvas.pack.js)0
-rw-r--r--forum/skins/default/media/js/flot-build.bat (renamed from templates/content/js/flot-build.bat)0
-rw-r--r--forum/skins/default/media/js/jquery-1.2.6.js (renamed from templates/content/js/jquery-1.2.6.js)0
-rw-r--r--forum/skins/default/media/js/jquery-1.2.6.min.js (renamed from templates/content/js/jquery-1.2.6.min.js)0
-rw-r--r--forum/skins/default/media/js/jquery.ajaxfileupload.js (renamed from templates/content/js/jquery.ajaxfileupload.js)0
-rw-r--r--forum/skins/default/media/js/jquery.flot.js (renamed from templates/content/js/jquery.flot.js)0
-rw-r--r--forum/skins/default/media/js/jquery.flot.pack.js (renamed from templates/content/js/jquery.flot.pack.js)0
-rw-r--r--forum/skins/default/media/js/jquery.form.js (renamed from templates/content/js/jquery.form.js)0
-rw-r--r--forum/skins/default/media/js/jquery.i18n.js (renamed from templates/content/js/jquery.i18n.js)0
-rw-r--r--forum/skins/default/media/js/jquery.openid.js (renamed from templates/content/js/jquery.openid.js)2
-rw-r--r--forum/skins/default/media/js/jquery.validate.pack.js (renamed from templates/content/js/jquery.validate.pack.js)0
-rw-r--r--forum/skins/default/media/js/se_hilite.js (renamed from templates/content/js/se_hilite.js)0
-rw-r--r--forum/skins/default/media/js/se_hilite_src.js (renamed from templates/content/js/se_hilite_src.js)0
-rw-r--r--forum/skins/default/media/js/wmd/images/wmd-buttons.png (renamed from templates/content/js/wmd/images/wmd-buttons.png)bin7465 -> 7465 bytes
-rw-r--r--forum/skins/default/media/js/wmd/showdown-min.js (renamed from templates/content/js/wmd/showdown-min.js)0
-rw-r--r--forum/skins/default/media/js/wmd/showdown.js (renamed from templates/content/js/wmd/showdown.js)0
-rw-r--r--forum/skins/default/media/js/wmd/wmd-min.js1
-rw-r--r--forum/skins/default/media/js/wmd/wmd-test.html (renamed from templates/content/js/wmd/wmd-test.html)0
-rw-r--r--forum/skins/default/media/js/wmd/wmd.css (renamed from templates/content/js/wmd/wmd.css)0
-rw-r--r--forum/skins/default/media/js/wmd/wmd.js (renamed from templates/content/js/wmd/wmd.js)10
-rw-r--r--forum/skins/default/media/js/yuicompressor-2.4.2.jar (renamed from templates/content/js/yuicompressor-2.4.2.jar)bin851219 -> 851219 bytes
-rw-r--r--forum/skins/default/media/style/default.css (renamed from templates/content/style/default.css)6
-rw-r--r--forum/skins/default/media/style/jquery.autocomplete.css (renamed from templates/content/style/jquery.autocomplete.css)0
-rw-r--r--forum/skins/default/media/style/openid.css (renamed from templates/content/style/openid.css)0
-rw-r--r--forum/skins/default/media/style/prettify.css (renamed from templates/content/style/prettify.css)0
-rw-r--r--forum/skins/default/media/style/style.css (renamed from templates/content/style/style.css)3
-rw-r--r--forum/skins/default/templates/404.html (renamed from templates/404.html)0
-rw-r--r--forum/skins/default/templates/500.html (renamed from templates/500.html)0
-rw-r--r--forum/skins/default/templates/about.html (renamed from templates/about.html)0
-rw-r--r--forum/skins/default/templates/answer_edit.html (renamed from templates/answer_edit.html)12
-rw-r--r--forum/skins/default/templates/answer_edit_tips.html (renamed from templates/answer_edit_tips.html)0
-rw-r--r--forum/skins/default/templates/ask.html (renamed from templates/ask.html)12
-rw-r--r--forum/skins/default/templates/authopenid/changeemail.html (renamed from templates/authopenid/changeemail.html)0
-rw-r--r--forum/skins/default/templates/authopenid/changeopenid.html (renamed from templates/authopenid/changeopenid.html)0
-rw-r--r--forum/skins/default/templates/authopenid/changepw.html (renamed from templates/authopenid/changepw.html)0
-rw-r--r--forum/skins/default/templates/authopenid/complete.html (renamed from templates/authopenid/complete.html)3
-rw-r--r--forum/skins/default/templates/authopenid/confirm_email.txt (renamed from templates/authopenid/confirm_email.txt)0
-rw-r--r--forum/skins/default/templates/authopenid/delete.html (renamed from templates/authopenid/delete.html)0
-rw-r--r--forum/skins/default/templates/authopenid/email_validation.txt (renamed from templates/authopenid/email_validation.txt)0
-rw-r--r--forum/skins/default/templates/authopenid/external_legacy_login_info.html (renamed from templates/authopenid/external_legacy_login_info.html)0
-rw-r--r--forum/skins/default/templates/authopenid/failure.html (renamed from templates/authopenid/failure.html)0
-rw-r--r--forum/skins/default/templates/authopenid/sendpw.html (renamed from templates/authopenid/sendpw.html)0
-rw-r--r--forum/skins/default/templates/authopenid/sendpw_email.txt (renamed from templates/authopenid/sendpw_email.txt)0
-rw-r--r--forum/skins/default/templates/authopenid/settings.html (renamed from templates/authopenid/settings.html)0
-rwxr-xr-xforum/skins/default/templates/authopenid/signin.html (renamed from templates/authopenid/signin.html)38
-rw-r--r--forum/skins/default/templates/authopenid/signup.html (renamed from templates/authopenid/signup.html)6
-rw-r--r--forum/skins/default/templates/authopenid/yadis.xrdf (renamed from templates/authopenid/yadis.xrdf)0
-rw-r--r--forum/skins/default/templates/badge.html (renamed from templates/badge.html)0
-rw-r--r--forum/skins/default/templates/badges.html (renamed from templates/badges.html)0
-rwxr-xr-xforum/skins/default/templates/base.html (renamed from templates/base.html)35
-rw-r--r--forum/skins/default/templates/base_content.html (renamed from templates/base_content.html)43
-rw-r--r--forum/skins/default/templates/book.html (renamed from templates/book.html)8
-rw-r--r--forum/skins/default/templates/close.html (renamed from templates/close.html)0
-rw-r--r--forum/skins/default/templates/edit_user_email_feeds_form.html (renamed from templates/edit_user_email_feeds_form.html)0
-rw-r--r--forum/skins/default/templates/faq.html (renamed from templates/faq.html)0
-rwxr-xr-xforum/skins/default/templates/fbconnect/xd_receiver.html10
-rw-r--r--forum/skins/default/templates/feedback.html (renamed from templates/feedback.html)0
-rw-r--r--forum/skins/default/templates/feedback_email.txt (renamed from templates/feedback_email.txt)0
-rw-r--r--forum/skins/default/templates/feeds/rss_description.html (renamed from templates/feeds/rss_description.html)0
-rw-r--r--forum/skins/default/templates/feeds/rss_title.html (renamed from templates/feeds/rss_title.html)0
-rw-r--r--forum/skins/default/templates/footer.html (renamed from templates/footer.html)2
-rw-r--r--forum/skins/default/templates/header.html (renamed from templates/header.html)2
-rw-r--r--forum/skins/default/templates/index.html (renamed from templates/index.html)10
-rw-r--r--forum/skins/default/templates/logout.html (renamed from templates/logout.html)0
-rw-r--r--forum/skins/default/templates/notarobot.html (renamed from templates/notarobot.html)0
-rw-r--r--forum/skins/default/templates/pagesize.html (renamed from templates/pagesize.html)0
-rw-r--r--forum/skins/default/templates/paginator.html (renamed from templates/paginator.html)0
-rw-r--r--forum/skins/default/templates/post_contributor_info.html (renamed from templates/post_contributor_info.html)0
-rw-r--r--forum/skins/default/templates/privacy.html (renamed from templates/privacy.html)0
-rw-r--r--forum/skins/default/templates/question.html (renamed from templates/question.html)80
-rw-r--r--forum/skins/default/templates/question_edit.html (renamed from templates/question_edit.html)12
-rw-r--r--forum/skins/default/templates/question_edit_tips.html (renamed from templates/question_edit_tips.html)0
-rw-r--r--forum/skins/default/templates/question_retag.html (renamed from templates/question_retag.html)6
-rw-r--r--forum/skins/default/templates/question_summary_list_roll.html (renamed from templates/question_summary_list_roll.html)2
-rw-r--r--forum/skins/default/templates/questions.html (renamed from templates/questions.html)8
-rw-r--r--forum/skins/default/templates/reopen.html (renamed from templates/reopen.html)0
-rw-r--r--forum/skins/default/templates/revisions_answer.html (renamed from templates/revisions_answer.html)8
-rw-r--r--forum/skins/default/templates/revisions_question.html (renamed from templates/revisions_question.html)8
-rw-r--r--forum/skins/default/templates/tag_selector.html (renamed from templates/tag_selector.html)4
-rw-r--r--forum/skins/default/templates/tags.html (renamed from templates/tags.html)2
-rw-r--r--forum/skins/default/templates/user.html (renamed from templates/user.html)4
-rw-r--r--forum/skins/default/templates/user_edit.html (renamed from templates/user_edit.html)2
-rw-r--r--forum/skins/default/templates/user_email_subscriptions.html (renamed from templates/user_email_subscriptions.html)0
-rw-r--r--forum/skins/default/templates/user_favorites.html (renamed from templates/user_favorites.html)0
-rw-r--r--forum/skins/default/templates/user_footer.html (renamed from templates/user_footer.html)0
-rw-r--r--forum/skins/default/templates/user_info.html (renamed from templates/user_info.html)0
-rw-r--r--forum/skins/default/templates/user_recent.html (renamed from templates/user_recent.html)0
-rw-r--r--forum/skins/default/templates/user_reputation.html (renamed from templates/user_reputation.html)4
-rw-r--r--forum/skins/default/templates/user_responses.html (renamed from templates/user_responses.html)0
-rw-r--r--forum/skins/default/templates/user_stats.html (renamed from templates/user_stats.html)6
-rw-r--r--forum/skins/default/templates/user_tabs.html (renamed from templates/user_tabs.html)0
-rw-r--r--forum/skins/default/templates/user_votes.html (renamed from templates/user_votes.html)4
-rw-r--r--forum/skins/default/templates/users.html (renamed from templates/users.html)0
-rw-r--r--forum/skins/default/templates/users_questions.html (renamed from templates/users_questions.html)6
-rw-r--r--forum/templatetags/extra_tags.py36
-rw-r--r--forum/upfiles/README2
-rw-r--r--forum/urls.py93
-rw-r--r--forum/user.py74
-rw-r--r--forum/views/__init__.py4
-rw-r--r--forum/views/books.py139
-rw-r--r--forum/views/content.py1394
-rw-r--r--forum/views/meta.py98
-rw-r--r--forum/views/users.py940
-rw-r--r--locale/en/LC_MESSAGES/django.mobin25611 -> 367 bytes
-rw-r--r--locale/en/LC_MESSAGES/django.po2698
-rwxr-xr-xosqa.iml10
-rw-r--r--session_messages/__init__.py37
-rw-r--r--session_messages/context_processors.py48
-rw-r--r--session_messages/models.py3
-rwxr-xr-xsettings.py3
-rw-r--r--templates/content/js/wmd/wmd-min.js1
-rwxr-xr-xtemplates/fbconnect/xd_receiver.html1
215 files changed, 4405 insertions, 2305 deletions
diff --git a/.gitignore b/.gitignore
index 69133c46..c02c6f1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
*.pyc
*.swp
*.log
+osqa.wsgi
nbproject
settings_local.py
diff --git a/INSTALL b/INSTALL
index 72cc76bf..f70b3ec7 100644
--- a/INSTALL
+++ b/INSTALL
@@ -4,7 +4,7 @@ A. PREREQUISITES
B. INSTALLATION
1. Settings file
2. Database
- 3. Running CNPROG in the development server
+ 3. Running OSQA in the development server
4. Installation under Apache/WSGI
5. Full text search
6. Email subscriptions
@@ -56,7 +56,7 @@ Notice that you will need to register with recaptcha.net and receive
recaptcha public and private keys that need to be saved in your
settings_local.py file
-NOTES: django_authopenid is included into CNPROG code
+NOTES: django_authopenid is included into OSQA code
and is significantly modified. http://code.google.com/p/django-authopenid/
no need to install this library
@@ -64,13 +64,13 @@ B. INSTALLATION
-----------------------------------------------
0. Make sure you have all above python libraries installed.
- make cnprog installation server-readable on Linux command might be:
- chown -R yourlogin:apache /path/to/CNPROG
+ make osqa installation server-readable on Linux command might be:
+ chown -R yourlogin:apache /path/to/OSQA
directories templates/upfiles and log must be server writable
on Linux type chmod
- chmod -R g+w /path/to/CNPROG/upfiles
+ chmod -R g+w /path/to/OSQA/upfiles
chmod -R g+w /path/to/log
above it is assumed that webserver runs under group named "apache"
@@ -87,11 +87,11 @@ Section C explains configuration paramaters.
Prepare your database by using the same database/account
configuration from above.
e.g,
-create database cnprog DEFAULT CHARACTER SET UTF8 COLLATE utf8_general_ci;
-grant all on cnprog.* to 'cnprog'@'localhost';
+create database osqa DEFAULT CHARACTER SET UTF8 COLLATE utf8_general_ci;
+grant all on osqa.* to 'osqa'@'localhost';
And then run "python manage.py syncdb" to synchronize your database.
-3. Running CNPROG on the development server
+3. Running OSQA on the development server
Run "python manage.py runserver" to startup django
development environment.
@@ -112,8 +112,8 @@ import os
import sys
sys.path.insert(0,'/one/level/above') #insert to make sure that forum will be found
-sys.path.append('/one/level/above/CNPROG') #maybe this is not necessary
-os.environ['DJANGO_SETTINGS_MODULE'] = 'CNPROG.settings'
+sys.path.append('/one/level/above/OSQA') #maybe this is not necessary
+os.environ['DJANGO_SETTINGS_MODULE'] = 'OSQA.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
-----------
@@ -138,26 +138,26 @@ WSGIPythonEggs /var/python/eggs #must be readable and writable by apache
#this allows "rooting" forum at http://example.com/forum, if you like
<VirtualHost ...your ip...:80>
ServerAdmin forum@example.com
- DocumentRoot /path/to/cnprog
+ DocumentRoot /path/to/osqa-site
ServerName example.com
#run mod_wsgi process for django in daemon mode
#this allows avoiding confused timezone settings when
#another application runs in the same virtual host
- WSGIDaemonProcess CNPROG
- WSGIProcessGroup CNPROG
+ WSGIDaemonProcess OSQA
+ WSGIProcessGroup OSQA
#force all content to be served as static files
#otherwise django will be crunching images through itself wasting time
- Alias /content/ /path/to/cnprog/templates/content/
- AliasMatch /([^/]*\.css) /path/to/cnprog/templates/content/style/$1
- <Directory /path/to/cnprog/templates/content>
+ Alias /m/ /path/to/osqa-site/forum/skins/
+ Alias /upfiles/ /path/to/osqa-site/forum/upfiles/
+ <Directory /path/to/osqa-site/forum/skins>
Order deny,allow
Allow from all
</Directory>
#this is your wsgi script described in the prev section
- WSGIScriptAlias / /path/to/cnprog/cnprog.wsgi
+ WSGIScriptAlias / /path/to/osqa-site/osqa.wsgi
#this will force admin interface to work only
#through https (optional)
@@ -166,35 +166,39 @@ WSGIPythonEggs /var/python/eggs #must be readable and writable by apache
RewriteEngine on
RewriteRule /nimda(.*)$ https://example.com/nimda$1 [L,R=301]
</Location>
- CustomLog /var/log/httpd/CNPROG/access_log common
- ErrorLog /var/log/httpd/CNPROG/error_log
+ CustomLog /var/log/httpd/OSQA/access_log common
+ ErrorLog /var/log/httpd/OSQA/error_log
</VirtualHost>
#(optional) run admin interface under https
<VirtualHost ..your ip..:443>
ServerAdmin forum@example.com
- DocumentRoot /path/to/cnrpog
+ DocumentRoot /path/to/osqa-site
ServerName example.com
SSLEngine on
SSLCertificateFile /path/to/ssl-certificate/server.crt
SSLCertificateKeyFile /path/to/ssl-certificate/server.key
- WSGIScriptAlias / /path/to/cnprogcnprog.wsgi
- CustomLog /var/log/httpd/CNPROG/access_log common
- ErrorLog /var/log/httpd/CNPROG/error_log
+ WSGIScriptAlias / /path/to/osqa-site/osqa.wsgi
+ CustomLog /var/log/httpd/OSQA/access_log common
+ ErrorLog /var/log/httpd/OSQA/error_log
DirectoryIndex index.html
</VirtualHost>
-------------
5. Full text search (using sphinx search)
+
Currently full text search works only with sphinx search engine
+ And builtin PostgreSQL (postgres only >= 8.3???)
+
+ 5.1 Instructions for Sphinx search setup
Sphinx at this time supports only MySQL and PostgreSQL databases
to enable this, install sphinx search engine and djangosphinx
configure sphinx, sample configuration can be found in
sphinx/sphinx.conf file usually goes somewhere in /etc tree
- build cnprog index first time manually
+ build osqa index first time manually
- % indexer --config /path/to/sphinx.conf --index cnprog
+ % indexer --config /path/to/sphinx.conf --index osqa
setup cron job to rebuild index periodically with command
your crontab entry may be something like
@@ -249,8 +253,8 @@ DEBUG=False #set to True to enable debug mode
#all forum parameters are set in file settings_local.py
-LOG_FILENAME = 'cnprog.log' #where logging messages should go
-DATABASE_NAME = 'cnprog' # Or path to database file if using sqlite3.
+LOG_FILENAME = 'osqa.log' #where logging messages should go
+DATABASE_NAME = 'osqa' # Or path to database file if using sqlite3.
DATABASE_USER = '' # Not used with sqlite3.
DATABASE_PASSWORD = '' # Not used with sqlite3.
DATABASE_ENGINE = 'mysql' #mysql, etc
@@ -258,19 +262,19 @@ SERVER_EMAIL = ''
DEFAULT_FROM_EMAIL = ''
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = '' #not necessary if mailserver is run on local machine
-EMAIL_SUBJECT_PREFIX = '[CNPROG] '
-EMAIL_HOST='cnprog.com'
+EMAIL_SUBJECT_PREFIX = '[OSQA] '
+EMAIL_HOST='osqa.com'
EMAIL_PORT='25'
EMAIL_USE_TLS=False
TIME_ZONE = 'America/Tijuana'
-APP_TITLE = u'CNPROG Q&A Forum' #title of your forum
-APP_KEYWORDS = u'CNPROG,forum,community' #keywords for search engines
+APP_TITLE = u'OSQA Q&A Forum' #title of your forum
+APP_KEYWORDS = u'OSQA,forum,community' #keywords for search engines
APP_DESCRIPTION = u'Ask and answer questions.' #site description for searche engines
APP_INTRO = u'<p>Ask and answer questions, make the world better!</p>' #slogan that goes to front page in logged out mode
APP_COPYRIGHT = '' #copyright message
#if you set FORUM_SCRIPT_ALIAS= 'forum/'
-#then CNPROG will run at url http://example.com/forum
+#then OSQA will run at url http://example.com/forum
#FORUM_SCRIPT_ALIAS cannot have leading slash, otherwise it can be set to anything
FORUM_SCRIPT_ALIAS = '' #no leading slash, default = '' empty string
@@ -278,7 +282,7 @@ LANGUAGE_CODE = 'en' #forum language (see language instructions on the wiki)
EMAIL_VALIDATION = 'off' #string - on|off
MIN_USERNAME_LENGTH = 1
EMAIL_UNIQUE = False #if True, email addresses must be unique in all accounts
-APP_URL = 'http://cnprog.com' #used by email notif system and RSS
+APP_URL = 'http://osqa.com' #used by email notif system and RSS
GOOGLE_SITEMAP_CODE = '' #code for google site crawler (look up google webmaster tools)
GOOGLE_ANALYTICS_KEY = '' #key to enable google analytics on this site
BOOKS_ON = False #if True - books tab will be on
@@ -287,10 +291,10 @@ WIKI_ON = True #if False - community wiki feature is disabled
#experimental - allow password login through external site
#must implement django_authopenid/external_login.py
#included prototype external_login works with Mediawiki
-USE_EXTERNAL_LEGACY_LOGIN = True #if false CNPROG uses it's own login/password
-EXTERNAL_LEGACY_LOGIN_HOST = 'login.cnprog.com'
+USE_EXTERNAL_LEGACY_LOGIN = True #if false OSQA uses it's own login/password
+EXTERNAL_LEGACY_LOGIN_HOST = 'login.osqa.com'
EXTERNAL_LEGACY_LOGIN_PORT = 80
-EXTERNAL_LEGACY_LOGIN_PROVIDER_NAME = '<span class="orange">CNPROG</span>'
+EXTERNAL_LEGACY_LOGIN_PROVIDER_NAME = '<span class="orange">OSQA</span>'
FEEDBACK_SITE_URL = None #None or url
LOGIN_URL = '/%s%s%s' % (FORUM_SCRIPT_ALIAS,'account/','signin/')
@@ -303,7 +307,7 @@ D. Customization
Other than settings_local.py the following will most likely need customization:
* locale/*/django.po - language files that may also contain your site-specific messages
if you want to start with english messages file - look for words like "forum" and
- "CNPROG" in the msgstr lines
+ "OSQA" in the msgstr lines
* templates/header.html and templates/footer.html may contain extra links
* templates/about.html - a place to explain for is your forum for
* templates/faq.html - put answers to users frequent questions
diff --git a/PENDING b/PENDING
new file mode 100644
index 00000000..0f053357
--- /dev/null
+++ b/PENDING
@@ -0,0 +1,32 @@
+There are two kinds of things that can be done:
+refactorings (think of jogging in the morning, going to a spa, well make the code better :)
+new features (go to law school, get a job, do something real)
+Just a joke - pick yourself a task and work on it.
+
+==Refactoring==
+* (see note 1) analyze and split /views/content.py - Evgeny
+* analyze and split models.py --> models/
+* create forum/modules directory
+* make modules load into the forum app like they
+ are the integral part of the forum
+* set up loading of default settings from inside the /forum dir
+* automatic dependency checking for modules
+* propose how to rename directory forum --> osqa
+ without breaking things and keeping name of the project root
+ named the same way - osqa
+
+==New features==
+Whoever wants - pick a feature from the WISH_LIST
+add it here and start working on it
+If you are not starting immediately - leave it on the wishlist :)
+
+==Notes==
+1)after this is done most new suggested features
+ may be worked on easily since most of them
+ only require editing view functions and templates
+
+ However, anyone can work on new features anyway - you'll
+ just have to probably copy-paste your code into
+ the branch undergoing refactoring which involves
+ splitting the files. Auto merging across split points
+ is harder or impossible.
diff --git a/TODO b/TODO
deleted file mode 100644
index 7c37071d..00000000
--- a/TODO
+++ /dev/null
@@ -1,3 +0,0 @@
-* per-tag email subscriptions
-* make sorting tabs work in question search - done
-* allow multiple logins to the same account
diff --git a/WISH_LIST b/WISH_LIST
new file mode 100644
index 00000000..6b106875
--- /dev/null
+++ b/WISH_LIST
@@ -0,0 +1,10 @@
+* The wonder bar (integrated the search / ask functionality)
+* The authentication system ???
+* allow multiple logins to the same account
+* more advanced templating/skinning system
+* per-tag email subscriptions
+* view for personalized news on the site
+* a little flag popping when there are news
+* drill-down mode for navigation by tags
+* improved admin console
+* sort out mess with profile - currently we patch django User
diff --git a/context.py b/context.py
index ca6ca163..9e22550f 100644
--- a/context.py
+++ b/context.py
@@ -16,6 +16,7 @@ def application_settings(context):
'USE_EXTERNAL_LEGACY_LOGIN':settings.USE_EXTERNAL_LEGACY_LOGIN,
'RESOURCE_REVISION':settings.RESOURCE_REVISION,
'USE_SPHINX_SEARCH':settings.USE_SPHINX_SEARCH,
+ 'OSQA_SKIN':settings.OSQA_DEFAULT_SKIN,
}
return {'settings':my_settings}
diff --git a/fbconnect/fb.py b/fbconnect/fb.py
index 99bc0b79..afcd8210 100755
--- a/fbconnect/fb.py
+++ b/fbconnect/fb.py
@@ -73,17 +73,24 @@ STATES = {
def get_user_state(request):
API_KEY = settings.FB_API_KEY
+ logging.debug('')
if API_KEY in request.COOKIES:
+ logging.debug('FB API key is in request cookies')
if check_cookies_signature(request.COOKIES):
+ logging.debug('FB cookie signature is fine')
if check_session_expiry(request.COOKIES):
+ logging.debug('FB session is not expired')
try:
uassoc = FBAssociation.objects.get(fbuid=request.COOKIES[API_KEY + '_user'])
+ logging.debug('found existing FB user association')
return (STATES['RETURNINGUSER'], uassoc.user)
except:
+ logging.debug('dont have FB association for this user')
return (STATES['FIRSTTIMER'], get_user_data(request.COOKIES))
else:
+ logging.debug('FB session expired')
return (STATES['SESSIONEXPIRED'], None)
+ logging.debug('FB state is INVALID')
return (STATES['INVALIDSTATE'], None)
-
diff --git a/fbconnect/urls.py b/fbconnect/urls.py
index 9b4ff0c9..bf2d4364 100755
--- a/fbconnect/urls.py
+++ b/fbconnect/urls.py
@@ -1,10 +1,13 @@
from django.conf.urls.defaults import *
from django.utils.translation import ugettext as _
from django.views.generic.simple import direct_to_template
+from django.conf import settings
from views import signin, register
urlpatterns = patterns('',
- url(r'^xd_receiver$', direct_to_template, {'template': 'fbconnect/xd_receiver.html'}, name='xd_receiver'),
+ url(r'^xd_receiver$', direct_to_template, {'template': 'fbconnect/xd_receiver.html',\
+ 'extra_context': {'APP_SHORT_NAME':settings.APP_SHORT_NAME}},\
+ name='xd_receiver'),
url(r'^%s$' % _('signin/'), signin, name="fb_signin"),
url(r'^%s%s$' % (_('signin/'), _('newquestion/')), signin, {'newquestion': True}, name="fb_signin_new_question"),
diff --git a/fbconnect/views.py b/fbconnect/views.py
index 5c308e45..1781f6bf 100755
--- a/fbconnect/views.py
+++ b/fbconnect/views.py
@@ -6,7 +6,7 @@ from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.contrib.auth import login, logout
from models import FBAssociation
-from forum.forms import EditUserEmailFeedsForm
+from forum.forms import SimpleEmailSubscribeForm
from django.conf import settings
import fb
@@ -15,9 +15,11 @@ import forms
import logging
def signin(request, newquestion = False, newanswer = False):
+ logging.debug('')
state, context = fb.get_user_state(request)
if state == fb.STATES['FIRSTTIMER']:
+ logging.debug('FB state = FIRSTTIMER')
if newquestion:
register_url = 'fb_user_register_new_question'
elif newanswer:
@@ -26,8 +28,10 @@ def signin(request, newquestion = False, newanswer = False):
register_url = 'fb_user_register'
return HttpResponseRedirect(reverse(register_url))
elif state == fb.STATES['RETURNINGUSER']:
+ logging.debug('FB state = RETURNINGUSER')
return login_and_forward(request, context, newquestion, newanswer)
elif state == fb.STATES['SESSIONEXPIRED']:
+ logging.debug('FB state = SESSIONEXPIRED')
response = logout(request, next_page=reverse('index'))
fb.delete_cookies(response)
return response
@@ -35,36 +39,41 @@ def signin(request, newquestion = False, newanswer = False):
return HttpResponseRedirect(reverse('index'))
def register(request, newquestion = False, newanswer = False):
+ logging.debug('')
state, context = fb.get_user_state(request)
if state == fb.STATES['FIRSTTIMER']:
-
- if 'bnewaccount' in request.POST.keys():
+ logging.debug('FB FIRSTTIMER - try to register locally')
+ logging.debug('request method is %s' % request.method)
+ if request.method == 'POST' and 'bnewaccount' in request.POST:
form1 = forms.FBConnectRegisterForm(request.POST)
- email_feeds_form = EditUserEmailFeedsForm(request.POST)
+ email_feeds_form = SimpleEmailSubscribeForm(request.POST)
if (form1.is_valid() and email_feeds_form.is_valid()):
tmp_pwd = User.objects.make_random_password()
user_ = User.objects.create_user(form1.cleaned_data['username'],
form1.cleaned_data['email'], tmp_pwd)
-
+
user_.set_unusable_password()
+ logging.debug('created new internal user %s' % form1.cleaned_data['username'])
uassoc = FBAssociation(user=user_, fbuid=context['uid'])
uassoc.save()
+ logging.debug('created new user association')
email_feeds_form.save(user_)
return login_and_forward(request, user_, newquestion, newanswer)
+ else:
+ logging.debug('form user input is invalid')
else:
form1 = forms.FBConnectRegisterForm(initial={
'next': '/',
'username': context['name'],
'email': '',
})
-
- email_feeds_form = EditUserEmailFeedsForm()
-
+ email_feeds_form = SimpleEmailSubscribeForm()
+
return render('authopenid/complete.html', {
'form1': form1,
'email_feeds_form': email_feeds_form,
@@ -73,25 +82,31 @@ def register(request, newquestion = False, newanswer = False):
'gravatar_faq_url':reverse('faq') + '#gravatar',
}, context_instance=RequestContext(request))
else:
+ logging.debug('not a FIRSTTIMER --> redirect to index view')
return HttpResponseRedirect(reverse('index'))
def login_and_forward(request, user, newquestion = False, newanswer = False):
old_session = request.session.session_key
user.backend = "django.contrib.auth.backends.ModelBackend"
+ logging.debug('attached auth.backends.ModelBackend to this FB user')
login(request, user)
+ logging.debug('user logged in!')
from forum.models import user_logged_in
user_logged_in.send(user=user,session_key=old_session,sender=None)
+ logging.debug('user_logged_in signal sent')
if (newquestion):
from forum.models import Question
question = Question.objects.filter(author=user).order_by('-added_at')[0]
+ logging.debug('redirecting to newly posted question')
return HttpResponseRedirect(question.get_absolute_url())
if (newanswer):
from forum.models import Answer
answer = Answer.objects.filter(author=user).order_by('-added_at')[0]
+ logging.debug('redirecting to newly posted answer')
return HttpResponseRedirect(answer.get_absolute_url())
+ logging.debug('redirecting to front page')
return HttpResponseRedirect('/')
-
diff --git a/forum/__init__.py b/forum/__init__.py
index e69de29b..a221a3ad 100644
--- a/forum/__init__.py
+++ b/forum/__init__.py
@@ -0,0 +1 @@
+__all__ = ['admin','auth','const','diff','feed','forms','managers','models','sitemap','urls','views']
diff --git a/forum/forms.py.orig b/forum/forms.py.orig
deleted file mode 100644
index 42becc11..00000000
--- a/forum/forms.py.orig
+++ /dev/null
@@ -1,352 +0,0 @@
-import re
-from datetime import date
-from django import forms
-from models import *
-from const import *
-from django.utils.translation import ugettext as _
-from utils.forms import NextUrlField, UserNameField
-from recaptcha_django import ReCaptchaField
-from django.conf import settings
-import logging
-
-class TitleField(forms.CharField):
- def __init__(self, *args, **kwargs):
- super(TitleField, self).__init__(*args, **kwargs)
- self.required = True
- self.widget = forms.TextInput(attrs={'size' : 70, 'autocomplete' : 'off'})
- self.max_length = 255
- self.label = _('title')
- self.help_text = _('please enter a descriptive title for your question')
- self.initial = ''
-
- def clean(self, value):
- if len(value) < 10:
- raise forms.ValidationError(_('title must be > 10 characters'))
-
- return value
-
-class EditorField(forms.CharField):
- def __init__(self, *args, **kwargs):
- super(EditorField, self).__init__(*args, **kwargs)
- self.required = True
- self.widget = forms.Textarea(attrs={'id':'editor'})
- self.label = _('content')
- self.help_text = u''
- self.initial = ''
-
- def clean(self, value):
- if len(value) < 10:
- raise forms.ValidationError(_('question content must be > 10 characters'))
-
- return value
-
-class TagNamesField(forms.CharField):
- def __init__(self, *args, **kwargs):
- super(TagNamesField, self).__init__(*args, **kwargs)
- self.required = True
- self.widget = forms.TextInput(attrs={'size' : 50, 'autocomplete' : 'off'})
- self.max_length = 255
- self.label = _('tags')
- #self.help_text = _('please use space to separate tags (this enables autocomplete feature)')
- self.help_text = _('Tags are short keywords, with no spaces within. Up to five tags can be used.')
- self.initial = ''
-
- def clean(self, value):
- value = super(TagNamesField, self).clean(value)
- data = value.strip()
- if len(data) < 1:
- raise forms.ValidationError(_('tags are required'))
-
- split_re = re.compile(r'[ ,]+')
- list = split_re.split(data)
- list_temp = []
- if len(list) > 5:
- raise forms.ValidationError(_('please use 5 tags or less'))
- for tag in list:
- if len(tag) > 20:
- raise forms.ValidationError(_('tags must be shorter than 20 characters'))
- #take tag regex from settings
- tagname_re = re.compile(r'[a-z0-9]+')
- if not tagname_re.match(tag):
- raise forms.ValidationError(_('please use following characters in tags: letters \'a-z\', numbers, and characters \'.-_#\''))
- # only keep one same tag
- if tag not in list_temp and len(tag.strip()) > 0:
- list_temp.append(tag)
- return u' '.join(list_temp)
-
-class WikiField(forms.BooleanField):
- def __init__(self, *args, **kwargs):
- super(WikiField, self).__init__(*args, **kwargs)
- self.required = False
- self.label = _('community wiki')
- self.help_text = _('if you choose community wiki option, the question and answer do not generate points and name of author will not be shown')
- def clean(self,value):
- return value and settings.WIKI_ON
-
-class EmailNotifyField(forms.BooleanField):
- def __init__(self, *args, **kwargs):
- super(EmailNotifyField, self).__init__(*args, **kwargs)
- self.required = False
- self.widget.attrs['class'] = 'nomargin'
-
-class SummaryField(forms.CharField):
- def __init__(self, *args, **kwargs):
- super(SummaryField, self).__init__(*args, **kwargs)
- self.required = False
- self.widget = forms.TextInput(attrs={'size' : 50, 'autocomplete' : 'off'})
- self.max_length = 300
- self.label = _('update summary:')
- self.help_text = _('enter a brief summary of your revision (e.g. fixed spelling, grammar, improved style, this field is optional)')
-
-class ModerateUserForm(forms.ModelForm):
- is_approved = forms.BooleanField(label=_("Automatically accept user's contributions for the email updates"),
- required=False)
-
- def clean_is_approved(self):
- if 'is_approved' not in self.cleaned_data:
- self.cleaned_data['is_approved'] = False
- return self.cleaned_data['is_approved']
-
- class Meta:
- model = User
- fields = ('is_approved',)
-
-class NotARobotForm(forms.Form):
- recaptcha = ReCaptchaField()
-
-class FeedbackForm(forms.Form):
- name = forms.CharField(label=_('Your name:'), required=False)
- email = forms.EmailField(label=_('Email (not shared with anyone):'), required=False)
- message = forms.CharField(label=_('Your message:'), max_length=800,widget=forms.Textarea(attrs={'cols':60}))
- next = NextUrlField()
-
-class AskForm(forms.Form):
- title = TitleField()
- text = EditorField()
- tags = TagNamesField()
- wiki = WikiField()
-
- openid = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 40, 'class':'openid-input'}))
- user = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35}))
- email = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35}))
-
-class AnswerForm(forms.Form):
- text = EditorField()
- wiki = WikiField()
- openid = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 40, 'class':'openid-input'}))
- user = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35}))
- email = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35}))
- email_notify = EmailNotifyField()
- def __init__(self, question, user, *args, **kwargs):
- super(AnswerForm, self).__init__(*args, **kwargs)
- self.fields['email_notify'].widget.attrs['id'] = 'question-subscribe-updates';
- if question.wiki and settings.WIKI_ON:
- self.fields['wiki'].initial = True
- if user.is_authenticated():
- if user in question.followed_by.all():
- self.fields['email_notify'].initial = True
- return
- self.fields['email_notify'].initial = False
-
-
-class CloseForm(forms.Form):
- reason = forms.ChoiceField(choices=CLOSE_REASONS)
-
-class RetagQuestionForm(forms.Form):
- tags = TagNamesField()
- # initialize the default values
- def __init__(self, question, *args, **kwargs):
- super(RetagQuestionForm, self).__init__(*args, **kwargs)
- self.fields['tags'].initial = question.tagnames
-
-class RevisionForm(forms.Form):
- """
- Lists revisions of a Question or Answer
- """
- revision = forms.ChoiceField(widget=forms.Select(attrs={'style' : 'width:520px'}))
-
- def __init__(self, post, latest_revision, *args, **kwargs):
- super(RevisionForm, self).__init__(*args, **kwargs)
- revisions = post.revisions.all().values_list(
- 'revision', 'author__username', 'revised_at', 'summary')
- date_format = '%c'
- self.fields['revision'].choices = [
- (r[0], u'%s - %s (%s) %s' % (r[0], r[1], r[2].strftime(date_format), r[3]))
- for r in revisions]
- self.fields['revision'].initial = latest_revision.revision
-
-class EditQuestionForm(forms.Form):
- title = TitleField()
- text = EditorField()
- tags = TagNamesField()
- summary = SummaryField()
-
- def __init__(self, question, revision, *args, **kwargs):
- super(EditQuestionForm, self).__init__(*args, **kwargs)
- self.fields['title'].initial = revision.title
- self.fields['text'].initial = revision.text
- self.fields['tags'].initial = revision.tagnames
- # Once wiki mode is enabled, it can't be disabled
- if not question.wiki:
- self.fields['wiki'] = WikiField()
-
-class EditAnswerForm(forms.Form):
- text = EditorField()
- summary = SummaryField()
-
- def __init__(self, answer, revision, *args, **kwargs):
- super(EditAnswerForm, self).__init__(*args, **kwargs)
- self.fields['text'].initial = revision.text
-
-class EditUserForm(forms.Form):
- email = forms.EmailField(label=u'Email', help_text=_('this email does not have to be linked to gravatar'), required=True, max_length=255, widget=forms.TextInput(attrs={'size' : 35}))
- #username = UserNameField(label=_('Screen name'))
- realname = forms.CharField(label=_('Real name'), required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35}))
- website = forms.URLField(label=_('Website'), required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35}))
- city = forms.CharField(label=_('Location'), required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35}))
- birthday = forms.DateField(label=_('Date of birth'), help_text=_('will not be shown, used to calculate age, format: YYYY-MM-DD'), required=False, widget=forms.TextInput(attrs={'size' : 35}))
- about = forms.CharField(label=_('Profile'), required=False, widget=forms.Textarea(attrs={'cols' : 60}))
-
- def __init__(self, user, *args, **kwargs):
- super(EditUserForm, self).__init__(*args, **kwargs)
- self.fields['username'].initial = user.username
- self.fields['username'].user_instance = user
- self.fields['email'].initial = user.email
- self.fields['realname'].initial = user.real_name
- self.fields['website'].initial = user.website
- self.fields['city'].initial = user.location
-
- if user.date_of_birth is not None:
- self.fields['birthday'].initial = user.date_of_birth
- else:
- self.fields['birthday'].initial = '1990-01-01'
- self.fields['about'].initial = user.about
- self.user = user
-
- def clean_email(self):
- """For security reason one unique email in database"""
- if self.user.email != self.cleaned_data['email']:
- #todo dry it, there is a similar thing in openidauth
- if settings.EMAIL_UNIQUE == True:
- if 'email' in self.cleaned_data:
- try:
- user = User.objects.get(email = self.cleaned_data['email'])
- except User.DoesNotExist:
- return self.cleaned_data['email']
- except User.MultipleObjectsReturned:
- raise forms.ValidationError(_('this email has already been registered, please use another one'))
- raise forms.ValidationError(_('this email has already been registered, please use another one'))
- return self.cleaned_data['email']
-
-class TagFilterSelectionForm(forms.ModelForm):
- tag_filter_setting = forms.ChoiceField(choices=TAG_EMAIL_FILTER_CHOICES, #imported from forum/const.py
- initial='ignored',
- label=_('Choose email tag filter'),
- widget=forms.RadioSelect)
- class Meta:
- model = User
- fields = ('tag_filter_setting',)
-
- def save(self):
- before = self.instance.tag_filter_setting
- super(TagFilterSelectionForm, self).save()
- after = self.instance.tag_filter_setting #User.objects.get(pk=self.instance.id).tag_filter_setting
- if before != after:
- return True
- return False
-
-class EditUserEmailFeedsForm(forms.Form):
- WN = (('w',_('weekly')),('n',_('no email')))
- DWN = (('d',_('daily')),('w',_('weekly')),('n',_('no email')))
- FORM_TO_MODEL_MAP = {
- 'all_questions':'q_all',
- 'asked_by_me':'q_ask',
- 'answered_by_me':'q_ans',
- 'individually_selected':'q_sel',
- }
- NO_EMAIL_INITIAL = {
- 'all_questions':'n',
- 'asked_by_me':'n',
- 'answered_by_me':'n',
- 'individually_selected':'n',
- }
- asked_by_me = forms.ChoiceField(choices=DWN,initial='w',
- widget=forms.RadioSelect,
- label=_('Asked by me'))
- answered_by_me = forms.ChoiceField(choices=DWN,initial='w',
- widget=forms.RadioSelect,
- label=_('Answered by me'))
- individually_selected = forms.ChoiceField(choices=DWN,initial='w',
- widget=forms.RadioSelect,
- label=_('Individually selected'))
- all_questions = forms.ChoiceField(choices=DWN,initial='w',
- widget=forms.RadioSelect,
- label=_('Entire forum (tag filtered)'),)
-
- def set_initial_values(self,user=None):
- KEY_MAP = dict([(v,k) for k,v in self.FORM_TO_MODEL_MAP.iteritems()])
- if user != None:
- settings = EmailFeedSetting.objects.filter(subscriber=user)
- initial_values = {}
- for setting in settings:
- feed_type = setting.feed_type
- form_field = KEY_MAP[feed_type]
- frequency = setting.frequency
- initial_values[form_field] = frequency
- self.initial = initial_values
- return self
-
- def reset(self):
- self.cleaned_data['all_questions'] = 'n'
- self.cleaned_data['asked_by_me'] = 'n'
- self.cleaned_data['answered_by_me'] = 'n'
- self.cleaned_data['individually_selected'] = 'n'
- self.initial = self.NO_EMAIL_INITIAL
- return self
-
- def save(self,user,save_unbound=False):
- """
- with save_unbound==True will bypass form validation and save initial values
- """
- changed = False
- for form_field, feed_type in self.FORM_TO_MODEL_MAP.items():
- s, created = EmailFeedSetting.objects.get_or_create(subscriber=user,\
- feed_type=feed_type)
- if save_unbound:
- #just save initial values instead
- if form_field in self.initial:
- new_value = self.initial[form_field]
- else:
- new_value = self.fields[form_field].initial
- else:
- new_value = self.cleaned_data[form_field]
- if s.frequency != new_value:
- s.frequency = new_value
- s.save()
- changed = True
- else:
- if created:
- s.save()
- if form_field == 'individually_selected':
- feed_type = ContentType.objects.get_for_model(Question)
- user.followed_questions.clear()
- return changed
-
-
-class SimpleEmailSubscribeForm(forms.Form):
- SIMPLE_SUBSCRIBE_CHOICES = (
- ('y',_('okay, let\'s try!')),
- ('n',_('no OSQA community email please, thanks'))
- )
- subscribe = forms.ChoiceField(widget=forms.widgets.RadioSelect(), \
- error_messages={'required':_('please choose one of the options above')},
- choices=SIMPLE_SUBSCRIBE_CHOICES)
-
- def save(self,user=None):
- EFF = EditUserEmailFeedsForm
- if self.cleaned_data['subscribe'] == 'y':
- email_settings_form = EFF()
- logging.debug('%s wants to subscribe' % user.username)
- else:
- email_settings_form = EFF(initial=EFF.NO_EMAIL_INITIAL)
- email_settings_form.save(user,save_unbound=True)
diff --git a/forum/models.py b/forum/models.py
index 86416030..8a24e631 100644
--- a/forum/models.py
+++ b/forum/models.py
@@ -22,7 +22,7 @@ if settings.USE_SPHINX_SEARCH == True:
from djangosphinx.models import SphinxSearch
from forum.managers import *
-from const import *
+from forum.const import *
def get_object_comments(self):
comments = self.comments.all().order_by('id')
@@ -619,58 +619,6 @@ class Activity(models.Model):
class Meta:
db_table = u'activity'
-class Book(models.Model):
- """
- Model for book info
- """
- user = models.ForeignKey(User)
- title = models.CharField(max_length=255)
- short_name = models.CharField(max_length=255)
- author = models.CharField(max_length=255)
- price = models.DecimalField(max_digits=6, decimal_places=2)
- pages = models.SmallIntegerField()
- published_at = models.DateTimeField()
- publication = models.CharField(max_length=255)
- cover_img = models.CharField(max_length=255)
- tagnames = models.CharField(max_length=125)
- added_at = models.DateTimeField()
- last_edited_at = models.DateTimeField()
- questions = models.ManyToManyField(Question, related_name='book', db_table='book_question')
-
- def get_absolute_url(self):
- return reverse('book', args=[django_urlquote(slugify(self.short_name))])
-
- def __unicode__(self):
- return self.title
- class Meta:
- db_table = u'book'
-
-class BookAuthorInfo(models.Model):
- """
- Model for book author info
- """
- user = models.ForeignKey(User)
- book = models.ForeignKey(Book)
- blog_url = models.CharField(max_length=255)
- added_at = models.DateTimeField()
- last_edited_at = models.DateTimeField()
-
- class Meta:
- db_table = u'book_author_info'
-
-class BookAuthorRss(models.Model):
- """
- Model for book author blog rss
- """
- user = models.ForeignKey(User)
- book = models.ForeignKey(Book)
- title = models.CharField(max_length=255)
- url = models.CharField(max_length=255)
- rss_created_at = models.DateTimeField()
- added_at = models.DateTimeField()
-
- class Meta:
- db_table = u'book_author_rss'
class AnonymousEmail(models.Model):
#validation key, if used
@@ -947,3 +895,61 @@ tags_updated.connect(record_update_tags, sender=Question)
post_save.connect(record_favorite_question, sender=FavoriteQuestion)
user_updated.connect(record_user_full_updated, sender=User)
user_logged_in.connect(post_stored_anonymous_content)
+
+#todo later split this out to the books extension models
+#from django.db import models
+#from django.contrib.auth.models import User
+#from forum.models import Question
+
+class Book(models.Model):
+ """
+ Model for book info
+ """
+ user = models.ForeignKey(User)
+ title = models.CharField(max_length=255)
+ short_name = models.CharField(max_length=255)
+ author = models.CharField(max_length=255)
+ price = models.DecimalField(max_digits=6, decimal_places=2)
+ pages = models.SmallIntegerField()
+ published_at = models.DateTimeField()
+ publication = models.CharField(max_length=255)
+ cover_img = models.CharField(max_length=255)
+ tagnames = models.CharField(max_length=125)
+ added_at = models.DateTimeField()
+ last_edited_at = models.DateTimeField()
+ questions = models.ManyToManyField(Question, related_name='book', db_table='book_question')
+
+ def get_absolute_url(self):
+ return reverse('book', args=[django_urlquote(slugify(self.short_name))])
+
+ def __unicode__(self):
+ return self.title
+ class Meta:
+ db_table = u'book'
+
+class BookAuthorInfo(models.Model):
+ """
+ Model for book author info
+ """
+ user = models.ForeignKey(User)
+ book = models.ForeignKey(Book)
+ blog_url = models.CharField(max_length=255)
+ added_at = models.DateTimeField()
+ last_edited_at = models.DateTimeField()
+
+ class Meta:
+ db_table = u'book_author_info'
+
+class BookAuthorRss(models.Model):
+ """
+ Model for book author blog rss
+ """
+ user = models.ForeignKey(User)
+ book = models.ForeignKey(Book)
+ title = models.CharField(max_length=255)
+ url = models.CharField(max_length=255)
+ rss_created_at = models.DateTimeField()
+ added_at = models.DateTimeField()
+
+ class Meta:
+ db_table = u'book_author_rss'
diff --git a/forum/skins/README b/forum/skins/README
new file mode 100644
index 00000000..b2f32b77
--- /dev/null
+++ b/forum/skins/README
@@ -0,0 +1,23 @@
+this directory contains available skins
+
+1) default - default skin with templates
+2) common - this directory is to media directory common to all or many templates
+
+to create a new skin just create another directory under skins/
+and start populating it with templates named the same way as in
+default/templates
+
+all paths must be the same except they will be under
+yourtemplate/templates
+
+media does not have to be composed of files named the same way as in default skin
+whatever media you link to from your templates - will be in operation
+
+templates are resolved in the following way:
+* check in skin named as in settings.OSQA_DEFAULT_SKIN
+* then skin named 'default'
+
+media is resolved with one extra option
+* settings.OSQA_DEFAULT_SKIN
+* 'default'
+* 'common'
diff --git a/forum/skins/__init__.py b/forum/skins/__init__.py
new file mode 100644
index 00000000..be6bd4f3
--- /dev/null
+++ b/forum/skins/__init__.py
@@ -0,0 +1,57 @@
+from django.conf import settings
+from django.template import loader
+from django.template.loaders import filesystem
+from django.http import HttpResponse
+import os.path
+import logging
+
+#module for skinning osqa
+#at this point skin can be changed only in settings file
+#via OSQA_DEFAULT_SKIN variable
+
+#note - Django template loaders use method django.utils._os.safe_join
+#to work on unicode file paths
+#here it is ignored because it is assumed that we won't use unicode paths
+
+def load_template_source(name, dirs=None):
+ try:
+ tname = os.path.join(settings.OSQA_DEFAULT_SKIN,'templates',name)
+ return filesystem.load_template_source(tname,dirs)
+ except:
+ tname = os.path.join('default','templates',name)
+ return filesystem.load_template_source(tname,dirs)
+load_template_source.is_usable = True
+
+def find_media_source(url):
+ """returns url prefixed with the skin name
+ of the first skin that contains the file
+ directories are searched in this order:
+ settings.OSQA_DEFAULT_SKIN, then 'default', then 'commmon'
+ if file is not found - returns None
+ and logs an error message
+ """
+ while url[0] == '/': url = url[1:]
+ d = os.path.dirname
+ n = os.path.normpath
+ j = os.path.join
+ f = os.path.isfile
+ skins = n(j(d(d(__file__)),'skins'))
+ try:
+ media = os.path.join(skins, settings.OSQA_DEFAULT_SKIN, url)
+ assert(f(media))
+ use_skin = settings.OSQA_DEFAULT_SKIN
+ except:
+ try:
+ media = j(skins, 'default', url)
+ assert(f(media))
+ use_skin = 'default'
+ except:
+ media = j(skins, 'common', url)
+ try:
+ assert(f(media))
+ use_skin = 'common'
+ except:
+ logging.error('could not find media for %s' % url)
+ use_skin = ''
+ return None
+ return use_skin + '/' + url
diff --git a/forum/skins/common/media/README b/forum/skins/common/media/README
new file mode 100644
index 00000000..3376e754
--- /dev/null
+++ b/forum/skins/common/media/README
@@ -0,0 +1 @@
+directory for media common to all or many templates
diff --git a/templates/content/images/blue-up-arrow-h18px.png b/forum/skins/default/media/images/blue-up-arrow-h18px.png
index e1f29e86..e1f29e86 100644
--- a/templates/content/images/blue-up-arrow-h18px.png
+++ b/forum/skins/default/media/images/blue-up-arrow-h18px.png
Binary files differ
diff --git a/templates/content/images/box-arrow.gif b/forum/skins/default/media/images/box-arrow.gif
index 89dcf5b3..89dcf5b3 100644
--- a/templates/content/images/box-arrow.gif
+++ b/forum/skins/default/media/images/box-arrow.gif
Binary files differ
diff --git a/templates/content/images/bullet_green.gif b/forum/skins/default/media/images/bullet_green.gif
index fa530910..fa530910 100644
--- a/templates/content/images/bullet_green.gif
+++ b/forum/skins/default/media/images/bullet_green.gif
Binary files differ
diff --git a/templates/content/images/cc-88x31.png b/forum/skins/default/media/images/cc-88x31.png
index 0f2a0f10..0f2a0f10 100644
--- a/templates/content/images/cc-88x31.png
+++ b/forum/skins/default/media/images/cc-88x31.png
Binary files differ
diff --git a/templates/content/images/cc-wiki.png b/forum/skins/default/media/images/cc-wiki.png
index 3e680538..3e680538 100644
--- a/templates/content/images/cc-wiki.png
+++ b/forum/skins/default/media/images/cc-wiki.png
Binary files differ
diff --git a/templates/content/images/close-small-dark.png b/forum/skins/default/media/images/close-small-dark.png
index 280c1fc7..280c1fc7 100644
--- a/templates/content/images/close-small-dark.png
+++ b/forum/skins/default/media/images/close-small-dark.png
Binary files differ
diff --git a/templates/content/images/close-small-hover.png b/forum/skins/default/media/images/close-small-hover.png
index 7899aec7..7899aec7 100644
--- a/templates/content/images/close-small-hover.png
+++ b/forum/skins/default/media/images/close-small-hover.png
Binary files differ
diff --git a/templates/content/images/close-small.png b/forum/skins/default/media/images/close-small.png
index 5a99d31f..5a99d31f 100644
--- a/templates/content/images/close-small.png
+++ b/forum/skins/default/media/images/close-small.png
Binary files differ
diff --git a/templates/content/images/dash.gif b/forum/skins/default/media/images/dash.gif
index d1ddc507..d1ddc507 100644
--- a/templates/content/images/dash.gif
+++ b/forum/skins/default/media/images/dash.gif
Binary files differ
diff --git a/templates/content/images/djangomade124x25_grey.gif b/forum/skins/default/media/images/djangomade124x25_grey.gif
index d34bb311..d34bb311 100644
--- a/templates/content/images/djangomade124x25_grey.gif
+++ b/forum/skins/default/media/images/djangomade124x25_grey.gif
Binary files differ
diff --git a/templates/content/images/dot-g.gif b/forum/skins/default/media/images/dot-g.gif
index 5d6bb28e..5d6bb28e 100644
--- a/templates/content/images/dot-g.gif
+++ b/forum/skins/default/media/images/dot-g.gif
Binary files differ
diff --git a/templates/content/images/dot-list.gif b/forum/skins/default/media/images/dot-list.gif
index f6a6b865..f6a6b865 100644
--- a/templates/content/images/dot-list.gif
+++ b/forum/skins/default/media/images/dot-list.gif
Binary files differ
diff --git a/templates/content/images/edit.png b/forum/skins/default/media/images/edit.png
index dcb09be0..dcb09be0 100644
--- a/templates/content/images/edit.png
+++ b/forum/skins/default/media/images/edit.png
Binary files differ
diff --git a/templates/content/images/expander-arrow-hide.gif b/forum/skins/default/media/images/expander-arrow-hide.gif
index feb6a618..feb6a618 100644
--- a/templates/content/images/expander-arrow-hide.gif
+++ b/forum/skins/default/media/images/expander-arrow-hide.gif
Binary files differ
diff --git a/templates/content/images/expander-arrow-show.gif b/forum/skins/default/media/images/expander-arrow-show.gif
index 6825c56e..6825c56e 100644
--- a/templates/content/images/expander-arrow-show.gif
+++ b/forum/skins/default/media/images/expander-arrow-show.gif
Binary files differ
diff --git a/templates/content/images/favicon.gif b/forum/skins/default/media/images/favicon.gif
index 910c2666..910c2666 100644
--- a/templates/content/images/favicon.gif
+++ b/forum/skins/default/media/images/favicon.gif
Binary files differ
diff --git a/templates/content/images/feed-icon-small.png b/forum/skins/default/media/images/feed-icon-small.png
index b3c949d2..b3c949d2 100644
--- a/templates/content/images/feed-icon-small.png
+++ b/forum/skins/default/media/images/feed-icon-small.png
Binary files differ
diff --git a/templates/content/images/gray-up-arrow-h18px.png b/forum/skins/default/media/images/gray-up-arrow-h18px.png
index 78767445..78767445 100644
--- a/templates/content/images/gray-up-arrow-h18px.png
+++ b/forum/skins/default/media/images/gray-up-arrow-h18px.png
Binary files differ
diff --git a/templates/content/images/grippie.png b/forum/skins/default/media/images/grippie.png
index 6524d416..6524d416 100644
--- a/templates/content/images/grippie.png
+++ b/forum/skins/default/media/images/grippie.png
Binary files differ
diff --git a/templates/content/images/indicator.gif b/forum/skins/default/media/images/indicator.gif
index 1c72ebb5..1c72ebb5 100644
--- a/templates/content/images/indicator.gif
+++ b/forum/skins/default/media/images/indicator.gif
Binary files differ
diff --git a/templates/content/images/logo.gif b/forum/skins/default/media/images/logo.gif
index ab690de2..ab690de2 100644
--- a/templates/content/images/logo.gif
+++ b/forum/skins/default/media/images/logo.gif
Binary files differ
diff --git a/templates/content/images/logo.png b/forum/skins/default/media/images/logo.png
index 6a250e35..6a250e35 100644
--- a/templates/content/images/logo.png
+++ b/forum/skins/default/media/images/logo.png
Binary files differ
diff --git a/templates/content/images/logo1.png b/forum/skins/default/media/images/logo1.png
index d79a6271..d79a6271 100644
--- a/templates/content/images/logo1.png
+++ b/forum/skins/default/media/images/logo1.png
Binary files differ
diff --git a/templates/content/images/logo2.png b/forum/skins/default/media/images/logo2.png
index bd3cccd9..bd3cccd9 100644
--- a/templates/content/images/logo2.png
+++ b/forum/skins/default/media/images/logo2.png
Binary files differ
diff --git a/templates/content/images/medala.gif b/forum/skins/default/media/images/medala.gif
index 93dd1a39..93dd1a39 100644
--- a/templates/content/images/medala.gif
+++ b/forum/skins/default/media/images/medala.gif
Binary files differ
diff --git a/templates/content/images/medala_on.gif b/forum/skins/default/media/images/medala_on.gif
index a18f9e85..a18f9e85 100644
--- a/templates/content/images/medala_on.gif
+++ b/forum/skins/default/media/images/medala_on.gif
Binary files differ
diff --git a/templates/content/images/new.gif b/forum/skins/default/media/images/new.gif
index 8a220b53..8a220b53 100644
--- a/templates/content/images/new.gif
+++ b/forum/skins/default/media/images/new.gif
Binary files differ
diff --git a/templates/content/images/nophoto.png b/forum/skins/default/media/images/nophoto.png
index 2daf0ffd..2daf0ffd 100644
--- a/templates/content/images/nophoto.png
+++ b/forum/skins/default/media/images/nophoto.png
Binary files differ
diff --git a/templates/content/images/openid.gif b/forum/skins/default/media/images/openid.gif
index 8540e12b..8540e12b 100644
--- a/templates/content/images/openid.gif
+++ b/forum/skins/default/media/images/openid.gif
Binary files differ
diff --git a/templates/content/images/openid/aol.gif b/forum/skins/default/media/images/openid/aol.gif
index decc4f12..decc4f12 100644
--- a/templates/content/images/openid/aol.gif
+++ b/forum/skins/default/media/images/openid/aol.gif
Binary files differ
diff --git a/templates/content/images/openid/blogger.ico b/forum/skins/default/media/images/openid/blogger.ico
index 1b9730b0..1b9730b0 100644
--- a/templates/content/images/openid/blogger.ico
+++ b/forum/skins/default/media/images/openid/blogger.ico
Binary files differ
diff --git a/templates/content/images/openid/claimid.ico b/forum/skins/default/media/images/openid/claimid.ico
index 2b80f491..2b80f491 100644
--- a/templates/content/images/openid/claimid.ico
+++ b/forum/skins/default/media/images/openid/claimid.ico
Binary files differ
diff --git a/templates/content/images/openid/facebook.gif b/forum/skins/default/media/images/openid/facebook.gif
index b997b358..b997b358 100644
--- a/templates/content/images/openid/facebook.gif
+++ b/forum/skins/default/media/images/openid/facebook.gif
Binary files differ
diff --git a/templates/content/images/openid/flickr.ico b/forum/skins/default/media/images/openid/flickr.ico
index 11f6e07f..11f6e07f 100644
--- a/templates/content/images/openid/flickr.ico
+++ b/forum/skins/default/media/images/openid/flickr.ico
Binary files differ
diff --git a/templates/content/images/openid/google.gif b/forum/skins/default/media/images/openid/google.gif
index 1b6cd07b..1b6cd07b 100644
--- a/templates/content/images/openid/google.gif
+++ b/forum/skins/default/media/images/openid/google.gif
Binary files differ
diff --git a/templates/content/images/openid/livejournal.ico b/forum/skins/default/media/images/openid/livejournal.ico
index f3d21ec5..f3d21ec5 100644
--- a/templates/content/images/openid/livejournal.ico
+++ b/forum/skins/default/media/images/openid/livejournal.ico
Binary files differ
diff --git a/templates/content/images/openid/myopenid.ico b/forum/skins/default/media/images/openid/myopenid.ico
index ceb06e6a..ceb06e6a 100644
--- a/templates/content/images/openid/myopenid.ico
+++ b/forum/skins/default/media/images/openid/myopenid.ico
Binary files differ
diff --git a/templates/content/images/openid/openid-inputicon.gif b/forum/skins/default/media/images/openid/openid-inputicon.gif
index cde836c8..cde836c8 100644
--- a/templates/content/images/openid/openid-inputicon.gif
+++ b/forum/skins/default/media/images/openid/openid-inputicon.gif
Binary files differ
diff --git a/templates/content/images/openid/openid.gif b/forum/skins/default/media/images/openid/openid.gif
index c718b0e6..c718b0e6 100644
--- a/templates/content/images/openid/openid.gif
+++ b/forum/skins/default/media/images/openid/openid.gif
Binary files differ
diff --git a/templates/content/images/openid/technorati.ico b/forum/skins/default/media/images/openid/technorati.ico
index fa1083c1..fa1083c1 100644
--- a/templates/content/images/openid/technorati.ico
+++ b/forum/skins/default/media/images/openid/technorati.ico
Binary files differ
diff --git a/templates/content/images/openid/verisign.ico b/forum/skins/default/media/images/openid/verisign.ico
index 3953af93..3953af93 100644
--- a/templates/content/images/openid/verisign.ico
+++ b/forum/skins/default/media/images/openid/verisign.ico
Binary files differ
diff --git a/templates/content/images/openid/vidoop.ico b/forum/skins/default/media/images/openid/vidoop.ico
index bbd9a0d5..bbd9a0d5 100644
--- a/templates/content/images/openid/vidoop.ico
+++ b/forum/skins/default/media/images/openid/vidoop.ico
Binary files differ
diff --git a/templates/content/images/openid/wordpress.ico b/forum/skins/default/media/images/openid/wordpress.ico
index 31b7d2c2..31b7d2c2 100644
--- a/templates/content/images/openid/wordpress.ico
+++ b/forum/skins/default/media/images/openid/wordpress.ico
Binary files differ
diff --git a/templates/content/images/openid/yahoo.gif b/forum/skins/default/media/images/openid/yahoo.gif
index 42adbfa5..42adbfa5 100644
--- a/templates/content/images/openid/yahoo.gif
+++ b/forum/skins/default/media/images/openid/yahoo.gif
Binary files differ
diff --git a/templates/content/images/quest-bg.gif b/forum/skins/default/media/images/quest-bg.gif
index b7540238..b7540238 100644
--- a/templates/content/images/quest-bg.gif
+++ b/forum/skins/default/media/images/quest-bg.gif
Binary files differ
diff --git a/templates/content/images/vote-accepted-on.png b/forum/skins/default/media/images/vote-accepted-on.png
index 2026f3bc..2026f3bc 100644
--- a/templates/content/images/vote-accepted-on.png
+++ b/forum/skins/default/media/images/vote-accepted-on.png
Binary files differ
diff --git a/templates/content/images/vote-accepted.png b/forum/skins/default/media/images/vote-accepted.png
index ecd18551..ecd18551 100644
--- a/templates/content/images/vote-accepted.png
+++ b/forum/skins/default/media/images/vote-accepted.png
Binary files differ
diff --git a/templates/content/images/vote-arrow-down-on.png b/forum/skins/default/media/images/vote-arrow-down-on.png
index 048dbb44..048dbb44 100644
--- a/templates/content/images/vote-arrow-down-on.png
+++ b/forum/skins/default/media/images/vote-arrow-down-on.png
Binary files differ
diff --git a/templates/content/images/vote-arrow-down.png b/forum/skins/default/media/images/vote-arrow-down.png
index e4fdec0a..e4fdec0a 100644
--- a/templates/content/images/vote-arrow-down.png
+++ b/forum/skins/default/media/images/vote-arrow-down.png
Binary files differ
diff --git a/templates/content/images/vote-arrow-up-on.png b/forum/skins/default/media/images/vote-arrow-up-on.png
index 56ad0c25..56ad0c25 100644
--- a/templates/content/images/vote-arrow-up-on.png
+++ b/forum/skins/default/media/images/vote-arrow-up-on.png
Binary files differ
diff --git a/templates/content/images/vote-arrow-up.png b/forum/skins/default/media/images/vote-arrow-up.png
index 6e9a51c7..6e9a51c7 100644
--- a/templates/content/images/vote-arrow-up.png
+++ b/forum/skins/default/media/images/vote-arrow-up.png
Binary files differ
diff --git a/templates/content/images/vote-favorite-off.png b/forum/skins/default/media/images/vote-favorite-off.png
index c1bef074..c1bef074 100644
--- a/templates/content/images/vote-favorite-off.png
+++ b/forum/skins/default/media/images/vote-favorite-off.png
Binary files differ
diff --git a/templates/content/images/vote-favorite-on.png b/forum/skins/default/media/images/vote-favorite-on.png
index 1f9c14ab..1f9c14ab 100644
--- a/templates/content/images/vote-favorite-on.png
+++ b/forum/skins/default/media/images/vote-favorite-on.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/aol.gif b/forum/skins/default/media/jquery-openid/images/aol.gif
index decc4f12..decc4f12 100644
--- a/templates/content/jquery-openid/images/aol.gif
+++ b/forum/skins/default/media/jquery-openid/images/aol.gif
Binary files differ
diff --git a/templates/content/jquery-openid/images/blogger-1.png b/forum/skins/default/media/jquery-openid/images/blogger-1.png
index 8b360ea5..8b360ea5 100644
--- a/templates/content/jquery-openid/images/blogger-1.png
+++ b/forum/skins/default/media/jquery-openid/images/blogger-1.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/blogger.ico b/forum/skins/default/media/jquery-openid/images/blogger.ico
index 1b9730b0..1b9730b0 100644
--- a/templates/content/jquery-openid/images/blogger.ico
+++ b/forum/skins/default/media/jquery-openid/images/blogger.ico
Binary files differ
diff --git a/templates/content/jquery-openid/images/claimid-0.png b/forum/skins/default/media/jquery-openid/images/claimid-0.png
index 4a0ea1b3..4a0ea1b3 100644
--- a/templates/content/jquery-openid/images/claimid-0.png
+++ b/forum/skins/default/media/jquery-openid/images/claimid-0.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/claimid.ico b/forum/skins/default/media/jquery-openid/images/claimid.ico
index 2b80f491..2b80f491 100644
--- a/templates/content/jquery-openid/images/claimid.ico
+++ b/forum/skins/default/media/jquery-openid/images/claimid.ico
Binary files differ
diff --git a/templates/content/jquery-openid/images/facebook.gif b/forum/skins/default/media/jquery-openid/images/facebook.gif
index b997b358..b997b358 100644
--- a/templates/content/jquery-openid/images/facebook.gif
+++ b/forum/skins/default/media/jquery-openid/images/facebook.gif
Binary files differ
diff --git a/templates/content/jquery-openid/images/flickr.ico b/forum/skins/default/media/jquery-openid/images/flickr.ico
index 11f6e07f..11f6e07f 100644
--- a/templates/content/jquery-openid/images/flickr.ico
+++ b/forum/skins/default/media/jquery-openid/images/flickr.ico
Binary files differ
diff --git a/templates/content/jquery-openid/images/flickr.png b/forum/skins/default/media/jquery-openid/images/flickr.png
index 142405a6..142405a6 100644
--- a/templates/content/jquery-openid/images/flickr.png
+++ b/forum/skins/default/media/jquery-openid/images/flickr.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/google.gif b/forum/skins/default/media/jquery-openid/images/google.gif
index 1b6cd07b..1b6cd07b 100644
--- a/templates/content/jquery-openid/images/google.gif
+++ b/forum/skins/default/media/jquery-openid/images/google.gif
Binary files differ
diff --git a/templates/content/jquery-openid/images/livejournal-1.png b/forum/skins/default/media/jquery-openid/images/livejournal-1.png
index e6436081..e6436081 100644
--- a/templates/content/jquery-openid/images/livejournal-1.png
+++ b/forum/skins/default/media/jquery-openid/images/livejournal-1.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/livejournal.ico b/forum/skins/default/media/jquery-openid/images/livejournal.ico
index f3d21ec5..f3d21ec5 100644
--- a/templates/content/jquery-openid/images/livejournal.ico
+++ b/forum/skins/default/media/jquery-openid/images/livejournal.ico
Binary files differ
diff --git a/templates/content/jquery-openid/images/myopenid-2.png b/forum/skins/default/media/jquery-openid/images/myopenid-2.png
index f64fb8e8..f64fb8e8 100644
--- a/templates/content/jquery-openid/images/myopenid-2.png
+++ b/forum/skins/default/media/jquery-openid/images/myopenid-2.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/myopenid.ico b/forum/skins/default/media/jquery-openid/images/myopenid.ico
index ceb06e6a..ceb06e6a 100644
--- a/templates/content/jquery-openid/images/myopenid.ico
+++ b/forum/skins/default/media/jquery-openid/images/myopenid.ico
Binary files differ
diff --git a/templates/content/jquery-openid/images/openid-inputicon.gif b/forum/skins/default/media/jquery-openid/images/openid-inputicon.gif
index cde836c8..cde836c8 100644
--- a/templates/content/jquery-openid/images/openid-inputicon.gif
+++ b/forum/skins/default/media/jquery-openid/images/openid-inputicon.gif
Binary files differ
diff --git a/templates/content/jquery-openid/images/openid.gif b/forum/skins/default/media/jquery-openid/images/openid.gif
index c718b0e6..c718b0e6 100644
--- a/templates/content/jquery-openid/images/openid.gif
+++ b/forum/skins/default/media/jquery-openid/images/openid.gif
Binary files differ
diff --git a/templates/content/jquery-openid/images/openidico.png b/forum/skins/default/media/jquery-openid/images/openidico.png
index ab622669..ab622669 100644
--- a/templates/content/jquery-openid/images/openidico.png
+++ b/forum/skins/default/media/jquery-openid/images/openidico.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/openidico16.png b/forum/skins/default/media/jquery-openid/images/openidico16.png
index ad718ac5..ad718ac5 100644
--- a/templates/content/jquery-openid/images/openidico16.png
+++ b/forum/skins/default/media/jquery-openid/images/openidico16.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/technorati-1.png b/forum/skins/default/media/jquery-openid/images/technorati-1.png
index f7195240..f7195240 100644
--- a/templates/content/jquery-openid/images/technorati-1.png
+++ b/forum/skins/default/media/jquery-openid/images/technorati-1.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/technorati.ico b/forum/skins/default/media/jquery-openid/images/technorati.ico
index fa1083c1..fa1083c1 100644
--- a/templates/content/jquery-openid/images/technorati.ico
+++ b/forum/skins/default/media/jquery-openid/images/technorati.ico
Binary files differ
diff --git a/templates/content/jquery-openid/images/verisign-2.png b/forum/skins/default/media/jquery-openid/images/verisign-2.png
index c1467008..c1467008 100644
--- a/templates/content/jquery-openid/images/verisign-2.png
+++ b/forum/skins/default/media/jquery-openid/images/verisign-2.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/verisign.ico b/forum/skins/default/media/jquery-openid/images/verisign.ico
index 3953af93..3953af93 100644
--- a/templates/content/jquery-openid/images/verisign.ico
+++ b/forum/skins/default/media/jquery-openid/images/verisign.ico
Binary files differ
diff --git a/templates/content/jquery-openid/images/vidoop.ico b/forum/skins/default/media/jquery-openid/images/vidoop.ico
index bbd9a0d5..bbd9a0d5 100644
--- a/templates/content/jquery-openid/images/vidoop.ico
+++ b/forum/skins/default/media/jquery-openid/images/vidoop.ico
Binary files differ
diff --git a/templates/content/jquery-openid/images/vidoop.png b/forum/skins/default/media/jquery-openid/images/vidoop.png
index 032c9e98..032c9e98 100644
--- a/templates/content/jquery-openid/images/vidoop.png
+++ b/forum/skins/default/media/jquery-openid/images/vidoop.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/wordpress.ico b/forum/skins/default/media/jquery-openid/images/wordpress.ico
index 31b7d2c2..31b7d2c2 100644
--- a/templates/content/jquery-openid/images/wordpress.ico
+++ b/forum/skins/default/media/jquery-openid/images/wordpress.ico
Binary files differ
diff --git a/templates/content/jquery-openid/images/wordpress.png b/forum/skins/default/media/jquery-openid/images/wordpress.png
index ee29f0cf..ee29f0cf 100644
--- a/templates/content/jquery-openid/images/wordpress.png
+++ b/forum/skins/default/media/jquery-openid/images/wordpress.png
Binary files differ
diff --git a/templates/content/jquery-openid/images/yahoo.gif b/forum/skins/default/media/jquery-openid/images/yahoo.gif
index 42adbfa5..42adbfa5 100644
--- a/templates/content/jquery-openid/images/yahoo.gif
+++ b/forum/skins/default/media/jquery-openid/images/yahoo.gif
Binary files differ
diff --git a/templates/content/jquery-openid/jquery.openid.js b/forum/skins/default/media/jquery-openid/jquery.openid.js
index 8d1cd204..8d1cd204 100644
--- a/templates/content/jquery-openid/jquery.openid.js
+++ b/forum/skins/default/media/jquery-openid/jquery.openid.js
diff --git a/templates/content/jquery-openid/openid.css b/forum/skins/default/media/jquery-openid/openid.css
index 1b7aaf82..1b7aaf82 100644
--- a/templates/content/jquery-openid/openid.css
+++ b/forum/skins/default/media/jquery-openid/openid.css
diff --git a/templates/content/js/com.cnprog.admin.js b/forum/skins/default/media/js/com.cnprog.admin.js
index 974dce23..974dce23 100644
--- a/templates/content/js/com.cnprog.admin.js
+++ b/forum/skins/default/media/js/com.cnprog.admin.js
diff --git a/templates/content/js/com.cnprog.editor.js b/forum/skins/default/media/js/com.cnprog.editor.js
index 18cc5166..18cc5166 100644
--- a/templates/content/js/com.cnprog.editor.js
+++ b/forum/skins/default/media/js/com.cnprog.editor.js
diff --git a/templates/content/js/com.cnprog.i18n.js b/forum/skins/default/media/js/com.cnprog.i18n.js
index 58cb8f16..58cb8f16 100644
--- a/templates/content/js/com.cnprog.i18n.js
+++ b/forum/skins/default/media/js/com.cnprog.i18n.js
diff --git a/templates/content/js/com.cnprog.post.js b/forum/skins/default/media/js/com.cnprog.post.js
index 668c80fe..4325e665 100644
--- a/templates/content/js/com.cnprog.post.js
+++ b/forum/skins/default/media/js/com.cnprog.post.js
@@ -153,17 +153,17 @@ var Vote = function(){
var setVoteImage = function(voteType, undo, object){
var flag = undo ? "" : "-on";
var arrow = (voteType == VoteType.questionUpVote || voteType == VoteType.answerUpVote) ? "up" : "down";
- object.attr("src", scriptUrl + "content/images/vote-arrow-"+ arrow + flag +".png");
+ object.attr("src", mediaUrl("media/images/vote-arrow-"+ arrow + flag +".png"));
// if undo voting, then undo the pair of arrows.
if(undo){
if(voteType == VoteType.questionUpVote || voteType == VoteType.questionDownVote){
- $(getQuestionVoteUpButton()).attr("src", scriptUrl + "content/images/vote-arrow-up.png");
- $(getQuestionVoteDownButton()).attr("src", scriptUrl + "content/images/vote-arrow-down.png");
+ $(getQuestionVoteUpButton()).attr("src", mediaUrl("media/images/vote-arrow-up.png"));
+ $(getQuestionVoteDownButton()).attr("src", mediaUrl("media/images/vote-arrow-down.png"));
}
else{
- $(getAnswerVoteUpButton(postId)).attr("src", scriptUrl + "content/images/vote-arrow-up.png");
- $(getAnswerVoteDownButton(postId)).attr("src", scriptUrl + "content/images/vote-arrow-down.png");
+ $(getAnswerVoteUpButton(postId)).attr("src", mediaUrl("media/images/vote-arrow-up.png"));
+ $(getAnswerVoteDownButton(postId)).attr("src", mediaUrl("media/images/vote-arrow-down.png"));
}
}
};
@@ -259,19 +259,19 @@ var Vote = function(){
showMessage(object, acceptOwnAnswerMessage);
}
else if(data.status == "1"){
- object.attr("src", scriptUrl + "content/images/vote-accepted.png");
+ object.attr("src", mediaUrl("media/images/vote-accepted.png"));
$("#"+answerContainerIdPrefix+postId).removeClass("accepted-answer");
$("#"+commentLinkIdPrefix+postId).removeClass("comment-link-accepted");
}
else if(data.success == "1"){
var acceptedButtons = 'div.'+ voteContainerId +' img[id^='+ imgIdPrefixAccept +']';
- $(acceptedButtons).attr("src", scriptUrl + "content/images/vote-accepted.png");
+ $(acceptedButtons).attr("src", mediaUrl("media/images/vote-accepted.png"));
var answers = ("div[id^="+answerContainerIdPrefix +"]");
$(answers).removeClass("accepted-answer");
var commentLinks = ("div[id^="+answerContainerIdPrefix +"] div[id^="+ commentLinkIdPrefix +"]");
$(commentLinks).removeClass("comment-link-accepted");
- object.attr("src", scriptUrl + "content/images/vote-accepted-on.png");
+ object.attr("src", mediaUrl("media/images/vote-accepted-on.png"));
$("#"+answerContainerIdPrefix+postId).addClass("accepted-answer");
$("#"+commentLinkIdPrefix+postId).addClass("comment-link-accepted");
}
@@ -285,7 +285,7 @@ var Vote = function(){
showMessage(object, favoriteAnonymousMessage.replace("{{QuestionID}}", questionId));
}
else if(data.status == "1"){
- object.attr("src", scriptUrl + "content/images/vote-favorite-off.png");
+ object.attr("src", mediaUrl("media/images/vote-favorite-off.png"));
var fav = getFavoriteNumber();
fav.removeClass("my-favorite-number");
if(data.count === 0){
@@ -294,7 +294,7 @@ var Vote = function(){
fav.text(data.count);
}
else if(data.success == "1"){
- object.attr("src", scriptUrl + "content/images/vote-favorite-on.png");
+ object.attr("src", mediaUrl("media/images/vote-favorite-on.png"));
var fav = getFavoriteNumber();
fav.text(data.count);
fav.addClass("my-favorite-number");
@@ -538,8 +538,8 @@ function createComments(type) {
var renderDeleteCommentIcon = function(post_id, delete_url){
if (canPostComments(post_id)){
var html = '';
- var img = scriptUrl + "content/images/close-small.png";
- var imgHover = scriptUrl + "content/images/close-small-hover.png";
+ var img = mediaUrl("media/images/close-small.png");
+ var imgHover = mediaUrl("media/images/close-small-hover.png");
html += '<img class="delete-icon" onclick="' + objectType + 'Comments.deleteComment($(this), ' + post_id + ', \'' + delete_url + '\')" src="' + img;
html += '" onmouseover="$(this).attr(\'src\', \'' + imgHover + '\')" onmouseout="$(this).attr(\'src\', \'' + img;
html += '\')" title="' + $.i18n._('delete this comment') + '" />';
@@ -624,12 +624,12 @@ function createComments(type) {
delete_icon.click(function(){CommentsClass.deleteComment($(this),comment_id,delete_url);});
delete_icon.unbind('mouseover').bind('mouseover',
function(){
- $(this).attr('src',scriptUrl + 'content/images/close-small-hover.png');
+ $(this).attr('src',mediaUrl('media/images/close-small-hover.png'));
}
);
delete_icon.unbind('mouseout').bind('mouseout',
function(){
- $(this).attr('src',scriptUrl + 'content/images/close-small.png');
+ $(this).attr('src',mediaUrl('media/images/close-small.png'));
}
);
}
diff --git a/templates/content/js/com.cnprog.tag_selector.js b/forum/skins/default/media/js/com.cnprog.tag_selector.js
index 06aefcfc..e3279e65 100644
--- a/templates/content/js/com.cnprog.tag_selector.js
+++ b/forum/skins/default/media/js/com.cnprog.tag_selector.js
@@ -45,10 +45,10 @@ function pickedTags(){
var setupTagDeleteEvents = function(obj,tag_store,tagname,reason,send_ajax){
obj.unbind('mouseover').bind('mouseover', function(){
- $(this).attr('src', scriptUrl + 'content/images/close-small-hover.png');
+ $(this).attr('src', mediaUrl('media/images/close-small-hover.png'));
});
obj.unbind('mouseout').bind('mouseout', function(){
- $(this).attr('src', scriptUrl + 'content/images/close-small-dark.png');
+ $(this).attr('src', mediaUrl('media/images/close-small-dark.png'));
});
obj.click( function(){
unpickTag(tag_store,tagname,reason,send_ajax);
@@ -88,7 +88,7 @@ function pickedTags(){
tag_link.html(tagname);
var del_link = $('<img></img>');
del_link.addClass('delete-icon');
- del_link.attr('src', scriptUrl + 'content/images/close-small-dark.png');
+ del_link.attr('src', mediaUrl('/media/images/close-small-dark.png'));
setupTagDeleteEvents(del_link, to_target, tagname, reason, true);
diff --git a/templates/content/js/com.cnprog.utils.js b/forum/skins/default/media/js/com.cnprog.utils.js
index 4c3aafba..93083288 100644
--- a/templates/content/js/com.cnprog.utils.js
+++ b/forum/skins/default/media/js/com.cnprog.utils.js
@@ -1,7 +1,11 @@
-//var $, scriptUrl;
+//var $, scriptUrl, osqaSkin
+var mediaUrl = function(resource){
+ return scriptUrl + 'm/' + osqaSkin + '/' + resource;
+};
+
var showMessage = function(object, msg) {
var div = $('<div class="vote-notification"><h3>' + msg + '</h3>(' +
- $.i18n._('click to close') + ')</div>');
+ $.i18n._('click to close') + ')</div>');
div.click(function(event) {
$(".vote-notification").fadeOut("fast", function() { $(this).remove(); });
@@ -37,11 +41,11 @@ var notify = function() {
function appendLoader(containerSelector) {
$(containerSelector).append('<img class="ajax-loader" ' +
- 'src="' + scriptUrl + 'content/images/indicator.gif" title="' +
- $.i18n._('loading...') +
- '" alt="' +
- $.i18n._('loading...') +
- '" />');
+ 'src="mediaUrl("media/images/indicator.gif")" title="' +
+ $.i18n._('loading...') +
+ '" alt="' +
+ $.i18n._('loading...') +
+ '" />');
}
function removeLoader() {
diff --git a/templates/content/js/compress.bat b/forum/skins/default/media/js/compress.bat
index 5b2673cf..5b2673cf 100644
--- a/templates/content/js/compress.bat
+++ b/forum/skins/default/media/js/compress.bat
diff --git a/templates/content/js/excanvas.pack.js b/forum/skins/default/media/js/excanvas.pack.js
index 71d6fbd9..71d6fbd9 100644
--- a/templates/content/js/excanvas.pack.js
+++ b/forum/skins/default/media/js/excanvas.pack.js
diff --git a/templates/content/js/flot-build.bat b/forum/skins/default/media/js/flot-build.bat
index f9f32cb7..f9f32cb7 100644
--- a/templates/content/js/flot-build.bat
+++ b/forum/skins/default/media/js/flot-build.bat
diff --git a/templates/content/js/jquery-1.2.6.js b/forum/skins/default/media/js/jquery-1.2.6.js
index 88e661ee..88e661ee 100644
--- a/templates/content/js/jquery-1.2.6.js
+++ b/forum/skins/default/media/js/jquery-1.2.6.js
diff --git a/templates/content/js/jquery-1.2.6.min.js b/forum/skins/default/media/js/jquery-1.2.6.min.js
index 82b98e1d..82b98e1d 100644
--- a/templates/content/js/jquery-1.2.6.min.js
+++ b/forum/skins/default/media/js/jquery-1.2.6.min.js
diff --git a/templates/content/js/jquery.ajaxfileupload.js b/forum/skins/default/media/js/jquery.ajaxfileupload.js
index 75292776..75292776 100644
--- a/templates/content/js/jquery.ajaxfileupload.js
+++ b/forum/skins/default/media/js/jquery.ajaxfileupload.js
diff --git a/templates/content/js/jquery.flot.js b/forum/skins/default/media/js/jquery.flot.js
index 83b61929..83b61929 100644
--- a/templates/content/js/jquery.flot.js
+++ b/forum/skins/default/media/js/jquery.flot.js
diff --git a/templates/content/js/jquery.flot.pack.js b/forum/skins/default/media/js/jquery.flot.pack.js
index a5714f12..a5714f12 100644
--- a/templates/content/js/jquery.flot.pack.js
+++ b/forum/skins/default/media/js/jquery.flot.pack.js
diff --git a/templates/content/js/jquery.form.js b/forum/skins/default/media/js/jquery.form.js
index 443114fd..443114fd 100644
--- a/templates/content/js/jquery.form.js
+++ b/forum/skins/default/media/js/jquery.form.js
diff --git a/templates/content/js/jquery.i18n.js b/forum/skins/default/media/js/jquery.i18n.js
index 0a155a31..0a155a31 100644
--- a/templates/content/js/jquery.i18n.js
+++ b/forum/skins/default/media/js/jquery.i18n.js
diff --git a/templates/content/js/jquery.openid.js b/forum/skins/default/media/js/jquery.openid.js
index 17e58e04..af7d8cb9 100644
--- a/templates/content/js/jquery.openid.js
+++ b/forum/skins/default/media/js/jquery.openid.js
@@ -81,7 +81,7 @@ var openid = {
cookie_name: 'openid_provider',
cookie_path: '/',
- img_path: '/content/images/openid/',
+ img_path: '/media/images/openid/',
input_id: null,
provider_url: null,
diff --git a/templates/content/js/jquery.validate.pack.js b/forum/skins/default/media/js/jquery.validate.pack.js
index 49134500..49134500 100644
--- a/templates/content/js/jquery.validate.pack.js
+++ b/forum/skins/default/media/js/jquery.validate.pack.js
diff --git a/templates/content/js/se_hilite.js b/forum/skins/default/media/js/se_hilite.js
index 42e99c8e..42e99c8e 100644
--- a/templates/content/js/se_hilite.js
+++ b/forum/skins/default/media/js/se_hilite.js
diff --git a/templates/content/js/se_hilite_src.js b/forum/skins/default/media/js/se_hilite_src.js
index b604f156..b604f156 100644
--- a/templates/content/js/se_hilite_src.js
+++ b/forum/skins/default/media/js/se_hilite_src.js
diff --git a/templates/content/js/wmd/images/wmd-buttons.png b/forum/skins/default/media/js/wmd/images/wmd-buttons.png
index 50b37090..50b37090 100644
--- a/templates/content/js/wmd/images/wmd-buttons.png
+++ b/forum/skins/default/media/js/wmd/images/wmd-buttons.png
Binary files differ
diff --git a/templates/content/js/wmd/showdown-min.js b/forum/skins/default/media/js/wmd/showdown-min.js
index 073613b1..073613b1 100644
--- a/templates/content/js/wmd/showdown-min.js
+++ b/forum/skins/default/media/js/wmd/showdown-min.js
diff --git a/templates/content/js/wmd/showdown.js b/forum/skins/default/media/js/wmd/showdown.js
index 3f4b9947..3f4b9947 100644
--- a/templates/content/js/wmd/showdown.js
+++ b/forum/skins/default/media/js/wmd/showdown.js
diff --git a/forum/skins/default/media/js/wmd/wmd-min.js b/forum/skins/default/media/js/wmd/wmd-min.js
new file mode 100644
index 00000000..aa643f1a
--- /dev/null
+++ b/forum/skins/default/media/js/wmd/wmd-min.js
@@ -0,0 +1 @@
+var Attacklab=Attacklab||{};Attacklab.wmdBase=function(){var y=top.Attacklab;var E=top.document;var s=top.RegExp;var l=top.navigator;y.Util={};y.Position={};y.Command={};y.Global={};var a=y.Util;var C=y.Position;var h=y.Command;var v=y.Global;v.isIE=/msie/.test(l.userAgent.toLowerCase());v.isIE_5or6=/msie 6/.test(l.userAgent.toLowerCase())||/msie 5/.test(l.userAgent.toLowerCase());v.isIE_7plus=v.isIE&&!v.isIE_5or6;v.isOpera=/opera/.test(l.userAgent.toLowerCase());v.isKonqueror=/konqueror/.test(l.userAgent.toLowerCase());var c="粗体 <strong> Ctrl-B";var f="斜体 <em> Ctrl-I";var z="超链接 <a> Ctrl-L";var u="引用 <blockquote> Ctrl-.";var e="代码 <pre><code> Ctrl-K";var d="图片 <img> Ctrl-G";var q="数字编号列表 <ol> Ctrl-O";var t="项目符号列表 <ul> Ctrl-U";var i="标题 <h1>/<h2> Ctrl-H";var p="水平线 <hr> Ctrl-R";var m="撤销 Ctrl-Z";var j="重做 Ctrl-Y";var B="<p style='margin-top: 0px'><b>输入图片地址</b></p><p>示例:<br />http://www.cnprog.com/images/temp.jpg \"我的截图\"</p>";var D="<p style='margin-top: 0px'><b>输入Web地址</b></p><p>示例:<br />http://www.cnprog.com/ \"我的网站\"</p>";var n='<div>或者上传本地图片:</div><input type="file" name="file-upload" id="file-upload" size="26" onchange="return ajaxFileUpload($(\'#image-url\'));"/><br><img id="loading" src="/media/images/indicator.gif" style="display:none;"/>';var b="http://";var g="http://";var o="images/";var A=500;var x=100;var k="http://wmd-editor.com/";var r="WMD website";var w="_blank";y.PanelCollection=function(){this.buttonBar=E.getElementById("wmd-button-bar");this.preview=E.getElementById("previewer");this.output=E.getElementById("wmd-output");this.input=E.getElementById("editor")};y.panels=undefined;y.ieCachedRange=null;y.ieRetardedClick=false;a.isVisible=function(F){if(window.getComputedStyle){return window.getComputedStyle(F,null).getPropertyValue("display")!=="none"}else{if(F.currentStyle){return F.currentStyle.display!=="none"}}};a.addEvent=function(G,F,H){if(G.attachEvent){G.attachEvent("on"+F,H)}else{G.addEventListener(F,H,false)}};a.removeEvent=function(G,F,H){if(G.detachEvent){G.detachEvent("on"+F,H)}else{G.removeEventListener(F,H,false)}};a.fixEolChars=function(F){F=F.replace(/\r\n/g,"\n");F=F.replace(/\r/g,"\n");return F};a.extendRegExp=function(H,J,G){if(J===null||J===undefined){J=""}if(G===null||G===undefined){G=""}var I=H.toString();var F;I=I.replace(/\/([gim]*)$/,"");F=s.$1;I=I.replace(/(^\/|\/$)/g,"");I=J+I+G;return new s(I,F)};a.createImage=function(F){var H=o+F;var G=E.createElement("img");G.className="wmd-button";G.src=H;return G};a.prompt=function(M,P,H){var I;var F;var K;var J=0;if(arguments.length==4){J=arguments[3]}if(P===undefined){P=""}var L=function(Q){var R=(Q.charCode||Q.keyCode);if(R===27){N(true)}};var N=function(Q){a.removeEvent(E.body,"keydown",L);var R=K.value;if(Q){R=null}else{R=R.replace("http://http://","http://");R=R.replace("http://https://","https://");R=R.replace("http://ftp://","ftp://");if(R.indexOf("http://")===-1&&R.indexOf("ftp://")===-1){R="http://"+R}}I.parentNode.removeChild(I);F.parentNode.removeChild(F);H(R);return false};var G=function(){F=E.createElement("div");F.className="wmd-prompt-background";style=F.style;style.position="absolute";style.top="0";style.zIndex="1000";if(v.isKonqueror){style.backgroundColor="transparent"}else{if(v.isIE){style.filter="alpha(opacity=50)"}else{style.opacity="0.5"}}var Q=C.getPageSize();style.height=Q[1]+"px";if(v.isIE){style.left=E.documentElement.scrollLeft;style.width=E.documentElement.clientWidth}else{style.left="0";style.width="100%"}E.body.appendChild(F)};var O=function(){I=E.createElement("div");I.className="wmd-prompt-dialog";I.style.padding="10px;";I.style.position="fixed";I.style.width="400px";I.style.zIndex="1001";var Q=E.createElement("div");Q.innerHTML=M;Q.style.padding="5px";I.appendChild(Q);var S=E.createElement("form");S.onsubmit=function(){return N(false)};style=S.style;style.padding="0";style.margin="0";style.cssFloat="left";style.width="100%";style.textAlign="center";style.position="relative";I.appendChild(S);K=E.createElement("input");if(J==1){K.id="image-url"}K.type="text";K.value=P;style=K.style;style.display="block";style.width="80%";style.marginLeft=style.marginRight="auto";S.appendChild(K);if(J==1){var R=E.createElement("div");R.innerHTML=n;R.style.padding="5px";S.appendChild(R)}var U=E.createElement("input");U.type="button";U.onclick=function(){return N(false)};U.value="OK";style=U.style;style.margin="10px";style.display="inline";style.width="7em";var T=E.createElement("input");T.type="button";T.onclick=function(){return N(true)};T.value="Cancel";style=T.style;style.margin="10px";style.display="inline";style.width="7em";if(/mac/.test(l.platform.toLowerCase())){S.appendChild(T);S.appendChild(U)}else{S.appendChild(U);S.appendChild(T)}a.addEvent(E.body,"keydown",L);I.style.top="50%";I.style.left="50%";I.style.display="block";if(v.isIE_5or6){I.style.position="absolute";I.style.top=E.documentElement.scrollTop+200+"px";I.style.left="50%"}E.body.appendChild(I);I.style.marginTop=-(C.getHeight(I)/2)+"px";I.style.marginLeft=-(C.getWidth(I)/2)+"px"};G();top.setTimeout(function(){O();var R=P.length;if(K.selectionStart!==undefined){K.selectionStart=0;K.selectionEnd=R}else{if(K.createTextRange){var Q=K.createTextRange();Q.collapse(false);Q.moveStart("character",-R);Q.moveEnd("character",R);Q.select()}}K.focus()},0)};C.getTop=function(H,G){var F=H.offsetTop;if(!G){while(H=H.offsetParent){F+=H.offsetTop}}return F};C.getHeight=function(F){return F.offsetHeight||F.scrollHeight};C.getWidth=function(F){return F.offsetWidth||F.scrollWidth};C.getPageSize=function(){var G,H;var F,K;if(self.innerHeight&&self.scrollMaxY){G=E.body.scrollWidth;H=self.innerHeight+self.scrollMaxY}else{if(E.body.scrollHeight>E.body.offsetHeight){G=E.body.scrollWidth;H=E.body.scrollHeight}else{G=E.body.offsetWidth;H=E.body.offsetHeight}}if(self.innerHeight){F=self.innerWidth;K=self.innerHeight}else{if(E.documentElement&&E.documentElement.clientHeight){F=E.documentElement.clientWidth;K=E.documentElement.clientHeight}else{if(E.body){F=E.body.clientWidth;K=E.body.clientHeight}}}var J=Math.max(G,F);var I=Math.max(H,K);return[J,I,F,K]};y.inputPoller=function(O,H){var F=this;var K=y.panels.input;var G;var I;var L;var J;this.tick=function(){if(!a.isVisible(K)){return}if(K.selectionStart||K.selectionStart===0){var Q=K.selectionStart;var P=K.selectionEnd;if(Q!=G||P!=I){G=Q;I=P;if(L!=K.value){L=K.value;return true}}}return false};var N=function(){if(!a.isVisible(K)){return}if(F.tick()){O()}};var M=function(){J=top.setInterval(N,H)};this.destroy=function(){top.clearInterval(J)};M()};y.undoManager=function(Q){var U=this;var O=[];var M=0;var L="none";var G;var R;var H;var K;var F=function(W,V){if(L!=W){L=W;if(!V){I()}}if(!v.isIE||L!="moving"){H=top.setTimeout(N,1)}else{K=null}};var N=function(){K=new y.TextareaState();R.tick();H=undefined};this.setCommandMode=function(){L="command";I();H=top.setTimeout(N,0)};this.canUndo=function(){return M>1};this.canRedo=function(){if(O[M+1]){return true}return false};this.undo=function(){if(U.canUndo()){if(G){G.restore();G=null}else{O[M]=new y.TextareaState();O[--M].restore();if(Q){Q()}}}L="none";y.panels.input.focus();N()};this.redo=function(){if(U.canRedo()){O[++M].restore();if(Q){Q()}}L="none";y.panels.input.focus();N()};var I=function(){var V=K||new y.TextareaState();if(!V){return false}if(L=="moving"){if(!G){G=V}return}if(G){if(O[M-1].text!=G.text){O[M++]=G}G=null}O[M++]=V;O[M+1]=null;if(Q){Q()}};var P=function(V){var X=false;if(V.ctrlKey||V.metaKey){var W=V.charCode||V.keyCode;var Y=String.fromCharCode(W);switch(Y){case"y":U.redo();X=true;break;case"z":if(!V.shiftKey){U.undo()}else{U.redo()}X=true;break}}if(X){if(V.preventDefault){V.preventDefault()}if(top.event){top.event.returnValue=false}return}};var T=function(V){if(!V.ctrlKey&&!V.metaKey){var W=V.keyCode;if((W>=33&&W<=40)||(W>=63232&&W<=63235)){F("moving")}else{if(W==8||W==46||W==127){F("deleting")}else{if(W==13){F("newlines")}else{if(W==27){F("escape")}else{if((W<16||W>20)&&W!=91){F("typing")}}}}}}};var J=function(){a.addEvent(y.panels.input,"keypress",function(W){if((W.ctrlKey||W.metaKey)&&(W.keyCode==89||W.keyCode==90)){W.preventDefault()}});var V=function(){if(v.isIE||(K&&K.text!=y.panels.input.value)){if(H==undefined){L="paste";I();N()}}};R=new y.inputPoller(V,x);a.addEvent(y.panels.input,"keydown",P);a.addEvent(y.panels.input,"keydown",T);a.addEvent(y.panels.input,"mousedown",function(){F("moving")});y.panels.input.onpaste=V;y.panels.input.ondrop=V};var S=function(){J();N();I()};this.destroy=function(){if(R){R.destroy()}};S()};y.editor=function(O){if(!O){O=function(){}}var L=y.panels.input;var I=0;var P=this;var K;var R;var G;var M;var N;var U=function(W){L.focus();if(W.textOp){if(N){N.setCommandMode()}var Y=new y.TextareaState();if(!Y){return}var Z=Y.getChunks();var V=function(){L.focus();if(Z){Y.setChunks(Z)}Y.restore();O()};var X=W.textOp(Z,V);if(!X){V()}}if(W.execute){W.execute(P)}};var S=function(){if(N){F(document.getElementById("wmd-undo-button"),N.canUndo());F(document.getElementById("wmd-redo-button"),N.canRedo())}};var F=function(V,X){var Y="0px";var Z="-20px";var W="-40px";if(X){V.style.backgroundPosition=V.XShift+" "+Y;V.onmouseover=function(){this.style.backgroundPosition=this.XShift+" "+W};V.onmouseout=function(){this.style.backgroundPosition=this.XShift+" "+Y};if(v.isIE){V.onmousedown=function(){y.ieRetardedClick=true;y.ieCachedRange=document.selection.createRange()}}if(!V.isHelp){V.onclick=function(){if(this.onmouseout){this.onmouseout()}U(this);return false}}}else{V.style.backgroundPosition=V.XShift+" "+Z;V.onmouseover=V.onmouseout=V.onclick=function(){}}};var J=function(){var Z=document.getElementById("wmd-button-bar");var W="0px";var Y="-20px";var ae="-40px";var ak=document.createElement("ul");ak.id="wmd-button-row";ak=Z.appendChild(ak);var ad=document.createElement("li");ad.className="wmd-button";ad.id="wmd-bold-button";ad.title=c;ad.XShift="0px";ad.textOp=h.doBold;F(ad,true);ak.appendChild(ad);var ac=document.createElement("li");ac.className="wmd-button";ac.id="wmd-italic-button";ac.title=f;ac.XShift="-20px";ac.textOp=h.doItalic;F(ac,true);ak.appendChild(ac);var ah=document.createElement("li");ah.className="wmd-spacer";ah.id="wmd-spacer1";ak.appendChild(ah);var ai=document.createElement("li");ai.className="wmd-button";ai.id="wmd-link-button";ai.title=z;ai.XShift="-40px";ai.textOp=function(ap,aq){return h.doLinkOrImage(ap,aq,false)};F(ai,true);ak.appendChild(ai);var al=document.createElement("li");al.className="wmd-button";al.id="wmd-quote-button";al.title=u;al.XShift="-60px";al.textOp=h.doBlockquote;F(al,true);ak.appendChild(al);var am=document.createElement("li");am.className="wmd-button";am.id="wmd-code-button";am.title=e;am.XShift="-80px";am.textOp=h.doCode;F(am,true);ak.appendChild(am);var aa=document.createElement("li");aa.className="wmd-button";aa.id="wmd-image-button";aa.title=d;aa.XShift="-100px";aa.textOp=function(ap,aq){return h.doLinkOrImage(ap,aq,true)};F(aa,true);ak.appendChild(aa);var ag=document.createElement("li");ag.className="wmd-spacer";ag.id="wmd-spacer2";ak.appendChild(ag);var ab=document.createElement("li");ab.className="wmd-button";ab.id="wmd-olist-button";ab.title=q;ab.XShift="-120px";ab.textOp=function(ap,aq){h.doList(ap,aq,true)};F(ab,true);ak.appendChild(ab);var ao=document.createElement("li");ao.className="wmd-button";ao.id="wmd-ulist-button";ao.title=t;ao.XShift="-140px";ao.textOp=function(ap,aq){h.doList(ap,aq,false)};F(ao,true);ak.appendChild(ao);var aj=document.createElement("li");aj.className="wmd-button";aj.id="wmd-heading-button";aj.title=i;aj.XShift="-160px";aj.textOp=h.doHeading;F(aj,true);ak.appendChild(aj);var X=document.createElement("li");X.className="wmd-button";X.id="wmd-hr-button";X.title=p;X.XShift="-180px";X.textOp=h.doHorizontalRule;F(X,true);ak.appendChild(X);var af=document.createElement("li");af.className="wmd-spacer";af.id="wmd-spacer3";ak.appendChild(af);var V=document.createElement("li");V.className="wmd-button";V.id="wmd-undo-button";V.title=m;V.XShift="-200px";V.execute=function(ap){ap.undo()};F(V,true);ak.appendChild(V);var an=document.createElement("li");an.className="wmd-button";an.id="wmd-redo-button";an.title=j;if(/win/.test(l.platform.toLowerCase())){an.title=j}else{an.title="重做 - Ctrl+Shift+Z"}an.XShift="-220px";an.execute=function(ap){ap.redo()};F(an,true);ak.appendChild(an);S()};var H=function(){if(/\?noundo/.test(E.location.href)){y.nativeUndo=true}if(!y.nativeUndo){N=new y.undoManager(function(){O();S()})}J();var W="keydown";if(v.isOpera){W="keypress"}a.addEvent(L,W,function(Y){if(Y.ctrlKey||Y.metaKey){var Z=Y.charCode||Y.keyCode;var X=String.fromCharCode(Z).toLowerCase();if(Z===46){X=""}if(Z===190){X="."}switch(X){case"b":U(document.getElementById("wmd-bold-button"));break;case"i":U(document.getElementById("wmd-italic-button"));break;case"l":U(document.getElementById("wmd-link-button"));break;case".":U(document.getElementById("wmd-quote-button"));break;case"k":U(document.getElementById("wmd-code-button"));break;case"g":U(document.getElementById("wmd-image-button"));break;case"o":U(document.getElementById("wmd-olist-button"));break;case"u":U(document.getElementById("wmd-ulist-button"));break;case"h":U(document.getElementById("wmd-heading-button"));break;case"r":U(document.getElementById("wmd-hr-button"));break;case"y":U(document.getElementById("wmd-redo-button"));break;case"z":if(Y.shiftKey){U(document.getElementById("wmd-redo-button"))}else{U(document.getElementById("wmd-undo-button"))}break;default:return}if(Y.preventDefault){Y.preventDefault()}if(top.event){top.event.returnValue=false}}});a.addEvent(L,"keyup",function(X){if(X.shiftKey&&!X.ctrlKey&&!X.metaKey){var Y=X.charCode||X.keyCode;if(Y===13){fakeButton={};fakeButton.textOp=h.doAutoindent;U(fakeButton)}}});if(L.form){var V=L.form.onsubmit;L.form.onsubmit=function(){Q();if(V){return V.apply(this,arguments)}}}};var Q=function(){if(y.showdown){var V=new y.showdown.converter()}var W=L.value;var X=function(){L.value=W};if(!/markdown/.test(y.wmd_env.output.toLowerCase())){if(V){L.value=V.makeHtml(W);top.setTimeout(X,0)}}return true};this.undo=function(){if(N){N.undo()}};this.redo=function(){if(N){N.redo()}};var T=function(){H()};this.destroy=function(){if(N){N.destroy()}if(G.parentNode){G.parentNode.removeChild(G)}if(L){L.style.marginTop=""}top.clearInterval(M)};T()};y.TextareaState=function(){var F=this;var G=y.panels.input;this.init=function(){if(!a.isVisible(G)){return}this.setInputAreaSelectionStartEnd();this.scrollTop=G.scrollTop;if(!this.text&&G.selectionStart||G.selectionStart===0){this.text=G.value}};this.setInputAreaSelection=function(){if(!a.isVisible(G)){return}if(G.selectionStart!==undefined&&!v.isOpera){G.focus();G.selectionStart=F.start;G.selectionEnd=F.end;G.scrollTop=F.scrollTop}else{if(E.selection){if(E.activeElement&&E.activeElement!==G){return}G.focus();var H=G.createTextRange();H.moveStart("character",-G.value.length);H.moveEnd("character",-G.value.length);H.moveEnd("character",F.end);H.moveStart("character",F.start);H.select()}}};this.setInputAreaSelectionStartEnd=function(){if(G.selectionStart||G.selectionStart===0){F.start=G.selectionStart;F.end=G.selectionEnd}else{if(E.selection){F.text=a.fixEolChars(G.value);var K;if(y.ieRetardedClick&&y.ieCachedRange){K=y.ieCachedRange;y.ieRetardedClick=false}else{K=E.selection.createRange()}var L=a.fixEolChars(K.text);var J="\x07";var I=J+L+J;K.text=I;var M=a.fixEolChars(G.value);K.moveStart("character",-I.length);K.text=L;F.start=M.indexOf(J);F.end=M.lastIndexOf(J)-J.length;var H=F.text.length-a.fixEolChars(G.value).length;if(H){K.moveStart("character",-L.length);while(H--){L+="\n";F.end+=1}K.text=L}this.setInputAreaSelection()}}};this.restore=function(){if(F.text!=undefined&&F.text!=G.value){G.value=F.text}this.setInputAreaSelection();G.scrollTop=F.scrollTop};this.getChunks=function(){var H=new y.Chunks();H.before=a.fixEolChars(F.text.substring(0,F.start));H.startTag="";H.selection=a.fixEolChars(F.text.substring(F.start,F.end));H.endTag="";H.after=a.fixEolChars(F.text.substring(F.end));H.scrollTop=F.scrollTop;return H};this.setChunks=function(H){H.before=H.before+H.startTag;H.after=H.endTag+H.after;if(v.isOpera){H.before=H.before.replace(/\n/g,"\r\n");H.selection=H.selection.replace(/\n/g,"\r\n");H.after=H.after.replace(/\n/g,"\r\n")}this.start=H.before.length;this.end=H.before.length+H.selection.length;this.text=H.before+H.selection+H.after;this.scrollTop=H.scrollTop};this.init()};y.Chunks=function(){};y.Chunks.prototype.findTags=function(G,I){var F=this;var H;if(G){H=a.extendRegExp(G,"","$");this.before=this.before.replace(H,function(J){F.startTag=F.startTag+J;return""});H=a.extendRegExp(G,"^","");this.selection=this.selection.replace(H,function(J){F.startTag=F.startTag+J;return""})}if(I){H=a.extendRegExp(I,"","$");this.selection=this.selection.replace(H,function(J){F.endTag=J+F.endTag;return""});H=a.extendRegExp(I,"^","");this.after=this.after.replace(H,function(J){F.endTag=J+F.endTag;return""})}};y.Chunks.prototype.trimWhitespace=function(F){this.selection=this.selection.replace(/^(\s*)/,"");if(!F){this.before+=s.$1}this.selection=this.selection.replace(/(\s*)$/,"");if(!F){this.after=s.$1+this.after}};y.Chunks.prototype.skipLines=function(H,G,F){if(H===undefined){H=1}if(G===undefined){G=1}H++;G++;var I;var J;this.selection=this.selection.replace(/(^\n*)/,"");this.startTag=this.startTag+s.$1;this.selection=this.selection.replace(/(\n*$)/,"");this.endTag=this.endTag+s.$1;this.startTag=this.startTag.replace(/(^\n*)/,"");this.before=this.before+s.$1;this.endTag=this.endTag.replace(/(\n*$)/,"");this.after=this.after+s.$1;if(this.before){I=J="";while(H--){I+="\\n?";J+="\n"}if(F){I="\\n*"}this.before=this.before.replace(new s(I+"$",""),J)}if(this.after){I=J="";while(G--){I+="\\n?";J+="\n"}if(F){I="\\n*"}this.after=this.after.replace(new s(I,""),J)}};h.prefixes="(?:\\s{4,}|\\s*>|\\s*-\\s+|\\s*\\d+\\.|=|\\+|-|_|\\*|#|\\s*\\[[^\n]]+\\]:)";h.unwrap=function(G){var F=new s("([^\\n])\\n(?!(\\n|"+h.prefixes+"))","g");G.selection=G.selection.replace(F,"$1 $2")};h.wrap=function(G,F){h.unwrap(G);var H=new s("(.{1,"+F+"})( +|$\\n?)","gm");G.selection=G.selection.replace(H,function(I,J){if(new s("^"+h.prefixes,"").test(I)){return I}return J+"\n"});G.selection=G.selection.replace(/\s+$/,"")};h.doBold=function(F,G){return h.doBorI(F,G,2,"strong text")};h.doItalic=function(F,G){return h.doBorI(F,G,1,"emphasized text")};h.doBorI=function(L,J,K,F){L.trimWhitespace();L.selection=L.selection.replace(/\n{2,}/g,"\n");L.before.search(/(\**$)/);var I=s.$1;L.after.search(/(^\**)/);var G=s.$1;var M=Math.min(I.length,G.length);if((M>=K)&&(M!=2||K!=1)){L.before=L.before.replace(s("[*]{"+K+"}$",""),"");L.after=L.after.replace(s("^[*]{"+K+"}",""),"")}else{if(!L.selection&&G){L.after=L.after.replace(/^([*_]*)/,"");L.before=L.before.replace(/(\s?)$/,"");var H=s.$1;L.before=L.before+G+H}else{if(!L.selection&&!G){L.selection=F}var N=K<=1?"*":"**";L.before=L.before+N;L.after=N+L.after}}return};h.stripLinkDefs=function(G,F){G=G.replace(/^[ ]{0,3}\[(\d+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|$)/gm,function(K,L,H,I,J){F[L]=K.replace(/\s*$/,"");if(I){F[L]=K.replace(/["(](.+?)[")]$/,"");return I+J}return""});return G};h.addLinkDef=function(M,I){var F=0;var H={};M.before=h.stripLinkDefs(M.before,H);M.selection=h.stripLinkDefs(M.selection,H);M.after=h.stripLinkDefs(M.after,H);var G="";var L=/(\[(?:\[[^\]]*\]|[^\[\]])*\][ ]?(?:\n[ ]*)?\[)(\d+)(\])/g;var K=function(O){F++;O=O.replace(/^[ ]{0,3}\[(\d+)\]:/," ["+F+"]:");G+="\n"+O};var J=function(P,Q,R,O){if(H[R]){K(H[R]);return Q+F+O}return P};M.before=M.before.replace(L,J);if(I){K(I)}else{M.selection=M.selection.replace(L,J)}var N=F;M.after=M.after.replace(L,J);if(M.after){M.after=M.after.replace(/\n*$/,"")}if(!M.after){M.selection=M.selection.replace(/\n*$/,"")}M.after+="\n\n"+G;return N};h.doLinkOrImage=function(F,G,I){F.trimWhitespace();F.findTags(/\s*!?\[/,/\][ ]?(?:\n[ ]*)?(\[.*?\])?/);if(F.endTag.length>1){F.startTag=F.startTag.replace(/!?\[/,"");F.endTag="";h.addLinkDef(F,null)}else{if(/\n\n/.test(F.selection)){h.addLinkDef(F,null);return}var H=function(L){if(L!==null){F.startTag=F.endTag="";var K=" [999]: "+L;var J=h.addLinkDef(F,K);F.startTag=I?"![":"[";F.endTag="]["+J+"]";if(!F.selection){if(I){F.selection="alt text"}else{F.selection="link text"}}}G()};if(I){a.prompt(B,b,H,1)}else{a.prompt(D,g,H)}return true}};a.makeAPI=function(){y.wmd={};y.wmd.editor=y.editor;y.wmd.previewManager=y.previewManager};a.startEditor=function(){if(y.wmd_env.autostart===false){a.makeAPI();return}var G;var F;var H=function(){y.panels=new y.PanelCollection();F=new y.previewManager();var I=F.refresh;G=new y.editor(I);F.refresh(true)};a.addEvent(top,"load",H)};y.previewManager=function(){var H=this;var V;var F;var N;var M;var S;var O;var I=3000;var P="delayed";var K=function(X,Y){a.addEvent(X,"input",Y);X.onpaste=Y;X.ondrop=Y;a.addEvent(X,"keypress",Y);a.addEvent(X,"keydown",Y);F=new y.inputPoller(Y,A)};var R=function(){var X=0;if(top.innerHeight){X=top.pageYOffset}else{if(E.documentElement&&E.documentElement.scrollTop){X=E.documentElement.scrollTop}else{if(E.body){X=E.body.scrollTop}}}return X};var L=function(){if(!y.panels.preview&&!y.panels.output){return}var Z=y.panels.input.value;if(Z&&Z==S){return}else{S=Z}var Y=new Date().getTime();if(!V&&y.showdown){V=new y.showdown.converter()}if(V){Z=V.makeHtml(Z)}var X=new Date().getTime();M=X-Y;G(Z);O=Z};var U=function(){if(N){top.clearTimeout(N);N=undefined}if(P!=="manual"){var X=0;if(P==="delayed"){X=M}if(X>I){X=I}N=top.setTimeout(L,X)}};var J=function(X){if(X.scrollHeight<=X.clientHeight){return 1}return X.scrollTop/(X.scrollHeight-X.clientHeight)};var W=function(){if(y.panels.preview){y.panels.preview.scrollTop=(y.panels.preview.scrollHeight-y.panels.preview.clientHeight)*J(y.panels.preview)}if(y.panels.output){y.panels.output.scrollTop=(y.panels.output.scrollHeight-y.panels.output.clientHeight)*J(y.panels.output)}};this.refresh=function(X){if(X){S="";L()}else{U()}};this.processingTime=function(){return M};this.output=function(){return O};this.setUpdateMode=function(X){P=X;H.refresh()};var Q=true;var G=function(aa){var X=C.getTop(y.panels.input)-R();if(y.panels.output){if(y.panels.output.value!==undefined){y.panels.output.value=aa;y.panels.output.readOnly=true}else{var Z=aa.replace(/&/g,"&amp;");Z=Z.replace(/</g,"&lt;");y.panels.output.innerHTML="<pre><code>"+Z+"</code></pre>"}}if(y.panels.preview){y.panels.preview.innerHTML=aa}W();if(Q){Q=false;return}var Y=C.getTop(y.panels.input)-R();if(v.isIE){top.setTimeout(function(){top.scrollBy(0,Y-X)},0)}else{top.scrollBy(0,Y-X)}};var T=function(){K(y.panels.input,U);L();if(y.panels.preview){y.panels.preview.scrollTop=0}if(y.panels.output){y.panels.output.scrollTop=0}};this.destroy=function(){if(F){F.destroy()}};T()};h.doAutoindent=function(F,G){F.before=F.before.replace(/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]*\n$/,"\n\n");F.before=F.before.replace(/(\n|^)[ ]{0,3}>[ \t]*\n$/,"\n\n");F.before=F.before.replace(/(\n|^)[ \t]+\n$/,"\n\n");if(/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]+.*\n$/.test(F.before)){if(h.doList){h.doList(F)}}if(/(\n|^)[ ]{0,3}>[ \t]+.*\n$/.test(F.before)){if(h.doBlockquote){h.doBlockquote(F)}}if(/(\n|^)(\t|[ ]{4,}).*\n$/.test(F.before)){if(h.doCode){h.doCode(F)}}};h.doBlockquote=function(F,G){F.selection=F.selection.replace(/^(\n*)([^\r]+?)(\n*)$/,function(L,K,J,I){F.before+=K;F.after=I+F.after;return J});F.before=F.before.replace(/(>[ \t]*)$/,function(J,I){F.selection=I+F.selection;return""});F.selection=F.selection.replace(/^(\s|>)+$/,"");F.selection=F.selection||"Blockquote";if(F.before){F.before=F.before.replace(/\n?$/,"\n")}if(F.after){F.after=F.after.replace(/^\n?/,"\n")}F.before=F.before.replace(/(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*$)/,function(I){F.startTag=I;return""});F.after=F.after.replace(/^(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*)/,function(I){F.endTag=I;return""});var H=function(J){var I=J?"> ":"";if(F.startTag){F.startTag=F.startTag.replace(/\n((>|\s)*)\n$/,function(L,K){return"\n"+K.replace(/^[ ]{0,3}>?[ \t]*$/gm,I)+"\n"})}if(F.endTag){F.endTag=F.endTag.replace(/^\n((>|\s)*)\n/,function(L,K){return"\n"+K.replace(/^[ ]{0,3}>?[ \t]*$/gm,I)+"\n"})}};if(/^(?![ ]{0,3}>)/m.test(F.selection)){h.wrap(F,y.wmd_env.lineLength-2);F.selection=F.selection.replace(/^/gm,"> ");H(true);F.skipLines()}else{F.selection=F.selection.replace(/^[ ]{0,3}> ?/gm,"");h.unwrap(F);H(false);if(!/^(\n|^)[ ]{0,3}>/.test(F.selection)&&F.startTag){F.startTag=F.startTag.replace(/\n{0,2}$/,"\n\n")}if(!/(\n|^)[ ]{0,3}>.*$/.test(F.selection)&&F.endTag){F.endTag=F.endTag.replace(/^\n{0,2}/,"\n\n")}}if(!/\n/.test(F.selection)){F.selection=F.selection.replace(/^(> *)/,function(I,J){F.startTag+=J;return""})}};h.doCode=function(F,G){var I=/\S[ ]*$/.test(F.before);var K=/^[ ]*\S/.test(F.after);if((!K&&!I)||/\n/.test(F.selection)){F.before=F.before.replace(/[ ]{4}$/,function(L){F.selection=L+F.selection;return""});var J=1;var H=1;if(/\n(\t|[ ]{4,}).*\n$/.test(F.before)){J=0}if(/^\n(\t|[ ]{4,})/.test(F.after)){H=0}F.skipLines(J,H);if(!F.selection){F.startTag=" ";F.selection="enter code here"}else{if(/^[ ]{0,3}\S/m.test(F.selection)){F.selection=F.selection.replace(/^/gm," ")}else{F.selection=F.selection.replace(/^[ ]{4}/gm,"")}}}else{F.trimWhitespace();F.findTags(/`/,/`/);if(!F.startTag&&!F.endTag){F.startTag=F.endTag="`";if(!F.selection){F.selection="enter code here"}}else{if(F.endTag&&!F.startTag){F.before+=F.endTag;F.endTag=""}else{F.startTag=F.endTag=""}}}};h.doList=function(Q,J,I){var S=/(\n|^)(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*$/;var R=/^\n*(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*/;var F="-";var N=1;var L=function(){var T;if(I){T=" "+N+". ";N++}else{T=" "+F+" "}return T};var M=function(T){if(I===undefined){I=/^\s*\d/.test(T)}T=T.replace(/^[ ]{0,3}([*+-]|\d+[.])\s/gm,function(U){return L()});return T};Q.findTags(/(\n|^)*[ ]{0,3}([*+-]|\d+[.])\s+/,null);if(Q.before&&!/\n$/.test(Q.before)&&!/^\n/.test(Q.startTag)){Q.before+=Q.startTag;Q.startTag=""}if(Q.startTag){var H=/\d+[.]/.test(Q.startTag);Q.startTag="";Q.selection=Q.selection.replace(/\n[ ]{4}/g,"\n");h.unwrap(Q);Q.skipLines();if(H){Q.after=Q.after.replace(R,M)}if(I==H){return}}var K=1;Q.before=Q.before.replace(S,function(T){if(/^\s*([*+-])/.test(T)){F=s.$1}K=/[^\n]\n\n[^\n]/.test(T)?1:0;return M(T)});if(!Q.selection){Q.selection="List item"}var O=L();var G=1;Q.after=Q.after.replace(R,function(T){G=/[^\n]\n\n[^\n]/.test(T)?1:0;return M(T)});Q.trimWhitespace(true);Q.skipLines(K,G,true);Q.startTag=O;var P=O.replace(/./g," ");h.wrap(Q,y.wmd_env.lineLength-P.length);Q.selection=Q.selection.replace(/\n/g,"\n"+P)};h.doHeading=function(H,I){H.selection=H.selection.replace(/\s+/g," ");H.selection=H.selection.replace(/(^\s+|\s+$)/g,"");if(!H.selection){H.startTag="## ";H.selection="Heading";H.endTag=" ##";return}var J=0;H.findTags(/#+[ ]*/,/[ ]*#+/);if(/#+/.test(H.startTag)){J=s.lastMatch.length}H.startTag=H.endTag="";H.findTags(null,/\s?(-+|=+)/);if(/=+/.test(H.endTag)){J=1}if(/-+/.test(H.endTag)){J=2}H.startTag=H.endTag="";H.skipLines(1,1);var K=J==0?2:J-1;if(K>0){var G=K>=2?"-":"=";var F=H.selection.length;if(F>y.wmd_env.lineLength){F=y.wmd_env.lineLength}H.endTag="\n";while(F--){H.endTag+=G}}};h.doHorizontalRule=function(F,G){F.startTag="----------\n";F.selection="";F.skipLines(2,1,true)}};Attacklab.wmd_env={};Attacklab.account_options={};Attacklab.wmd_defaults={version:1,output:"Markdown",lineLength:40,delayLoad:false};if(!Attacklab.wmd){Attacklab.wmd=function(){Attacklab.loadEnv=function(){var b=function(d){if(!d){return}for(var c in d){Attacklab.wmd_env[c]=d[c]}};b(Attacklab.wmd_defaults);b(Attacklab.account_options);b(top.wmd_options);Attacklab.full=true;var a="bold italic link blockquote code image ol ul heading hr";Attacklab.wmd_env.buttons=Attacklab.wmd_env.buttons||a};Attacklab.loadEnv()};Attacklab.wmd();Attacklab.wmdBase();Attacklab.Util.startEditor()}; \ No newline at end of file
diff --git a/templates/content/js/wmd/wmd-test.html b/forum/skins/default/media/js/wmd/wmd-test.html
index d748501a..d748501a 100644
--- a/templates/content/js/wmd/wmd-test.html
+++ b/forum/skins/default/media/js/wmd/wmd-test.html
diff --git a/templates/content/js/wmd/wmd.css b/forum/skins/default/media/js/wmd/wmd.css
index 80c226c8..80c226c8 100644
--- a/templates/content/js/wmd/wmd.css
+++ b/forum/skins/default/media/js/wmd/wmd.css
diff --git a/templates/content/js/wmd/wmd.js b/forum/skins/default/media/js/wmd/wmd.js
index 2234250b..9888cda0 100644
--- a/templates/content/js/wmd/wmd.js
+++ b/forum/skins/default/media/js/wmd/wmd.js
@@ -52,13 +52,9 @@ Attacklab.wmdBase = function(){
var imageDialogText = "<p style='margin-top: 0px'>" + $.i18n._('enter image url') + '</p>';
var linkDialogText = "<p style='margin-top: 0px'>" + $.i18n._('enter url') + '</p>';
var uploadImageHTML ="<div>" + $.i18n._('upload image') + "</div>" +
- "<input type=\"file\" name=\"file-upload\" id=\"file-upload\" size=\"26\" "+
- "onchange=\"return ajaxFileUpload($('#image-url'));\"/><br>" +
-<<<<<<< HEAD:templates/content/js/wmd/wmd.js
- "<img id=\"loading\" src=\"" + $.i18n._("/") + "content/images/indicator.gif\" style=\"display:none;\"/>";
-=======
- "<img id=\"loading\" src=\"" + scriptUrl + "content/images/indicator.gif\" style=\"display:none;\"/>";
->>>>>>> 82d35490db90878f013523c4d1a5ec3af2df8b23:templates/content/js/wmd/wmd.js
+ '<input type="file" name="file-upload" id="file-upload" size="26" '+
+ 'onchange="return ajaxFileUpload($("#image-url"));"/><br>' +
+ '<img id="loading" src="mediaUrl("media/images/indicator.gif")" style="display:none;"/>';
// The default text that appears in the dialog input box when entering
// links.
diff --git a/templates/content/js/yuicompressor-2.4.2.jar b/forum/skins/default/media/js/yuicompressor-2.4.2.jar
index c29470bd..c29470bd 100644
--- a/templates/content/js/yuicompressor-2.4.2.jar
+++ b/forum/skins/default/media/js/yuicompressor-2.4.2.jar
Binary files differ
diff --git a/templates/content/style/default.css b/forum/skins/default/media/style/default.css
index 2bc185ad..27da1dab 100644
--- a/templates/content/style/default.css
+++ b/forum/skins/default/media/style/default.css
@@ -7,9 +7,9 @@ Style sheet for cnprog.com
All rights reserved. 2008 CNPROG.COM
*/
-@import url(content/style/jquery.autocomplete.css);
-@import url(content/style/openid.css);
-@import url(content/style/prettify.css);
+@import url(media/style/jquery.autocomplete.css);
+@import url(media/style/openid.css);
+@import url(media/style/prettify.css);
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, form, label, table, caption, tbody, tfoot, thead, tr, th, td
{
diff --git a/templates/content/style/jquery.autocomplete.css b/forum/skins/default/media/style/jquery.autocomplete.css
index 3bf2c2d9..3bf2c2d9 100644
--- a/templates/content/style/jquery.autocomplete.css
+++ b/forum/skins/default/media/style/jquery.autocomplete.css
diff --git a/templates/content/style/openid.css b/forum/skins/default/media/style/openid.css
index 0d201df2..0d201df2 100644
--- a/templates/content/style/openid.css
+++ b/forum/skins/default/media/style/openid.css
diff --git a/templates/content/style/prettify.css b/forum/skins/default/media/style/prettify.css
index 10a37577..10a37577 100644
--- a/templates/content/style/prettify.css
+++ b/forum/skins/default/media/style/prettify.css
diff --git a/templates/content/style/style.css b/forum/skins/default/media/style/style.css
index 3ff95fd2..88c7e7db 100644
--- a/templates/content/style/style.css
+++ b/forum/skins/default/media/style/style.css
@@ -1266,6 +1266,9 @@ p.space-above {
.margin-bottom {
margin-bottom: 10px;
}
+.margin-top {
+ margin-top: 10px;
+}
.inline-block {
display:inline-block;
}
diff --git a/templates/404.html b/forum/skins/default/templates/404.html
index 227de3ae..227de3ae 100644
--- a/templates/404.html
+++ b/forum/skins/default/templates/404.html
diff --git a/templates/500.html b/forum/skins/default/templates/500.html
index 51e73178..51e73178 100644
--- a/templates/500.html
+++ b/forum/skins/default/templates/500.html
diff --git a/templates/about.html b/forum/skins/default/templates/about.html
index 66dcc3fd..66dcc3fd 100644
--- a/templates/about.html
+++ b/forum/skins/default/templates/about.html
diff --git a/templates/answer_edit.html b/forum/skins/default/templates/answer_edit.html
index cd247a3c..2d736f30 100644
--- a/templates/answer_edit.html
+++ b/forum/skins/default/templates/answer_edit.html
@@ -4,12 +4,12 @@
{% load extra_tags %}
{% block title %}{% spaceless %}{% trans "Edit answer" %}{% endspaceless %}{% endblock %}
{% block forejs %}
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.editor.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.post.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/jquery.validate.pack.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/wmd/showdown.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/wmd/wmd.js" %}'></script>
- <link rel="stylesheet" type="text/css" href="{% href "/content/js/wmd/wmd.css" %}" />
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.post.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.validate.pack.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/showdown.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/wmd.js" %}'></script>
+ <link rel="stylesheet" type="text/css" href="{% media "/media/js/wmd/wmd.css" %}" />
<script type="text/javascript">
$().ready(function(){
diff --git a/templates/answer_edit_tips.html b/forum/skins/default/templates/answer_edit_tips.html
index c390da06..c390da06 100644
--- a/templates/answer_edit_tips.html
+++ b/forum/skins/default/templates/answer_edit_tips.html
diff --git a/templates/ask.html b/forum/skins/default/templates/ask.html
index 2efd9864..84253be5 100644
--- a/templates/ask.html
+++ b/forum/skins/default/templates/ask.html
@@ -4,12 +4,12 @@
{% load extra_tags %}
{% block title %}{% spaceless %}{% trans "Ask a question" %}{% endspaceless %}{% endblock %}
{% block forejs %}
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.editor.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.post.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/jquery.validate.pack.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/wmd/showdown.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/wmd/wmd.js" %}'></script>
- <link rel="stylesheet" type="text/css" href="{% href "/content/js/wmd/wmd.css" %}" />
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.post.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.validate.pack.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/showdown.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/wmd.js" %}'></script>
+ <link rel="stylesheet" type="text/css" href="{% media "/media/js/wmd/wmd.css" %}" />
<script type="text/javascript">
$().ready(function(){
//set current module button style
diff --git a/templates/authopenid/changeemail.html b/forum/skins/default/templates/authopenid/changeemail.html
index 94d1881c..94d1881c 100644
--- a/templates/authopenid/changeemail.html
+++ b/forum/skins/default/templates/authopenid/changeemail.html
diff --git a/templates/authopenid/changeopenid.html b/forum/skins/default/templates/authopenid/changeopenid.html
index d01788fb..d01788fb 100644
--- a/templates/authopenid/changeopenid.html
+++ b/forum/skins/default/templates/authopenid/changeopenid.html
diff --git a/templates/authopenid/changepw.html b/forum/skins/default/templates/authopenid/changepw.html
index 8b059544..8b059544 100644
--- a/templates/authopenid/changepw.html
+++ b/forum/skins/default/templates/authopenid/changepw.html
diff --git a/templates/authopenid/complete.html b/forum/skins/default/templates/authopenid/complete.html
index 85f6d8b1..72dca1a5 100644
--- a/templates/authopenid/complete.html
+++ b/forum/skins/default/templates/authopenid/complete.html
@@ -96,6 +96,9 @@ parameters:
<p>{% trans "receive updates motivational blurb" %}</p>
<div class='simple-subscribe-options'>
{{email_feeds_form.subscribe}}
+ {% if email_feeds_form.errors %}
+ <p class="error">{% trans "please select one of the options above" %}</p>
+ {% endif %}
</div>
<p class='space-above'>{% trans "Tag filter tool will be your right panel, once you log in." %}</p>
<div class="submit-row"><input type="submit" class="submit" name="bnewaccount" value="{% trans "create account" %}"/></div>
diff --git a/templates/authopenid/confirm_email.txt b/forum/skins/default/templates/authopenid/confirm_email.txt
index 0b3b2505..0b3b2505 100644
--- a/templates/authopenid/confirm_email.txt
+++ b/forum/skins/default/templates/authopenid/confirm_email.txt
diff --git a/templates/authopenid/delete.html b/forum/skins/default/templates/authopenid/delete.html
index 0f9f1c60..0f9f1c60 100644
--- a/templates/authopenid/delete.html
+++ b/forum/skins/default/templates/authopenid/delete.html
diff --git a/templates/authopenid/email_validation.txt b/forum/skins/default/templates/authopenid/email_validation.txt
index d741614f..d741614f 100644
--- a/templates/authopenid/email_validation.txt
+++ b/forum/skins/default/templates/authopenid/email_validation.txt
diff --git a/templates/authopenid/external_legacy_login_info.html b/forum/skins/default/templates/authopenid/external_legacy_login_info.html
index 3318499c..3318499c 100644
--- a/templates/authopenid/external_legacy_login_info.html
+++ b/forum/skins/default/templates/authopenid/external_legacy_login_info.html
diff --git a/templates/authopenid/failure.html b/forum/skins/default/templates/authopenid/failure.html
index d075d6b0..d075d6b0 100644
--- a/templates/authopenid/failure.html
+++ b/forum/skins/default/templates/authopenid/failure.html
diff --git a/templates/authopenid/sendpw.html b/forum/skins/default/templates/authopenid/sendpw.html
index 6241c811..6241c811 100644
--- a/templates/authopenid/sendpw.html
+++ b/forum/skins/default/templates/authopenid/sendpw.html
diff --git a/templates/authopenid/sendpw_email.txt b/forum/skins/default/templates/authopenid/sendpw_email.txt
index c4910d12..c4910d12 100644
--- a/templates/authopenid/sendpw_email.txt
+++ b/forum/skins/default/templates/authopenid/sendpw_email.txt
diff --git a/templates/authopenid/settings.html b/forum/skins/default/templates/authopenid/settings.html
index 66ea5953..66ea5953 100644
--- a/templates/authopenid/settings.html
+++ b/forum/skins/default/templates/authopenid/settings.html
diff --git a/templates/authopenid/signin.html b/forum/skins/default/templates/authopenid/signin.html
index 51b8aa7f..4e060d0f 100755
--- a/templates/authopenid/signin.html
+++ b/forum/skins/default/templates/authopenid/signin.html
@@ -4,10 +4,10 @@
{% load extra_tags %}
{% block title %}{% spaceless %}{% trans "User login" %}{% endspaceless %}{% endblock %}
{% block forejs %}
- <script type='text/javascript' src='{% href "/content/js/jquery.validate.pack.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.validate.pack.js" %}'></script>
- <link rel="stylesheet" type="text/css" media="screen" href="{% href "/content/jquery-openid/openid.css" %}"/>
- <script type="text/javascript" src="{% href "/content/jquery-openid/jquery.openid.js" %}"></script>
+ <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/jquery-openid/openid.css" %}"/>
+ <script type="text/javascript" src="{% media "/media/jquery-openid/jquery.openid.js" %}"></script>
<script type="text/javascript"> $().ready( function() { $("form.openid:eq(0)").openid(); })</script>
<!--<script type="text/javascript">
$().ready(function(){
@@ -44,34 +44,34 @@
<ul class="providers">
<li class="local" title="Local login">
<div class="logo_box local_login_box">
- <img src="{% href "/content/jquery-openid/images/local-login.png" %}" alt="your icon here" />
+ <img src="{% media "/media/jquery-openid/images/local-login.png" %}" alt="your icon here" />
</div>
<span></span>
</li>
<li class="direct" title="Google">
<div class="logo_box google_box">
- <img src="{% href "/content/jquery-openid/images/google.gif" %}" alt="icon" /><span>https://www.google.com/accounts/o8/id</span>
+ <img src="{% media "/media/jquery-openid/images/google.gif" %}" alt="icon" /><span>https://www.google.com/accounts/o8/id</span>
</div>
</li>
<li class="direct" title="Yahoo">
<div class="logo_box yahoo_box">
- <img src="{% href "/content/jquery-openid/images/yahoo.gif" %}" alt="icon" /><span>http://yahoo.com/</span>
+ <img src="{% media "/media/jquery-openid/images/yahoo.gif" %}" alt="icon" /><span>http://yahoo.com/</span>
</div>
</li>
<li class="username" title="AOL screen name">
<div class="logo_box aol_box">
- <img src="{% href "/content/jquery-openid/images/aol.gif" %}" alt="icon" /><span>http://openid.aol.com/<strong>username</strong></span>
+ <img src="{% media "/media/jquery-openid/images/aol.gif" %}" alt="icon" /><span>http://openid.aol.com/<strong>username</strong></span>
</div>
</li>
</ul>
<ul id="openid_small_providers" class="providers">
<!--<li class="openid" title="OpenID">
<div class="logo_box openid_box">
- <img src="/content/jquery-openid/images/openid.gif" alt="icon" />
+ <img src="/media/jquery-openid/images/openid.gif" alt="icon" />
</div>
<span><strong>http://{your-openid-url}</strong></span>
</li>-->
- <li class="direct first_tiny_li facebook" title="Facebook Connect">
+ <li class="first_tiny_li facebook" title="Facebook Connect">
{% if question %}
<fb:login-button onlogin="window.location = '{% url fb_signin_new_question %}'"></fb:login-button>
{% else %}
@@ -83,43 +83,43 @@
{% endif %}
</li>
<li class="openid" title="OpenID URL">
- <img src="{% href "/content/jquery-openid/images/openidico16.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/openidico16.png" %}" alt="icon" />
<span>http://{your-openid-url}</span>
</li>
<li class="username" title="MyOpenID user name">
- <img src="{% href "/content/jquery-openid/images/myopenid-2.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/myopenid-2.png" %}" alt="icon" />
<span>http://<strong>username</strong>.myopenid.com/</span>
</li>
<li class="username" title="Flickr user name">
- <img src="{% href "/content/jquery-openid/images/flickr.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/flickr.png" %}" alt="icon" />
<span>http://flickr.com/<strong>username</strong>/</span>
</li>
<li class="username" title="Technorati user name">
- <img src="{% href "/content/jquery-openid/images/technorati-1.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/technorati-1.png" %}" alt="icon" />
<span>http://technorati.com/people/technorati/<strong>username</strong>/</span>
</li>
<li class="username" title="Wordpress blog name">
- <img src="{% href "/content/jquery-openid/images/wordpress.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/wordpress.png" %}" alt="icon" />
<span>http://<strong>username</strong>.wordpress.com</span>
</li>
<li class="username" title="Blogger blog name">
- <img src="{% href "/content/jquery-openid/images/blogger-1.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/blogger-1.png" %}" alt="icon" />
<span>http://<strong>username</strong>.blogspot.com/</span>
</li>
<li class="username" title="LiveJournal blog name">
- <img src="{% href "/content/jquery-openid/images/livejournal-1.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/livejournal-1.png" %}" alt="icon" />
<span>http://<strong>username</strong>.livejournal.com</span>
</li>
<li class="username" title="ClaimID user name">
- <img src="{% href "/content/jquery-openid/images/claimid-0.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/claimid-0.png" %}" alt="icon" />
<span>http://claimid.com/<strong>username</strong></span>
</li>
<li class="username" title="Vidoop user name">
- <img src="{% href "/content/jquery-openid/images/vidoop.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/vidoop.png" %}" alt="icon" />
<span>http://<strong>username</strong>.myvidoop.com/</span>
</li>
<li class="username" title="Verisign user name">
- <img src="{% href "/content/jquery-openid/images/verisign-2.png" %}" alt="icon" />
+ <img src="{% media "/media/jquery-openid/images/verisign-2.png" %}" alt="icon" />
<span>http://<strong>username</strong>.pip.verisignlabs.com/</span>
</li>
</ul>
diff --git a/templates/authopenid/signup.html b/forum/skins/default/templates/authopenid/signup.html
index d800eaf9..fdb236c2 100644
--- a/templates/authopenid/signup.html
+++ b/forum/skins/default/templates/authopenid/signup.html
@@ -15,10 +15,12 @@
<li><label for="password1_id">{{form.password1.label}}</label>{{form.password1}}{{form.password1.errors}}</li>
<li><label for="password2_id">{{form.password2.label}}</label>{{form.password2}}{{form.password2.errors}}</li>
</ul>
- <p class="signup_p">{% trans "receive updates motivational blurb" %}</p>
- <p class="signup_p">{% trans "Please select your preferred email update schedule for the following groups of questions:" %}</p>
+ <p class="margin-top">{% trans "receive updates motivational blurb" %}</p>
<div class='simple-subscribe-options'>
{{email_feeds_form.subscribe}}
+ {% if email_feeds_form.errors %}
+ <p class="error">{% trans "please select one of the options above" %}</p>
+ {% endif %}
</div>
<p class="signup_p">{% trans "Please read and type in the two words below to help us prevent automated account creation." %}</p>
{{form.recaptcha}}
diff --git a/templates/authopenid/yadis.xrdf b/forum/skins/default/templates/authopenid/yadis.xrdf
index a9ed44fe..a9ed44fe 100644
--- a/templates/authopenid/yadis.xrdf
+++ b/forum/skins/default/templates/authopenid/yadis.xrdf
diff --git a/templates/badge.html b/forum/skins/default/templates/badge.html
index af6aa2a2..af6aa2a2 100644
--- a/templates/badge.html
+++ b/forum/skins/default/templates/badge.html
diff --git a/templates/badges.html b/forum/skins/default/templates/badges.html
index 8de93df5..8de93df5 100644
--- a/templates/badges.html
+++ b/forum/skins/default/templates/badges.html
diff --git a/templates/base.html b/forum/skins/default/templates/base.html
index d4eb731b..58ef0627 100755
--- a/templates/base.html
+++ b/forum/skins/default/templates/base.html
@@ -13,38 +13,21 @@
{% if settings.GOOGLE_SITEMAP_CODE %}
<meta name="google-site-verification" content="{{settings.GOOGLE_SITEMAP_CODE}}" />
{% endif %}
- <link rel="shortcut icon" href="{% href "/content/images/favicon.ico" %}" />
- <link href="{% href "/content/style/style.css" %}" rel="stylesheet" type="text/css" />
+ <link rel="shortcut icon" href="{% media "/media/images/favicon.ico" %}" />
+ <link href="{% media "/media/style/style.css" %}" rel="stylesheet" type="text/css" />
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">google.load("jquery", "1.2.6");</script>
- <script type="text/javascript">
-<<<<<<< HEAD:templates/base.html
- var i18nLang = '{{settings.LANGUAGE_CODE}}';
-=======
- var i18nLang = '{{settings.LANGUAGE_CODE}}';
- var scriptUrl = '/{{settings.FORUM_SCRIPT_ALIAS}}'
->>>>>>> 82d35490db90878f013523c4d1a5ec3af2df8b23:templates/base.html
- </script>
<script type='text/javascript' src='{% href "/content/js/com.cnprog.i18n.js" %}'></script>
<script type='text/javascript' src='{% href "/content/js/jquery.i18n.js" %}'></script>
<script type='text/javascript' src='{% href "/content/js/com.cnprog.utils.js" %}'></script>
- <!--<script type="text/javascript">
- var uservoiceJsHost = ("https:" == document.location.protocol) ? "https://uservoice.com" : "http://cdn.uservoice.com";
- document.write(unescape("%3Cscript src='" + uservoiceJsHost + "/javascripts/widgets/tab.js' type='text/javascript'%3E%3C/script%3E"))
- </script>
<script type="text/javascript">
- UserVoice.Tab.show({
- key: 'cnprog',
- host: 'cnprog.uservoice.com',
- forum: 'general',
- alignment: 'left', /* 'left', 'right' */
- background_color:'#777',
- text_color: 'white', /* 'white', 'black' */
- hover_color: '#06C',
- lang: 'en' /* 'en', 'de', 'nl', 'es', 'fr' */
- })
- </script>-->
- <!-- todo move this to settings -->
+ var i18nLang = '{{settings.LANGUAGE_CODE}}';
+ var scriptUrl = '/{{settings.FORUM_SCRIPT_ALIAS}}'
+ var osqaSkin = '{{settings.OSQA_SKIN}}';
+ </script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.i18n.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.i18n.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.utils.js" %}'></script>
{% if user_messages %}
<style type="text/css">
body { margin-top:2.4em; }
diff --git a/templates/base_content.html b/forum/skins/default/templates/base_content.html
index 0ff4a9fd..d1cf673b 100644
--- a/templates/base_content.html
+++ b/forum/skins/default/templates/base_content.html
@@ -6,51 +6,24 @@
<head>
<title>{% block title %}{% endblock %} - {{ settings.APP_TITLE }}</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<<<<<<< HEAD:templates/base_content.html
- <meta name="verify-v1" content="{{ settings.GOOGLE_SITEMAP_CODE }}" />
-=======
{% if settings.GOOGLE_SITEMAP_CODE %}
<meta name="google-site-verification" content="{{ settings.GOOGLE_SITEMAP_CODE }}" />
{% endif %}
->>>>>>> 82d35490db90878f013523c4d1a5ec3af2df8b23:templates/base_content.html
- <link rel="shortcut icon" href="{% href "/content/images/favicon.ico" %}" />
- <link href="{% href "/content/style/style.css" %}" rel="stylesheet" type="text/css" />
- {% spaceless %}
+ <link rel="shortcut icon" href="{% media "/media/images/favicon.ico" %}" />
+ <link href="{% media "/media/style/style.css" %}" rel="stylesheet" type="text/css" />
+ {% spaceless %}
{% block forestyle %}{% endblock %}
{% endspaceless %}
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">google.load("jquery", "1.2.6");</script>
- <script type="text/javascript">
-<<<<<<< HEAD:templates/base_content.html
- var i18nLang = '{{ settings.LANGUAGE_CODE }}';
-=======
+ <script type="text/javascript">
var i18nLang = '{{ settings.LANGUAGE_CODE }}';
var scriptUrl = '/{{settings.FORUM_SCRIPT_ALIAS}}'
->>>>>>> 82d35490db90878f013523c4d1a5ec3af2df8b23:templates/base_content.html
- </script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.i18n.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/jquery.i18n.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.utils.js" %}'></script>
-
- <!-- <script type="text/javascript">
- var uservoiceJsHost = ("https:" == document.location.protocol) ? "https://uservoice.com" : "http://cdn.uservoice.com";
- document.write(unescape("%3Cscript src='" + uservoiceJsHost + "/javascripts/widgets/tab.js' type='text/javascript'%3E%3C/script%3E"))
+ var osqaSkin = '{{settings.OSQA_SKIN}}';
</script>
- <script type="text/javascript">
- UserVoice.Tab.show({
- //EDIT!!!
- key: 'uservoicekey',
- host: 'where.uservoice.com',
- forum: 'general',
- alignment: 'left', /* 'left', 'right' */
- background_color:'#777',
- text_color: 'white', /* 'white', 'black' */
- hover_color: '#06C',
- lang: 'en' /* 'en', 'de', 'nl', 'es', 'fr' */
- })
- </script>-->
- <!-- todo move this to settings-->
-
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.i18n.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.i18n.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.utils.js" %}'></script>
{% if user_messages %}
<style type="text/css">
body { margin-top:2.4em; }
diff --git a/templates/book.html b/forum/skins/default/templates/book.html
index e83268e4..8574fa73 100644
--- a/templates/book.html
+++ b/forum/skins/default/templates/book.html
@@ -85,12 +85,12 @@
{% if question.favourite_count %}
{% if question.favorited_myself %}
<div class="favorites-count">
- <img title="{% trans "this question was selected as favorite" %} {{question.favourite_count}} {% trans "number of times" %}" src="{% href "/content/images/vote-favorite-on.png" %}">
+ <img title="{% trans "this question was selected as favorite" %} {{question.favourite_count}} {% trans "number of times" %}" src="{% media "/media/images/vote-favorite-on.png" %}">
<div><b>{{question.favourite_count|intcomma}}</b></div>
</div>
{% else %}
<div class="favorites-count-off">
- <img title="{% trans "this question was selected as favorite" %} {{question.favourite_count}} {% trans "number of times" %}" src="{% href "/content/images/vote-favorite-off.png" %}">
+ <img title="{% trans "this question was selected as favorite" %} {{question.favourite_count}} {% trans "number of times" %}" src="{% media "/media/images/vote-favorite-off.png" %}">
<div><b>{{question.favourite_count|intcomma}}</b></div>
</div>
{% endif %}
@@ -122,7 +122,7 @@
</h3>
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url forum.views.tag tag|urlencode %}" title="{% "see questions tagged with" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url tag_questions tag|urlencode %}" title="{% "see questions tagged with" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
<div class="started">
@@ -144,7 +144,7 @@
</div>
<div class="bookFeed">
<div id="feeds">
- <a href="{% href "/feeds/rss" %} " title="{% trans "subscribe to book RSS feed" %}">{% trans "subscribe to the questions feed" %}</a>
+ <a href="{% media "/feeds/rss" %} " title="{% trans "subscribe to book RSS feed" %}">{% trans "subscribe to the questions feed" %}</a>
</div>
</div>
diff --git a/templates/close.html b/forum/skins/default/templates/close.html
index d9e73507..d9e73507 100644
--- a/templates/close.html
+++ b/forum/skins/default/templates/close.html
diff --git a/templates/edit_user_email_feeds_form.html b/forum/skins/default/templates/edit_user_email_feeds_form.html
index 65902e7e..65902e7e 100644
--- a/templates/edit_user_email_feeds_form.html
+++ b/forum/skins/default/templates/edit_user_email_feeds_form.html
diff --git a/templates/faq.html b/forum/skins/default/templates/faq.html
index 236f4f76..236f4f76 100644
--- a/templates/faq.html
+++ b/forum/skins/default/templates/faq.html
diff --git a/forum/skins/default/templates/fbconnect/xd_receiver.html b/forum/skins/default/templates/fbconnect/xd_receiver.html
new file mode 100755
index 00000000..a03c61bc
--- /dev/null
+++ b/forum/skins/default/templates/fbconnect/xd_receiver.html
@@ -0,0 +1,10 @@
+<!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" >
+{% load i18n %}
+ <head>
+ <title>{% blocktrans %}Connect to {{APP_SHORT_NAME}} with Facebook!{% endblocktrans %}
+ </head>
+ <body>
+ <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>
+ </body>
+</html>
diff --git a/templates/feedback.html b/forum/skins/default/templates/feedback.html
index 38bb48ff..38bb48ff 100644
--- a/templates/feedback.html
+++ b/forum/skins/default/templates/feedback.html
diff --git a/templates/feedback_email.txt b/forum/skins/default/templates/feedback_email.txt
index df768180..df768180 100644
--- a/templates/feedback_email.txt
+++ b/forum/skins/default/templates/feedback_email.txt
diff --git a/templates/feeds/rss_description.html b/forum/skins/default/templates/feeds/rss_description.html
index fa781907..fa781907 100644
--- a/templates/feeds/rss_description.html
+++ b/forum/skins/default/templates/feeds/rss_description.html
diff --git a/templates/feeds/rss_title.html b/forum/skins/default/templates/feeds/rss_title.html
index 7899fce3..7899fce3 100644
--- a/templates/feeds/rss_title.html
+++ b/forum/skins/default/templates/feeds/rss_title.html
diff --git a/templates/footer.html b/forum/skins/default/templates/footer.html
index 66feff8a..89d4801f 100644
--- a/templates/footer.html
+++ b/forum/skins/default/templates/footer.html
@@ -28,7 +28,7 @@
</div>
<div id="licenseLogo">
<a href="http://creativecommons.org/licenses/by/3.0/">
- <img src="{% href "/content/images/cc-wiki.png" %}" title="Creative Commons: Attribution - Share Alike" alt="cc-wiki" width="50" height="68" />
+ <img src="{% media "/media/images/cc-wiki.png" %}" title="Creative Commons: Attribution - Share Alike" alt="cc-wiki" width="50" height="68" />
</a>
</div>
</div>
diff --git a/templates/header.html b/forum/skins/default/templates/header.html
index 60644d0e..3b29ffc4 100644
--- a/templates/header.html
+++ b/forum/skins/default/templates/header.html
@@ -18,7 +18,7 @@
<td width="23%">
<div id="logo">
<a href="{% url index %}">
- <img src="{% href "/content/images/logo.png" %}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/>
+ <img src="{% media "/media/images/logo.png" %}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/>
</a>
</div>
</td>
diff --git a/templates/index.html b/forum/skins/default/templates/index.html
index b920db1b..30cba1be 100644
--- a/templates/index.html
+++ b/forum/skins/default/templates/index.html
@@ -17,8 +17,8 @@
$("#nav_questions").attr('className',"on");
});
</script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.editor.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.tag_selector.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.tag_selector.js" %}'></script>
{% endblock %}
{% block content %}
<div class="tabBar">
@@ -103,7 +103,7 @@
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url forum.views.tag tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
@@ -130,7 +130,7 @@
<div class="tags">
{% for tag in tags %}
<a rel="tag"
- title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url forum.views.tag tag.name|urlencode %}">{{ tag.name }}</a>
+ title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
{% endfor %}
</div>
<div class="more"><a href="{% url tags %}">{% trans "popular tags" %} »</a> </div>
@@ -154,7 +154,7 @@
</div>
{% endif %}
<div id="feeds">
-<a href="{% href "/feeds/rss" %}" title="{% trans "subscribe to last 30 questions by RSS" %}">{% trans "subscribe to the questions feed" %}</a>
+<a href="{% media "/feeds/rss" %}" title="{% trans "subscribe to last 30 questions by RSS" %}">{% trans "subscribe to the questions feed" %}</a>
</div>
{% endblock %}
{% block tail %}
diff --git a/templates/logout.html b/forum/skins/default/templates/logout.html
index 650ba044..650ba044 100644
--- a/templates/logout.html
+++ b/forum/skins/default/templates/logout.html
diff --git a/templates/notarobot.html b/forum/skins/default/templates/notarobot.html
index 698c5696..698c5696 100644
--- a/templates/notarobot.html
+++ b/forum/skins/default/templates/notarobot.html
diff --git a/templates/pagesize.html b/forum/skins/default/templates/pagesize.html
index 5037f1f6..5037f1f6 100644
--- a/templates/pagesize.html
+++ b/forum/skins/default/templates/pagesize.html
diff --git a/templates/paginator.html b/forum/skins/default/templates/paginator.html
index 2fba5425..2fba5425 100644
--- a/templates/paginator.html
+++ b/forum/skins/default/templates/paginator.html
diff --git a/templates/post_contributor_info.html b/forum/skins/default/templates/post_contributor_info.html
index 9997be5f..9997be5f 100644
--- a/templates/post_contributor_info.html
+++ b/forum/skins/default/templates/post_contributor_info.html
diff --git a/templates/privacy.html b/forum/skins/default/templates/privacy.html
index e66086dd..e66086dd 100644
--- a/templates/privacy.html
+++ b/forum/skins/default/templates/privacy.html
diff --git a/templates/question.html b/forum/skins/default/templates/question.html
index 5fbbbfa7..ae562b6b 100644
--- a/templates/question.html
+++ b/forum/skins/default/templates/question.html
@@ -531,13 +531,13 @@
<meta name="keywords" content="{{question.tagname_meta_generator}}" />
<link rel="canonical" href="{{settings.APP_URL}}{{question.get_absolute_url}}" />
{% if not question.closed %}
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.editor.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/wmd/showdown.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/wmd/wmd.js" %}'></script>
- <link rel="stylesheet" type="text/css" href="{% href "/content/js/wmd/wmd.css" %}" />
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/showdown.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/wmd.js" %}'></script>
+ <link rel="stylesheet" type="text/css" href="{% media "/media/js/wmd/wmd.css" %}" />
{% endif %}
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.post.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/jquery.validate.pack.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.post.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.validate.pack.js" %}'></script>
<script type="text/javascript">
// define reputation needs for comments
@@ -590,55 +590,53 @@
{% if question_vote %}
<img id="question-img-upvote-{{ question.id }}" class="question-img-upvote"
{% if question_vote.is_upvote %}
- src="{% href "/content/images/vote-arrow-up-on.png" %}"
+ src="{% media "/media/images/vote-arrow-up-on.png" %}"
{% else %}
- src="{% href "/content/images/vote-arrow-up.png" %}"
+ src="{% media "/media/images/vote-arrow-up.png" %}"
{% endif %}
alt="{% trans "i like this post (click again to cancel)" %}"
- title="{% trans "i like this post (click again to cancel)" %}" />
+ title="{% trans "i like this post (click again to cancel)" %}" />
<div id="question-vote-number-{{ question.id }}" class="vote-number"
- title="{% trans "current number of votes" %}">
+ title="{% trans "current number of votes" %}">
{{ question.score }}
</div>
<img id="question-img-downvote-{{ question.id }}" class="question-img-downvote"
{% if question_vote.is_downvote %}
- src="{% href "/content/images/vote-arrow-down-on.png" %}"
+ src="{% media "/media/images/vote-arrow-down-on.png" %}"
{% else %}
- src="{% href "/content/images/vote-arrow-down.png" %}"
+ src="{% media "/media/images/vote-arrow-down.png" %}"
{% endif %}
alt="{% trans "i dont like this post (click again to cancel)" %}"
- title="{% trans "i dont like this post (click again to cancel)" %}" />
+ title="{% trans "i dont like this post (click again to cancel)" %}" />
{% else %}
<img id="question-img-upvote-{{ question.id }}" class="question-img-upvote"
alt="{% trans "i like this post (click again to cancel)" %}"
- src="{% href "/content/images/vote-arrow-up.png" %}"
- title="{% trans "i like this post (click again to cancel)" %}" />
+ src="{% media "/media/images/vote-arrow-up.png" %}"
+ title="{% trans "i like this post (click again to cancel)" %}" />
<div id="question-vote-number-{{ question.id }}" class="vote-number"
- title="{% trans "current number of votes" %}">
+ title="{% trans "current number of votes" %}">
{{ question.score }}
</div>
<img id="question-img-downvote-{{ question.id }}" class="question-img-downvote"
- src="{% href "/content/images/vote-arrow-down.png" %}"
+ src="{% media "/media/images/vote-arrow-down.png" %}"
alt="{% trans "i dont like this post (click again to cancel)" %}"
title="{% trans "i dont like this post (click again to cancel)" %}" />
-
{% endif %}
{% if favorited %}
- <img class="question-img-favorite" src="{% href "/content/images/vote-favorite-on.png" %}"
- alt="{% trans "mark this question as favorite (click again to cancel)" %}"
- title="{% trans "mark this question as favorite (click again to cancel)" %}" />
+ <img class="question-img-favorite" src="{% media "/media/images/vote-favorite-on.png" %}"
+ alt="{% trans "mark this question as favorite (click again to cancel)" %}"
+ title="{% trans "mark this question as favorite (click again to cancel)" %}" />
<div id="favorite-number" class="favorite-number my-favorite-number">
{{ question.favourite_count }}
</div>
{% else %}
- <img class="question-img-favorite" src="{% href "/content/images/vote-favorite-off.png" %}"
- alt="{% trans "remove favorite mark from this question (click again to restore mark)" %}"
- title="{% trans "remove favorite mark from this question (click again to restore mark)" %}" />
+ <img class="question-img-favorite" src="{% media "/media/images/vote-favorite-off.png" %}"
+ alt="{% trans "remove favorite mark from this question (click again to restore mark)" %}"
+ title="{% trans "remove favorite mark from this question (click again to restore mark)" %}" />
<div id="favorite-number" class="favorite-number">
{% ifnotequal question.favourite_count 0 %}{{ question.favourite_count }}{% endifnotequal %}
</div>
-
{% endif %}
</div>
@@ -651,7 +649,7 @@
<div id="question-controls" class="post-controls">
<div id="question-tags" class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url forum.views.tag tag|urlencode %}" class="post-tag"
+ <a href="{% url tag_questions tag|urlencode %}" class="post-tag"
title="{% blocktrans with tag as tagname %}see questions tagged '{{ tagname }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
@@ -698,7 +696,7 @@
<span class="comment-age">({% diff_date comment.added_at %})</span>
{% if request.user|can_delete_comment:comment %}
<img class="delete-icon"
- src="{% href "/content/images/close-small.png" %}"
+ src="{% media "/media/images/close-small.png" %}"
title="{% trans "delete this comment" %}"/>
{% endif %}
{% endspaceless %}
@@ -737,8 +735,8 @@
{% if question.closed %}
<div class="question-status" style="margin-bottom:15px">
<h3>{% blocktrans with question.get_close_reason_display as close_reason %}The question has been closed for the following reason "{{ close_reason }}" by{% endblocktrans %}
- <a href="{{ question.closed_by.get_profile_url }}">{{ question.closed_by.username }}</a>
- {% blocktrans with question.closed_at as closed_at %}close date {{closed_at}}{% endblocktrans %}</h3>
+ <a href="{{ question.closed_by.get_profile_url }}">{{ question.closed_by.username }}</a>
+ {% blocktrans with question.closed_at as closed_at %}close date {{closed_at}}{% endblocktrans %}</h3>
</div>
{% endif %}
{% if answers %}
@@ -771,28 +769,28 @@
<td style="width:30px;vertical-align:top">
<div class="vote-buttons">
<img id="answer-img-upvote-{{ answer.id }}" class="answer-img-upvote"
- src="{% blockresource %}/content/images/vote-arrow-up{% get_user_vote_image user_answer_votes answer.id 1 %}.png{% endblockresource %}"
+ src="{% blockmedia %}/media/images/vote-arrow-up{% get_user_vote_image user_answer_votes answer.id 1 %}.png{% endblockmedia %}"
alt="{% trans "i like this answer (click again to cancel)" %}"
title="{% trans "i like this answer (click again to cancel)" %}"/>
<div id="answer-vote-number-{{ answer.id }}" class="vote-number" title="{% trans "current number of votes" %}">
{{ answer.score }}
</div>
<img id="answer-img-downvote-{{ answer.id }}" class="answer-img-downvote"
- src="{% blockresource %}/content/images/vote-arrow-down{% get_user_vote_image user_answer_votes answer.id -1 %}.png{% endblockresource %}"
- alt="{% trans "i dont like this answer (click again to cancel)" %}"
- title="{% trans "i dont like this answer (click again to cancel)" %}" />
+ src="{% blockmedia %}/media/images/vote-arrow-down{% get_user_vote_image user_answer_votes answer.id -1 %}.png{% endblockmedia %}"
+ alt="{% trans "i dont like this answer (click again to cancel)" %}"
+ title="{% trans "i dont like this answer (click again to cancel)" %}" />
{% ifequal request.user question.author %}
<img id="answer-img-accept-{{ answer.id }}" class="answer-img-accept"
- src="{% blockresource %}/content/images/vote-accepted{% if answer.accepted %}-on{% endif %}.png{% endblockresource %}"
- alt="{% trans "mark this answer as favorite (click again to undo)" %}"
- title="{% trans "mark this answer as favorite (click again to undo)" %}" />
+ src="{% blockmedia %}/media/images/vote-accepted{% if answer.accepted %}-on{% endif %}.png{% endblockmedia %}"
+ alt="{% trans "mark this answer as favorite (click again to undo)" %}"
+ title="{% trans "mark this answer as favorite (click again to undo)" %}" />
{% else %}
{% if answer.accepted %}
<img id="answer-img-accept-{{ answer.id }}" class="answer-img-accept"
- src="{% blockresource %}/content/images/vote-accepted{% if answer.accepted %}-on{% endif %}.png{% endblockresource %}"
- alt="{% trans "the author of the question has selected this answer as correct" %}"
- title="{% trans "the author of the question has selected this answer as correct" %}" />
+ src="{% blockmedia %}/media/images/vote-accepted{% if answer.accepted %}-on{% endif %}.png{% endblockmedia %}"
+ alt="{% trans "the author of the question has selected this answer as correct" %}"
+ title="{% trans "the author of the question has selected this answer as correct" %}" />
{% endif %}
{% endifequal %}
</div>
@@ -847,7 +845,7 @@
<span class="comment-age">({% diff_date comment.added_at %})</span>
{% if request.user|can_delete_comment:comment %}
<img class="delete-icon"
- src="{% href "/content/images/close-small.png" %}"
+ src="{% media "/media/images/close-small.png" %}"
title="{% trans "delete this comment" %}"/>
{% endif %}
{% endspaceless %}
@@ -996,7 +994,7 @@
</p>
<p class="tags" >
{% for tag in tags %}
- <a href="{% url forum.views.tag tag.name|urlencode %}"
+ <a href="{% url tag_questions tag.name|urlencode %}"
title="{% trans "see questions tagged"%}'{{tag.name}}'{% trans "using tags" %}"
rel="tag">{{ tag.name }}</a> <span class="tag-number">&#215;{{ tag.used_count|intcomma }}</span><br/>
{% endfor %}
diff --git a/templates/question_edit.html b/forum/skins/default/templates/question_edit.html
index 7a10b6ae..5a6268c9 100644
--- a/templates/question_edit.html
+++ b/forum/skins/default/templates/question_edit.html
@@ -4,12 +4,12 @@
{% load extra_tags %}
{% block title %}{% spaceless %}{% trans "Edit question" %}{% endspaceless %}{% endblock %}
{% block forejs %}
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.editor.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.post.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/jquery.validate.pack.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/wmd/showdown.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/wmd/wmd.js" %}'></script>
- <link rel="stylesheet" type="text/css" href="{% href "/content/js/wmd/wmd.css" %}" />
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.post.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.validate.pack.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/showdown.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/wmd/wmd.js" %}'></script>
+ <link rel="stylesheet" type="text/css" href="{% media "/media/js/wmd/wmd.css" %}" />
<script type="text/javascript">
//todo move javascript out
$().ready(function(){
diff --git a/templates/question_edit_tips.html b/forum/skins/default/templates/question_edit_tips.html
index 4cabea79..4cabea79 100644
--- a/templates/question_edit_tips.html
+++ b/forum/skins/default/templates/question_edit_tips.html
diff --git a/templates/question_retag.html b/forum/skins/default/templates/question_retag.html
index b7957962..03f3da04 100644
--- a/templates/question_retag.html
+++ b/forum/skins/default/templates/question_retag.html
@@ -3,9 +3,9 @@
{% load extra_tags %}
{% block title %}{% spaceless %}{% trans "Change tags" %}{% endspaceless %}{% endblock %}
{% block forejs %}
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.editor.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.post.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/jquery.validate.pack.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.post.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.validate.pack.js" %}'></script>
<script type="text/javascript">
$().ready(function(){
diff --git a/templates/question_summary_list_roll.html b/forum/skins/default/templates/question_summary_list_roll.html
index 7312dca9..57685d6d 100644
--- a/templates/question_summary_list_roll.html
+++ b/forum/skins/default/templates/question_summary_list_roll.html
@@ -49,7 +49,7 @@
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url forum.views.tag tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
diff --git a/templates/questions.html b/forum/skins/default/templates/questions.html
index aa9a38e3..2e593f90 100644
--- a/templates/questions.html
+++ b/forum/skins/default/templates/questions.html
@@ -293,8 +293,8 @@
Hilite.debug_referrer = location.href;
});
</script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.editor.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.tag_selector.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.tag_selector.js" %}'></script>
{% endblock %}
{% block content %}
<div class="tabBar">
@@ -407,7 +407,7 @@
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url forum.views.tag tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
@@ -498,7 +498,7 @@
<h3 class="subtitle">{% trans "Related tags" %}</h3>
<div class="tags">
{% for tag in tags %}
- <a rel="tag" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}" href="{% url forum.views.tag tag.name|urlencode %}">{{ tag.name }}</a>
+ <a rel="tag" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
<span class="tag-number">&#215; {{ tag.used_count|intcomma }}</span>
<br />
{% endfor %}
diff --git a/templates/reopen.html b/forum/skins/default/templates/reopen.html
index 37fb69c1..37fb69c1 100644
--- a/templates/reopen.html
+++ b/forum/skins/default/templates/reopen.html
diff --git a/templates/revisions_answer.html b/forum/skins/default/templates/revisions_answer.html
index 974e589c..b2e33dfe 100644
--- a/templates/revisions_answer.html
+++ b/forum/skins/default/templates/revisions_answer.html
@@ -6,8 +6,8 @@
{% load humanize %}
{% block title %}{% spaceless %}{% trans "Revision history" %}{% endspaceless %}{% endblock %}
{% block forejs %}
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.editor.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.post.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.post.js" %}'></script>
<script type="text/javascript">
//todo - take this out into .js file
$().ready(function(){
@@ -24,7 +24,7 @@
var arrow = $("#rev-arrow-" + id);
var visible = arrow.attr("src").indexOf("hide") > -1;
- var path = $.i18n._('/') + "content/images/expander-arrow-" +
+ var path = $.i18n._('/') + "media/images/expander-arrow-" +
(visible ? "show" : "hide") + ".gif" + "?v={{settings.RESOURCE_REVISION}}";
arrow.attr("src", path);
$("#rev-body-" + id).slideToggle("fast");
@@ -46,7 +46,7 @@
<table width="100%">
<tr>
<td width="20" style="vertical-align:middle"><img id="rev-arrow-{{ revision.revision }}"
- src="{% href "/content/images/expander-arrow-show.gif" %}"
+ src="{% media "/media/images/expander-arrow-show.gif" %}"
alt="{% trans "click to hide/show revision" %}"/>
</td>
<td width="30px" style="vertical-align:middle"><span class="revision-number" title="{% trans "revision" %} {{ revision.revision }}">{{ revision.revision }}</span></td>
diff --git a/templates/revisions_question.html b/forum/skins/default/templates/revisions_question.html
index 83512e4a..86d52a36 100644
--- a/templates/revisions_question.html
+++ b/forum/skins/default/templates/revisions_question.html
@@ -7,8 +7,8 @@
{% load humanize %}
{% block title %}{% spaceless %}{% trans "Revision history" %}{% endspaceless %}{% endblock %}
{% block forejs %}
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.editor.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.post.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.post.js" %}'></script>
<script type="text/javascript">
//todo - take this out into .js file
$().ready(function(){
@@ -25,7 +25,7 @@
var arrow = $("#rev-arrow-" + id);
var visible = arrow.attr("src").indexOf("hide") > -1;
- var path = $.i18n._('/') + "content/images/expander-arrow-" +
+ var path = $.i18n._('/') + "media/images/expander-arrow-" +
(visible ? "show" : "hide") + ".gif" + "?v={{settings.RESOURCE_REVISION}}";
arrow.attr("src", path);
$("#rev-body-" + id).slideToggle("fast");
@@ -46,7 +46,7 @@
<table width="100%">
<tr>
<td width="20" style="vertical-align:middle"><img id="rev-arrow-{{ revision.revision }}"
- src="{% href "/content/images/expander-arrow-show.gif" %}"
+ src="{% media "/media/images/expander-arrow-show.gif" %}"
alt="{% trans "click to hide/show revision" %}"/>
</td>
<td width="30px" style="vertical-align:middle"><span class="revision-number" title="{% trans "revision" %} {{ revision.revision }}">{{ revision.revision }}</span></td>
diff --git a/templates/tag_selector.html b/forum/skins/default/templates/tag_selector.html
index 94d23f3c..7686d717 100644
--- a/templates/tag_selector.html
+++ b/forum/skins/default/templates/tag_selector.html
@@ -10,7 +10,7 @@
title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
<img class="delete-icon"
- src="{% href "/content/images/close-small-dark.png" %}"
+ src="{% media "/media/images/close-small-dark.png" %}"
title="{% blocktrans %}remove '{{tag_name}}' from the list of interesting tags{% endblocktrans %}"/>
</span>
{% endspaceless %}
@@ -27,7 +27,7 @@
title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
<img class="delete-icon"
- src="{% href "/content/images/close-small-dark.png" %}"
+ src="{% media "/media/images/close-small-dark.png" %}"
title="{% blocktrans %}remove '{{tag_name}}' from the list of ignored tags{% endblocktrans %}"/>
</span>
{% endspaceless %}
diff --git a/templates/tags.html b/forum/skins/default/templates/tags.html
index 1bde187f..50f90fb1 100644
--- a/templates/tags.html
+++ b/forum/skins/default/templates/tags.html
@@ -46,7 +46,7 @@
<ul class="tagsList tags">
{% for tag in tags.object_list %}
<li>
- <a href="{% url forum.views.tag tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">
+ <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">
{{ tag }}
</a>&nbsp;
<span class="tag-number">&#215; {{ tag.used_count|intcomma }}</span>
diff --git a/templates/user.html b/forum/skins/default/templates/user.html
index 6e4098e9..5931f31c 100644
--- a/templates/user.html
+++ b/forum/skins/default/templates/user.html
@@ -12,8 +12,8 @@
{% endblock %}
{% block forejs %}
{% if request.user|can_moderate_users %}
- <script type='text/javascript' src='{% href "/content/js/com.cnprog.admin.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/jquery.form.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/com.cnprog.admin.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.form.js" %}'></script>
{% endif %}
<script type="text/javascript">
var viewUserID = {{view_user.id}};
diff --git a/templates/user_edit.html b/forum/skins/default/templates/user_edit.html
index bc5056f9..040ebff4 100644
--- a/templates/user_edit.html
+++ b/forum/skins/default/templates/user_edit.html
@@ -24,7 +24,7 @@
{% if request.user.email %}
{% gravatar request.user 128 %}
{% else %}
- <img src="{% href "/content/images/nophoto.png" %}">
+ <img src="{% media "/media/images/nophoto.png" %}">
{% endif %}
<div style="padding:20px 0 0 20px;font-weight:bold;font-size:150%">
<a href="http://www.gravatar.com/" target="_blank"
diff --git a/templates/user_email_subscriptions.html b/forum/skins/default/templates/user_email_subscriptions.html
index 10440529..10440529 100644
--- a/templates/user_email_subscriptions.html
+++ b/forum/skins/default/templates/user_email_subscriptions.html
diff --git a/templates/user_favorites.html b/forum/skins/default/templates/user_favorites.html
index 9db01e9a..9db01e9a 100644
--- a/templates/user_favorites.html
+++ b/forum/skins/default/templates/user_favorites.html
diff --git a/templates/user_footer.html b/forum/skins/default/templates/user_footer.html
index ee347742..ee347742 100644
--- a/templates/user_footer.html
+++ b/forum/skins/default/templates/user_footer.html
diff --git a/templates/user_info.html b/forum/skins/default/templates/user_info.html
index 4ebcddd6..4ebcddd6 100644
--- a/templates/user_info.html
+++ b/forum/skins/default/templates/user_info.html
diff --git a/templates/user_recent.html b/forum/skins/default/templates/user_recent.html
index b704ab25..b704ab25 100644
--- a/templates/user_recent.html
+++ b/forum/skins/default/templates/user_recent.html
diff --git a/templates/user_reputation.html b/forum/skins/default/templates/user_reputation.html
index 16127140..776935ae 100644
--- a/templates/user_reputation.html
+++ b/forum/skins/default/templates/user_reputation.html
@@ -4,8 +4,8 @@
{% load extra_filters %}
{% load humanize %}
{% block userjs %}
- <script type='text/javascript' src='{% href "/content/js/excanvas.pack.js" %}'></script>
- <script type='text/javascript' src='{% href "/content/js/jquery.flot.pack.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/excanvas.pack.js" %}'></script>
+ <script type='text/javascript' src='{% media "/media/js/jquery.flot.pack.js" %}'></script>
<script type="text/javascript">
$().ready(function(){
diff --git a/templates/user_responses.html b/forum/skins/default/templates/user_responses.html
index c4f4ffed..c4f4ffed 100644
--- a/templates/user_responses.html
+++ b/forum/skins/default/templates/user_responses.html
diff --git a/templates/user_stats.html b/forum/skins/default/templates/user_stats.html
index ecc39807..a3f88131 100644
--- a/templates/user_stats.html
+++ b/forum/skins/default/templates/user_stats.html
@@ -69,12 +69,12 @@
<table>
<tr>
<td width="60">
- <img style="cursor: default;" src="{% href "/content/images/vote-arrow-up-on.png" %}" alt="{% trans "thumb up" %}" />
+ <img style="cursor: default;" src="{% media "/media/images/vote-arrow-up-on.png" %}" alt="{% trans "thumb up" %}" />
<span title="{% trans "user has voted up this many times" %}" class="vote-count">{{up_votes}}</span>
</td>
<td width="60">
- <img style="cursor: default;" src="{% href "/content/images/vote-arrow-down-on.png" %}" alt="{% trans "thumb down" %}" />
+ <img style="cursor: default;" src="{% media "/media/images/vote-arrow-down-on.png" %}" alt="{% trans "thumb down" %}" />
<span title="{% trans "user voted down this many times" %}" class="vote-count">{{down_votes}}</span>
</td>
@@ -98,7 +98,7 @@
{% for tag in user_tags%}
<a rel="tag"
title="{% blocktrans with tag.name as tag_name %}see other questions with {{view_user}}'s contributions tagged '{{ tag_name }}' {% endblocktrans %}"
- href="{% url forum.views.tag tag|urlencode %}?user={{view_user.username}}">{{tag.name}}</a>
+ href="{% url tag_questions tag|urlencode %}?user={{view_user.username}}">{{tag.name}}</a>
<span class="tag-number">&#215; {{ tag.user_tag_usage_count|intcomma }}</span><br/>
{% if forloop.counter|divisibleby:"10" %}
</td>
diff --git a/templates/user_tabs.html b/forum/skins/default/templates/user_tabs.html
index 908e8430..908e8430 100644
--- a/templates/user_tabs.html
+++ b/forum/skins/default/templates/user_tabs.html
diff --git a/templates/user_votes.html b/forum/skins/default/templates/user_votes.html
index 94d7fcbd..b56aab01 100644
--- a/templates/user_votes.html
+++ b/forum/skins/default/templates/user_votes.html
@@ -12,9 +12,9 @@
<div style="width:150px;float:left">{% diff_date vote.voted_at 3 %}</div>
<div style="width:30px;float:left">
{% ifequal vote.vote 1 %}
- <img src="{% href "/content/images/vote-arrow-up-on.png" %}" title="{% trans "upvote" %}">
+ <img src="{% media "/media/images/vote-arrow-up-on.png" %}" title="{% trans "upvote" %}">
{% else %}
- <img src="{% href "/content/images/vote-arrow-down-on.png" %}" title="{% trans "downvote" %}">
+ <img src="{% media "/media/images/vote-arrow-down-on.png" %}" title="{% trans "downvote" %}">
{% endifequal %}
</div>
<div style="float:left;overflow:hidden;width:750px">
diff --git a/templates/users.html b/forum/skins/default/templates/users.html
index 3a59b0c0..3a59b0c0 100644
--- a/templates/users.html
+++ b/forum/skins/default/templates/users.html
diff --git a/templates/users_questions.html b/forum/skins/default/templates/users_questions.html
index b445a74c..8049d832 100644
--- a/templates/users_questions.html
+++ b/forum/skins/default/templates/users_questions.html
@@ -10,14 +10,14 @@
<div class="favorites-count">
<img title="{% trans "this questions was selected as favorite" %} {{question.favourite_count}} {% trans "number of times" %}"
alt="{% trans "thumb-up on" %}"
- src="{% href "/content/images/vote-favorite-on.png" %}"/>
+ src="{% media "/media/images/vote-favorite-on.png" %}"/>
<div><b>{{question.favourite_count|intcomma}}</b></div>
</div>
{% else %}
<div class="favorites-count-off">
<img title="{% trans "this question was selected as favorite" %}{{question.favourite_count}} {% trans "number of times" %}"
alt="{% trans "thumb-up off" %}"
- src="{% href "/content/images/vote-favorite-off.png" %}"/>
+ src="{% media "/media/images/vote-favorite-off.png" %}"/>
<div><b>{{question.favourite_count|intcomma}}</b></div>
</div>
{% endif %}
@@ -49,7 +49,7 @@
{% convert2tagname_list question %}
{% for tag in question.tagnames %}
<!--todo - move trans below to blocktrans -->
- <a href="{% url forum.views.tag tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
<div class="started">
diff --git a/forum/templatetags/extra_tags.py b/forum/templatetags/extra_tags.py
index 4f79e497..26c52b8d 100644
--- a/forum/templatetags/extra_tags.py
+++ b/forum/templatetags/extra_tags.py
@@ -13,6 +13,7 @@ from forum.models import Question, Answer, QuestionRevision, AnswerRevision
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from django.conf import settings
+from forum import skins
register = template.Library()
@@ -276,9 +277,11 @@ def get_latest_changed_timestamp():
return timestr
@register.simple_tag
-def href(url):
- url = '///' + settings.FORUM_SCRIPT_ALIAS + '/' + url
- return posixpath.normpath(url) + '?v=%d' % settings.RESOURCE_REVISION
+def media(url):
+ url = skins.find_media_source(url)
+ if url:
+ url = '///' + settings.FORUM_SCRIPT_ALIAS + '/m/' + url
+ return posixpath.normpath(url) + '?v=%d' % settings.RESOURCE_REVISION
class ItemSeparatorNode(template.Node):
def __init__(self,separator):
@@ -323,29 +326,32 @@ def joinitems(parser,token):
return JoinItemListNode(separator=sep_node,items=nodelist)
-class BlockResourceNode(template.Node):
+class BlockMediaUrlNode(template.Node):
def __init__(self,nodelist):
self.items = nodelist
def render(self,context):
- out = '///' + settings.FORUM_SCRIPT_ALIAS
+ prefix = '///' + settings.FORUM_SCRIPT_ALIAS + 'm/'
+ url = ''
if self.items:
- out += '/'
+ url += '/'
for item in self.items:
- bit = item.render(context)
- out += bit
- out = os.path.normpath(out) + '?v=%d' % settings.RESOURCE_REVISION
+ url += item.render(context)
+
+ url = skins.find_media_source(url)
+ url = prefix + url
+ out = posixpath.normpath(url) + '?v=%d' % settings.RESOURCE_REVISION
return out.replace(' ','')
-@register.tag(name='blockresource')
-def blockresource(parser,token):
+@register.tag(name='blockmedia')
+def blockmedia(parser,token):
try:
tagname = token.split_contents()
except ValueError:
- raise template.TemplateSyntaxError("blockresource tag does not use arguments")
+ raise template.TemplateSyntaxError("blockmedia tag does not use arguments")
nodelist = []
while True:
- nodelist.append(parser.parse(('endblockresource')))
+ nodelist.append(parser.parse(('endblockmedia')))
next = parser.next_token()
- if next.contents == 'endblockresource':
+ if next.contents == 'endblockmedia':
break
- return BlockResourceNode(nodelist)
+ return BlockMediaUrlNode(nodelist)
diff --git a/forum/upfiles/README b/forum/upfiles/README
new file mode 100644
index 00000000..17bf8ecb
--- /dev/null
+++ b/forum/upfiles/README
@@ -0,0 +1,2 @@
+This directory is to contain uploaded images and other files
+must be writable by the webserver
diff --git a/forum/urls.py b/forum/urls.py
index 42746d44..fe335538 100644
--- a/forum/urls.py
+++ b/forum/urls.py
@@ -5,6 +5,7 @@ from forum import views as app
from forum.feed import RssLastestQuestionsFeed
from forum.sitemap import QuestionsSitemap
from django.utils.translation import ugettext as _
+import logging
admin.autodiscover()
feeds = {
@@ -14,78 +15,78 @@ sitemaps = {
'questions': QuestionsSitemap
}
-APP_PATH = os.path.dirname(os.path.dirname(__file__))
+APP_PATH = os.path.dirname(__file__)
urlpatterns = patterns('',
- url(r'^$', app.index, name='index'),
+ url(r'^$', app.content.index, name='index'),
url(r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
- (r'^favicon\.ico$', 'django.views.generic.simple.redirect_to', {'url': '/content/images/favicon.ico'}),
- (r'^favicon\.gif$', 'django.views.generic.simple.redirect_to', {'url': '/content/images/favicon.gif'}),
- (r'^content/(?P<path>.*)$', 'django.views.static.serve',
- {'document_root': os.path.join(APP_PATH, 'templates/content').replace('\\','/')}
+ #(r'^favicon\.ico$', 'django.views.generic.simple.redirect_to', {'url': '/media/images/favicon.ico'}),
+ #(r'^favicon\.gif$', 'django.views.generic.simple.redirect_to', {'url': '/media/images/favicon.gif'}),
+ (r'^m/(?P<path>.*)$', 'django.views.static.serve',
+ {'document_root': os.path.join(APP_PATH,'skins').replace('\\','/')}
),
(r'^%s(?P<path>.*)$' % _('upfiles/'), 'django.views.static.serve',
- {'document_root': os.path.join(APP_PATH, 'templates/upfiles').replace('\\','/')}
+ {'document_root': os.path.join(APP_PATH,'upfiles').replace('\\','/')}
),
(r'^%s/$' % _('signin/'), 'django_authopenid.views.signin'),
- url(r'^%s$' % _('about/'), app.about, name='about'),
- url(r'^%s$' % _('faq/'), app.faq, name='faq'),
- url(r'^%s$' % _('privacy/'), app.privacy, name='privacy'),
- url(r'^%s$' % _('logout/'), app.logout, name='logout'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('comments/')), app.answer_comments, name='answer_comments'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('edit/')), app.edit_answer, name='edit_answer'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('revisions/')), app.answer_revisions, name='answer_revisions'),
- url(r'^%s$' % _('questions/'), app.questions, name='questions'),
- url(r'^%s%s$' % (_('questions/'), _('ask/')), app.ask, name='ask'),
- url(r'^%s%s$' % (_('questions/'), _('unanswered/')), app.unanswered, name='unanswered'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('edit/')), app.edit_question, name='edit_question'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('close/')), app.close, name='close'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('reopen/')), app.reopen, name='reopen'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('answer/')), app.answer, name='answer'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('vote/')), app.vote, name='vote'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('revisions/')), app.question_revisions, name='question_revisions'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('comments/')), app.question_comments, name='question_comments'),
- url(r'^%s$' % _('command/'), app.ajax_command, name='call_ajax'),
+ url(r'^%s$' % _('about/'), app.meta.about, name='about'),
+ url(r'^%s$' % _('faq/'), app.meta.faq, name='faq'),
+ url(r'^%s$' % _('privacy/'), app.meta.privacy, name='privacy'),
+ url(r'^%s$' % _('logout/'), app.meta.logout, name='logout'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('comments/')), app.content.answer_comments, name='answer_comments'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('edit/')), app.content.edit_answer, name='edit_answer'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('revisions/')), app.content.answer_revisions, name='answer_revisions'),
+ url(r'^%s$' % _('questions/'), app.content.questions, name='questions'),
+ url(r'^%s%s$' % (_('questions/'), _('ask/')), app.content.ask, name='ask'),
+ url(r'^%s%s$' % (_('questions/'), _('unanswered/')), app.content.unanswered, name='unanswered'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('edit/')), app.content.edit_question, name='edit_question'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('close/')), app.content.close, name='close'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('reopen/')), app.content.reopen, name='reopen'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('answer/')), app.content.answer, name='answer'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('vote/')), app.content.vote, name='vote'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('revisions/')), app.content.question_revisions, name='question_revisions'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('comments/')), app.content.question_comments, name='question_comments'),
+ url(r'^%s$' % _('command/'), app.content.ajax_command, name='call_ajax'),
url(r'^%s(?P<object_id>\d+)/%s(?P<comment_id>\d+)/%s$' % (_('questions/'), _('comments/'),_('delete/')), \
- app.delete_comment, kwargs={'commented_object_type':'question'},\
+ app.content.delete_comment, kwargs={'commented_object_type':'question'},\
name='delete_question_comment'),
url(r'^%s(?P<object_id>\d+)/%s(?P<comment_id>\d+)/%s$' % (_('answers/'), _('comments/'),_('delete/')), \
- app.delete_comment, kwargs={'commented_object_type':'answer'}, \
+ app.content.delete_comment, kwargs={'commented_object_type':'answer'}, \
name='delete_answer_comment'), \
#place general question item in the end of other operations
- url(r'^%s(?P<id>\d+)/' % _('question/'), app.question, name='question'),
- url(r'^%s$' % _('tags/'), app.tags, name='tags'),
- url(r'^%s(?P<tag>[^/]+)/$' % _('tags/'), app.tag, name='tag_questions'),
+ url(r'^%s(?P<id>\d+)/' % _('question/'), app.content.question, name='question'),
+ url(r'^%s$' % _('tags/'), app.content.tags, name='tags'),
+ url(r'^%s(?P<tag>[^/]+)/$' % _('tags/'), app.content.tag, name='tag_questions'),
- url(r'^%s%s(?P<tag>[^/]+)/$' % (_('mark-tag/'),_('interesting/')), app.mark_tag, \
+ url(r'^%s%s(?P<tag>[^/]+)/$' % (_('mark-tag/'),_('interesting/')), app.content.mark_tag, \
kwargs={'reason':'good','action':'add'}, \
name='mark_interesting_tag'),
- url(r'^%s%s(?P<tag>[^/]+)/$' % (_('mark-tag/'),_('ignored/')), app.mark_tag, \
+ url(r'^%s%s(?P<tag>[^/]+)/$' % (_('mark-tag/'),_('ignored/')), app.content.mark_tag, \
kwargs={'reason':'bad','action':'add'}, \
name='mark_ignored_tag'),
- url(r'^%s(?P<tag>[^/]+)/$' % _('unmark-tag/'), app.mark_tag, \
+ url(r'^%s(?P<tag>[^/]+)/$' % _('unmark-tag/'), app.content.mark_tag, \
kwargs={'action':'remove'}, \
name='mark_ignored_tag'),
- url(r'^%s$' % _('users/'),app.users, name='users'),
- url(r'^%s(?P<id>\d+)/$' % _('moderate-user/'), app.moderate_user, name='moderate_user'),
- url(r'^%s(?P<id>\d+)/%s$' % (_('users/'), _('edit/')), app.edit_user, name='edit_user'),
- url(r'^%s(?P<id>\d+)//*' % _('users/'), app.user, name='user'),
- url(r'^%s$' % _('badges/'),app.badges, name='badges'),
- url(r'^%s(?P<id>\d+)//*' % _('badges/'), app.badge, name='badge'),
- url(r'^%s%s$' % (_('messages/'), _('markread/')),app.read_message, name='read_message'),
+ url(r'^%s$' % _('users/'),app.users.users, name='users'),
+ url(r'^%s(?P<id>\d+)/$' % _('moderate-user/'), app.users.moderate_user, name='moderate_user'),
+ url(r'^%s(?P<id>\d+)/%s$' % (_('users/'), _('edit/')), app.users.edit_user, name='edit_user'),
+ url(r'^%s(?P<id>\d+)//*' % _('users/'), app.users.user, name='user'),
+ url(r'^%s$' % _('badges/'),app.meta.badges, name='badges'),
+ url(r'^%s(?P<id>\d+)//*' % _('badges/'), app.meta.badge, name='badge'),
+ url(r'^%s%s$' % (_('messages/'), _('markread/')),app.meta.read_message, name='read_message'),
# (r'^admin/doc/' % _('admin/doc'), include('django.contrib.admindocs.urls')),
(r'^%s(.*)' % _('nimda/'), admin.site.root),
url(r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}),
- (r'^%s$' % _('upload/'), app.upload),
- url(r'^%s$' % _('books/'), app.books, name='books'),
- url(r'^%s%s(?P<short_name>[^/]+)/$' % (_('books/'), _('ask/')), app.ask_book, name='ask_book'),
- url(r'^%s(?P<short_name>[^/]+)/$' % _('books/'), app.book, name='book'),
- url(r'^%s$' % _('search/'), app.search, name='search'),
- url(r'^%s$' % _('feedback/'), app.feedback, name='feedback'),
+ (r'^%s$' % _('upload/'), app.content.upload),
+ url(r'^%s$' % _('books/'), app.books.books, name='books'),
+ url(r'^%s%s(?P<short_name>[^/]+)/$' % (_('books/'), _('ask/')), app.books.ask_book, name='ask_book'),
+ url(r'^%s(?P<short_name>[^/]+)/$' % _('books/'), app.books.book, name='book'),
+ url(r'^%s$' % _('search/'), app.content.search, name='search'),
+ url(r'^%s$' % _('feedback/'), app.meta.feedback, name='feedback'),
(r'^%sfb/' % _('account/'), include('fbconnect.urls')),
(r'^%s' % _('account/'), include('django_authopenid.urls')),
(r'^i18n/', include('django.conf.urls.i18n')),
diff --git a/forum/user.py b/forum/user.py
deleted file mode 100644
index 40bf6a89..00000000
--- a/forum/user.py
+++ /dev/null
@@ -1,74 +0,0 @@
-from django.utils.translation import ugettext as _
-class UserView:
- def __init__(self, id, tab_title, tab_description, page_title, view_name, template_file, data_size=0):
- self.id = id
- self.tab_title = tab_title
- self.tab_description = tab_description
- self.page_title = page_title
- self.view_name = view_name
- self.template_file = template_file
- self.data_size = data_size
-
-
-USER_TEMPLATE_VIEWS = (
- UserView(
- id = 'stats',
- tab_title = _('overview'),
- tab_description = _('user profile'),
- page_title = _('user profile overview'),
- view_name = 'user_stats',
- template_file = 'user_stats.html'
- ),
- UserView(
- id = 'recent',
- tab_title = _('recent activity'),
- tab_description = _('recent user activity'),
- page_title = _('profile - recent activity'),
- view_name = 'user_recent',
- template_file = 'user_recent.html',
- data_size = 50
- ),
- UserView(
- id = 'responses',
- tab_title = _('responses'),
- tab_description = _('comments and answers to others questions'),
- page_title = _('profile - responses'),
- view_name = 'user_responses',
- template_file = 'user_responses.html',
- data_size = 50
- ),
- UserView(
- id = 'reputation',
- tab_title = _('reputation'),
- tab_description = _('user reputation in the community'),
- page_title = _('profile - user reputation'),
- view_name = 'user_reputation',
- template_file = 'user_reputation.html'
- ),
- UserView(
- id = 'favorites',
- tab_title = _('favorite questions'),
- tab_description = _('users favorite questions'),
- page_title = _('profile - favorite questions'),
- view_name = 'user_favorites',
- template_file = 'user_favorites.html',
- data_size = 50
- ),
- UserView(
- id = 'votes',
- tab_title = _('casted votes'),
- tab_description = _('user vote record'),
- page_title = _('profile - votes'),
- view_name = 'user_votes',
- template_file = 'user_votes.html',
- data_size = 50
- ),
- UserView(
- id = 'email_subscriptions',
- tab_title = _('email subscriptions'),
- tab_description = _('email subscription settings'),
- page_title = _('profile - email subscriptions'),
- view_name = 'user_email_subscriptions',
- template_file = 'user_email_subscriptions.html'
- )
-)
diff --git a/forum/views/__init__.py b/forum/views/__init__.py
new file mode 100644
index 00000000..7fdb6f61
--- /dev/null
+++ b/forum/views/__init__.py
@@ -0,0 +1,4 @@
+import content
+import users
+import meta
+import books
diff --git a/forum/views/books.py b/forum/views/books.py
new file mode 100644
index 00000000..bb1bfe85
--- /dev/null
+++ b/forum/views/books.py
@@ -0,0 +1,139 @@
+from django.contrib.auth.decorators import login_required
+from django.core.urlresolvers import reverse
+from django.shortcuts import render_to_response
+from forum.models import BookAuthorInfo, BookAuthorRss, Book
+from forum.models import Question, QuestionRevision
+from django.http import HttpResponseRedirect
+
+def books(request):
+ """this view seems to redirect to a default book
+ maybe it should instead show some popular titles?
+ """
+ return HttpResponseRedirect(reverse('books') + 'mysql-zhaoyang')
+
+def book(request, short_name, unanswered=False):
+ """
+ 1. questions list
+ 2. book info
+ 3. author info and blog rss items
+ """
+ """
+ List of Questions, Tagged questions, and Unanswered questions.
+ """
+ books = Book.objects.extra(where=['short_name = %s'], params=[short_name])
+ match_count = len(books)
+ if match_count == 0:
+ raise Http404
+ else:
+ # the book info
+ book = books[0]
+ # get author info
+ author_info = BookAuthorInfo.objects.get(book=book)
+ # get author rss info
+ author_rss = BookAuthorRss.objects.filter(book=book)
+
+ # get pagesize from session, if failed then get default value
+ user_page_size = request.session.get("pagesize", QUESTIONS_PAGE_SIZE)
+ # set pagesize equal to logon user specified value in database
+ if request.user.is_authenticated() and request.user.questions_per_page > 0:
+ user_page_size = request.user.questions_per_page
+
+ try:
+ page = int(request.GET.get('page', '1'))
+ except ValueError:
+ page = 1
+
+ view_id = request.GET.get('sort', None)
+ view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
+ try:
+ orderby = view_dic[view_id]
+ except KeyError:
+ view_id = "latest"
+ orderby = "-added_at"
+
+ # check if request is from tagged questions
+ if unanswered:
+ # check if request is from unanswered questions
+ # Article.objects.filter(publications__id__exact=1)
+ objects = Question.objects.filter(book__id__exact=book.id, deleted=False, answer_count=0).order_by(orderby)
+ else:
+ objects = Question.objects.filter(book__id__exact=book.id, deleted=False).order_by(orderby)
+
+ # RISK - inner join queries
+ objects = objects.select_related();
+ objects_list = Paginator(objects, user_page_size)
+ questions = objects_list.page(page)
+
+ return render_to_response('book.html', {
+ "book" : book,
+ "author_info" : author_info,
+ "author_rss" : author_rss,
+ "questions" : questions,
+ "context" : {
+ 'is_paginated' : True,
+ 'pages': objects_list.num_pages,
+ 'page': page,
+ 'has_previous': questions.has_previous(),
+ 'has_next': questions.has_next(),
+ 'previous': questions.previous_page_number(),
+ 'next': questions.next_page_number(),
+ 'base_url' : request.path + '?sort=%s&' % view_id,
+ 'pagesize' : user_page_size
+ }
+ }, context_instance=RequestContext(request))
+
+@login_required
+def ask_book(request, short_name):
+ if request.method == "POST":
+ form = AskForm(request.POST)
+ if form.is_valid():
+ added_at = datetime.datetime.now()
+ html = sanitize_html(markdowner.convert(form.cleaned_data['text']))
+ question = Question(
+ title = strip_tags(form.cleaned_data['title']),
+ author = request.user,
+ added_at = added_at,
+ last_activity_at = added_at,
+ last_activity_by = request.user,
+ wiki = form.cleaned_data['wiki'],
+ tagnames = form.cleaned_data['tags'].strip(),
+ html = html,
+ summary = strip_tags(html)[:120]
+ )
+ if question.wiki:
+ question.last_edited_by = question.author
+ question.last_edited_at = added_at
+ question.wikified_at = added_at
+
+ question.save()
+
+ # create the first revision
+ QuestionRevision.objects.create(
+ question = question,
+ revision = 1,
+ title = question.title,
+ author = request.user,
+ revised_at = added_at,
+ tagnames = question.tagnames,
+ summary = CONST['default_version'],
+ text = form.cleaned_data['text']
+ )
+
+ books = Book.objects.extra(where=['short_name = %s'], params=[short_name])
+ match_count = len(books)
+ if match_count == 1:
+ # the book info
+ book = books[0]
+ book.questions.add(question)
+
+ return HttpResponseRedirect(question.get_absolute_url())
+ else:
+ form = AskForm()
+
+ tags = _get_tags_cache_json()
+ return render_to_response('ask.html', {
+ 'form' : form,
+ 'tags' : tags,
+ 'email_validation_faq_url': reverse('faq') + '#validate',
+ }, context_instance=RequestContext(request))
+
diff --git a/forum/views/content.py b/forum/views/content.py
new file mode 100644
index 00000000..3fd3017d
--- /dev/null
+++ b/forum/views/content.py
@@ -0,0 +1,1394 @@
+# encoding:utf-8
+import os.path
+import time, datetime, calendar, random
+import logging
+from urllib import quote, unquote
+from django.conf import settings
+from django.core.files.storage import default_storage
+from django.shortcuts import render_to_response, get_object_or_404
+from django.contrib.auth.decorators import login_required
+from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, Http404
+from django.core.paginator import Paginator, EmptyPage, InvalidPage
+from django.template import RequestContext, loader
+from django.utils.html import *
+from django.utils import simplejson
+from django.core import serializers
+from django.db import transaction
+from django.db.models import Count, Q
+from django.contrib.contenttypes.models import ContentType
+from django.utils.translation import ugettext as _
+from django.utils.datastructures import SortedDict
+from django.template.defaultfilters import slugify
+from django.core.exceptions import PermissionDenied
+
+from utils.html import sanitize_html
+from utils.decorators import ajax_method, ajax_login_required
+from markdown2 import Markdown
+#from lxml.html.diff import htmldiff
+from forum.diff import textDiff as htmldiff
+from forum.forms import *
+from forum.models import *
+from forum.auth import *
+from forum.const import *
+from forum import auth
+from utils.forms import get_next_url
+
+# used in index page
+INDEX_PAGE_SIZE = 20
+INDEX_AWARD_SIZE = 15
+INDEX_TAGS_SIZE = 100
+# used in tags list
+DEFAULT_PAGE_SIZE = 60
+# used in questions
+QUESTIONS_PAGE_SIZE = 10
+# used in answers
+ANSWERS_PAGE_SIZE = 10
+
+markdowner = Markdown(html4tags=True)
+
+#system to display main content
+def _get_tags_cache_json():#service routine used by views requiring tag list in the javascript space
+ """returns list of all tags in json format
+ no caching yet, actually
+ """
+ tags = Tag.objects.filter(deleted=False).all()
+ tags_list = []
+ for tag in tags:
+ dic = {'n': tag.name, 'c': tag.used_count}
+ tags_list.append(dic)
+ tags = simplejson.dumps(tags_list)
+ return tags
+
+def _get_and_remember_questions_sort_method(request, view_dic, default):#service routine used by q listing views and question view
+ """manages persistence of post sort order
+ it is assumed that when user wants newest question -
+ then he/she wants newest answers as well, etc.
+ how far should this assumption actually go - may be a good question
+ """
+ if default not in view_dic:
+ raise Exception('default value must be in view_dic')
+
+ q_sort_method = request.REQUEST.get('sort', None)
+ if q_sort_method == None:
+ q_sort_method = request.session.get('questions_sort_method', default)
+
+ if q_sort_method not in view_dic:
+ q_sort_method = default
+ request.session['questions_sort_method'] = q_sort_method
+ return q_sort_method, view_dic[q_sort_method]
+
+#refactor? - we have these
+#views that generate a listing of questions in one way or another:
+#index, unanswered, questions, search, tag
+#should we dry them up?
+#related topics - information drill-down, search refinement
+
+def index(request):#generates front page - shows listing of questions sorted in various ways
+ """index view mapped to the root url of the Q&A site
+ """
+ view_dic = {
+ "latest":"-last_activity_at",
+ "hottest":"-answer_count",
+ "mostvoted":"-score",
+ }
+ view_id, orderby = _get_and_remember_questions_sort_method(request, view_dic, 'latest')
+
+ page_size = request.session.get('pagesize', QUESTIONS_PAGE_SIZE)
+ questions = Question.objects.exclude(deleted=True).order_by(orderby)[:page_size]
+ # RISK - inner join queries
+ questions = questions.select_related()
+ tags = Tag.objects.get_valid_tags(INDEX_TAGS_SIZE)
+
+ awards = Award.objects.get_recent_awards()
+
+ (interesting_tag_names, ignored_tag_names) = (None, None)
+ if request.user.is_authenticated():
+ pt = MarkedTag.objects.filter(user=request.user)
+ interesting_tag_names = pt.filter(reason='good').values_list('tag__name', flat=True)
+ ignored_tag_names = pt.filter(reason='bad').values_list('tag__name', flat=True)
+
+ tags_autocomplete = _get_tags_cache_json()
+
+ return render_to_response('index.html', {
+ 'interesting_tag_names': interesting_tag_names,
+ 'tags_autocomplete': tags_autocomplete,
+ 'ignored_tag_names': ignored_tag_names,
+ "questions" : questions,
+ "tab_id" : view_id,
+ "tags" : tags,
+ "awards" : awards[:INDEX_AWARD_SIZE],
+ }, context_instance=RequestContext(request))
+
+def unanswered(request):#generates listing of unanswered questions
+ return questions(request, unanswered=True)
+
+def questions(request, tagname=None, unanswered=False):#a view generating listing of questions, used by 'unanswered' too
+ """
+ List of Questions, Tagged questions, and Unanswered questions.
+ """
+ # template file
+ # "questions.html" or maybe index.html in the future
+ template_file = "questions.html"
+ # Set flag to False by default. If it is equal to True, then need to be saved.
+ pagesize_changed = False
+ # get pagesize from session, if failed then get default value
+ pagesize = request.session.get("pagesize",10)
+ try:
+ page = int(request.GET.get('page', '1'))
+ except ValueError:
+ page = 1
+
+ view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
+ view_id, orderby = _get_and_remember_questions_sort_method(request,view_dic,'latest')
+
+ # check if request is from tagged questions
+ qs = Question.objects.exclude(deleted=True)
+
+ if tagname is not None:
+ qs = qs.filter(tags__name = unquote(tagname))
+
+ if unanswered:
+ qs = qs.exclude(answer_accepted=True)
+
+ author_name = None
+ #user contributed questions & answers
+ if 'user' in request.GET:
+ try:
+ author_name = request.GET['user']
+ u = User.objects.get(username=author_name)
+ qs = qs.filter(Q(author=u) | Q(answers__author=u))
+ except User.DoesNotExist:
+ author_name = None
+
+ if request.user.is_authenticated():
+ uid_str = str(request.user.id)
+ qs = qs.extra(
+ select = SortedDict([
+ (
+ 'interesting_score',
+ 'SELECT COUNT(1) FROM forum_markedtag, question_tags '
+ + 'WHERE forum_markedtag.user_id = %s '
+ + 'AND forum_markedtag.tag_id = question_tags.tag_id '
+ + 'AND forum_markedtag.reason = \'good\' '
+ + 'AND question_tags.question_id = question.id'
+ ),
+ ]),
+ select_params = (uid_str,),
+ )
+ if request.user.hide_ignored_questions:
+ ignored_tags = Tag.objects.filter(user_selections__reason='bad',
+ user_selections__user = request.user)
+ qs = qs.exclude(tags__in=ignored_tags)
+ else:
+ qs = qs.extra(
+ select = SortedDict([
+ (
+ 'ignored_score',
+ 'SELECT COUNT(1) FROM forum_markedtag, question_tags '
+ + 'WHERE forum_markedtag.user_id = %s '
+ + 'AND forum_markedtag.tag_id = question_tags.tag_id '
+ + 'AND forum_markedtag.reason = \'bad\' '
+ + 'AND question_tags.question_id = question.id'
+ )
+ ]),
+ select_params = (uid_str, )
+ )
+
+ qs = qs.select_related(depth=1).order_by(orderby)
+
+ objects_list = Paginator(qs, pagesize)
+ questions = objects_list.page(page)
+
+ # Get related tags from this page objects
+ if questions.object_list.count() > 0:
+ related_tags = Tag.objects.get_tags_by_questions(questions.object_list)
+ else:
+ related_tags = None
+ tags_autocomplete = _get_tags_cache_json()
+
+ # get the list of interesting and ignored tags
+ (interesting_tag_names, ignored_tag_names) = (None, None)
+ if request.user.is_authenticated():
+ pt = MarkedTag.objects.filter(user=request.user)
+ interesting_tag_names = pt.filter(reason='good').values_list('tag__name', flat=True)
+ ignored_tag_names = pt.filter(reason='bad').values_list('tag__name', flat=True)
+
+ return render_to_response(template_file, {
+ "questions" : questions,
+ "author_name" : author_name,
+ "tab_id" : view_id,
+ "questions_count" : objects_list.count,
+ "tags" : related_tags,
+ "tags_autocomplete" : tags_autocomplete,
+ "searchtag" : tagname,
+ "is_unanswered" : unanswered,
+ "interesting_tag_names": interesting_tag_names,
+ 'ignored_tag_names': ignored_tag_names,
+ "context" : {
+ 'is_paginated' : True,
+ 'pages': objects_list.num_pages,
+ 'page': page,
+ 'has_previous': questions.has_previous(),
+ 'has_next': questions.has_next(),
+ 'previous': questions.previous_page_number(),
+ 'next': questions.next_page_number(),
+ 'base_url' : request.path + '?sort=%s&' % view_id,
+ 'pagesize' : pagesize
+ }}, context_instance=RequestContext(request))
+
+def search(request): #generates listing of questions matching a search query - including tags and just words
+ """generates listing of questions matching a search query
+ supports full text search in mysql db using sphinx and internally in postgresql
+ falls back on simple partial string matching approach if
+ full text search function is not available
+ """
+ if request.method == "GET":
+ keywords = request.GET.get("q")
+ search_type = request.GET.get("t")
+ try:
+ page = int(request.GET.get('page', '1'))
+ except ValueError:
+ page = 1
+ if keywords is None:
+ return HttpResponseRedirect(reverse(index))
+ if search_type == 'tag':
+ return HttpResponseRedirect(reverse('tags') + '?q=%s&page=%s' % (keywords.strip(), page))
+ elif search_type == "user":
+ return HttpResponseRedirect(reverse('users') + '?q=%s&page=%s' % (keywords.strip(), page))
+ elif search_type == "question":
+
+ template_file = "questions.html"
+ # Set flag to False by default. If it is equal to True, then need to be saved.
+ pagesize_changed = False
+ # get pagesize from session, if failed then get default value
+ user_page_size = request.session.get("pagesize", QUESTIONS_PAGE_SIZE)
+ # set pagesize equal to logon user specified value in database
+ if request.user.is_authenticated() and request.user.questions_per_page > 0:
+ user_page_size = request.user.questions_per_page
+
+ try:
+ page = int(request.GET.get('page', '1'))
+ # get new pagesize from UI selection
+ pagesize = int(request.GET.get('pagesize', user_page_size))
+ if pagesize <> user_page_size:
+ pagesize_changed = True
+
+ except ValueError:
+ page = 1
+ pagesize = user_page_size
+
+ # save this pagesize to user database
+ if pagesize_changed:
+ request.session["pagesize"] = pagesize
+ if request.user.is_authenticated():
+ user = request.user
+ user.questions_per_page = pagesize
+ user.save()
+
+ view_id = request.GET.get('sort', None)
+ view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
+ try:
+ orderby = view_dic[view_id]
+ except KeyError:
+ view_id = "latest"
+ orderby = "-added_at"
+
+ if settings.USE_PG_FTS:
+ objects = Question.objects.filter(deleted=False).extra(
+ select={
+ 'ranking': "ts_rank_cd(tsv, plainto_tsquery(%s), 32)",
+ },
+ where=["tsv @@ plainto_tsquery(%s)"],
+ params=[keywords],
+ select_params=[keywords]
+ ).order_by('-ranking')
+
+ elif settings.USE_SPHINX_SEARCH == True:
+ #search index is now free of delete questions and answers
+ #so there is not "antideleted" filtering here
+ objects = Question.search.query(keywords)
+ #no related selection either because we're relying on full text search here
+ else:
+ objects = Question.objects.filter(deleted=False).extra(where=['title like %s'], params=['%' + keywords + '%']).order_by(orderby)
+ # RISK - inner join queries
+ objects = objects.select_related();
+
+ objects_list = Paginator(objects, pagesize)
+ questions = objects_list.page(page)
+
+ # Get related tags from this page objects
+ related_tags = []
+ for question in questions.object_list:
+ tags = list(question.tags.all())
+ for tag in tags:
+ if tag not in related_tags:
+ related_tags.append(tag)
+
+ #if is_search is true in the context, prepend this string to soting tabs urls
+ search_uri = "?q=%s&page=%d&t=question" % ("+".join(keywords.split()), page)
+
+ return render_to_response(template_file, {
+ "questions" : questions,
+ "tab_id" : view_id,
+ "questions_count" : objects_list.count,
+ "tags" : related_tags,
+ "searchtag" : None,
+ "searchtitle" : keywords,
+ "keywords" : keywords,
+ "is_unanswered" : False,
+ "is_search": True,
+ "search_uri": search_uri,
+ "context" : {
+ 'is_paginated' : True,
+ 'pages': objects_list.num_pages,
+ 'page': page,
+ 'has_previous': questions.has_previous(),
+ 'has_next': questions.has_next(),
+ 'previous': questions.previous_page_number(),
+ 'next': questions.next_page_number(),
+ 'base_url' : request.path + '?t=question&q=%s&sort=%s&' % (keywords, view_id),
+ 'pagesize' : pagesize
+ }}, context_instance=RequestContext(request))
+
+ else:
+ raise Http404
+
+def tag(request, tag):#stub generates listing of questions tagged with a single tag
+ return questions(request, tagname=tag)
+
+def tags(request):#view showing a listing of available tags - plain list
+ stag = ""
+ is_paginated = True
+ sortby = request.GET.get('sort', 'used')
+ try:
+ page = int(request.GET.get('page', '1'))
+ except ValueError:
+ page = 1
+
+ if request.method == "GET":
+ stag = request.GET.get("q", "").strip()
+ if stag != '':
+ objects_list = Paginator(Tag.objects.filter(deleted=False).exclude(used_count=0).extra(where=['name like %s'], params=['%' + stag + '%']), DEFAULT_PAGE_SIZE)
+ else:
+ if sortby == "name":
+ objects_list = Paginator(Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("name"), DEFAULT_PAGE_SIZE)
+ else:
+ objects_list = Paginator(Tag.objects.all().filter(deleted=False).exclude(used_count=0).order_by("-used_count"), DEFAULT_PAGE_SIZE)
+
+ try:
+ tags = objects_list.page(page)
+ except (EmptyPage, InvalidPage):
+ tags = objects_list.page(objects_list.num_pages)
+
+ return render_to_response('tags.html', {
+ "tags" : tags,
+ "stag" : stag,
+ "tab_id" : sortby,
+ "keywords" : stag,
+ "context" : {
+ 'is_paginated' : is_paginated,
+ 'pages': objects_list.num_pages,
+ 'page': page,
+ 'has_previous': tags.has_previous(),
+ 'has_next': tags.has_next(),
+ 'previous': tags.previous_page_number(),
+ 'next': tags.next_page_number(),
+ 'base_url' : reverse('tags') + '?sort=%s&' % sortby
+ }
+ }, context_instance=RequestContext(request))
+
+def question(request, id):#refactor - long subroutine. display question body, answers and comments
+ """view that displays body of the question and
+ all answers to it
+ """
+ try:
+ page = int(request.GET.get('page', '1'))
+ except ValueError:
+ page = 1
+
+ view_id = request.GET.get('sort', None)
+ view_dic = {"latest":"-added_at", "oldest":"added_at", "votes":"-score" }
+ try:
+ orderby = view_dic[view_id]
+ except KeyError:
+ qsm = request.session.get('questions_sort_method',None)
+ if qsm in ('mostvoted','latest'):
+ logging.debug('loaded from session ' + qsm)
+ if qsm == 'mostvoted':
+ view_id = 'votes'
+ orderby = '-score'
+ else:
+ view_id = 'latest'
+ orderby = '-added_at'
+ else:
+ view_id = "votes"
+ orderby = "-score"
+
+ logging.debug('view_id=' + str(view_id))
+
+ question = get_object_or_404(Question, id=id)
+ try:
+ pattern = r'/%s%s%d/([\w-]+)' % (settings.FORUM_SCRIPT_ALIAS,_('question/'), question.id)
+ path_re = re.compile(pattern)
+ logging.debug(pattern)
+ logging.debug(request.path)
+ m = path_re.match(request.path)
+ if m:
+ slug = m.group(1)
+ logging.debug('have slug %s' % slug)
+ assert(slug == slugify(question.title))
+ else:
+ logging.debug('no match!')
+ except:
+ return HttpResponseRedirect(question.get_absolute_url())
+
+ if question.deleted and not auth.can_view_deleted_post(request.user, question):
+ raise Http404
+ answer_form = AnswerForm(question,request.user)
+ answers = Answer.objects.get_answers_from_question(question, request.user)
+ answers = answers.select_related(depth=1)
+
+ favorited = question.has_favorite_by_user(request.user)
+ if request.user.is_authenticated():
+ question_vote = question.votes.select_related().filter(user=request.user)
+ else:
+ question_vote = None #is this correct?
+ if question_vote is not None and question_vote.count() > 0:
+ question_vote = question_vote[0]
+
+ user_answer_votes = {}
+ for answer in answers:
+ vote = answer.get_user_vote(request.user)
+ if vote is not None and not user_answer_votes.has_key(answer.id):
+ vote_value = -1
+ if vote.is_upvote():
+ vote_value = 1
+ user_answer_votes[answer.id] = vote_value
+
+ if answers is not None:
+ answers = answers.order_by("-accepted", orderby)
+
+ filtered_answers = []
+ for answer in answers:
+ if answer.deleted == True:
+ if answer.author_id == request.user.id:
+ filtered_answers.append(answer)
+ else:
+ filtered_answers.append(answer)
+
+ objects_list = Paginator(filtered_answers, ANSWERS_PAGE_SIZE)
+ page_objects = objects_list.page(page)
+
+ #todo: merge view counts per user and per session
+ #1) view count per session
+ update_view_count = False
+ if 'question_view_times' not in request.session:
+ request.session['question_view_times'] = {}
+
+ last_seen = request.session['question_view_times'].get(question.id,None)
+ updated_when, updated_who = question.get_last_update_info()
+
+ if updated_who != request.user:
+ if last_seen:
+ if last_seen < updated_when:
+ update_view_count = True
+ else:
+ update_view_count = True
+
+ request.session['question_view_times'][question.id] = datetime.datetime.now()
+
+ if update_view_count:
+ question.view_count += 1
+ question.save()
+
+ #2) question view count per user
+ if request.user.is_authenticated():
+ try:
+ question_view = QuestionView.objects.get(who=request.user, question=question)
+ except QuestionView.DoesNotExist:
+ question_view = QuestionView(who=request.user, question=question)
+ question_view.when = datetime.datetime.now()
+ question_view.save()
+
+ return render_to_response('question.html', {
+ "question" : question,
+ "question_vote" : question_vote,
+ "question_comment_count":question.comments.count(),
+ "answer" : answer_form,
+ "answers" : page_objects.object_list,
+ "user_answer_votes": user_answer_votes,
+ "tags" : question.tags.all(),
+ "tab_id" : view_id,
+ "favorited" : favorited,
+ "similar_questions" : Question.objects.get_similar_questions(question),
+ "context" : {
+ 'is_paginated' : True,
+ 'pages': objects_list.num_pages,
+ 'page': page,
+ 'has_previous': page_objects.has_previous(),
+ 'has_next': page_objects.has_next(),
+ 'previous': page_objects.previous_page_number(),
+ 'next': page_objects.next_page_number(),
+ 'base_url' : request.path + '?sort=%s&' % view_id,
+ 'extend_url' : "#sort-top"
+ }
+ }, context_instance=RequestContext(request))
+
+QUESTION_REVISION_TEMPLATE = ('<h1>%(title)s</h1>\n'
+ '<div class="text">%(html)s</div>\n'
+ '<div class="tags">%(tags)s</div>')
+def question_revisions(request, id):
+ post = get_object_or_404(Question, id=id)
+ revisions = list(post.revisions.all())
+ revisions.reverse()
+ for i, revision in enumerate(revisions):
+ revision.html = QUESTION_REVISION_TEMPLATE % {
+ 'title': revision.title,
+ 'html': sanitize_html(markdowner.convert(revision.text)),
+ 'tags': ' '.join(['<a class="post-tag">%s</a>' % tag
+ for tag in revision.tagnames.split(' ')]),
+ }
+ if i > 0:
+ revisions[i].diff = htmldiff(revisions[i-1].html, revision.html)
+ else:
+ revisions[i].diff = QUESTION_REVISION_TEMPLATE % {
+ 'title': revisions[0].title,
+ 'html': sanitize_html(markdowner.convert(revisions[0].text)),
+ 'tags': ' '.join(['<a class="post-tag">%s</a>' % tag
+ for tag in revisions[0].tagnames.split(' ')]),
+ }
+ revisions[i].summary = _('initial version')
+ return render_to_response('revisions_question.html', {
+ 'post': post,
+ 'revisions': revisions,
+ }, context_instance=RequestContext(request))
+
+ANSWER_REVISION_TEMPLATE = ('<div class="text">%(html)s</div>')
+def answer_revisions(request, id):
+ post = get_object_or_404(Answer, id=id)
+ revisions = list(post.revisions.all())
+ revisions.reverse()
+ for i, revision in enumerate(revisions):
+ revision.html = ANSWER_REVISION_TEMPLATE % {
+ 'html': sanitize_html(markdowner.convert(revision.text))
+ }
+ if i > 0:
+ revisions[i].diff = htmldiff(revisions[i-1].html, revision.html)
+ else:
+ revisions[i].diff = revisions[i].text
+ revisions[i].summary = _('initial version')
+ return render_to_response('revisions_answer.html', {
+ 'post': post,
+ 'revisions': revisions,
+ }, context_instance=RequestContext(request))
+#system to collect user actions and change content and store in the database
+def create_new_answer( question=None, author=None, #service subroutine - refactor
+ added_at=None, wiki=False,\
+ text='', email_notify=False):
+ """refactor
+ non-view subroutine
+ initializes the answer and revision
+ and updates stuff in the corresponding question
+ probably there is more Django-ish way to do it
+ """
+
+ html = sanitize_html(markdowner.convert(text))
+
+ #create answer
+ answer = Answer(
+ question = question,
+ author = author,
+ added_at = added_at,
+ wiki = wiki,
+ html = html
+ )
+ if answer.wiki:
+ answer.last_edited_by = answer.author
+ answer.last_edited_at = added_at
+ answer.wikified_at = added_at
+
+ answer.save()
+
+ #update question data
+ question.last_activity_at = added_at
+ question.last_activity_by = author
+ question.save()
+ Question.objects.update_answer_count(question)
+
+ #update revision
+ AnswerRevision.objects.create(
+ answer = answer,
+ revision = 1,
+ author = author,
+ revised_at = added_at,
+ summary = CONST['default_version'],
+ text = text
+ )
+
+ #set notification/delete
+ if email_notify:
+ if author not in question.followed_by.all():
+ question.followed_by.add(author)
+ else:
+ #not sure if this is necessary. ajax should take care of this...
+ try:
+ question.followed_by.remove(author)
+ except:
+ pass
+
+def create_new_question(title=None,author=None,added_at=None, #service subroutine - refactor
+ wiki=False,tagnames=None,summary=None,
+ text=None):
+ """refactor
+ this is not a view saves new question and revision
+ and maybe should become one of the methods on Question object?
+ """
+ html = sanitize_html(markdowner.convert(text))
+ question = Question(
+ title = title,
+ author = author,
+ added_at = added_at,
+ last_activity_at = added_at,
+ last_activity_by = author,
+ wiki = wiki,
+ tagnames = tagnames,
+ html = html,
+ summary = summary
+ )
+ if question.wiki:
+ question.last_edited_by = question.author
+ question.last_edited_at = added_at
+ question.wikified_at = added_at
+
+ question.save()
+
+ # create the first revision
+ QuestionRevision.objects.create(
+ question = question,
+ revision = 1,
+ title = question.title,
+ author = author,
+ revised_at = added_at,
+ tagnames = question.tagnames,
+ summary = CONST['default_version'],
+ text = text
+ )
+ return question
+
+def upload(request):#ajax upload file to a question or answer
+ class FileTypeNotAllow(Exception):
+ pass
+ class FileSizeNotAllow(Exception):
+ pass
+ class UploadPermissionNotAuthorized(Exception):
+ pass
+
+ #<result><msg><![CDATA[%s]]></msg><error><![CDATA[%s]]></error><file_url>%s</file_url></result>
+ xml_template = "<result><msg><![CDATA[%s]]></msg><error><![CDATA[%s]]></error><file_url>%s</file_url></result>"
+
+ try:
+ f = request.FILES['file-upload']
+ # check upload permission
+ if not auth.can_upload_files(request.user):
+ raise UploadPermissionNotAuthorized
+
+ # check file type
+ file_name_suffix = os.path.splitext(f.name)[1].lower()
+ if not file_name_suffix in settings.ALLOW_FILE_TYPES:
+ raise FileTypeNotAllow
+
+ # generate new file name
+ new_file_name = str(time.time()).replace('.', str(random.randint(0,100000))) + file_name_suffix
+ # use default storage to store file
+ default_storage.save(new_file_name, f)
+ # check file size
+ # byte
+ size = default_storage.size(new_file_name)
+ if size > settings.ALLOW_MAX_FILE_SIZE:
+ default_storage.delete(new_file_name)
+ raise FileSizeNotAllow
+
+ result = xml_template % ('Good', '', default_storage.url(new_file_name))
+ except UploadPermissionNotAuthorized:
+ result = xml_template % ('', _('uploading images is limited to users with >60 reputation points'), '')
+ except FileTypeNotAllow:
+ result = xml_template % ('', _("allowed file types are 'jpg', 'jpeg', 'gif', 'bmp', 'png', 'tiff'"), '')
+ except FileSizeNotAllow:
+ result = xml_template % ('', _("maximum upload file size is %sK") % settings.ALLOW_MAX_FILE_SIZE / 1024, '')
+ except Exception:
+ result = xml_template % ('', _('Error uploading file. Please contact the site administrator. Thank you. %s' % Exception), '')
+
+ return HttpResponse(result, mimetype="application/xml")
+
+#@login_required #actually you can post anonymously, but then must register
+def ask(request):#view used to ask a new question
+ """a view to ask a new question
+ gives space for q title, body, tags and checkbox for to post as wiki
+
+ user can start posting a question anonymously but then
+ must login/register in order for the question go be shown
+ """
+ if request.method == "POST":
+ form = AskForm(request.POST)
+ if form.is_valid():
+
+ added_at = datetime.datetime.now()
+ title = strip_tags(form.cleaned_data['title'].strip())
+ wiki = form.cleaned_data['wiki']
+ tagnames = form.cleaned_data['tags'].strip()
+ text = form.cleaned_data['text']
+ html = sanitize_html(markdowner.convert(text))
+ summary = strip_tags(html)[:120]
+
+ if request.user.is_authenticated():
+ author = request.user
+
+ question = create_new_question(
+ title = title,
+ author = author,
+ added_at = added_at,
+ wiki = wiki,
+ tagnames = tagnames,
+ summary = summary,
+ text = text
+ )
+
+ return HttpResponseRedirect(question.get_absolute_url())
+ else:
+ request.session.flush()
+ session_key = request.session.session_key
+ question = AnonymousQuestion(
+ session_key = session_key,
+ title = title,
+ tagnames = tagnames,
+ wiki = wiki,
+ text = text,
+ summary = summary,
+ added_at = added_at,
+ ip_addr = request.META['REMOTE_ADDR'],
+ )
+ question.save()
+ return HttpResponseRedirect(reverse('user_signin_new_question'))
+ else:
+ form = AskForm()
+
+ tags = _get_tags_cache_json()
+ return render_to_response('ask.html', {
+ 'form' : form,
+ 'tags' : tags,
+ 'email_validation_faq_url':reverse('faq') + '#validate',
+ }, context_instance=RequestContext(request))
+
+@login_required
+def close(request, id):#close question
+ """view to initiate and process
+ question close
+ """
+ question = get_object_or_404(Question, id=id)
+ if not auth.can_close_question(request.user, question):
+ return HttpResponse('Permission denied.')
+ if request.method == 'POST':
+ form = CloseForm(request.POST)
+ if form.is_valid():
+ reason = form.cleaned_data['reason']
+ question.closed = True
+ question.closed_by = request.user
+ question.closed_at = datetime.datetime.now()
+ question.close_reason = reason
+ question.save()
+ return HttpResponseRedirect(question.get_absolute_url())
+ else:
+ form = CloseForm()
+ return render_to_response('close.html', {
+ 'form' : form,
+ 'question' : question,
+ }, context_instance=RequestContext(request))
+
+@login_required
+def reopen(request, id):#re-open question
+ """view to initiate and process
+ question close
+ """
+ question = get_object_or_404(Question, id=id)
+ # open question
+ if not auth.can_reopen_question(request.user, question):
+ return HttpResponse('Permission denied.')
+ if request.method == 'POST' :
+ Question.objects.filter(id=question.id).update(closed=False,
+ closed_by=None, closed_at=None, close_reason=None)
+ return HttpResponseRedirect(question.get_absolute_url())
+ else:
+ return render_to_response('reopen.html', {
+ 'question' : question,
+ }, context_instance=RequestContext(request))
+
+@login_required
+def edit_question(request, id):#edit or retag a question
+ """view to edit question
+ """
+ question = get_object_or_404(Question, id=id)
+ if question.deleted and not auth.can_view_deleted_post(request.user, question):
+ raise Http404
+ if auth.can_edit_post(request.user, question):
+ return _edit_question(request, question)
+ elif auth.can_retag_questions(request.user):
+ return _retag_question(request, question)
+ else:
+ raise Http404
+
+def _retag_question(request, question):#non-url subview of edit question - just retag
+ """retag question sub-view used by
+ view "edit_question"
+ """
+ if request.method == 'POST':
+ form = RetagQuestionForm(question, request.POST)
+ if form.is_valid():
+ if form.has_changed():
+ latest_revision = question.get_latest_revision()
+ retagged_at = datetime.datetime.now()
+ # Update the Question itself
+ Question.objects.filter(id=question.id).update(
+ tagnames = form.cleaned_data['tags'],
+ last_edited_at = retagged_at,
+ last_edited_by = request.user,
+ last_activity_at = retagged_at,
+ last_activity_by = request.user
+ )
+ # Update the Question's tag associations
+ tags_updated = Question.objects.update_tags(question,
+ form.cleaned_data['tags'], request.user)
+ # Create a new revision
+ QuestionRevision.objects.create(
+ question = question,
+ title = latest_revision.title,
+ author = request.user,
+ revised_at = retagged_at,
+ tagnames = form.cleaned_data['tags'],
+ summary = CONST['retagged'],
+ text = latest_revision.text
+ )
+ # send tags updated singal
+ tags_updated.send(sender=question.__class__, question=question)
+
+ return HttpResponseRedirect(question.get_absolute_url())
+ else:
+ form = RetagQuestionForm(question)
+ return render_to_response('question_retag.html', {
+ 'question': question,
+ 'form' : form,
+ 'tags' : _get_tags_cache_json(),
+ }, context_instance=RequestContext(request))
+
+def _edit_question(request, question):#non-url subview of edit_question - just edit the body/title
+ latest_revision = question.get_latest_revision()
+ revision_form = None
+ if request.method == 'POST':
+ if 'select_revision' in request.POST:
+ # user has changed revistion number
+ revision_form = RevisionForm(question, latest_revision, request.POST)
+ if revision_form.is_valid():
+ # Replace with those from the selected revision
+ form = EditQuestionForm(question,
+ QuestionRevision.objects.get(question=question,
+ revision=revision_form.cleaned_data['revision']))
+ else:
+ form = EditQuestionForm(question, latest_revision, request.POST)
+ else:
+ # Always check modifications against the latest revision
+ form = EditQuestionForm(question, latest_revision, request.POST)
+ if form.is_valid():
+ html = sanitize_html(markdowner.convert(form.cleaned_data['text']))
+ if form.has_changed():
+ edited_at = datetime.datetime.now()
+ tags_changed = (latest_revision.tagnames !=
+ form.cleaned_data['tags'])
+ tags_updated = False
+ # Update the Question itself
+ updated_fields = {
+ 'title': form.cleaned_data['title'],
+ 'last_edited_at': edited_at,
+ 'last_edited_by': request.user,
+ 'last_activity_at': edited_at,
+ 'last_activity_by': request.user,
+ 'tagnames': form.cleaned_data['tags'],
+ 'summary': strip_tags(html)[:120],
+ 'html': html,
+ }
+
+ # only save when it's checked
+ # because wiki doesn't allow to be edited if last version has been enabled already
+ # and we make sure this in forms.
+ if ('wiki' in form.cleaned_data and
+ form.cleaned_data['wiki']):
+ updated_fields['wiki'] = True
+ updated_fields['wikified_at'] = edited_at
+
+ Question.objects.filter(
+ id=question.id).update(**updated_fields)
+ # Update the Question's tag associations
+ if tags_changed:
+ tags_updated = Question.objects.update_tags(
+ question, form.cleaned_data['tags'], request.user)
+ # Create a new revision
+ revision = QuestionRevision(
+ question = question,
+ title = form.cleaned_data['title'],
+ author = request.user,
+ revised_at = edited_at,
+ tagnames = form.cleaned_data['tags'],
+ text = form.cleaned_data['text'],
+ )
+ if form.cleaned_data['summary']:
+ revision.summary = form.cleaned_data['summary']
+ else:
+ revision.summary = 'No.%s Revision' % latest_revision.revision
+ revision.save()
+
+ return HttpResponseRedirect(question.get_absolute_url())
+ else:
+
+ revision_form = RevisionForm(question, latest_revision)
+ form = EditQuestionForm(question, latest_revision)
+ return render_to_response('question_edit.html', {
+ 'question': question,
+ 'revision_form': revision_form,
+ 'form' : form,
+ 'tags' : _get_tags_cache_json()
+ }, context_instance=RequestContext(request))
+
+@login_required
+def edit_answer(request, id):
+ answer = get_object_or_404(Answer, id=id)
+ if answer.deleted and not auth.can_view_deleted_post(request.user, answer):
+ raise Http404
+ elif not auth.can_edit_post(request.user, answer):
+ raise Http404
+ else:
+ latest_revision = answer.get_latest_revision()
+ if request.method == "POST":
+ if 'select_revision' in request.POST:
+ # user has changed revistion number
+ revision_form = RevisionForm(answer, latest_revision, request.POST)
+ if revision_form.is_valid():
+ # Replace with those from the selected revision
+ form = EditAnswerForm(answer,
+ AnswerRevision.objects.get(answer=answer,
+ revision=revision_form.cleaned_data['revision']))
+ else:
+ form = EditAnswerForm(answer, latest_revision, request.POST)
+ else:
+ form = EditAnswerForm(answer, latest_revision, request.POST)
+ if form.is_valid():
+ html = sanitize_html(markdowner.convert(form.cleaned_data['text']))
+ if form.has_changed():
+ edited_at = datetime.datetime.now()
+ updated_fields = {
+ 'last_edited_at': edited_at,
+ 'last_edited_by': request.user,
+ 'html': html,
+ }
+ Answer.objects.filter(id=answer.id).update(**updated_fields)
+
+ revision = AnswerRevision(
+ answer=answer,
+ author=request.user,
+ revised_at=edited_at,
+ text=form.cleaned_data['text']
+ )
+
+ if form.cleaned_data['summary']:
+ revision.summary = form.cleaned_data['summary']
+ else:
+ revision.summary = 'No.%s Revision' % latest_revision.revision
+ revision.save()
+
+ answer.question.last_activity_at = edited_at
+ answer.question.last_activity_by = request.user
+ answer.question.save()
+
+ return HttpResponseRedirect(answer.get_absolute_url())
+ else:
+ revision_form = RevisionForm(answer, latest_revision)
+ form = EditAnswerForm(answer, latest_revision)
+ return render_to_response('answer_edit.html', {
+ 'answer': answer,
+ 'revision_form': revision_form,
+ 'form': form,
+ }, context_instance=RequestContext(request))
+
+
+def answer(request, id):#process a new answer
+ question = get_object_or_404(Question, id=id)
+ if request.method == "POST":
+ form = AnswerForm(question, request.user, request.POST)
+ if form.is_valid():
+ wiki = form.cleaned_data['wiki']
+ text = form.cleaned_data['text']
+ update_time = datetime.datetime.now()
+
+ if request.user.is_authenticated():
+ create_new_answer(
+ question=question,
+ author=request.user,
+ added_at=update_time,
+ wiki=wiki,
+ text=text,
+ email_notify=form.cleaned_data['email_notify']
+ )
+ else:
+ request.session.flush()
+ html = sanitize_html(markdowner.convert(text))
+ summary = strip_tags(html)[:120]
+ anon = AnonymousAnswer(
+ question=question,
+ wiki=wiki,
+ text=text,
+ summary=summary,
+ session_key=request.session.session_key,
+ ip_addr=request.META['REMOTE_ADDR'],
+ )
+ anon.save()
+ return HttpResponseRedirect(reverse('user_signin_new_answer'))
+
+ return HttpResponseRedirect(question.get_absolute_url())
+
+def question_comments(request, id):#ajax handler for loading comments to question
+ question = get_object_or_404(Question, id=id)
+ user = request.user
+ return __comments(request, question, 'question')
+
+def answer_comments(request, id):#ajax handler for loading comments on answer
+ answer = get_object_or_404(Answer, id=id)
+ user = request.user
+ return __comments(request, answer, 'answer')
+
+def __comments(request, obj, type):#non-view generic ajax handler to load comments to an object
+ # only support get post comments by ajax now
+ user = request.user
+ if request.is_ajax():
+ if request.method == "GET":
+ response = __generate_comments_json(obj, type, user)
+ elif request.method == "POST":
+ if auth.can_add_comments(user,obj):
+ comment_data = request.POST.get('comment')
+ comment = Comment(content_object=obj, comment=comment_data, user=request.user)
+ comment.save()
+ obj.comment_count = obj.comment_count + 1
+ obj.save()
+ response = __generate_comments_json(obj, type, user)
+ else:
+ response = HttpResponseForbidden(mimetype="application/json")
+ return response
+
+def __generate_comments_json(obj, type, user):#non-view generates json data for the post comments
+ comments = obj.comments.all().order_by('id')
+ # {"Id":6,"PostId":38589,"CreationDate":"an hour ago","Text":"hello there!","UserDisplayName":"Jarrod Dixon","UserUrl":"/users/3/jarrod-dixon","DeleteUrl":null}
+ json_comments = []
+ from forum.templatetags.extra_tags import diff_date
+ for comment in comments:
+ comment_user = comment.user
+ delete_url = ""
+ if user != None and auth.can_delete_comment(user, comment):
+ #/posts/392845/comments/219852/delete
+ #todo translate this url
+ delete_url = reverse(index) + type + "s/%s/comments/%s/delete/" % (obj.id, comment.id)
+ json_comments.append({"id" : comment.id,
+ "object_id" : obj.id,
+ "comment_age" : diff_date(comment.added_at),
+ "text" : comment.comment,
+ "user_display_name" : comment_user.username,
+ "user_url" : comment_user.get_profile_url(),
+ "delete_url" : delete_url
+ })
+
+ data = simplejson.dumps(json_comments)
+ return HttpResponse(data, mimetype="application/json")
+
+def delete_comment(request, object_id='', comment_id='', commented_object_type=None):#ajax handler to delete comment
+ response = None
+ commented_object = None
+ if commented_object_type == 'question':
+ commented_object = Question
+ elif commented_object_type == 'answer':
+ commented_object = Answer
+
+ if request.is_ajax():
+ comment = get_object_or_404(Comment, id=comment_id)
+ if auth.can_delete_comment(request.user, comment):
+ obj = get_object_or_404(commented_object, id=object_id)
+ obj.comments.remove(comment)
+ obj.comment_count = obj.comment_count - 1
+ obj.save()
+ user = request.user
+ return __generate_comments_json(obj, commented_object_type, user)
+ raise PermissionDenied()
+
+
+def vote(request, id):#refactor - pretty incomprehensible view used by various ajax calls
+#issues: this subroutine is too long, contains many magic numbers and other issues
+#it's called "vote" but many actions processed here have nothing to do with voting
+ """
+ vote_type:
+ acceptAnswer : 0,
+ questionUpVote : 1,
+ questionDownVote : 2,
+ favorite : 4,
+ answerUpVote: 5,
+ answerDownVote:6,
+ offensiveQuestion : 7,
+ offensiveAnswer:8,
+ removeQuestion: 9,
+ removeAnswer:10
+ questionSubscribeUpdates:11
+
+ accept answer code:
+ response_data['allowed'] = -1, Accept his own answer 0, no allowed - Anonymous 1, Allowed - by default
+ response_data['success'] = 0, failed 1, Success - by default
+ response_data['status'] = 0, By default 1, Answer has been accepted already(Cancel)
+
+ vote code:
+ allowed = -3, Don't have enough votes left
+ -2, Don't have enough reputation score
+ -1, Vote his own post
+ 0, no allowed - Anonymous
+ 1, Allowed - by default
+ status = 0, By default
+ 1, Cancel
+ 2, Vote is too old to be canceled
+
+ offensive code:
+ allowed = -3, Don't have enough flags left
+ -2, Don't have enough reputation score to do this
+ 0, not allowed
+ 1, allowed
+ status = 0, by default
+ 1, can't do it again
+ """
+ response_data = {
+ "allowed": 1,
+ "success": 1,
+ "status" : 0,
+ "count" : 0,
+ "message" : ''
+ }
+
+ def __can_vote(vote_score, user):#refactor - belongs to auth.py
+ if vote_score == 1:#refactor magic number
+ return auth.can_vote_up(request.user)
+ else:
+ return auth.can_vote_down(request.user)
+
+ try:
+ if not request.user.is_authenticated():
+ response_data['allowed'] = 0
+ response_data['success'] = 0
+
+ elif request.is_ajax() and request.method == 'POST':
+ question = get_object_or_404(Question, id=id)
+ vote_type = request.POST.get('type')
+
+ #accept answer
+ if vote_type == '0':
+ answer_id = request.POST.get('postId')
+ answer = get_object_or_404(Answer, id=answer_id)
+ # make sure question author is current user
+ if question.author == request.user:
+ # answer user who is also question author is not allow to accept answer
+ if answer.author == question.author:
+ response_data['success'] = 0
+ response_data['allowed'] = -1
+ # check if answer has been accepted already
+ elif answer.accepted:
+ onAnswerAcceptCanceled(answer, request.user)
+ response_data['status'] = 1
+ else:
+ # set other answers in this question not accepted first
+ for answer_of_question in Answer.objects.get_answers_from_question(question, request.user):
+ if answer_of_question != answer and answer_of_question.accepted:
+ onAnswerAcceptCanceled(answer_of_question, request.user)
+
+ #make sure retrieve data again after above author changes, they may have related data
+ answer = get_object_or_404(Answer, id=answer_id)
+ onAnswerAccept(answer, request.user)
+ else:
+ response_data['allowed'] = 0
+ response_data['success'] = 0
+ # favorite
+ elif vote_type == '4':
+ has_favorited = False
+ fav_questions = FavoriteQuestion.objects.filter(question=question)
+ # if the same question has been favorited before, then delete it
+ if fav_questions is not None:
+ for item in fav_questions:
+ if item.user == request.user:
+ item.delete()
+ response_data['status'] = 1
+ response_data['count'] = len(fav_questions) - 1
+ if response_data['count'] < 0:
+ response_data['count'] = 0
+ has_favorited = True
+ # if above deletion has not been executed, just insert a new favorite question
+ if not has_favorited:
+ new_item = FavoriteQuestion(question=question, user=request.user)
+ new_item.save()
+ response_data['count'] = FavoriteQuestion.objects.filter(question=question).count()
+ Question.objects.update_favorite_count(question)
+
+ elif vote_type in ['1', '2', '5', '6']:
+ post_id = id
+ post = question
+ vote_score = 1
+ if vote_type in ['5', '6']:
+ answer_id = request.POST.get('postId')
+ answer = get_object_or_404(Answer, id=answer_id)
+ post_id = answer_id
+ post = answer
+ if vote_type in ['2', '6']:
+ vote_score = -1
+
+ if post.author == request.user:
+ response_data['allowed'] = -1
+ elif not __can_vote(vote_score, request.user):
+ response_data['allowed'] = -2
+ elif post.votes.filter(user=request.user).count() > 0:
+ vote = post.votes.filter(user=request.user)[0]
+ # unvote should be less than certain time
+ if (datetime.datetime.now().day - vote.voted_at.day) >= VOTE_RULES['scope_deny_unvote_days']:
+ response_data['status'] = 2
+ else:
+ voted = vote.vote
+ if voted > 0:
+ # cancel upvote
+ onUpVotedCanceled(vote, post, request.user)
+
+ else:
+ # cancel downvote
+ onDownVotedCanceled(vote, post, request.user)
+
+ response_data['status'] = 1
+ response_data['count'] = post.score
+ elif Vote.objects.get_votes_count_today_from_user(request.user) >= VOTE_RULES['scope_votes_per_user_per_day']:
+ response_data['allowed'] = -3
+ else:
+ vote = Vote(user=request.user, content_object=post, vote=vote_score, voted_at=datetime.datetime.now())
+ if vote_score > 0:
+ # upvote
+ onUpVoted(vote, post, request.user)
+ else:
+ # downvote
+ onDownVoted(vote, post, request.user)
+
+ votes_left = VOTE_RULES['scope_votes_per_user_per_day'] - Vote.objects.get_votes_count_today_from_user(request.user)
+ if votes_left <= VOTE_RULES['scope_warn_votes_left']:
+ response_data['message'] = u'%s votes left' % votes_left
+ response_data['count'] = post.score
+ elif vote_type in ['7', '8']:
+ post = question
+ post_id = id
+ if vote_type == '8':
+ post_id = request.POST.get('postId')
+ post = get_object_or_404(Answer, id=post_id)
+
+ if FlaggedItem.objects.get_flagged_items_count_today(request.user) >= VOTE_RULES['scope_flags_per_user_per_day']:
+ response_data['allowed'] = -3
+ elif not auth.can_flag_offensive(request.user):
+ response_data['allowed'] = -2
+ elif post.flagged_items.filter(user=request.user).count() > 0:
+ response_data['status'] = 1
+ else:
+ item = FlaggedItem(user=request.user, content_object=post, flagged_at=datetime.datetime.now())
+ onFlaggedItem(item, post, request.user)
+ response_data['count'] = post.offensive_flag_count
+ # send signal when question or answer be marked offensive
+ mark_offensive.send(sender=post.__class__, instance=post, mark_by=request.user)
+ elif vote_type in ['9', '10']:
+ post = question
+ post_id = id
+ if vote_type == '10':
+ post_id = request.POST.get('postId')
+ post = get_object_or_404(Answer, id=post_id)
+
+ if not auth.can_delete_post(request.user, post):
+ response_data['allowed'] = -2
+ elif post.deleted == True:
+ logging.debug('debug restoring post in view')
+ onDeleteCanceled(post, request.user)
+ response_data['status'] = 1
+ else:
+ onDeleted(post, request.user)
+ delete_post_or_answer.send(sender=post.__class__, instance=post, delete_by=request.user)
+ elif vote_type == '11':#subscribe q updates
+ user = request.user
+ if user.is_authenticated():
+ if user not in question.followed_by.all():
+ question.followed_by.add(user)
+ if settings.EMAIL_VALIDATION == 'on' and user.email_isvalid == False:
+ response_data['message'] = \
+ _('subscription saved, %(email)s needs validation, see %(details_url)s') \
+ % {'email':user.email,'details_url':reverse('faq') + '#validate'}
+ feed_setting = EmailFeedSetting.objects.get(subscriber=user,feed_type='q_sel')
+ if feed_setting.frequency == 'n':
+ feed_setting.frequency = 'd'
+ feed_setting.save()
+ if 'message' in response_data:
+ response_data['message'] += '<br/>'
+ response_data['message'] = _('email update frequency has been set to daily')
+ #response_data['status'] = 1
+ #responst_data['allowed'] = 1
+ else:
+ pass
+ #response_data['status'] = 0
+ #response_data['allowed'] = 0
+ elif vote_type == '12':#unsubscribe q updates
+ user = request.user
+ if user.is_authenticated():
+ if user in question.followed_by.all():
+ question.followed_by.remove(user)
+ else:
+ response_data['success'] = 0
+ response_data['message'] = u'Request mode is not supported. Please try again.'
+
+ data = simplejson.dumps(response_data)
+
+ except Exception, e:
+ response_data['message'] = str(e)
+ data = simplejson.dumps(response_data)
+ return HttpResponse(data, mimetype="application/json")
+
+#internally grouped views - used by the tagging system
+@ajax_login_required
+def mark_tag(request, tag=None, **kwargs):#tagging system
+ action = kwargs['action']
+ ts = MarkedTag.objects.filter(user=request.user, tag__name=tag)
+ if action == 'remove':
+ logging.debug('deleting tag %s' % tag)
+ ts.delete()
+ else:
+ reason = kwargs['reason']
+ if len(ts) == 0:
+ try:
+ t = Tag.objects.get(name=tag)
+ mt = MarkedTag(user=request.user, reason=reason, tag=t)
+ mt.save()
+ except:
+ pass
+ else:
+ ts.update(reason=reason)
+ return HttpResponse(simplejson.dumps(''), mimetype="application/json")
+
+@ajax_login_required
+def ajax_toggle_ignored_questions(request):#ajax tagging and tag-filtering system
+ if request.user.hide_ignored_questions:
+ new_hide_setting = False
+ else:
+ new_hide_setting = True
+ request.user.hide_ignored_questions = new_hide_setting
+ request.user.save()
+
+@ajax_method
+def ajax_command(request):#refactor? view processing ajax commands - note "vote" and view others do it too
+ if 'command' not in request.POST:
+ return HttpResponseForbidden(mimetype="application/json")
+ if request.POST['command'] == 'toggle-ignored-questions':
+ return ajax_toggle_ignored_questions(request)
+
diff --git a/forum/views/meta.py b/forum/views/meta.py
new file mode 100644
index 00000000..b7a1183c
--- /dev/null
+++ b/forum/views/meta.py
@@ -0,0 +1,98 @@
+from django.shortcuts import render_to_response, get_object_or_404
+from django.core.urlresolvers import reverse
+from django.template import RequestContext
+from django.http import HttpResponseRedirect, HttpResponse
+from forum.forms import FeedbackForm
+from django.core.mail import mail_admins
+from django.utils.translation import ugettext as _
+from utils.forms import get_next_url
+from forum.models import Badge, Award
+
+def about(request):
+ return render_to_response('about.html', context_instance=RequestContext(request))
+
+def faq(request):
+ data = {
+ 'gravatar_faq_url': reverse('faq') + '#gravatar',
+ 'send_email_key_url': reverse('send_email_key'),
+ 'ask_question_url': reverse('ask'),
+ }
+ return render_to_response('faq.html', data, context_instance=RequestContext(request))
+
+def feedback(request):
+ data = {}
+ form = None
+ if request.method == "POST":
+ form = FeedbackForm(request.POST)
+ if form.is_valid():
+ if not request.user.is_authenticated:
+ data['email'] = form.cleaned_data.get('email',None)
+ data['message'] = form.cleaned_data['message']
+ data['name'] = form.cleaned_data.get('name',None)
+ message = render_to_response('feedback_email.txt',data,context_instance=RequestContext(request))
+ mail_admins(_('Q&A forum feedback'), message)
+ msg = _('Thanks for the feedback!')
+ request.user.message_set.create(message=msg)
+ return HttpResponseRedirect(get_next_url(request))
+ else:
+ form = FeedbackForm(initial={'next':get_next_url(request)})
+
+ data['form'] = form
+ return render_to_response('feedback.html', data, context_instance=RequestContext(request))
+feedback.CANCEL_MESSAGE=_('We look forward to hearing your feedback! Please, give it next time :)')
+
+def privacy(request):
+ return render_to_response('privacy.html', context_instance=RequestContext(request))
+
+def logout(request):#refactor/change behavior?
+#currently you click logout and you get
+#to this view which actually asks you again - do you really want to log out?
+#I guess rationale was to tell the user that s/he may be still logged in
+#through their external login sytem and we'd want to remind them about it
+#however it might be a little annoying
+#why not just show a message: you are logged out of osqa, but
+#if you really want to log out -> go to your openid provider
+ return render_to_response('logout.html', {
+ 'next' : get_next_url(request),
+ }, context_instance=RequestContext(request))
+
+def badges(request):#user status/reputation system
+ badges = Badge.objects.all().order_by('type')
+ my_badges = []
+ if request.user.is_authenticated():
+ my_badges = Award.objects.filter(user=request.user)
+ my_badges.query.group_by = ['badge_id']
+
+ return render_to_response('badges.html', {
+ 'badges' : badges,
+ 'mybadges' : my_badges,
+ 'feedback_faq_url' : reverse('feedback'),
+ }, context_instance=RequestContext(request))
+
+def badge(request, id):
+ badge = get_object_or_404(Badge, id=id)
+ awards = Award.objects.extra(
+ select={'id': 'auth_user.id',
+ 'name': 'auth_user.username',
+ 'rep':'auth_user.reputation',
+ 'gold': 'auth_user.gold',
+ 'silver': 'auth_user.silver',
+ 'bronze': 'auth_user.bronze'},
+ tables=['award', 'auth_user'],
+ where=['badge_id=%s AND user_id=auth_user.id'],
+ params=[id]
+ ).distinct('id')
+
+ return render_to_response('badge.html', {
+ 'awards' : awards,
+ 'badge' : badge,
+ }, context_instance=RequestContext(request))
+
+#osqa-user communication system
+def read_message(request):#marks message a read
+ if request.method == "POST":
+ if request.POST['formdata'] == 'required':
+ request.session['message_silent'] = 1
+ if request.user.is_authenticated():
+ request.user.delete_messages()
+ return HttpResponse('')
diff --git a/forum/views/users.py b/forum/views/users.py
new file mode 100644
index 00000000..2c7f5c34
--- /dev/null
+++ b/forum/views/users.py
@@ -0,0 +1,940 @@
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.models import User
+from django.core.paginator import Paginator, EmptyPage, InvalidPage
+from django.core.urlresolvers import reverse
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template import RequestContext
+from django.http import HttpResponse, HttpResponseForbidden
+from django.utils.translation import ugettext as _
+from forum.forms import *#incomplete list is EditUserForm, ModerateUserForm, TagFilterSelectionForm,
+from forum import auth
+
+question_type = ContentType.objects.get_for_model(Question)
+answer_type = ContentType.objects.get_for_model(Answer)
+comment_type = ContentType.objects.get_for_model(Comment)
+question_revision_type = ContentType.objects.get_for_model(QuestionRevision)
+answer_revision_type = ContentType.objects.get_for_model(AnswerRevision)
+repute_type = ContentType.objects.get_for_model(Repute)
+question_type_id = question_type.id
+answer_type_id = answer_type.id
+comment_type_id = comment_type.id
+question_revision_type_id = question_revision_type.id
+answer_revision_type_id = answer_revision_type.id
+repute_type_id = repute_type.id
+
+USERS_PAGE_SIZE = 35# refactor - move to some constants file
+
+def users(request):
+ is_paginated = True
+ sortby = request.GET.get('sort', 'reputation')
+ suser = request.REQUEST.get('q', "")
+ try:
+ page = int(request.GET.get('page', '1'))
+ except ValueError:
+ page = 1
+
+ if suser == "":
+ if sortby == "newest":
+ objects_list = Paginator(User.objects.all().order_by('-date_joined'), USERS_PAGE_SIZE)
+ elif sortby == "last":
+ objects_list = Paginator(User.objects.all().order_by('date_joined'), USERS_PAGE_SIZE)
+ elif sortby == "user":
+ objects_list = Paginator(User.objects.all().order_by('username'), USERS_PAGE_SIZE)
+ # default
+ else:
+ objects_list = Paginator(User.objects.all().order_by('-reputation'), USERS_PAGE_SIZE)
+ base_url = reverse('users') + '?sort=%s&' % sortby
+ else:
+ sortby = "reputation"
+ objects_list = Paginator(User.objects.extra(where=['username like %s'], params=['%' + suser + '%']).order_by('-reputation'), USERS_PAGE_SIZE)
+ base_url = reverse('users') + '?name=%s&sort=%s&' % (suser, sortby)
+
+ try:
+ users = objects_list.page(page)
+ except (EmptyPage, InvalidPage):
+ users = objects_list.page(objects_list.num_pages)
+
+ return render_to_response('users.html', {
+ "users" : users,
+ "suser" : suser,
+ "keywords" : suser,
+ "tab_id" : sortby,
+ "context" : {
+ 'is_paginated' : is_paginated,
+ 'pages': objects_list.num_pages,
+ 'page': page,
+ 'has_previous': users.has_previous(),
+ 'has_next': users.has_next(),
+ 'previous': users.previous_page_number(),
+ 'next': users.next_page_number(),
+ 'base_url' : base_url
+ }
+
+ }, context_instance=RequestContext(request))
+
+@login_required
+def moderate_user(request, id):
+ """ajax handler of user moderation
+ """
+ if not auth.can_moderate_users(request.user) or request.method != 'POST':
+ raise Http404
+ if not request.is_ajax():
+ return HttpResponseForbidden(mimetype="application/json")
+
+ user = get_object_or_404(User, id=id)
+ form = ModerateUserForm(request.POST, instance=user)
+
+ if form.is_valid():
+ form.save()
+ logging.debug('data saved')
+ response = HttpResponse(simplejson.dumps(''), mimetype="application/json")
+ else:
+ response = HttpResponseForbidden(mimetype="application/json")
+ return response
+
+@login_required
+def edit_user(request, id):
+ user = get_object_or_404(User, id=id)
+ if request.user != user:
+ raise Http404
+ if request.method == "POST":
+ form = EditUserForm(user, request.POST)
+ if form.is_valid():
+ new_email = sanitize_html(form.cleaned_data['email'])
+
+ from django_authopenid.views import set_new_email
+ set_new_email(user, new_email)
+
+ #user.username = sanitize_html(form.cleaned_data['username'])
+ user.real_name = sanitize_html(form.cleaned_data['realname'])
+ user.website = sanitize_html(form.cleaned_data['website'])
+ user.location = sanitize_html(form.cleaned_data['city'])
+ user.date_of_birth = sanitize_html(form.cleaned_data['birthday'])
+ if len(user.date_of_birth) == 0:
+ user.date_of_birth = '1900-01-01'
+ user.about = sanitize_html(form.cleaned_data['about'])
+
+ user.save()
+ # send user updated singal if full fields have been updated
+ if user.email and user.real_name and user.website and user.location and \
+ user.date_of_birth and user.about:
+ user_updated.send(sender=user.__class__, instance=user, updated_by=user)
+ return HttpResponseRedirect(user.get_profile_url())
+ else:
+ form = EditUserForm(user)
+ return render_to_response('user_edit.html', {
+ 'form' : form,
+ 'gravatar_faq_url' : reverse('faq') + '#gravatar',
+ }, context_instance=RequestContext(request))
+
+def user_stats(request, user_id, user_view):
+ user = get_object_or_404(User, id=user_id)
+ questions = Question.objects.extra(
+ select={
+ 'vote_count' : 'question.score',
+ 'favorited_myself' : 'SELECT count(*) FROM favorite_question f WHERE f.user_id = %s AND f.question_id = question.id',
+ 'la_user_id' : 'auth_user.id',
+ 'la_username' : 'auth_user.username',
+ 'la_user_gold' : 'auth_user.gold',
+ 'la_user_silver' : 'auth_user.silver',
+ 'la_user_bronze' : 'auth_user.bronze',
+ 'la_user_reputation' : 'auth_user.reputation'
+ },
+ select_params=[user_id],
+ tables=['question', 'auth_user'],
+ where=['question.deleted=False AND question.author_id=%s AND question.last_activity_by_id = auth_user.id'],
+ params=[user_id],
+ order_by=['-vote_count', '-last_activity_at']
+ ).values('vote_count',
+ 'favorited_myself',
+ 'id',
+ 'title',
+ 'author_id',
+ 'added_at',
+ 'answer_accepted',
+ 'answer_count',
+ 'comment_count',
+ 'view_count',
+ 'favourite_count',
+ 'summary',
+ 'tagnames',
+ 'vote_up_count',
+ 'vote_down_count',
+ 'last_activity_at',
+ 'la_user_id',
+ 'la_username',
+ 'la_user_gold',
+ 'la_user_silver',
+ 'la_user_bronze',
+ 'la_user_reputation')[:100]
+
+ answered_questions = Question.objects.extra(
+ select={
+ 'vote_up_count' : 'answer.vote_up_count',
+ 'vote_down_count' : 'answer.vote_down_count',
+ 'answer_id' : 'answer.id',
+ 'accepted' : 'answer.accepted',
+ 'vote_count' : 'answer.score',
+ 'comment_count' : 'answer.comment_count'
+ },
+ tables=['question', 'answer'],
+ where=['answer.deleted=False AND question.deleted=False AND answer.author_id=%s AND answer.question_id=question.id'],
+ params=[user_id],
+ order_by=['-vote_count', '-answer_id'],
+ select_params=[user_id]
+ ).distinct().values('comment_count',
+ 'id',
+ 'answer_id',
+ 'title',
+ 'author_id',
+ 'accepted',
+ 'vote_count',
+ 'answer_count',
+ 'vote_up_count',
+ 'vote_down_count')[:100]
+
+ up_votes = Vote.objects.get_up_vote_count_from_user(user)
+ down_votes = Vote.objects.get_down_vote_count_from_user(user)
+ votes_today = Vote.objects.get_votes_count_today_from_user(user)
+ votes_total = auth.VOTE_RULES['scope_votes_per_user_per_day']
+
+ question_id_set = set(map(lambda v: v['id'], list(questions))) \
+ | set(map(lambda v: v['id'], list(answered_questions)))
+
+ user_tags = Tag.objects.filter(questions__id__in = question_id_set)
+ try:
+ from django.db.models import Count
+ awards = Award.objects.extra(
+ select={'id': 'badge.id',
+ 'name':'badge.name',
+ 'description': 'badge.description',
+ 'type': 'badge.type'},
+ tables=['award', 'badge'],
+ order_by=['-awarded_at'],
+ where=['user_id=%s AND badge_id=badge.id'],
+ params=[user.id]
+ ).values('id', 'name', 'description', 'type')
+ total_awards = awards.count()
+ awards = awards.annotate(count = Count('badge__id'))
+ user_tags = user_tags.annotate(user_tag_usage_count=Count('name'))
+
+ except ImportError:
+ awards = Award.objects.extra(
+ select={'id': 'badge.id',
+ 'count': 'count(badge_id)',
+ 'name':'badge.name',
+ 'description': 'badge.description',
+ 'type': 'badge.type'},
+ tables=['award', 'badge'],
+ order_by=['-awarded_at'],
+ where=['user_id=%s AND badge_id=badge.id'],
+ params=[user.id]
+ ).values('id', 'count', 'name', 'description', 'type')
+ total_awards = awards.count()
+ awards.query.group_by = ['badge_id']
+
+ user_tags = user_tags.extra(
+ select={'user_tag_usage_count': 'COUNT(1)',},
+ order_by=['-user_tag_usage_count'],
+ )
+ user_tags.query.group_by = ['name']
+
+ if auth.can_moderate_users(request.user):
+ moderate_user_form = ModerateUserForm(instance=user)
+ else:
+ moderate_user_form = None
+
+ return render_to_response(user_view.template_file,{
+ 'moderate_user_form': moderate_user_form,
+ "tab_name" : user_view.id,
+ "tab_description" : user_view.tab_description,
+ "page_title" : user_view.page_title,
+ "view_user" : user,
+ "questions" : questions,
+ "answered_questions" : answered_questions,
+ "up_votes" : up_votes,
+ "down_votes" : down_votes,
+ "total_votes": up_votes + down_votes,
+ "votes_today_left": votes_total-votes_today,
+ "votes_total_per_day": votes_total,
+ "user_tags" : user_tags[:50],
+ "awards": awards,
+ "total_awards" : total_awards,
+ }, context_instance=RequestContext(request))
+
+def user_recent(request, user_id, user_view):
+ user = get_object_or_404(User, id=user_id)
+ def get_type_name(type_id):
+ for item in TYPE_ACTIVITY:
+ if type_id in item:
+ return item[1]
+
+ class Event:
+ def __init__(self, time, type, title, summary, answer_id, question_id):
+ self.time = time
+ self.type = get_type_name(type)
+ self.type_id = type
+ self.title = title
+ self.summary = summary
+ slug_title = slugify(title)
+ self.title_link = reverse('question', kwargs={'id':question_id}) + u'%s' % slug_title
+ if int(answer_id) > 0:
+ self.title_link += '#%s' % answer_id
+
+ class AwardEvent:
+ def __init__(self, time, type, id):
+ self.time = time
+ self.type = get_type_name(type)
+ self.type_id = type
+ self.badge = get_object_or_404(Badge, id=id)
+
+ activities = []
+ # ask questions
+ questions = Activity.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'active_at' : 'activity.active_at',
+ 'activity_type' : 'activity.activity_type'
+ },
+ tables=['activity', 'question'],
+ where=['activity.content_type_id = %s AND activity.object_id = ' +
+ 'question.id AND question.deleted=False AND activity.user_id = %s AND activity.activity_type = %s'],
+ params=[question_type_id, user_id, TYPE_ACTIVITY_ASK_QUESTION],
+ order_by=['-activity.active_at']
+ ).values(
+ 'title',
+ 'question_id',
+ 'active_at',
+ 'activity_type'
+ )
+ if len(questions) > 0:
+ questions = [(Event(q['active_at'], q['activity_type'], q['title'], '', '0', \
+ q['question_id'])) for q in questions]
+ activities.extend(questions)
+
+ # answers
+ answers = Activity.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'answer_id' : 'answer.id',
+ 'active_at' : 'activity.active_at',
+ 'activity_type' : 'activity.activity_type'
+ },
+ tables=['activity', 'answer', 'question'],
+ where=['activity.content_type_id = %s AND activity.object_id = answer.id AND ' +
+ 'answer.question_id=question.id AND answer.deleted=False AND activity.user_id=%s AND '+
+ 'activity.activity_type=%s AND question.deleted=False'],
+ params=[answer_type_id, user_id, TYPE_ACTIVITY_ANSWER],
+ order_by=['-activity.active_at']
+ ).values(
+ 'title',
+ 'question_id',
+ 'answer_id',
+ 'active_at',
+ 'activity_type'
+ )
+ if len(answers) > 0:
+ answers = [(Event(q['active_at'], q['activity_type'], q['title'], '', q['answer_id'], \
+ q['question_id'])) for q in answers]
+ activities.extend(answers)
+
+ # question comments
+ comments = Activity.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'comment.object_id',
+ 'added_at' : 'comment.added_at',
+ 'activity_type' : 'activity.activity_type'
+ },
+ tables=['activity', 'question', 'comment'],
+
+ where=['activity.content_type_id = %s AND activity.object_id = comment.id AND '+
+ 'activity.user_id = comment.user_id AND comment.object_id=question.id AND '+
+ 'comment.content_type_id=%s AND activity.user_id = %s AND activity.activity_type=%s AND ' +
+ 'question.deleted=False'],
+ params=[comment_type_id, question_type_id, user_id, TYPE_ACTIVITY_COMMENT_QUESTION],
+ order_by=['-comment.added_at']
+ ).values(
+ 'title',
+ 'question_id',
+ 'added_at',
+ 'activity_type'
+ )
+
+ if len(comments) > 0:
+ comments = [(Event(q['added_at'], q['activity_type'], q['title'], '', '0', \
+ q['question_id'])) for q in comments]
+ activities.extend(comments)
+
+ # answer comments
+ comments = Activity.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'answer_id' : 'answer.id',
+ 'added_at' : 'comment.added_at',
+ 'activity_type' : 'activity.activity_type'
+ },
+ tables=['activity', 'question', 'answer', 'comment'],
+
+ where=['activity.content_type_id = %s AND activity.object_id = comment.id AND '+
+ 'activity.user_id = comment.user_id AND comment.object_id=answer.id AND '+
+ 'comment.content_type_id=%s AND question.id = answer.question_id AND '+
+ 'activity.user_id = %s AND activity.activity_type=%s AND '+
+ 'answer.deleted=False AND question.deleted=False'],
+ params=[comment_type_id, answer_type_id, user_id, TYPE_ACTIVITY_COMMENT_ANSWER],
+ order_by=['-comment.added_at']
+ ).values(
+ 'title',
+ 'question_id',
+ 'answer_id',
+ 'added_at',
+ 'activity_type'
+ )
+
+ if len(comments) > 0:
+ comments = [(Event(q['added_at'], q['activity_type'], q['title'], '', q['answer_id'], \
+ q['question_id'])) for q in comments]
+ activities.extend(comments)
+
+ # question revisions
+ revisions = Activity.objects.extra(
+ select={
+ 'title' : 'question_revision.title',
+ 'question_id' : 'question_revision.question_id',
+ 'added_at' : 'activity.active_at',
+ 'activity_type' : 'activity.activity_type',
+ 'summary' : 'question_revision.summary'
+ },
+ tables=['activity', 'question_revision', 'question'],
+ where=['activity.content_type_id = %s AND activity.object_id = question_revision.id AND '+
+ 'question_revision.id=question.id AND question.deleted=False AND '+
+ 'activity.user_id = question_revision.author_id AND activity.user_id = %s AND '+
+ 'activity.activity_type=%s'],
+ params=[question_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_QUESTION],
+ order_by=['-activity.active_at']
+ ).values(
+ 'title',
+ 'question_id',
+ 'added_at',
+ 'activity_type',
+ 'summary'
+ )
+
+ if len(revisions) > 0:
+ revisions = [(Event(q['added_at'], q['activity_type'], q['title'], q['summary'], '0', \
+ q['question_id'])) for q in revisions]
+ activities.extend(revisions)
+
+ # answer revisions
+ revisions = Activity.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'answer_id' : 'answer.id',
+ 'added_at' : 'activity.active_at',
+ 'activity_type' : 'activity.activity_type',
+ 'summary' : 'answer_revision.summary'
+ },
+ tables=['activity', 'answer_revision', 'question', 'answer'],
+
+ where=['activity.content_type_id = %s AND activity.object_id = answer_revision.id AND '+
+ 'activity.user_id = answer_revision.author_id AND activity.user_id = %s AND '+
+ 'answer_revision.answer_id=answer.id AND answer.question_id = question.id AND '+
+ 'question.deleted=False AND answer.deleted=False AND '+
+ 'activity.activity_type=%s'],
+ params=[answer_revision_type_id, user_id, TYPE_ACTIVITY_UPDATE_ANSWER],
+ order_by=['-activity.active_at']
+ ).values(
+ 'title',
+ 'question_id',
+ 'added_at',
+ 'answer_id',
+ 'activity_type',
+ 'summary'
+ )
+
+ if len(revisions) > 0:
+ revisions = [(Event(q['added_at'], q['activity_type'], q['title'], q['summary'], \
+ q['answer_id'], q['question_id'])) for q in revisions]
+ activities.extend(revisions)
+
+ # accepted answers
+ accept_answers = Activity.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'added_at' : 'activity.active_at',
+ 'activity_type' : 'activity.activity_type',
+ },
+ tables=['activity', 'answer', 'question'],
+ where=['activity.content_type_id = %s AND activity.object_id = answer.id AND '+
+ 'activity.user_id = question.author_id AND activity.user_id = %s AND '+
+ 'answer.deleted=False AND question.deleted=False AND '+
+ 'answer.question_id=question.id AND activity.activity_type=%s'],
+ params=[answer_type_id, user_id, TYPE_ACTIVITY_MARK_ANSWER],
+ order_by=['-activity.active_at']
+ ).values(
+ 'title',
+ 'question_id',
+ 'added_at',
+ 'activity_type',
+ )
+ if len(accept_answers) > 0:
+ accept_answers = [(Event(q['added_at'], q['activity_type'], q['title'], '', '0', \
+ q['question_id'])) for q in accept_answers]
+ activities.extend(accept_answers)
+ #award history
+ awards = Activity.objects.extra(
+ select={
+ 'badge_id' : 'badge.id',
+ 'awarded_at': 'award.awarded_at',
+ 'activity_type' : 'activity.activity_type'
+ },
+ tables=['activity', 'award', 'badge'],
+ where=['activity.user_id = award.user_id AND activity.user_id = %s AND '+
+ 'award.badge_id=badge.id AND activity.object_id=award.id AND activity.activity_type=%s'],
+ params=[user_id, TYPE_ACTIVITY_PRIZE],
+ order_by=['-activity.active_at']
+ ).values(
+ 'badge_id',
+ 'awarded_at',
+ 'activity_type'
+ )
+ if len(awards) > 0:
+ awards = [(AwardEvent(q['awarded_at'], q['activity_type'], q['badge_id'])) for q in awards]
+ activities.extend(awards)
+
+ activities.sort(lambda x,y: cmp(y.time, x.time))
+
+ return render_to_response(user_view.template_file,{
+ "tab_name" : user_view.id,
+ "tab_description" : user_view.tab_description,
+ "page_title" : user_view.page_title,
+ "view_user" : user,
+ "activities" : activities[:user_view.data_size]
+ }, context_instance=RequestContext(request))
+
+def user_responses(request, user_id, user_view):
+ """
+ We list answers for question, comments, and answer accepted by others for this user.
+ """
+ class Response:
+ def __init__(self, type, title, question_id, answer_id, time, username, user_id, content):
+ self.type = type
+ self.title = title
+ self.titlelink = reverse('question', args=[question_id]) + u'%s#%s' % (slugify(title), answer_id)
+ self.time = time
+ self.userlink = reverse('users') + u'%s/%s/' % (user_id, username)
+ self.username = username
+ self.content = u'%s ...' % strip_tags(content)[:300]
+
+ def __unicode__(self):
+ return u'%s %s' % (self.type, self.titlelink)
+
+ user = get_object_or_404(User, id=user_id)
+ responses = []
+ answers = Answer.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'answer_id' : 'answer.id',
+ 'added_at' : 'answer.added_at',
+ 'html' : 'answer.html',
+ 'username' : 'auth_user.username',
+ 'user_id' : 'auth_user.id'
+ },
+ select_params=[user_id],
+ tables=['answer', 'question', 'auth_user'],
+ where=['answer.question_id = question.id AND answer.deleted=False AND question.deleted=False AND '+
+ 'question.author_id = %s AND answer.author_id <> %s AND answer.author_id=auth_user.id'],
+ params=[user_id, user_id],
+ order_by=['-answer.id']
+ ).values(
+ 'title',
+ 'question_id',
+ 'answer_id',
+ 'added_at',
+ 'html',
+ 'username',
+ 'user_id'
+ )
+ if len(answers) > 0:
+ answers = [(Response(TYPE_RESPONSE['QUESTION_ANSWERED'], a['title'], a['question_id'],
+ a['answer_id'], a['added_at'], a['username'], a['user_id'], a['html'])) for a in answers]
+ responses.extend(answers)
+
+
+ # question comments
+ comments = Comment.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'comment.object_id',
+ 'added_at' : 'comment.added_at',
+ 'comment' : 'comment.comment',
+ 'username' : 'auth_user.username',
+ 'user_id' : 'auth_user.id'
+ },
+ tables=['question', 'auth_user', 'comment'],
+ where=['question.deleted=False AND question.author_id = %s AND comment.object_id=question.id AND '+
+ 'comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id'],
+ params=[user_id, question_type_id, user_id],
+ order_by=['-comment.added_at']
+ ).values(
+ 'title',
+ 'question_id',
+ 'added_at',
+ 'comment',
+ 'username',
+ 'user_id'
+ )
+
+ if len(comments) > 0:
+ comments = [(Response(TYPE_RESPONSE['QUESTION_COMMENTED'], c['title'], c['question_id'],
+ '', c['added_at'], c['username'], c['user_id'], c['comment'])) for c in comments]
+ responses.extend(comments)
+
+ # answer comments
+ comments = Comment.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'answer_id' : 'answer.id',
+ 'added_at' : 'comment.added_at',
+ 'comment' : 'comment.comment',
+ 'username' : 'auth_user.username',
+ 'user_id' : 'auth_user.id'
+ },
+ tables=['answer', 'auth_user', 'comment', 'question'],
+ where=['answer.deleted=False AND answer.author_id = %s AND comment.object_id=answer.id AND '+
+ 'comment.content_type_id=%s AND comment.user_id <> %s AND comment.user_id = auth_user.id '+
+ 'AND question.id = answer.question_id'],
+ params=[user_id, answer_type_id, user_id],
+ order_by=['-comment.added_at']
+ ).values(
+ 'title',
+ 'question_id',
+ 'answer_id',
+ 'added_at',
+ 'comment',
+ 'username',
+ 'user_id'
+ )
+
+ if len(comments) > 0:
+ comments = [(Response(TYPE_RESPONSE['ANSWER_COMMENTED'], c['title'], c['question_id'],
+ c['answer_id'], c['added_at'], c['username'], c['user_id'], c['comment'])) for c in comments]
+ responses.extend(comments)
+
+ # answer has been accepted
+ answers = Answer.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'answer_id' : 'answer.id',
+ 'added_at' : 'answer.accepted_at',
+ 'html' : 'answer.html',
+ 'username' : 'auth_user.username',
+ 'user_id' : 'auth_user.id'
+ },
+ select_params=[user_id],
+ tables=['answer', 'question', 'auth_user'],
+ where=['answer.question_id = question.id AND answer.deleted=False AND question.deleted=False AND '+
+ 'answer.author_id = %s AND answer.accepted=True AND question.author_id=auth_user.id'],
+ params=[user_id],
+ order_by=['-answer.id']
+ ).values(
+ 'title',
+ 'question_id',
+ 'answer_id',
+ 'added_at',
+ 'html',
+ 'username',
+ 'user_id'
+ )
+ if len(answers) > 0:
+ answers = [(Response(TYPE_RESPONSE['ANSWER_ACCEPTED'], a['title'], a['question_id'],
+ a['answer_id'], a['added_at'], a['username'], a['user_id'], a['html'])) for a in answers]
+ responses.extend(answers)
+
+ # sort posts by time
+ responses.sort(lambda x,y: cmp(y.time, x.time))
+
+ return render_to_response(user_view.template_file,{
+ "tab_name" : user_view.id,
+ "tab_description" : user_view.tab_description,
+ "page_title" : user_view.page_title,
+ "view_user" : user,
+ "responses" : responses[:user_view.data_size],
+
+ }, context_instance=RequestContext(request))
+
+def user_votes(request, user_id, user_view):
+ user = get_object_or_404(User, id=user_id)
+ if not auth.can_view_user_votes(request.user, user):
+ raise Http404
+ votes = []
+ question_votes = Vote.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'answer_id' : 0,
+ 'voted_at' : 'vote.voted_at',
+ 'vote' : 'vote',
+ },
+ select_params=[user_id],
+ tables=['vote', 'question', 'auth_user'],
+ where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = question.id '+
+ 'AND vote.user_id=auth_user.id'],
+ params=[question_type_id, user_id],
+ order_by=['-vote.id']
+ ).values(
+ 'title',
+ 'question_id',
+ 'answer_id',
+ 'voted_at',
+ 'vote',
+ )
+ if(len(question_votes) > 0):
+ votes.extend(question_votes)
+
+ answer_votes = Vote.objects.extra(
+ select={
+ 'title' : 'question.title',
+ 'question_id' : 'question.id',
+ 'answer_id' : 'answer.id',
+ 'voted_at' : 'vote.voted_at',
+ 'vote' : 'vote',
+ },
+ select_params=[user_id],
+ tables=['vote', 'answer', 'question', 'auth_user'],
+ where=['vote.content_type_id = %s AND vote.user_id = %s AND vote.object_id = answer.id '+
+ 'AND answer.question_id = question.id AND vote.user_id=auth_user.id'],
+ params=[answer_type_id, user_id],
+ order_by=['-vote.id']
+ ).values(
+ 'title',
+ 'question_id',
+ 'answer_id',
+ 'voted_at',
+ 'vote',
+ )
+ if(len(answer_votes) > 0):
+ votes.extend(answer_votes)
+ votes.sort(lambda x,y: cmp(y['voted_at'], x['voted_at']))
+ return render_to_response(user_view.template_file,{
+ "tab_name" : user_view.id,
+ "tab_description" : user_view.tab_description,
+ "page_title" : user_view.page_title,
+ "view_user" : user,
+ "votes" : votes[:user_view.data_size]
+
+ }, context_instance=RequestContext(request))
+
+def user_reputation(request, user_id, user_view):
+ user = get_object_or_404(User, id=user_id)
+ try:
+ from django.db.models import Sum
+ reputation = Repute.objects.extra(
+ select={'question_id':'question_id',
+ 'title': 'question.title'},
+ tables=['repute', 'question'],
+ order_by=['-reputed_at'],
+ where=['user_id=%s AND question_id=question.id'],
+ params=[user.id]
+ ).values('question_id', 'title', 'reputed_at', 'reputation')
+ reputation = reputation.annotate(positive=Sum("positive"), negative=Sum("negative"))
+ except ImportError:
+ reputation = Repute.objects.extra(
+ select={'positive':'sum(positive)', 'negative':'sum(negative)', 'question_id':'question_id',
+ 'title': 'question.title'},
+ tables=['repute', 'question'],
+ order_by=['-reputed_at'],
+ where=['user_id=%s AND question_id=question.id'],
+ params=[user.id]
+ ).values('positive', 'negative', 'question_id', 'title', 'reputed_at', 'reputation')
+ reputation.query.group_by = ['question_id']
+
+ rep_list = []
+ for rep in Repute.objects.filter(user=user).order_by('reputed_at'):
+ dic = '[%s,%s]' % (calendar.timegm(rep.reputed_at.timetuple()) * 1000, rep.reputation)
+ rep_list.append(dic)
+ reps = ','.join(rep_list)
+ reps = '[%s]' % reps
+
+ return render_to_response(user_view.template_file, {
+ "tab_name": user_view.id,
+ "tab_description": user_view.tab_description,
+ "page_title": user_view.page_title,
+ "view_user": user,
+ "reputation": reputation,
+ "reps": reps
+ }, context_instance=RequestContext(request))
+
+def user_favorites(request, user_id, user_view):
+ user = get_object_or_404(User, id=user_id)
+ questions = Question.objects.extra(
+ select={
+ 'vote_count' : 'question.vote_up_count + question.vote_down_count',
+ 'favorited_myself' : 'SELECT count(*) FROM favorite_question f WHERE f.user_id = %s '+
+ 'AND f.question_id = question.id',
+ 'la_user_id' : 'auth_user.id',
+ 'la_username' : 'auth_user.username',
+ 'la_user_gold' : 'auth_user.gold',
+ 'la_user_silver' : 'auth_user.silver',
+ 'la_user_bronze' : 'auth_user.bronze',
+ 'la_user_reputation' : 'auth_user.reputation'
+ },
+ select_params=[user_id],
+ tables=['question', 'auth_user', 'favorite_question'],
+ where=['question.deleted=True AND question.last_activity_by_id = auth_user.id '+
+ 'AND favorite_question.question_id = question.id AND favorite_question.user_id = %s'],
+ params=[user_id],
+ order_by=['-vote_count', '-question.id']
+ ).values('vote_count',
+ 'favorited_myself',
+ 'id',
+ 'title',
+ 'author_id',
+ 'added_at',
+ 'answer_accepted',
+ 'answer_count',
+ 'comment_count',
+ 'view_count',
+ 'favourite_count',
+ 'summary',
+ 'tagnames',
+ 'vote_up_count',
+ 'vote_down_count',
+ 'last_activity_at',
+ 'la_user_id',
+ 'la_username',
+ 'la_user_gold',
+ 'la_user_silver',
+ 'la_user_bronze',
+ 'la_user_reputation')
+ return render_to_response(user_view.template_file,{
+ "tab_name" : user_view.id,
+ "tab_description" : user_view.tab_description,
+ "page_title" : user_view.page_title,
+ "questions" : questions[:user_view.data_size],
+ "view_user" : user
+ }, context_instance=RequestContext(request))
+
+def user_email_subscriptions(request, user_id, user_view):
+ user = get_object_or_404(User, id=user_id)
+ if request.method == 'POST':
+ email_feeds_form = EditUserEmailFeedsForm(request.POST)
+ tag_filter_form = TagFilterSelectionForm(request.POST, instance=user)
+ if email_feeds_form.is_valid() and tag_filter_form.is_valid():
+
+ action_status = None
+ tag_filter_saved = tag_filter_form.save()
+ if tag_filter_saved:
+ action_status = _('changes saved')
+ if 'save' in request.POST:
+ feeds_saved = email_feeds_form.save(user)
+ if feeds_saved:
+ action_status = _('changes saved')
+ elif 'stop_email' in request.POST:
+ email_stopped = email_feeds_form.reset().save(user)
+ initial_values = EditUserEmailFeedsForm.NO_EMAIL_INITIAL
+ email_feeds_form = EditUserEmailFeedsForm(initial=initial_values)
+ if email_stopped:
+ action_status = _('email updates canceled')
+ else:
+ email_feeds_form = EditUserEmailFeedsForm()
+ email_feeds_form.set_initial_values(user)
+ tag_filter_form = TagFilterSelectionForm(instance=user)
+ action_status = None
+ return render_to_response(user_view.template_file,{
+ 'tab_name':user_view.id,
+ 'tab_description':user_view.tab_description,
+ 'page_title':user_view.page_title,
+ 'view_user':user,
+ 'email_feeds_form':email_feeds_form,
+ 'tag_filter_selection_form':tag_filter_form,
+ 'action_status':action_status,
+ }, context_instance=RequestContext(request))
+
+class UserView:
+ def __init__(self, id, tab_title, tab_description, page_title, view_func, template_file, data_size=0):
+ self.id = id
+ self.tab_title = tab_title
+ self.tab_description = tab_description
+ self.page_title = page_title
+ self.view_func = view_func
+ self.template_file = template_file
+ self.data_size = data_size
+
+USER_TEMPLATE_VIEWS = (
+ UserView(
+ id = 'stats',
+ tab_title = _('overview'),
+ tab_description = _('user profile'),
+ page_title = _('user profile overview'),
+ view_func = user_stats,
+ template_file = 'user_stats.html'
+ ),
+ UserView(
+ id = 'recent',
+ tab_title = _('recent activity'),
+ tab_description = _('recent user activity'),
+ page_title = _('profile - recent activity'),
+ view_func = user_recent,
+ template_file = 'user_recent.html',
+ data_size = 50
+ ),
+ UserView(
+ id = 'responses',
+ tab_title = _('responses'),
+ tab_description = _('comments and answers to others questions'),
+ page_title = _('profile - responses'),
+ view_func = user_responses,
+ template_file = 'user_responses.html',
+ data_size = 50
+ ),
+ UserView(
+ id = 'reputation',
+ tab_title = _('reputation'),
+ tab_description = _('user reputation in the community'),
+ page_title = _('profile - user reputation'),
+ view_func = user_reputation,
+ template_file = 'user_reputation.html'
+ ),
+ UserView(
+ id = 'favorites',
+ tab_title = _('favorite questions'),
+ tab_description = _('users favorite questions'),
+ page_title = _('profile - favorite questions'),
+ view_func = user_favorites,
+ template_file = 'user_favorites.html',
+ data_size = 50
+ ),
+ UserView(
+ id = 'votes',
+ tab_title = _('casted votes'),
+ tab_description = _('user vote record'),
+ page_title = _('profile - votes'),
+ view_func = user_votes,
+ template_file = 'user_votes.html',
+ data_size = 50
+ ),
+ UserView(
+ id = 'email_subscriptions',
+ tab_title = _('email subscriptions'),
+ tab_description = _('email subscription settings'),
+ page_title = _('profile - email subscriptions'),
+ view_func = user_email_subscriptions,
+ template_file = 'user_email_subscriptions.html'
+ )
+)
+
+def user(request, id):
+ sort = request.GET.get('sort', 'stats')
+ user_view = dict((v.id, v) for v in USER_TEMPLATE_VIEWS).get(sort, USER_TEMPLATE_VIEWS[0])
+ from forum.views import users
+ func = user_view.view_func
+ return func(request, id, user_view)
diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo
index 502c1075..b87457df 100644
--- a/locale/en/LC_MESSAGES/django.mo
+++ b/locale/en/LC_MESSAGES/django.mo
Binary files differ
diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po
index 3ce3d53d..3b8a13cd 100644
--- a/locale/en/LC_MESSAGES/django.po
+++ b/locale/en/LC_MESSAGES/django.po
@@ -8,305 +8,234 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-12-09 08:54-0800\n"
-"PO-Revision-Date: 2009-12-15 16:53-0600\n"
+"POT-Creation-Date: 2010-02-16 00:17-0500\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: django_authopenid/forms.py:70
-msgid "choose a username"
-msgstr "Choose screen name"
-
-#: django_authopenid/forms.py:76
-msgid "user name is required"
-msgstr ""
-
-#: django_authopenid/forms.py:77
-msgid "sorry, this name is taken, please choose another"
-msgstr ""
-
-#: django_authopenid/forms.py:78
-msgid "sorry, this name is not allowed, please choose another"
-msgstr ""
-
-#: django_authopenid/forms.py:79
-msgid "sorry, there is no user with this name"
-msgstr ""
-
-#: django_authopenid/forms.py:80
-msgid "sorry, we have a serious error - user name is taken by several users"
-msgstr ""
-
-#: django_authopenid/forms.py:81
-msgid "user name can only consist of letters, empty space and underscore"
-msgstr ""
-
-#: django_authopenid/forms.py:116
-msgid "your email address"
-msgstr "Your email <i>(never shared)</i>"
-
-#: django_authopenid/forms.py:117
-msgid "email address is required"
-msgstr ""
-
-#: django_authopenid/forms.py:118
-msgid "please enter a valid email address"
-msgstr ""
-
-#: django_authopenid/forms.py:119
-msgid "this email is already used by someone else, please choose another"
-msgstr ""
-
-#: django_authopenid/forms.py:163 django_authopenid/views.py:118
+#: django_authopenid/forms.py:71 django_authopenid/views.py:118
msgid "i-names are not supported"
msgstr ""
-#: django_authopenid/forms.py:219
+#: django_authopenid/forms.py:134
msgid "Account with this name already exists on the forum"
msgstr ""
-#: django_authopenid/forms.py:220
+#: django_authopenid/forms.py:135
msgid "can't have two logins to the same account yet, sorry."
msgstr ""
-#: django_authopenid/forms.py:242
+#: django_authopenid/forms.py:157
msgid "Please enter valid username and password (both are case-sensitive)."
msgstr ""
-#: django_authopenid/forms.py:245 django_authopenid/forms.py:295
+#: django_authopenid/forms.py:160 django_authopenid/forms.py:210
msgid "This account is inactive."
msgstr ""
-#: django_authopenid/forms.py:247
+#: django_authopenid/forms.py:162
msgid "Login failed."
msgstr ""
-#: django_authopenid/forms.py:249
+#: django_authopenid/forms.py:164
msgid "Please enter username and password"
msgstr ""
-#: django_authopenid/forms.py:251
+#: django_authopenid/forms.py:166
msgid "Please enter your password"
msgstr ""
-#: django_authopenid/forms.py:253
+#: django_authopenid/forms.py:168
msgid "Please enter user name"
msgstr ""
-#: django_authopenid/forms.py:291
+#: django_authopenid/forms.py:206
msgid ""
"Please enter a valid username and password. Note that "
"both fields are case-sensitive."
msgstr ""
-#: django_authopenid/forms.py:313
-msgid "choose password"
-msgstr "Password"
-
-#: django_authopenid/forms.py:314
-msgid "password is required"
-msgstr ""
-
-#: django_authopenid/forms.py:317
-msgid "retype password"
-msgstr "Password <i>(please retype)</i>"
-
-#: django_authopenid/forms.py:318
-msgid "please, retype your password"
-msgstr ""
-
-#: django_authopenid/forms.py:319
-msgid "sorry, entered passwords did not match, please try again"
-msgstr ""
-
-#: django_authopenid/forms.py:344
+#: django_authopenid/forms.py:229
msgid "Current password"
msgstr ""
-#: django_authopenid/forms.py:346
-msgid "New password"
-msgstr ""
-
-#: django_authopenid/forms.py:348
-msgid "Retype new password"
-msgstr ""
-
-#: django_authopenid/forms.py:359
+#: django_authopenid/forms.py:240
msgid ""
"Old password is incorrect. Please enter the correct "
"password."
msgstr ""
-#: django_authopenid/forms.py:371
-msgid "new passwords do not match"
-msgstr ""
-
-#: django_authopenid/forms.py:435
+#: django_authopenid/forms.py:305
msgid "Your user name (<i>required</i>)"
msgstr ""
-#: django_authopenid/forms.py:450
+#: django_authopenid/forms.py:320
msgid "Incorrect username."
-msgstr "sorry, there is no such user name"
+msgstr ""
-#: django_authopenid/urls.py:9 django_authopenid/urls.py:10
-#: django_authopenid/urls.py:11 django_authopenid/urls.py:13 forum/urls.py:24
+#: django_authopenid/urls.py:23 django_authopenid/urls.py:24
+#: django_authopenid/urls.py:25 django_authopenid/urls.py:27
+#: fbconnect/urls.py:12 fbconnect/urls.py:13 fbconnect/urls.py:14
+#: forum/urls.py:30
msgid "signin/"
msgstr ""
-#: django_authopenid/urls.py:10
+#: django_authopenid/urls.py:24 fbconnect/urls.py:13 fbconnect/urls.py:17
msgid "newquestion/"
msgstr ""
-#: django_authopenid/urls.py:11
+#: django_authopenid/urls.py:25 fbconnect/urls.py:14 fbconnect/urls.py:18
msgid "newanswer/"
msgstr ""
-#: django_authopenid/urls.py:12
+#: django_authopenid/urls.py:26
msgid "signout/"
msgstr ""
-#: django_authopenid/urls.py:13
+#: django_authopenid/urls.py:27
msgid "complete/"
msgstr ""
-#: django_authopenid/urls.py:15
-msgid "external-login/"
-msgstr ""
-
-#: django_authopenid/urls.py:16
+#: django_authopenid/urls.py:29 fbconnect/urls.py:16 fbconnect/urls.py:17
+#: fbconnect/urls.py:18
msgid "register/"
msgstr ""
-#: django_authopenid/urls.py:17
+#: django_authopenid/urls.py:30
msgid "signup/"
msgstr ""
-#: django_authopenid/urls.py:19
+#: django_authopenid/urls.py:32
msgid "sendpw/"
msgstr ""
-#: django_authopenid/urls.py:20 django_authopenid/urls.py:24
+#: django_authopenid/urls.py:33 django_authopenid/urls.py:37
msgid "password/"
msgstr ""
-#: django_authopenid/urls.py:20
+#: django_authopenid/urls.py:33
msgid "confirm/"
msgstr ""
-#: django_authopenid/urls.py:23
+#: django_authopenid/urls.py:36
msgid "account_settings"
msgstr ""
-#: django_authopenid/urls.py:25 django_authopenid/urls.py:26
-#: django_authopenid/urls.py:27 django_authopenid/urls.py:28
+#: django_authopenid/urls.py:38 django_authopenid/urls.py:39
+#: django_authopenid/urls.py:40 django_authopenid/urls.py:41
msgid "email/"
msgstr ""
-#: django_authopenid/urls.py:25
+#: django_authopenid/urls.py:38
msgid "validate/"
msgstr ""
-#: django_authopenid/urls.py:26
+#: django_authopenid/urls.py:39
msgid "change/"
msgstr ""
-#: django_authopenid/urls.py:27
+#: django_authopenid/urls.py:40
msgid "sendkey/"
msgstr ""
-#: django_authopenid/urls.py:28
+#: django_authopenid/urls.py:41
msgid "verify/"
msgstr ""
-#: django_authopenid/urls.py:29
+#: django_authopenid/urls.py:42
msgid "openid/"
msgstr ""
-#: django_authopenid/urls.py:30 forum/urls.py:44 forum/urls.py:48
+#: django_authopenid/urls.py:43 forum/urls.py:50 forum/urls.py:54
msgid "delete/"
msgstr ""
-#: django_authopenid/views.py:124
+#: django_authopenid/urls.py:51
+msgid "external-login/forgot-password/"
+msgstr ""
+
+#: django_authopenid/urls.py:54
+msgid "external-login/signup/"
+msgstr ""
+
+#: django_authopenid/views.py:125
#, python-format
msgid "OpenID %(openid_url)s is invalid"
msgstr ""
-#: django_authopenid/views.py:532
+#: django_authopenid/views.py:593
msgid "Welcome email subject line"
-msgstr "Welcome to the Q&A forum"
+msgstr ""
-#: django_authopenid/views.py:627
+#: django_authopenid/views.py:699
msgid "Password changed."
msgstr ""
-#: django_authopenid/views.py:639 django_authopenid/views.py:645
+#: django_authopenid/views.py:711 django_authopenid/views.py:717
#, python-format
msgid "your email needs to be validated see %(details_url)s"
msgstr ""
-"Your email needs to be validated. Please see details <a "
-"id='validate_email_alert' href='%(details_url)s'>here</a>."
-#: django_authopenid/views.py:666
+#: django_authopenid/views.py:738
msgid "Email verification subject line"
-msgstr "Verification Email from Q&A forum"
+msgstr ""
-#: django_authopenid/views.py:752
+#: django_authopenid/views.py:829
msgid "your email was not changed"
msgstr ""
-#: django_authopenid/views.py:799 django_authopenid/views.py:951
+#: django_authopenid/views.py:877 django_authopenid/views.py:1035
#, python-format
msgid "No OpenID %s found associated in our database"
msgstr ""
-#: django_authopenid/views.py:803 django_authopenid/views.py:958
+#: django_authopenid/views.py:881 django_authopenid/views.py:1042
#, python-format
msgid "The OpenID %s isn't associated to current user logged in"
msgstr ""
-#: django_authopenid/views.py:811
+#: django_authopenid/views.py:889
msgid "Email Changed."
msgstr ""
-#: django_authopenid/views.py:886
+#: django_authopenid/views.py:967
msgid "This OpenID is already associated with another account."
msgstr ""
-#: django_authopenid/views.py:891
+#: django_authopenid/views.py:972
#, python-format
msgid "OpenID %s is now associated with your account."
msgstr ""
-#: django_authopenid/views.py:961
+#: django_authopenid/views.py:1045
msgid "Account deleted."
msgstr ""
-#: django_authopenid/views.py:1004
+#: django_authopenid/views.py:1097
msgid "Request for new password"
msgstr ""
-#: django_authopenid/views.py:1017
+#: django_authopenid/views.py:1111
msgid "A new password and the activation link were sent to your email address."
msgstr ""
-#: django_authopenid/views.py:1047
+#: django_authopenid/views.py:1143
#, python-format
msgid ""
"Could not change password. Confirmation key '%s' is not "
"registered."
msgstr ""
-#: django_authopenid/views.py:1056
+#: django_authopenid/views.py:1153
msgid ""
"Can not change password. User don't exist anymore in our "
"database."
msgstr ""
-#: django_authopenid/views.py:1065
+#: django_authopenid/views.py:1163
#, python-format
msgid "Password changed for %s. You may now sign in."
msgstr ""
@@ -363,7 +292,7 @@ msgstr ""
msgid "question"
msgstr ""
-#: forum/const.py:58 templates/book.html:110
+#: forum/const.py:58 forum/skins/default/templates/book.html:110
msgid "answer"
msgstr ""
@@ -385,7 +314,7 @@ msgstr ""
#: forum/const.py:63
msgid "received award"
-msgstr "received badge"
+msgstr ""
#: forum/const.py:64
msgid "marked best answer"
@@ -439,7 +368,8 @@ msgstr ""
msgid "[deleted]"
msgstr ""
-#: forum/const.py:87 forum/views.py:849 forum/views.py:868
+#: forum/const.py:87 forum/views.py:792 forum/views.py:811
+#: forum/views/content.py:560 forum/views/content.py:579
msgid "initial version"
msgstr ""
@@ -452,7 +382,7 @@ msgid "exclude ignored tags"
msgstr ""
#: forum/const.py:92
-msgid "allow only interesting tags"
+msgid "allow only selected tags"
msgstr ""
#: forum/feed.py:18
@@ -463,553 +393,460 @@ msgstr ""
msgid "latest questions"
msgstr ""
-#: forum/feed.py:19 forum/urls.py:52
-msgid "question/"
-msgstr ""
-
-#: forum/forms.py:16 templates/answer_edit_tips.html:35
-#: templates/answer_edit_tips.html.py:39 templates/question_edit_tips.html:32
-#: templates/question_edit_tips.html:37
+#: forum/forms.py:18 forum/skins/default/templates/answer_edit_tips.html:35
+#: forum/skins/default/templates/answer_edit_tips.html:39
+#: forum/skins/default/templates/question_edit_tips.html:32
+#: forum/skins/default/templates/question_edit_tips.html:37
msgid "title"
msgstr ""
-#: forum/forms.py:17
+#: forum/forms.py:19
msgid "please enter a descriptive title for your question"
msgstr ""
-#: forum/forms.py:22
+#: forum/forms.py:24
msgid "title must be > 10 characters"
msgstr ""
-#: forum/forms.py:31
+#: forum/forms.py:33
msgid "content"
msgstr ""
-#: forum/forms.py:37
+#: forum/forms.py:39
msgid "question content must be > 10 characters"
msgstr ""
-#: forum/forms.py:47 templates/header.html:28 templates/header.html.py:62
+#: forum/forms.py:49 forum/skins/default/templates/header.html:28
+#: forum/skins/default/templates/header.html:56
msgid "tags"
msgstr ""
-#: forum/forms.py:49
+#: forum/forms.py:51
msgid ""
"Tags are short keywords, with no spaces within. Up to five tags can be used."
msgstr ""
-#: forum/forms.py:56 templates/question_retag.html:39
+#: forum/forms.py:58 forum/skins/default/templates/question_retag.html:39
msgid "tags are required"
msgstr ""
-#: forum/forms.py:62
+#: forum/forms.py:64
msgid "please use 5 tags or less"
msgstr ""
-#: forum/forms.py:65
+#: forum/forms.py:67
msgid "tags must be shorter than 20 characters"
msgstr ""
-#: forum/forms.py:69
+#: forum/forms.py:71
msgid ""
"please use following characters in tags: letters 'a-z', numbers, and "
"characters '.-_#'"
msgstr ""
-#: forum/forms.py:79 templates/index.html:61 templates/index.html.py:73
-#: templates/post_contributor_info.html:7
-#: templates/question_summary_list_roll.html:26
-#: templates/question_summary_list_roll.html:38 templates/questions.html:92
-#: templates/questions.html.py:104 templates/unanswered.html:51
-#: templates/unanswered.html.py:63
+#: forum/forms.py:81 forum/skins/default/templates/index.html:62
+#: forum/skins/default/templates/index.html:74
+#: forum/skins/default/templates/post_contributor_info.html:7
+#: forum/skins/default/templates/question_summary_list_roll.html:26
+#: forum/skins/default/templates/question_summary_list_roll.html:38
+#: forum/skins/default/templates/questions.html:97
+#: forum/skins/default/templates/questions.html:109
+#: forum/skins/default/templates/questions.html:366
+#: forum/skins/default/templates/questions.html:378
+#: templates/unanswered.html:51 templates/unanswered.html.py:63
msgid "community wiki"
msgstr ""
-#: forum/forms.py:80
+#: forum/forms.py:82
msgid ""
"if you choose community wiki option, the question and answer do not generate "
"points and name of author will not be shown"
msgstr ""
-#: forum/forms.py:96
+#: forum/forms.py:98
msgid "update summary:"
msgstr ""
-#: forum/forms.py:97
+#: forum/forms.py:99
msgid ""
"enter a brief summary of your revision (e.g. fixed spelling, grammar, "
"improved style, this field is optional)"
msgstr ""
-#: forum/forms.py:100
+#: forum/forms.py:102
msgid "Automatically accept user's contributions for the email updates"
msgstr ""
-#: forum/forms.py:113
+#: forum/forms.py:118
msgid "Your name:"
msgstr ""
-#: forum/forms.py:114
+#: forum/forms.py:119
msgid "Email (not shared with anyone):"
msgstr ""
-#: forum/forms.py:115
+#: forum/forms.py:120
msgid "Your message:"
msgstr ""
-#: forum/forms.py:197
+#: forum/forms.py:203
msgid "this email does not have to be linked to gravatar"
msgstr ""
-#: forum/forms.py:198
+#: forum/forms.py:205
msgid "Screen name"
msgstr ""
-#: forum/forms.py:199
+#: forum/forms.py:206
msgid "Real name"
msgstr ""
-#: forum/forms.py:200
+#: forum/forms.py:207
msgid "Website"
msgstr ""
-#: forum/forms.py:201
+#: forum/forms.py:208
msgid "Location"
msgstr ""
-#: forum/forms.py:202
+#: forum/forms.py:209
msgid "Date of birth"
msgstr ""
-#: forum/forms.py:202
+#: forum/forms.py:209
msgid "will not be shown, used to calculate age, format: YYYY-MM-DD"
msgstr ""
-#: forum/forms.py:203 templates/authopenid/settings.html:21
+#: forum/forms.py:210
+#: forum/skins/default/templates/authopenid/settings.html:21
msgid "Profile"
msgstr ""
-#: forum/forms.py:231 forum/forms.py:232
+#: forum/forms.py:241 forum/forms.py:242
msgid "this email has already been registered, please use another one"
msgstr ""
-#: forum/forms.py:238
+#: forum/forms.py:248
msgid "Choose email tag filter"
msgstr ""
-#: forum/forms.py:245 forum/forms.py:246
+#: forum/forms.py:263 forum/forms.py:264
msgid "weekly"
msgstr ""
-#: forum/forms.py:245 forum/forms.py:246
+#: forum/forms.py:263 forum/forms.py:264
msgid "no email"
msgstr ""
-#: forum/forms.py:246
+#: forum/forms.py:264
msgid "daily"
msgstr ""
-#: forum/forms.py:261
+#: forum/forms.py:279
msgid "Asked by me"
msgstr ""
-#: forum/forms.py:264
+#: forum/forms.py:282
msgid "Answered by me"
msgstr ""
-#: forum/forms.py:267
+#: forum/forms.py:285
msgid "Individually selected"
msgstr ""
-#: forum/forms.py:270
+#: forum/forms.py:288
msgid "Entire forum (tag filtered)"
msgstr ""
-#: forum/models.py:51
-msgid "Entire forum"
+#: forum/forms.py:342
+msgid "okay, let's try!"
+msgstr ""
+
+#: forum/forms.py:343
+msgid "no OSQA community email please, thanks"
+msgstr ""
+
+#: forum/forms.py:346
+msgid "please choose one of the options above"
msgstr ""
#: forum/models.py:52
-msgid "Questions that I asked"
+msgid "Entire forum"
msgstr ""
#: forum/models.py:53
-msgid "Questions that I answered"
+msgid "Questions that I asked"
msgstr ""
#: forum/models.py:54
+msgid "Questions that I answered"
+msgstr ""
+
+#: forum/models.py:55
msgid "Individually selected questions"
msgstr ""
-#: forum/models.py:57
+#: forum/models.py:58
msgid "Weekly"
msgstr ""
-#: forum/models.py:58
+#: forum/models.py:59
msgid "Daily"
msgstr ""
-#: forum/models.py:59
+#: forum/models.py:60
msgid "No email"
msgstr ""
-#: forum/models.py:301
+#: forum/models.py:321
#, python-format
msgid "%(author)s modified the question"
msgstr ""
-#: forum/models.py:305
+#: forum/models.py:325
#, python-format
msgid "%(people)s posted %(new_answer_count)s new answers"
msgstr ""
-#: forum/models.py:310
+#: forum/models.py:330
#, python-format
msgid "%(people)s commented the question"
msgstr ""
-#: forum/models.py:315
+#: forum/models.py:335
#, python-format
msgid "%(people)s commented answers"
msgstr ""
-#: forum/models.py:317
+#: forum/models.py:337
#, python-format
msgid "%(people)s commented an answer"
msgstr ""
-#: forum/models.py:348
+#: forum/models.py:368
msgid "interesting"
msgstr ""
-#: forum/models.py:348
+#: forum/models.py:368
msgid "ignored"
msgstr ""
-#: forum/models.py:511 templates/badges.html:53
+#: forum/models.py:541 forum/skins/default/templates/badges.html:53
msgid "gold"
msgstr ""
-#: forum/models.py:512 templates/badges.html:61
+#: forum/models.py:542 forum/skins/default/templates/badges.html:61
msgid "silver"
msgstr ""
-#: forum/models.py:513 templates/badges.html:68
+#: forum/models.py:543 forum/skins/default/templates/badges.html:68
msgid "bronze"
msgstr ""
-#: forum/urls.py:21
+#: forum/urls.py:27
msgid "upfiles/"
msgstr ""
-#: forum/urls.py:25
+#: forum/urls.py:31
msgid "about/"
msgstr ""
-#: forum/urls.py:26
+#: forum/urls.py:32
msgid "faq/"
msgstr ""
-#: forum/urls.py:27
+#: forum/urls.py:33
msgid "privacy/"
msgstr ""
-#: forum/urls.py:28
+#: forum/urls.py:34
msgid "logout/"
msgstr ""
-#: forum/urls.py:29 forum/urls.py:30 forum/urls.py:31 forum/urls.py:48
+#: forum/urls.py:35 forum/urls.py:36 forum/urls.py:37 forum/urls.py:54
msgid "answers/"
msgstr ""
-#: forum/urls.py:29 forum/urls.py:41 forum/urls.py:44 forum/urls.py:48
+#: forum/urls.py:35 forum/urls.py:47 forum/urls.py:50 forum/urls.py:54
msgid "comments/"
msgstr ""
-#: forum/urls.py:30 forum/urls.py:35 forum/urls.py:70
-#: templates/user_info.html:45
+#: forum/urls.py:36 forum/urls.py:41 forum/urls.py:76
+#: forum/skins/default/templates/user_info.html:45
msgid "edit/"
msgstr ""
-#: forum/urls.py:31 forum/urls.py:40
+#: forum/urls.py:37 forum/urls.py:46
msgid "revisions/"
msgstr ""
-#: forum/urls.py:32 forum/urls.py:33 forum/urls.py:34 forum/urls.py:35
-#: forum/urls.py:36 forum/urls.py:37 forum/urls.py:38 forum/urls.py:39
-#: forum/urls.py:40 forum/urls.py:41 forum/urls.py:44
+#: forum/urls.py:38 forum/urls.py:39 forum/urls.py:40 forum/urls.py:41
+#: forum/urls.py:42 forum/urls.py:43 forum/urls.py:44 forum/urls.py:45
+#: forum/urls.py:46 forum/urls.py:47 forum/urls.py:50
msgid "questions/"
msgstr ""
-#: forum/urls.py:33 forum/urls.py:80
+#: forum/urls.py:39 forum/urls.py:86
msgid "ask/"
msgstr ""
-#: forum/urls.py:34
+#: forum/urls.py:40
msgid "unanswered/"
msgstr ""
-#: forum/urls.py:36
+#: forum/urls.py:42
msgid "close/"
msgstr ""
-#: forum/urls.py:37
+#: forum/urls.py:43
msgid "reopen/"
msgstr ""
-#: forum/urls.py:38
+#: forum/urls.py:44
msgid "answer/"
msgstr ""
-#: forum/urls.py:39
+#: forum/urls.py:45
msgid "vote/"
msgstr ""
-#: forum/urls.py:42
+#: forum/urls.py:48
msgid "command/"
msgstr ""
-#: forum/urls.py:53 forum/urls.py:54
+#: forum/urls.py:58 forum/views.py:437 forum/views/content.py:431
+msgid "question/"
+msgstr ""
+
+#: forum/urls.py:59 forum/urls.py:60
msgid "tags/"
msgstr ""
-#: forum/urls.py:56 forum/urls.py:60
+#: forum/urls.py:62 forum/urls.py:66
msgid "mark-tag/"
msgstr ""
-#: forum/urls.py:56
+#: forum/urls.py:62
msgid "interesting/"
msgstr ""
-#: forum/urls.py:60
+#: forum/urls.py:66
msgid "ignored/"
msgstr ""
-#: forum/urls.py:64
+#: forum/urls.py:70
msgid "unmark-tag/"
msgstr ""
-#: forum/urls.py:68 forum/urls.py:70 forum/urls.py:71
+#: forum/urls.py:74 forum/urls.py:76 forum/urls.py:77
msgid "users/"
msgstr ""
-#: forum/urls.py:69
+#: forum/urls.py:75
msgid "moderate-user/"
msgstr ""
-#: forum/urls.py:72 forum/urls.py:73
+#: forum/urls.py:78 forum/urls.py:79
msgid "badges/"
msgstr ""
-"Your subscription is saved, but email address %(email)s needs to be "
-"validated, please see <a href='%(details_url)s'>more details here</a>"
-#: forum/views.py:1022
-msgid "email update frequency has been set to daily"
-msgstr ""
-
-#: forum/views.py:1826
-msgid "changes saved"
-msgstr ""
-
-#: forum/views.py:1832
-msgid "email updates canceled"
-msgstr ""
-
-#: forum/views.py:1999
-msgid "uploading images is limited to users with >60 reputation points"
-msgstr "sorry, file uploading requires karma >60"
-
-#: forum/urls.py:74
+#: forum/urls.py:80
msgid "messages/"
msgstr ""
-#: forum/urls.py:74
+#: forum/urls.py:80
msgid "markread/"
msgstr ""
-#: forum/urls.py:76
+#: forum/urls.py:82
msgid "nimda/"
msgstr ""
-#: forum/urls.py:78
+#: forum/urls.py:84
msgid "upload/"
msgstr ""
-#: forum/urls.py:79 forum/urls.py:80 forum/urls.py:81
+#: forum/urls.py:85 forum/urls.py:86 forum/urls.py:87
msgid "books/"
msgstr ""
-#: forum/urls.py:82
+#: forum/urls.py:88
msgid "search/"
msgstr ""
-"<p>Please remember that you can always <a href='%(link)s'>adjust</a> frequency of the "
-"email updates or turn them off entirely.<br/>If you believe that this message "
-"was sent in an error, please email about it the forum administrator at %(email)"
-"s.</p>"
-"<p>Sincerely,</p><p>Your friendly Q&A forum server.</p>"
-#: forum/urls.py:83
+#: forum/urls.py:89
msgid "feedback/"
msgstr ""
-#: forum/urls.py:84
+#: forum/urls.py:90 forum/urls.py:91
msgid "account/"
msgstr ""
-#: forum/user.py:16 templates/user_tabs.html:7
-msgid "overview"
-msgstr ""
-
-#: forum/user.py:17
-msgid "user profile"
-msgstr ""
-
-#: forum/user.py:18
-msgid "user profile overview"
-msgstr ""
-
-#: forum/user.py:24 templates/user_tabs.html:9
-msgid "recent activity"
-msgstr ""
-
-#: forum/user.py:25
-msgid "recent user activity"
-msgstr ""
-
-#: forum/user.py:26
-msgid "profile - recent activity"
-msgstr ""
-
-#: forum/user.py:33 templates/user_tabs.html:13
-msgid "responses"
-msgstr ""
-
-#: forum/user.py:34 templates/user_tabs.html:12
-msgid "comments and answers to others questions"
-msgstr ""
-
-#: forum/user.py:35
-msgid "profile - responses"
-msgstr ""
-
-#: forum/user.py:42 templates/user_info.html:22 templates/users.html:26
-msgid "reputation"
-msgstr "karma"
-
-#: forum/user.py:43
-msgid "user reputation in the community"
-msgstr "user karma"
-
-#: forum/user.py:44
-msgid "profile - user reputation"
-msgstr "Profile - User's Karma"
-
-#: forum/user.py:50
-msgid "favorite questions"
-msgstr ""
-
-#: forum/user.py:51
-msgid "users favorite questions"
-msgstr ""
-
-#: forum/user.py:52
-msgid "profile - favorite questions"
-msgstr ""
-
-#: forum/user.py:59 templates/user_tabs.html:20
-msgid "casted votes"
-msgstr "votes"
-
-#: forum/user.py:60 templates/user_tabs.html:20
-msgid "user vote record"
-msgstr ""
-
-#: forum/user.py:61
-msgid "profile - votes"
-msgstr ""
-
-#: forum/user.py:68 templates/user_tabs.html:28
-msgid "email subscriptions"
-msgstr ""
-
-#: forum/user.py:69 templates/user_tabs.html:27
-msgid "email subscription settings"
-msgstr ""
-
-#: forum/user.py:70
-msgid "profile - email subscriptions"
-msgstr ""
-
-#: forum/views.py:141
+#: forum/views.py:141 forum/views/meta.py:33
msgid "Q&A forum feedback"
msgstr ""
-#: forum/views.py:142
+#: forum/views.py:142 forum/views/meta.py:34
msgid "Thanks for the feedback!"
msgstr ""
-#: forum/views.py:150
+#: forum/views.py:150 forum/views/meta.py:42
msgid "We look forward to hearing your feedback! Please, give it next time :)"
msgstr ""
-#: forum/views.py:1150
+#: forum/views.py:1095 forum/views/content.py:1327
#, python-format
msgid "subscription saved, %(email)s needs validation, see %(details_url)s"
msgstr ""
-"Your subscription is saved, but email address %(email)s needs to be "
-"validated, please see <a href='%(details_url)s'>more details here</a>"
-#: forum/views.py:1158
+#: forum/views.py:1103 forum/views/content.py:1335
msgid "email update frequency has been set to daily"
msgstr ""
-#: forum/views.py:2032
+#: forum/views.py:1980 forum/views.py:1984 forum/views/users.py:836
+#: forum/views/users.py:840
msgid "changes saved"
msgstr ""
-#: forum/views.py:2038
+#: forum/views.py:1990 forum/views/users.py:846
msgid "email updates canceled"
msgstr ""
-#: forum/views.py:2207
+#: forum/views.py:2157 forum/views/content.py:713
msgid "uploading images is limited to users with >60 reputation points"
-msgstr "sorry, file uploading requires karma >60"
+msgstr ""
-#: forum/views.py:2209
+#: forum/views.py:2159 forum/views/content.py:715
msgid "allowed file types are 'jpg', 'jpeg', 'gif', 'bmp', 'png', 'tiff'"
msgstr ""
-#: forum/views.py:2211
+#: forum/views.py:2161 forum/views/content.py:717
#, python-format
msgid "maximum upload file size is %sK"
msgstr ""
-#: forum/views.py:2213
+#: forum/views.py:2163 forum/views/content.py:719
#, python-format
msgid ""
"Error uploading file. Please contact the site administrator. Thank you. %s"
msgstr ""
-#: forum/management/commands/send_email_alerts.py:160
+#: forum/management/commands/send_email_alerts.py:156
msgid "email update message subject"
-msgstr "news from Q&A forum"
+msgstr ""
-#: forum/management/commands/send_email_alerts.py:161
+#: forum/management/commands/send_email_alerts.py:158
#, python-format
msgid "%(name)s, this is an update message header for a question"
msgid_plural "%(name)s, this is an update message header for %(num)d questions"
msgstr[0] ""
-"<p>Dear %(name)s,</p></p>The following question has been updated on the Q&A "
-"forum:</p>"
msgstr[1] ""
-"<p>Dear %(name)s,</p><p>The following %(num)d questions have been updated on "
-"the Q&A forum:</p>"
-#: forum/management/commands/send_email_alerts.py:172
+#: forum/management/commands/send_email_alerts.py:169
msgid "new question"
msgstr ""
-#: forum/management/commands/send_email_alerts.py:182
+#: forum/management/commands/send_email_alerts.py:179
#, python-format
msgid "There is also one question which was recently "
msgid_plural ""
@@ -1017,352 +854,291 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: forum/management/commands/send_email_alerts.py:187
+#: forum/management/commands/send_email_alerts.py:184
msgid ""
"Perhaps you could look up previously sent forum reminders in your mailbox."
msgstr ""
-#: forum/management/commands/send_email_alerts.py:191
+#: forum/management/commands/send_email_alerts.py:188
#, python-format
msgid ""
"go to %(link)s to change frequency of email updates or %(email)s "
"administrator"
msgstr ""
-"<p>Please remember that you can always <a href='%(link)s'>adjust</a> "
-"frequency of the email updates or turn them off entirely.<br/>If you believe "
-"that this message was sent in an error, please email about it the forum "
-"administrator at %(email)s.</p><p>Sincerely,</p><p>Your friendly Q&A forum "
-"server.</p>"
-
-#: forum/templatetags/extra_tags.py:163 forum/templatetags/extra_tags.py:192
-#: templates/header.html:33
-msgid "badges"
-msgstr ""
-
-#: forum/templatetags/extra_tags.py:164 forum/templatetags/extra_tags.py:191
-msgid "reputation points"
-msgstr "karma"
-
-#: forum/templatetags/extra_tags.py:247
-msgid "%b %d at %H:%M"
-msgstr ""
-#: forum/templatetags/extra_tags.py:249
-msgid "%b %d '%y at %H:%M"
-msgstr ""
-
-#: forum/templatetags/extra_tags.py:251
-msgid "2 days ago"
-msgstr ""
-
-#: forum/templatetags/extra_tags.py:253
-msgid "yesterday"
-msgstr ""
-
-#: forum/templatetags/extra_tags.py:255
-#, python-format
-msgid "%(hr)d hour ago"
-msgid_plural "%(hr)d hours ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: forum/templatetags/extra_tags.py:257
-#, python-format
-msgid "%(min)d min ago"
-msgid_plural "%(min)d mins ago"
-msgstr[0] ""
-msgstr[1] ""
-
-#: middleware/anon_user.py:33
-#, python-format
-msgid "first time greeting with %(url)s"
-msgstr ""
-
-#: templates/404.html:24
+#: forum/skins/default/templates/404.html:24
msgid "Sorry, could not find the page you requested."
msgstr ""
-#: templates/404.html:26
+#: forum/skins/default/templates/404.html:26
msgid "This might have happened for the following reasons:"
msgstr ""
-#: templates/404.html:28
+#: forum/skins/default/templates/404.html:28
msgid "this question or answer has been deleted;"
msgstr ""
-#: templates/404.html:29
+#: forum/skins/default/templates/404.html:29
msgid "url has error - please check it;"
msgstr ""
-#: templates/404.html:30
+#: forum/skins/default/templates/404.html:30
msgid ""
"the page you tried to visit is protected or you don't have sufficient "
"points, see"
msgstr ""
-#: templates/404.html:31
+#: forum/skins/default/templates/404.html:31
msgid "if you believe this error 404 should not have occured, please"
msgstr ""
-#: templates/404.html:32
+#: forum/skins/default/templates/404.html:32
msgid "report this problem"
msgstr ""
-#: templates/404.html:41 templates/500.html:27
+#: forum/skins/default/templates/404.html:41
+#: forum/skins/default/templates/500.html:27
msgid "back to previous page"
msgstr ""
-#: templates/404.html:42
+#: forum/skins/default/templates/404.html:42
msgid "see all questions"
msgstr ""
-#: templates/404.html:43
+#: forum/skins/default/templates/404.html:43
msgid "see all tags"
msgstr ""
-"<span class=\"strong big\">You are welcome to start submitting your question "
-"anonymously</span>. When you submit the post, you will be redirected to the "
-"login/signup page. Your question will be saved in the current session and "
-"will be published after you log in. Login/signup process is very simple. "
-"Login takes about 30 seconds, initial signup takes a minute or less."
-#: templates/500.html:22
+#: forum/skins/default/templates/500.html:22
msgid "sorry, system error"
msgstr ""
-#: templates/500.html:24
+#: forum/skins/default/templates/500.html:24
msgid "system error log is recorded, error will be fixed as soon as possible"
msgstr ""
-#: templates/500.html:25
+#: forum/skins/default/templates/500.html:25
msgid "please report the error to the site administrators if you wish"
msgstr ""
-#: templates/500.html:28
+#: forum/skins/default/templates/500.html:28
msgid "see latest questions"
msgstr ""
-"<span class='strong big'>Looks like your email address, %(email)s has not "
-"yet been validated.</span> To post messages you must verify your email, "
-"please see <a href='%(email_validation_faq_url)s'>more details here</a>."
-"<br>You can submit your question now and validate email after that. Your "
-"question will saved as pending meanwhile. "
-#: templates/500.html:29
+#: forum/skins/default/templates/500.html:29
msgid "see tags"
msgstr ""
-#: templates/about.html:6 templates/about.html.py:11
+#: forum/skins/default/templates/about.html:6
+#: forum/skins/default/templates/about.html:11
msgid "About"
msgstr ""
-#: templates/about.html:21
-msgid ""
-"<strong>CNPROG <span class=\"orange\">Q&amp;A</span></strong> is a "
-"collaboratively edited question\n"
-" and answer site created for the <strong>CNPROG</strong> "
-"community.\n"
-" "
-msgstr ""
-
-#: templates/about.html:25
-msgid ""
-"Here you can <strong>ask</strong> and <strong>answer</strong> questions, "
-"<strong>comment</strong>\n"
-" and <strong>vote</strong> for the questions of others and their answers. "
-"Both questions and answers\n"
-" <strong>can be revised</strong> and improved. Questions can be "
-"<strong>tagged</strong> with\n"
-" the relevant keywords to simplify future access and organize the "
-"accumulated material."
-msgstr ""
-
-#: templates/about.html:31
-msgid ""
-"This <span class=\"orange\">Q&amp;A</span> site is moderated by its members, "
-"hopefully - including yourself!\n"
-" Moderation rights are gradually assigned to the site users based on the "
-"accumulated <strong>\"reputation\"</strong>\n"
-" points. These points are added to the users account when others vote for "
-"his/her questions or answers.\n"
-" These points (very) roughly reflect the level of trust of the community."
-msgstr ""
-
-#: templates/answer_edit.html:5 templates/answer_edit.html.py:48
+#: forum/skins/default/templates/answer_edit.html:5
+#: forum/skins/default/templates/answer_edit.html:48
msgid "Edit answer"
msgstr ""
-#: templates/answer_edit.html:25 templates/answer_edit.html.py:28
-#: templates/ask.html:26 templates/ask.html.py:29 templates/question.html:45
-#: templates/question.html.py:48 templates/question_edit.html:25
-#: templates/question_edit.html.py:28
+#: forum/skins/default/templates/answer_edit.html:25
+#: forum/skins/default/templates/answer_edit.html:28
+#: forum/skins/default/templates/ask.html:26
+#: forum/skins/default/templates/ask.html:29
+#: forum/skins/default/templates/question.html:46
+#: forum/skins/default/templates/question.html:49
+#: forum/skins/default/templates/question.html:565
+#: forum/skins/default/templates/question.html:568
+#: forum/skins/default/templates/question_edit.html:25
+#: forum/skins/default/templates/question_edit.html:28
msgid "hide preview"
msgstr ""
-#: templates/answer_edit.html:28 templates/ask.html:29
-#: templates/question.html:48 templates/question_edit.html:28
+#: forum/skins/default/templates/answer_edit.html:28
+#: forum/skins/default/templates/ask.html:29
+#: forum/skins/default/templates/question.html:49
+#: forum/skins/default/templates/question.html:568
+#: forum/skins/default/templates/question_edit.html:28
msgid "show preview"
msgstr ""
-"If your questions and answers are highly voted, your contribution to this "
-"Q&amp;A community will be recognized with the variety of badges."
-#: templates/answer_edit.html:48 templates/question_edit.html:66
-#: templates/question_retag.html:53 templates/revisions_answer.html:38
-#: templates/revisions_question.html:38
+#: forum/skins/default/templates/answer_edit.html:48
+#: forum/skins/default/templates/question_edit.html:66
+#: forum/skins/default/templates/question_retag.html:53
+#: forum/skins/default/templates/revisions_answer.html:38
+#: forum/skins/default/templates/revisions_question.html:38
msgid "back"
msgstr ""
-#: templates/answer_edit.html:53 templates/question_edit.html:71
-#: templates/revisions_answer.html:52 templates/revisions_question.html:52
+#: forum/skins/default/templates/answer_edit.html:53
+#: forum/skins/default/templates/question_edit.html:71
+#: forum/skins/default/templates/revisions_answer.html:52
+#: forum/skins/default/templates/revisions_question.html:52
msgid "revision"
msgstr ""
-#: templates/answer_edit.html:56 templates/question_edit.html:75
+#: forum/skins/default/templates/answer_edit.html:56
+#: forum/skins/default/templates/question_edit.html:75
msgid "select revision"
msgstr ""
-#: templates/answer_edit.html:63 templates/ask.html:97
-#: templates/question.html:434 templates/question_edit.html:92
+#: forum/skins/default/templates/answer_edit.html:63
+#: forum/skins/default/templates/ask.html:97
+#: forum/skins/default/templates/question.html:443
+#: forum/skins/default/templates/question.html:952
+#: forum/skins/default/templates/question_edit.html:92
msgid "Toggle the real time Markdown editor preview"
msgstr ""
-#: templates/answer_edit.html:63 templates/ask.html:97
-#: templates/question.html:435 templates/question_edit.html:92
+#: forum/skins/default/templates/answer_edit.html:63
+#: forum/skins/default/templates/ask.html:97
+#: forum/skins/default/templates/question.html:444
+#: forum/skins/default/templates/question.html:953
+#: forum/skins/default/templates/question_edit.html:92
msgid "toggle preview"
msgstr ""
-#: templates/answer_edit.html:72 templates/question_edit.html:118
-#: templates/question_retag.html:74
+#: forum/skins/default/templates/answer_edit.html:72
+#: forum/skins/default/templates/question_edit.html:124
+#: forum/skins/default/templates/question_retag.html:74
msgid "Save edit"
msgstr ""
-#: templates/answer_edit.html:73 templates/close.html:29
-#: templates/feedback.html:50 templates/question_edit.html:119
-#: templates/question_retag.html:75 templates/reopen.html:30
-#: templates/user_edit.html:87 templates/authopenid/changeemail.html:40
+#: forum/skins/default/templates/answer_edit.html:73
+#: forum/skins/default/templates/close.html:29
+#: forum/skins/default/templates/feedback.html:50
+#: forum/skins/default/templates/question_edit.html:125
+#: forum/skins/default/templates/question_retag.html:75
+#: forum/skins/default/templates/reopen.html:30
+#: forum/skins/default/templates/user_edit.html:87
+#: forum/skins/default/templates/authopenid/changeemail.html:40
msgid "Cancel"
msgstr ""
-#: templates/answer_edit_tips.html:4
+#: forum/skins/default/templates/answer_edit_tips.html:4
msgid "answer tips"
-msgstr "Tips"
+msgstr ""
-#: templates/answer_edit_tips.html:7
+#: forum/skins/default/templates/answer_edit_tips.html:7
msgid "please make your answer relevant to this community"
msgstr ""
-#: templates/answer_edit_tips.html:10
+#: forum/skins/default/templates/answer_edit_tips.html:10
msgid "try to give an answer, rather than engage into a discussion"
msgstr ""
-#: templates/answer_edit_tips.html:13
+#: forum/skins/default/templates/answer_edit_tips.html:13
msgid "please try to provide details"
msgstr ""
-#: templates/answer_edit_tips.html:16 templates/question_edit_tips.html:13
+#: forum/skins/default/templates/answer_edit_tips.html:16
+#: forum/skins/default/templates/question_edit_tips.html:13
msgid "be clear and concise"
msgstr ""
-#: templates/answer_edit_tips.html:20 templates/question_edit_tips.html:17
+#: forum/skins/default/templates/answer_edit_tips.html:20
+#: forum/skins/default/templates/question_edit_tips.html:17
msgid "see frequently asked questions"
msgstr ""
-#: templates/answer_edit_tips.html:26 templates/question_edit_tips.html:23
+#: forum/skins/default/templates/answer_edit_tips.html:26
+#: forum/skins/default/templates/question_edit_tips.html:23
msgid "Markdown tips"
-msgstr "Markdown basics"
+msgstr ""
-#: templates/answer_edit_tips.html:29 templates/question_edit_tips.html:26
+#: forum/skins/default/templates/answer_edit_tips.html:29
+#: forum/skins/default/templates/question_edit_tips.html:26
msgid "*italic* or __italic__"
msgstr ""
-#: templates/answer_edit_tips.html:32 templates/question_edit_tips.html:29
+#: forum/skins/default/templates/answer_edit_tips.html:32
+#: forum/skins/default/templates/question_edit_tips.html:29
msgid "**bold** or __bold__"
msgstr ""
-#: templates/answer_edit_tips.html:35 templates/question_edit_tips.html:32
+#: forum/skins/default/templates/answer_edit_tips.html:35
+#: forum/skins/default/templates/question_edit_tips.html:32
msgid "link"
msgstr ""
-#: templates/answer_edit_tips.html:35 templates/answer_edit_tips.html.py:39
-#: templates/question_edit_tips.html:32 templates/question_edit_tips.html:37
+#: forum/skins/default/templates/answer_edit_tips.html:35
+#: forum/skins/default/templates/answer_edit_tips.html:39
+#: forum/skins/default/templates/question_edit_tips.html:32
+#: forum/skins/default/templates/question_edit_tips.html:37
msgid "text"
msgstr ""
-#: templates/answer_edit_tips.html:39 templates/question_edit_tips.html:37
+#: forum/skins/default/templates/answer_edit_tips.html:39
+#: forum/skins/default/templates/question_edit_tips.html:37
msgid "image"
msgstr ""
-#: templates/answer_edit_tips.html:43 templates/question_edit_tips.html:41
+#: forum/skins/default/templates/answer_edit_tips.html:43
+#: forum/skins/default/templates/question_edit_tips.html:41
msgid "numbered list:"
msgstr ""
-#: templates/answer_edit_tips.html:48 templates/question_edit_tips.html:46
+#: forum/skins/default/templates/answer_edit_tips.html:48
+#: forum/skins/default/templates/question_edit_tips.html:46
msgid "basic HTML tags are also supported"
msgstr ""
-#: templates/answer_edit_tips.html:52 templates/question_edit_tips.html:50
+#: forum/skins/default/templates/answer_edit_tips.html:52
+#: forum/skins/default/templates/question_edit_tips.html:50
msgid "learn more about Markdown"
msgstr ""
-#: templates/ask.html:5 templates/ask.html.py:61
+#: forum/skins/default/templates/ask.html:5
+#: forum/skins/default/templates/ask.html:61
msgid "Ask a question"
msgstr ""
-#: templates/ask.html:68
+#: forum/skins/default/templates/ask.html:68
msgid "login to post question info"
msgstr ""
-"<span class=\"strong big\">You are welcome to start submitting your question "
-"anonymously</span>. When you submit the post, you will be redirected to the "
-"login/signup page. Your question will be saved in the current session and "
-"will be published after you log in. Login/signup process is very simple. "
-"Login takes about 30 seconds, initial signup takes a minute or less."
-#: templates/ask.html:74
+#: forum/skins/default/templates/ask.html:74
#, python-format
msgid ""
"must have valid %(email)s to post, \n"
" see %(email_validation_faq_url)s\n"
" "
msgstr ""
-"<span class='strong big'>Looks like your email address, %(email)s has not "
-"yet been validated.</span> To post messages you must verify your email, "
-"please see <a href='%(email_validation_faq_url)s'>more details here</a>."
-"<br>You can submit your question now and validate email after that. Your "
-"question will saved as pending meanwhile. "
-#: templates/ask.html:112
+#: forum/skins/default/templates/ask.html:112
+#: forum/skins/default/templates/ask.html:119
+#: forum/skins/default/templates/question_edit.html:120
msgid "(required)"
msgstr ""
-#: templates/ask.html:119
+#: forum/skins/default/templates/ask.html:126
msgid "Login/signup to post your question"
-msgstr "Login/Signup to Post"
+msgstr ""
-#: templates/ask.html:121
+#: forum/skins/default/templates/ask.html:128
msgid "Ask your question"
-msgstr "Ask Your Question"
+msgstr ""
-#: templates/badge.html:6 templates/badge.html.py:17
+#: forum/skins/default/templates/badge.html:6
+#: forum/skins/default/templates/badge.html:17
msgid "Badge"
msgstr ""
-#: templates/badge.html:26
+#: forum/skins/default/templates/badge.html:26
msgid "The users have been awarded with badges:"
msgstr ""
-#: templates/badges.html:6
+#: forum/skins/default/templates/badges.html:6
msgid "Badges summary"
msgstr ""
-#: templates/badges.html:17
+#: forum/skins/default/templates/badges.html:17
msgid "Badges"
msgstr ""
-#: templates/badges.html:21
+#: forum/skins/default/templates/badges.html:21
msgid "Community gives you awards for your questions, answers and votes."
msgstr ""
-"If your questions and answers are highly voted, your contribution to this "
-"Q&amp;A community will be recognized with the variety of badges."
-#: templates/badges.html:22
+#: forum/skins/default/templates/badges.html:22
#, python-format
msgid ""
"Below is the list of available badges and number \n"
@@ -1370,233 +1146,228 @@ msgid ""
"(feedback_faq_url)s.\n"
" "
msgstr ""
-"Currently badges differ only by their level: <strong>gold</strong>, "
-"<strong>silver</strong> and <strong>bronze</strong> (their meanings are "
-"described on the right). In the future there will be many types of badges at "
-"each level. <strong>Please give us your <a href='%(feedback_faq_url)"
-"s'>feedback</a></strong> - what kinds of badges would you like to see and "
-"suggest the activity for which those badges might be awarded."
-#: templates/badges.html:50
+#: forum/skins/default/templates/badges.html:50
msgid "Community badges"
-msgstr "Badge levels"
+msgstr ""
-#: templates/badges.html:56
+#: forum/skins/default/templates/badges.html:56
msgid "gold badge description"
msgstr ""
-"Gold badge is the highest award in this community. To obtain it have to show "
-"profound knowledge and ability in addition to your active participation."
-#: templates/badges.html:64
+#: forum/skins/default/templates/badges.html:64
msgid "silver badge description"
msgstr ""
-"Obtaining silver badge requires significant patience. If you have received "
-"one, that means you have greatly contributed to this community."
-#: templates/badges.html:67
+#: forum/skins/default/templates/badges.html:67
msgid "bronze badge: often given as a special honor"
msgstr ""
-#: templates/badges.html:71
+#: forum/skins/default/templates/badges.html:71
msgid "bronze badge description"
msgstr ""
-"If you are an active participant in this community, you will be recognized "
-"with this badge."
-#: templates/book.html:7
+#: forum/skins/default/templates/book.html:7
msgid "reading channel"
msgstr ""
-#: templates/book.html:26
+#: forum/skins/default/templates/book.html:26
msgid "[author]"
msgstr ""
-#: templates/book.html:30
+#: forum/skins/default/templates/book.html:30
msgid "[publisher]"
msgstr ""
-#: templates/book.html:34
+#: forum/skins/default/templates/book.html:34
msgid "[publication date]"
msgstr ""
-#: templates/book.html:38
+#: forum/skins/default/templates/book.html:38
msgid "[price]"
msgstr ""
-#: templates/book.html:39
+#: forum/skins/default/templates/book.html:39
msgid "currency unit"
msgstr ""
-#: templates/book.html:42
+#: forum/skins/default/templates/book.html:42
msgid "[pages]"
msgstr ""
-#: templates/book.html:43
+#: forum/skins/default/templates/book.html:43
msgid "pages abbreviation"
msgstr ""
-#: templates/book.html:46
+#: forum/skins/default/templates/book.html:46
msgid "[tags]"
msgstr ""
-#: templates/book.html:56
+#: forum/skins/default/templates/book.html:56
msgid "author blog"
msgstr ""
-#: templates/book.html:62
+#: forum/skins/default/templates/book.html:62
msgid "book directory"
msgstr ""
-#: templates/book.html:66
+#: forum/skins/default/templates/book.html:66
msgid "buy online"
msgstr ""
-#: templates/book.html:79
+#: forum/skins/default/templates/book.html:79
msgid "reader questions"
msgstr ""
-#: templates/book.html:82
+#: forum/skins/default/templates/book.html:82
msgid "ask the author"
msgstr ""
-#: templates/book.html:88 templates/book.html.py:93
-#: templates/users_questions.html:18
+#: forum/skins/default/templates/book.html:88
+#: forum/skins/default/templates/book.html:93
+#: forum/skins/default/templates/users_questions.html:18
msgid "this question was selected as favorite"
msgstr ""
-#: templates/book.html:88 templates/book.html.py:93
-#: templates/users_questions.html:11 templates/users_questions.html.py:18
+#: forum/skins/default/templates/book.html:88
+#: forum/skins/default/templates/book.html:93
+#: forum/skins/default/templates/users_questions.html:11
+#: forum/skins/default/templates/users_questions.html:18
msgid "number of times"
msgstr ""
-#: templates/book.html:105 templates/index.html:49
-#: templates/question_summary_list_roll.html:14 templates/questions.html:80
-#: templates/unanswered.html:39 templates/users_questions.html:32
+#: forum/skins/default/templates/book.html:105
+#: forum/skins/default/templates/index.html:50
+#: forum/skins/default/templates/question_summary_list_roll.html:14
+#: forum/skins/default/templates/questions.html:85
+#: forum/skins/default/templates/questions.html:354
+#: forum/skins/default/templates/users_questions.html:32
+#: templates/unanswered.html:39
msgid "votes"
msgstr ""
-#: templates/book.html:108
+#: forum/skins/default/templates/book.html:108
msgid "the answer has been accepted to be correct"
msgstr ""
-#: templates/book.html:115 templates/index.html:50
-#: templates/question_summary_list_roll.html:15 templates/questions.html:81
-#: templates/unanswered.html:40 templates/users_questions.html:40
+#: forum/skins/default/templates/book.html:115
+#: forum/skins/default/templates/index.html:51
+#: forum/skins/default/templates/question_summary_list_roll.html:15
+#: forum/skins/default/templates/questions.html:86
+#: forum/skins/default/templates/questions.html:355
+#: forum/skins/default/templates/users_questions.html:40
+#: templates/unanswered.html:40
msgid "views"
msgstr ""
-#: templates/book.html:125 templates/index.html:105
-#: templates/question.html:480 templates/question_summary_list_roll.html:52
-#: templates/questions.html:136 templates/tags.html:49
+#: forum/skins/default/templates/book.html:125
+#: forum/skins/default/templates/index.html:106
+#: forum/skins/default/templates/question.html:489
+#: forum/skins/default/templates/question.html:998
+#: forum/skins/default/templates/question_summary_list_roll.html:52
+#: forum/skins/default/templates/questions.html:141
+#: forum/skins/default/templates/questions.html:258
+#: forum/skins/default/templates/questions.html:410
+#: forum/skins/default/templates/tags.html:49
+#: forum/skins/default/templates/users_questions.html:52
#: templates/unanswered.html:95 templates/unanswered.html.py:122
-#: templates/users_questions.html:52
msgid "using tags"
msgstr ""
-#: templates/book.html:147
+#: forum/skins/default/templates/book.html:147
msgid "subscribe to book RSS feed"
msgstr ""
-#: templates/book.html:147 templates/index.html:156
+#: forum/skins/default/templates/book.html:147
+#: forum/skins/default/templates/index.html:157
msgid "subscribe to the questions feed"
msgstr ""
-#: templates/close.html:6 templates/close.html.py:16
+#: forum/skins/default/templates/close.html:6
+#: forum/skins/default/templates/close.html:16
msgid "Close question"
msgstr ""
-#: templates/close.html:19
+#: forum/skins/default/templates/close.html:19
msgid "Close the question"
msgstr ""
-#: templates/close.html:25
+#: forum/skins/default/templates/close.html:25
msgid "Reasons"
msgstr ""
-#: templates/close.html:28
+#: forum/skins/default/templates/close.html:28
msgid "OK to close"
msgstr ""
-#: templates/faq.html:11
+#: forum/skins/default/templates/faq.html:11
msgid "Frequently Asked Questions "
msgstr ""
-#: templates/faq.html:16
+#: forum/skins/default/templates/faq.html:16
msgid "What kinds of questions can I ask here?"
msgstr ""
-#: templates/faq.html:17
+#: forum/skins/default/templates/faq.html:17
msgid ""
"Most importanly - questions should be <strong>relevant</strong> to this "
"community."
msgstr ""
-#: templates/faq.html:18
+#: forum/skins/default/templates/faq.html:18
msgid ""
"Before asking the question - please make sure to use search to see whether "
"your question has alredy been answered."
msgstr ""
-"Before you ask - please make sure to search for a similar question. You can "
-"search questions by their title or tags."
-#: templates/faq.html:21
+#: forum/skins/default/templates/faq.html:21
msgid "What questions should I avoid asking?"
-msgstr "What kinds of questions should be avoided?"
+msgstr ""
-#: templates/faq.html:22
+#: forum/skins/default/templates/faq.html:22
msgid ""
"Please avoid asking questions that are not relevant to this community, too "
"subjective and argumentative."
msgstr ""
-#: templates/faq.html:27
+#: forum/skins/default/templates/faq.html:27
msgid "What should I avoid in my answers?"
msgstr ""
-#: templates/faq.html:28
+#: forum/skins/default/templates/faq.html:28
msgid ""
"is a Q&A site, not a discussion group. Therefore - please avoid having "
"discussions in your answers, comment facility allows some space for brief "
"discussions."
msgstr ""
-"is a <strong>question and answer</strong> site - <strong>it is not a "
-"discussion group</strong>. Please avoid holding debates in your answers as "
-"they tend to dilute the essense of questions and answers. For the brief "
-"discussions please use commenting facility."
-#: templates/faq.html:32
+#: forum/skins/default/templates/faq.html:32
msgid "Who moderates this community?"
msgstr ""
-#: templates/faq.html:33
+#: forum/skins/default/templates/faq.html:33
msgid "The short answer is: <strong>you</strong>."
msgstr ""
-#: templates/faq.html:34
+#: forum/skins/default/templates/faq.html:34
msgid "This website is moderated by the users."
msgstr ""
-#: templates/faq.html:35
+#: forum/skins/default/templates/faq.html:35
msgid ""
"The reputation system allows users earn the authorization to perform a "
"variety of moderation tasks."
msgstr ""
-"Karma system allows users to earn rights to perform a variety of moderation "
-"tasks"
-#: templates/faq.html:40
+#: forum/skins/default/templates/faq.html:40
msgid "How does reputation system work?"
-msgstr "How does karma system work?"
+msgstr ""
-#: templates/faq.html:41
+#: forum/skins/default/templates/faq.html:41
msgid "Rep system summary"
msgstr ""
-"When a question or answer is upvoted, the user who posted them will gain "
-"some points, which are called \"karma points\". These points serve as a "
-"rough measure of the community trust to him/her. Various moderation tasks "
-"are gradually assigned to the users based on those points."
-#: templates/faq.html:42
+#: forum/skins/default/templates/faq.html:42
msgid ""
"For example, if you ask an interesting question or give a helpful answer, "
"your input will be upvoted. On the other hand if the answer is misleading - "
@@ -1607,150 +1378,134 @@ msgid ""
"type of moderation task."
msgstr ""
-#: templates/faq.html:53 templates/user_votes.html:15
+#: forum/skins/default/templates/faq.html:53
+#: forum/skins/default/templates/user_votes.html:15
msgid "upvote"
msgstr ""
-#: templates/faq.html:57
+#: forum/skins/default/templates/faq.html:57
msgid "use tags"
msgstr ""
-#: templates/faq.html:62
+#: forum/skins/default/templates/faq.html:62
msgid "add comments"
msgstr ""
-#: templates/faq.html:66 templates/user_votes.html:17
+#: forum/skins/default/templates/faq.html:66
+#: forum/skins/default/templates/user_votes.html:17
msgid "downvote"
msgstr ""
-#: templates/faq.html:69
+#: forum/skins/default/templates/faq.html:69
msgid "open and close own questions"
msgstr ""
-#: templates/faq.html:73
+#: forum/skins/default/templates/faq.html:73
msgid "retag questions"
msgstr ""
-#: templates/faq.html:78
+#: forum/skins/default/templates/faq.html:78
msgid "edit community wiki questions"
msgstr ""
-#: templates/faq.html:83
+#: forum/skins/default/templates/faq.html:83
msgid "edit any answer"
msgstr ""
-#: templates/faq.html:87
+#: forum/skins/default/templates/faq.html:87
msgid "open any closed question"
msgstr ""
-#: templates/faq.html:91
+#: forum/skins/default/templates/faq.html:91
msgid "delete any comment"
msgstr ""
-#: templates/faq.html:95
+#: forum/skins/default/templates/faq.html:95
msgid "delete any questions and answers and perform other moderation tasks"
msgstr ""
-#: templates/faq.html:102
+#: forum/skins/default/templates/faq.html:102
msgid "how to validate email title"
-msgstr "How to validate email and why?"
+msgstr ""
-#: templates/faq.html:104
+#: forum/skins/default/templates/faq.html:104
#, python-format
msgid ""
"how to validate email info with %(send_email_key_url)s %(gravatar_faq_url)s"
msgstr ""
-"<form style='margin:0;padding:0;' action='%(send_email_key_url)s'><p><span "
-"class=\"bigger strong\">How?</span> If you have just set or changed your "
-"email address - <strong>check your email and click the included link</"
-"strong>.<br>The link contains a key generated specifically for you. You can "
-"also <button style='display:inline' type='submit'><strong>get a new key</"
-"strong></button> and check your email again.</p></form><span class=\"bigger "
-"strong\">Why?</span> Email validation is required to make sure that "
-"<strong>only you can post messages</strong> on your behalf and to "
-"<strong>minimize spam</strong> posts.<br>With email you can "
-"<strong>subscribe for updates</strong> on the most interesting questions. "
-"Also, when you sign up for the first time - create a unique <a href='%"
-"(gravatar_faq_url)s'><strong>gravatar</strong></a> personal image.</p>"
-
-#: templates/faq.html:108
+
+#: forum/skins/default/templates/faq.html:108
msgid "what is gravatar"
-msgstr "What is gravatar?"
+msgstr ""
-#: templates/faq.html:109
+#: forum/skins/default/templates/faq.html:109
msgid "gravatar faq info"
msgstr ""
-"<strong>Gravatar</strong> means <strong>g</strong>lobally <strong>r</"
-"strong>ecognized <strong>avatar</strong> - your unique avatar image "
-"associated with your email address. It's simply a picture that shows next to "
-"your posts on the websites that support gravatar protocol. By default gravar "
-"appears as a square filled with a snowflake-like figure. You can <strong>set "
-"your image</strong> at <a href='http://gravatar.com'><strong>gravatar.com</"
-"strong></a>"
-#: templates/faq.html:112
+#: forum/skins/default/templates/faq.html:112
msgid "To register, do I need to create new password?"
msgstr ""
-#: templates/faq.html:113
+#: forum/skins/default/templates/faq.html:113
msgid ""
"No, you don't have to. You can login through any service that supports "
"OpenID, e.g. Google, Yahoo, AOL, etc."
msgstr ""
-#: templates/faq.html:114
+#: forum/skins/default/templates/faq.html:114
msgid "Login now!"
msgstr ""
-#: templates/faq.html:119
+#: forum/skins/default/templates/faq.html:119
msgid "Why other people can edit my questions/answers?"
msgstr ""
-#: templates/faq.html:120
+#: forum/skins/default/templates/faq.html:120
msgid "Goal of this site is..."
msgstr ""
-#: templates/faq.html:120
+#: forum/skins/default/templates/faq.html:120
msgid ""
"So questions and answers can be edited like wiki pages by experienced users "
"of this site and this improves the overall quality of the knowledge base "
"content."
msgstr ""
-#: templates/faq.html:121
+#: forum/skins/default/templates/faq.html:121
msgid "If this approach is not for you, we respect your choice."
msgstr ""
-#: templates/faq.html:125
+#: forum/skins/default/templates/faq.html:125
msgid "Still have questions?"
msgstr ""
-#: templates/faq.html:126
+#: forum/skins/default/templates/faq.html:126
#, python-format
msgid ""
"Please ask your question at %(ask_question_url)s, help make our community "
"better!"
msgstr ""
-"Please <a href='%(ask_question_url)s'>ask</a> your question, help make our "
-"community better!"
-#: templates/faq.html:128 templates/header.html:27 templates/header.html.py:61
+#: forum/skins/default/templates/faq.html:128
+#: forum/skins/default/templates/header.html:27
+#: forum/skins/default/templates/header.html:55
msgid "questions"
msgstr ""
-#: templates/faq.html:128 templates/index.html:161
+#: forum/skins/default/templates/faq.html:128
+#: forum/skins/default/templates/index.html:162
msgid "."
msgstr ""
-#: templates/feedback.html:6
+#: forum/skins/default/templates/feedback.html:6
msgid "Feedback"
msgstr ""
-#: templates/feedback.html:11
+#: forum/skins/default/templates/feedback.html:11
msgid "Give us your feedback!"
msgstr ""
-#: templates/feedback.html:17
+#: forum/skins/default/templates/feedback.html:17
#, python-format
msgid ""
"\n"
@@ -1760,7 +1515,7 @@ msgid ""
" "
msgstr ""
-#: templates/feedback.html:24
+#: forum/skins/default/templates/feedback.html:24
msgid ""
"\n"
" <span class='big strong'>Dear visitor</span>, we look forward to "
@@ -1769,255 +1524,284 @@ msgid ""
" "
msgstr ""
-#: templates/feedback.html:41
+#: forum/skins/default/templates/feedback.html:41
msgid "(this field is required)"
msgstr ""
-#: templates/feedback.html:49
+#: forum/skins/default/templates/feedback.html:49
msgid "Send Feedback"
msgstr ""
-#: templates/feedback_email.txt:3
-#, python-format
-msgid ""
-"\n"
-"Hello, this is a %(site_title)s forum feedback message\n"
-msgstr ""
-
-#: templates/feedback_email.txt:9
-msgid "Sender is"
-msgstr ""
-
-#: templates/feedback_email.txt:11 templates/feedback_email.txt.py:14
-msgid "email"
-msgstr ""
-
-#: templates/feedback_email.txt:13
-msgid "anonymous"
-msgstr ""
-
-#: templates/feedback_email.txt:19
-msgid "Message body:"
-msgstr ""
-
-#: templates/footer.html:8 templates/header.html:13 templates/index.html:119
+#: forum/skins/default/templates/footer.html:8
+#: forum/skins/default/templates/header.html:13
+#: forum/skins/default/templates/index.html:120
msgid "about"
msgstr ""
-#: templates/footer.html:9 templates/header.html:14 templates/index.html:120
-#: templates/question_edit_tips.html:17
+#: forum/skins/default/templates/footer.html:9
+#: forum/skins/default/templates/header.html:14
+#: forum/skins/default/templates/index.html:121
+#: forum/skins/default/templates/question_edit_tips.html:17
msgid "faq"
msgstr ""
-#: templates/footer.html:10
-msgid "blog"
-msgstr ""
-
-#: templates/footer.html:11
-msgid "contact us"
-msgstr ""
-
-#: templates/footer.html:12
+#: forum/skins/default/templates/footer.html:10
msgid "privacy policy"
msgstr ""
-#: templates/footer.html:21
+#: forum/skins/default/templates/footer.html:19
msgid "give feedback"
msgstr ""
-#: templates/header.html:9
+#: forum/skins/default/templates/header.html:9
msgid "logout"
msgstr ""
-#: templates/header.html:11
+#: forum/skins/default/templates/header.html:11
msgid "login"
msgstr ""
-#: templates/header.html:21
+#: forum/skins/default/templates/header.html:21
msgid "back to home page"
msgstr ""
-#: templates/header.html:29 templates/header.html.py:63
+#: forum/skins/default/templates/header.html:29
+#: forum/skins/default/templates/header.html:57
msgid "users"
msgstr ""
-#: templates/header.html:31
+#: forum/skins/default/templates/header.html:31
msgid "books"
msgstr ""
-#: templates/header.html:34
-msgid "unanswered questions"
-msgstr "unanswered"
+#: forum/skins/default/templates/header.html:33
+#: forum/templatetags/extra_tags.py:165 forum/templatetags/extra_tags.py:194
+msgid "badges"
+msgstr ""
-#: templates/header.html:38
-msgid "my profile"
+#: forum/skins/default/templates/header.html:34
+msgid "unanswered questions"
msgstr ""
-#: templates/header.html:42
+#: forum/skins/default/templates/header.html:36
msgid "ask a question"
msgstr ""
-#: templates/header.html:57
+#: forum/skins/default/templates/header.html:51
msgid "search"
msgstr ""
-#: templates/index.html:8
+#: forum/skins/default/templates/index.html:8
msgid "Home"
msgstr ""
-#: templates/index.html:25 templates/questions.html:8
+#: forum/skins/default/templates/index.html:25
+#: forum/skins/default/templates/questions.html:9
+#: forum/skins/default/templates/questions.html:282
msgid "Questions"
msgstr ""
-#: templates/index.html:27
+#: forum/skins/default/templates/index.html:27
msgid "last updated questions"
msgstr ""
-#: templates/index.html:27 templates/questions.html:47
+#: forum/skins/default/templates/index.html:27
+#: forum/skins/default/templates/questions.html:52
+#: forum/skins/default/templates/questions.html:321
#: templates/unanswered.html:21
msgid "newest"
msgstr ""
-#: templates/index.html:28 templates/questions.html:49
+#: forum/skins/default/templates/index.html:28
+#: forum/skins/default/templates/questions.html:53
+#: forum/skins/default/templates/questions.html:322
+msgid "most recently updated questions"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:28
+#: forum/skins/default/templates/questions.html:53
+#: forum/skins/default/templates/questions.html:322
+msgid "active"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:29
+#: forum/skins/default/templates/questions.html:54
+#: forum/skins/default/templates/questions.html:323
msgid "hottest questions"
msgstr ""
-#: templates/index.html:28 templates/questions.html:49
+#: forum/skins/default/templates/index.html:29
+#: forum/skins/default/templates/questions.html:54
+#: forum/skins/default/templates/questions.html:323
msgid "hottest"
msgstr ""
-#: templates/index.html:29 templates/questions.html:50
+#: forum/skins/default/templates/index.html:30
+#: forum/skins/default/templates/questions.html:55
+#: forum/skins/default/templates/questions.html:324
msgid "most voted questions"
msgstr ""
-#: templates/index.html:29 templates/questions.html:50
+#: forum/skins/default/templates/index.html:30
+#: forum/skins/default/templates/questions.html:55
+#: forum/skins/default/templates/questions.html:324
msgid "most voted"
msgstr ""
-#: templates/index.html:30
+#: forum/skins/default/templates/index.html:31
msgid "all questions"
msgstr ""
-#: templates/index.html:48 templates/question_summary_list_roll.html:13
-#: templates/questions.html:79 templates/unanswered.html:38
-#: templates/users_questions.html:36
+#: forum/skins/default/templates/index.html:49
+#: forum/skins/default/templates/question_summary_list_roll.html:13
+#: forum/skins/default/templates/questions.html:84
+#: forum/skins/default/templates/questions.html:353
+#: forum/skins/default/templates/users_questions.html:36
+#: templates/unanswered.html:38
msgid "answers"
msgstr ""
-#: templates/index.html:80 templates/index.html.py:94
-#: templates/questions.html:111 templates/questions.html.py:125
+#: forum/skins/default/templates/index.html:81
+#: forum/skins/default/templates/index.html:95
+#: forum/skins/default/templates/questions.html:116
+#: forum/skins/default/templates/questions.html:130
+#: forum/skins/default/templates/questions.html:385
+#: forum/skins/default/templates/questions.html:399
#: templates/unanswered.html:70 templates/unanswered.html.py:84
msgid "Posted:"
msgstr ""
-#: templates/index.html:83 templates/index.html.py:88
-#: templates/questions.html:114 templates/questions.html.py:119
+#: forum/skins/default/templates/index.html:84
+#: forum/skins/default/templates/index.html:89
+#: forum/skins/default/templates/questions.html:119
+#: forum/skins/default/templates/questions.html:124
+#: forum/skins/default/templates/questions.html:388
+#: forum/skins/default/templates/questions.html:393
#: templates/unanswered.html:73 templates/unanswered.html.py:78
msgid "Updated:"
msgstr ""
-#: templates/index.html:105 templates/question.html:480
-#: templates/question_summary_list_roll.html:52 templates/questions.html:136
-#: templates/tags.html:49 templates/unanswered.html:95
-#: templates/unanswered.html.py:122 templates/users_questions.html:52
+#: forum/skins/default/templates/index.html:106
+#: forum/skins/default/templates/question.html:489
+#: forum/skins/default/templates/question.html:998
+#: forum/skins/default/templates/question_summary_list_roll.html:52
+#: forum/skins/default/templates/questions.html:141
+#: forum/skins/default/templates/questions.html:258
+#: forum/skins/default/templates/questions.html:410
+#: forum/skins/default/templates/tags.html:49
+#: forum/skins/default/templates/users_questions.html:52
+#: templates/unanswered.html:95 templates/unanswered.html.py:122
msgid "see questions tagged"
msgstr ""
-#: templates/index.html:116
+#: forum/skins/default/templates/index.html:117
msgid "welcome to website"
-msgstr "Welcome to Q&amp;A forum"
+msgstr ""
-#: templates/index.html:127
+#: forum/skins/default/templates/index.html:128
msgid "Recent tags"
msgstr ""
-#: templates/index.html:132 templates/question.html:135
+#: forum/skins/default/templates/index.html:133
+#: forum/skins/default/templates/question.html:136
+#: forum/skins/default/templates/question.html:653
#, python-format
msgid "see questions tagged '%(tagname)s'"
msgstr ""
-#: templates/index.html:135 templates/index.html.py:161
+#: forum/skins/default/templates/index.html:136
+#: forum/skins/default/templates/index.html:162
msgid "popular tags"
-msgstr "tags"
+msgstr ""
-#: templates/index.html:140
+#: forum/skins/default/templates/index.html:141
msgid "Recent awards"
-msgstr "Recent badges"
+msgstr ""
-#: templates/index.html:146
+#: forum/skins/default/templates/index.html:147
msgid "given to"
msgstr ""
-#: templates/index.html:151
+#: forum/skins/default/templates/index.html:152
msgid "all awards"
-msgstr "all badges"
+msgstr ""
-#: templates/index.html:156
+#: forum/skins/default/templates/index.html:157
msgid "subscribe to last 30 questions by RSS"
msgstr ""
-#: templates/index.html:161
+#: forum/skins/default/templates/index.html:162
msgid "Still looking for more? See"
msgstr ""
-#: templates/index.html:161
+#: forum/skins/default/templates/index.html:162
msgid "complete list of questions"
-msgstr "list of all questions"
+msgstr ""
-#: templates/index.html:161 templates/authopenid/signup.html:18
+#: forum/skins/default/templates/index.html:162
+#: forum/skins/default/templates/authopenid/signup.html:28
msgid "or"
msgstr ""
-#: templates/index.html:161
+#: forum/skins/default/templates/index.html:162
msgid "Please help us answer"
msgstr ""
-#: templates/index.html:161
+#: forum/skins/default/templates/index.html:162
msgid "list of unanswered questions"
-msgstr "unanswered questions"
+msgstr ""
-#: templates/logout.html:6 templates/logout.html.py:16
+#: forum/skins/default/templates/logout.html:6
+#: forum/skins/default/templates/logout.html:16
msgid "Logout"
msgstr ""
-#: templates/logout.html:19
+#: forum/skins/default/templates/logout.html:19
msgid ""
"As a registered user you can login with your OpenID, log out of the site or "
"permanently remove your account."
msgstr ""
-"Clicking <strong>Logout</strong> will log you out from the forumbut will not "
-"sign you off from your OpenID provider.</p><p>If you wish to sign off "
-"completely - please make sure to log out from your OpenID provider as well."
-#: templates/logout.html:20
+#: forum/skins/default/templates/logout.html:20
msgid "Logout now"
-msgstr "Logout Now"
+msgstr ""
-#: templates/pagesize.html:6
+#: forum/skins/default/templates/notarobot.html:3
+msgid "Please prove that you are a Human Being"
+msgstr ""
+
+#: forum/skins/default/templates/notarobot.html:10
+msgid "I am a Human Being"
+msgstr ""
+
+#: forum/skins/default/templates/pagesize.html:6
msgid "posts per page"
msgstr ""
-#: templates/paginator.html:6 templates/paginator.html.py:7
+#: forum/skins/default/templates/paginator.html:6
+#: forum/skins/default/templates/paginator.html:7
msgid "previous"
msgstr ""
-#: templates/paginator.html:19
+#: forum/skins/default/templates/paginator.html:19
msgid "current page"
msgstr ""
-#: templates/paginator.html:22 templates/paginator.html.py:29
+#: forum/skins/default/templates/paginator.html:22
+#: forum/skins/default/templates/paginator.html:29
msgid "page number "
msgstr ""
-#: templates/paginator.html:22 templates/paginator.html.py:29
+#: forum/skins/default/templates/paginator.html:22
+#: forum/skins/default/templates/paginator.html:29
msgid "number - make blank in english"
msgstr ""
-#: templates/paginator.html:33
+#: forum/skins/default/templates/paginator.html:33
msgid "next page"
msgstr ""
-#: templates/post_contributor_info.html:9
+#: forum/skins/default/templates/post_contributor_info.html:9
#, python-format
msgid ""
"\n"
@@ -2030,141 +1814,170 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/post_contributor_info.html:19
+#: forum/skins/default/templates/post_contributor_info.html:19
msgid "asked"
msgstr ""
-#: templates/post_contributor_info.html:22
+#: forum/skins/default/templates/post_contributor_info.html:22
msgid "answered"
msgstr ""
-#: templates/post_contributor_info.html:24
+#: forum/skins/default/templates/post_contributor_info.html:24
msgid "posted"
msgstr ""
-#: templates/post_contributor_info.html:45
+#: forum/skins/default/templates/post_contributor_info.html:45
msgid "updated"
msgstr ""
-#: templates/privacy.html:6 templates/privacy.html.py:11
+#: forum/skins/default/templates/privacy.html:6
+#: forum/skins/default/templates/privacy.html:11
msgid "Privacy policy"
msgstr ""
-#: templates/privacy.html:15
+#: forum/skins/default/templates/privacy.html:15
msgid "general message about privacy"
msgstr ""
-"Respecting users privacy is an important core principle of this Q&amp;A "
-"forum. Information on this page details how this forum protects your "
-"privacy, and what type of information is collected."
-#: templates/privacy.html:18
+#: forum/skins/default/templates/privacy.html:18
msgid "Site Visitors"
msgstr ""
-#: templates/privacy.html:20
+#: forum/skins/default/templates/privacy.html:20
msgid "what technical information is collected about visitors"
msgstr ""
-"Information on question views, revisions of questions and answers - both "
-"times and content are recorded for each user in order to correctly count "
-"number of views, maintain data integrity and report relevant updates."
-#: templates/privacy.html:23
+#: forum/skins/default/templates/privacy.html:23
msgid "Personal Information"
msgstr ""
-#: templates/privacy.html:25
+#: forum/skins/default/templates/privacy.html:25
msgid "details on personal information policies"
msgstr ""
-"Members of this community may choose to display personally identifiable "
-"information in their profiles. Forum will never display such information "
-"without a request from the user."
-#: templates/privacy.html:28
+#: forum/skins/default/templates/privacy.html:28
msgid "Other Services"
msgstr ""
-#: templates/privacy.html:30
+#: forum/skins/default/templates/privacy.html:30
msgid "details on sharing data with third parties"
msgstr ""
-"None of the data that is not openly shown on the forum by the choice of the "
-"user is shared with any third party."
-#: templates/privacy.html:35
+#: forum/skins/default/templates/privacy.html:35
msgid "cookie policy details"
msgstr ""
-"Forum software relies on the internet cookie technology to keep track of "
-"user sessions. Cookies must be enabled in your browser so that forum can "
-"work for you."
-#: templates/privacy.html:37
+#: forum/skins/default/templates/privacy.html:37
msgid "Policy Changes"
msgstr ""
-#: templates/privacy.html:38
+#: forum/skins/default/templates/privacy.html:38
msgid "how privacy policies can be changed"
msgstr ""
-"These policies may be adjusted to improve protection of user's privacy. "
-"Whenever such changes occur, users will be notified via the internal "
-"messaging system. "
-#: templates/question.html:77 templates/question.html.py:78
-#: templates/question.html:94 templates/question.html.py:96
+#: forum/skins/default/templates/question.html:78
+#: forum/skins/default/templates/question.html:79
+#: forum/skins/default/templates/question.html:95
+#: forum/skins/default/templates/question.html:97
+#: forum/skins/default/templates/question.html:597
+#: forum/skins/default/templates/question.html:598
+#: forum/skins/default/templates/question.html:614
+#: forum/skins/default/templates/question.html:616
msgid "i like this post (click again to cancel)"
msgstr ""
-#: templates/question.html:80 templates/question.html.py:98
-#: templates/question.html:257
+#: forum/skins/default/templates/question.html:81
+#: forum/skins/default/templates/question.html:99
+#: forum/skins/default/templates/question.html:258
+#: forum/skins/default/templates/question.html:600
+#: forum/skins/default/templates/question.html:618
+#: forum/skins/default/templates/question.html:775
msgid "current number of votes"
msgstr ""
-#: templates/question.html:89 templates/question.html.py:90
-#: templates/question.html:103 templates/question.html.py:104
+#: forum/skins/default/templates/question.html:90
+#: forum/skins/default/templates/question.html:91
+#: forum/skins/default/templates/question.html:104
+#: forum/skins/default/templates/question.html:105
+#: forum/skins/default/templates/question.html:609
+#: forum/skins/default/templates/question.html:610
+#: forum/skins/default/templates/question.html:623
+#: forum/skins/default/templates/question.html:624
msgid "i dont like this post (click again to cancel)"
msgstr ""
-#: templates/question.html:109 templates/question.html.py:110
+#: forum/skins/default/templates/question.html:110
+#: forum/skins/default/templates/question.html:111
+#: forum/skins/default/templates/question.html:628
+#: forum/skins/default/templates/question.html:629
msgid "mark this question as favorite (click again to cancel)"
msgstr ""
-#: templates/question.html:116 templates/question.html.py:117
+#: forum/skins/default/templates/question.html:117
+#: forum/skins/default/templates/question.html:118
+#: forum/skins/default/templates/question.html:635
+#: forum/skins/default/templates/question.html:636
msgid "remove favorite mark from this question (click again to restore mark)"
msgstr ""
-#: templates/question.html:140 templates/question.html.py:294
-#: templates/revisions_answer.html:58 templates/revisions_question.html:58
+#: forum/skins/default/templates/question.html:141
+#: forum/skins/default/templates/question.html:295
+#: forum/skins/default/templates/question.html:658
+#: forum/skins/default/templates/question.html:812
+#: forum/skins/default/templates/revisions_answer.html:58
+#: forum/skins/default/templates/revisions_question.html:58
msgid "edit"
msgstr ""
-#: templates/question.html:145
+#: forum/skins/default/templates/question.html:146
+#: forum/skins/default/templates/question.html:663
msgid "reopen"
msgstr ""
-#: templates/question.html:149
+#: forum/skins/default/templates/question.html:150
+#: forum/skins/default/templates/question.html:667
msgid "close"
msgstr ""
-#: templates/question.html:155 templates/question.html.py:299
+#: forum/skins/default/templates/question.html:156
+#: forum/skins/default/templates/question.html:301
+#: forum/skins/default/templates/question.html:673
+#: forum/skins/default/templates/question.html:817
msgid ""
"report as offensive (i.e containing spam, advertising, malicious text, etc.)"
msgstr ""
-#: templates/question.html:156 templates/question.html.py:300
+#: forum/skins/default/templates/question.html:157
+#: forum/skins/default/templates/question.html:302
+#: forum/skins/default/templates/question.html:674
+#: forum/skins/default/templates/question.html:818
msgid "flag offensive"
msgstr ""
-#: templates/question.html:164 templates/question.html.py:311
+#: forum/skins/default/templates/question.html:165
+#: forum/skins/default/templates/question.html:313
+#: forum/skins/default/templates/question.html:682
+#: forum/skins/default/templates/question.html:829
msgid "delete"
msgstr ""
-#: templates/question.html:182 templates/question.html.py:331
+#: forum/skins/default/templates/question.html:183
+#: forum/skins/default/templates/question.html:333
+#: forum/skins/default/templates/question.html:700
+#: forum/skins/default/templates/question.html:849
msgid "delete this comment"
msgstr ""
-#: templates/question.html:193 templates/question.html.py:342
+#: forum/skins/default/templates/question.html:194
+#: forum/skins/default/templates/question.html:344
+#: forum/skins/default/templates/question.html:368
+#: forum/skins/default/templates/question.html:711
+#: forum/skins/default/templates/question.html:860
msgid "add comment"
-msgstr "post a comment"
+msgstr ""
-#: templates/question.html:197
+#: forum/skins/default/templates/question.html:198
+#: forum/skins/default/templates/question.html:715
#, python-format
msgid ""
"\n"
@@ -2178,7 +1991,8 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/question.html:203
+#: forum/skins/default/templates/question.html:204
+#: forum/skins/default/templates/question.html:721
#, python-format
msgid ""
"\n"
@@ -2193,18 +2007,21 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/question.html:219
+#: forum/skins/default/templates/question.html:220
+#: forum/skins/default/templates/question.html:737
#, python-format
msgid ""
"The question has been closed for the following reason \"%(close_reason)s\" by"
msgstr ""
-#: templates/question.html:221
+#: forum/skins/default/templates/question.html:222
+#: forum/skins/default/templates/question.html:739
#, python-format
msgid "close date %(closed_at)s"
msgstr ""
-#: templates/question.html:229
+#: forum/skins/default/templates/question.html:230
+#: forum/skins/default/templates/question.html:747
#, python-format
msgid ""
"\n"
@@ -2217,59 +2034,81 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/question.html:237
+#: forum/skins/default/templates/question.html:238
+#: forum/skins/default/templates/question.html:755
msgid "oldest answers will be shown first"
msgstr ""
-#: templates/question.html:237
+#: forum/skins/default/templates/question.html:238
+#: forum/skins/default/templates/question.html:755
msgid "oldest answers"
-msgstr "oldest"
+msgstr ""
-#: templates/question.html:239
+#: forum/skins/default/templates/question.html:240
+#: forum/skins/default/templates/question.html:757
msgid "newest answers will be shown first"
msgstr ""
-#: templates/question.html:239
+#: forum/skins/default/templates/question.html:240
+#: forum/skins/default/templates/question.html:757
msgid "newest answers"
-msgstr "newest"
+msgstr ""
-#: templates/question.html:241
+#: forum/skins/default/templates/question.html:242
+#: forum/skins/default/templates/question.html:759
msgid "most voted answers will be shown first"
msgstr ""
-#: templates/question.html:241
+#: forum/skins/default/templates/question.html:242
+#: forum/skins/default/templates/question.html:759
msgid "popular answers"
-msgstr "most voted"
+msgstr ""
-#: templates/question.html:255 templates/question.html.py:256
+#: forum/skins/default/templates/question.html:256
+#: forum/skins/default/templates/question.html:257
+#: forum/skins/default/templates/question.html:773
+#: forum/skins/default/templates/question.html:774
msgid "i like this answer (click again to cancel)"
msgstr ""
-#: templates/question.html:262 templates/question.html.py:263
+#: forum/skins/default/templates/question.html:263
+#: forum/skins/default/templates/question.html:264
+#: forum/skins/default/templates/question.html:780
+#: forum/skins/default/templates/question.html:781
msgid "i dont like this answer (click again to cancel)"
msgstr ""
-#: templates/question.html:268 templates/question.html.py:269
+#: forum/skins/default/templates/question.html:269
+#: forum/skins/default/templates/question.html:270
+#: forum/skins/default/templates/question.html:786
+#: forum/skins/default/templates/question.html:787
msgid "mark this answer as favorite (click again to undo)"
msgstr ""
-#: templates/question.html:274 templates/question.html.py:275
+#: forum/skins/default/templates/question.html:275
+#: forum/skins/default/templates/question.html:276
+#: forum/skins/default/templates/question.html:792
+#: forum/skins/default/templates/question.html:793
msgid "the author of the question has selected this answer as correct"
msgstr ""
-#: templates/question.html:288
+#: forum/skins/default/templates/question.html:289
+#: forum/skins/default/templates/question.html:806
msgid "answer permanent link"
msgstr ""
-#: templates/question.html:289
+#: forum/skins/default/templates/question.html:290
+#: forum/skins/default/templates/question.html:807
msgid "permanent link"
-msgstr "link"
+msgstr ""
-#: templates/question.html:311
+#: forum/skins/default/templates/question.html:313
+#: forum/skins/default/templates/question.html:829
msgid "undelete"
msgstr ""
-#: templates/question.html:346
+#: forum/skins/default/templates/question.html:348
+#: forum/skins/default/templates/question.html:864
#, python-format
msgid ""
"\n"
@@ -2284,7 +2123,8 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/question.html:352
+#: forum/skins/default/templates/question.html:354
+#: forum/skins/default/templates/question.html:870
#, python-format
msgid ""
"\n"
@@ -2299,18 +2139,24 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/question.html:378 templates/question.html.py:381
+#: forum/skins/default/templates/question.html:367
+msgid "comments"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:387
+#: forum/skins/default/templates/question.html:390
+#: forum/skins/default/templates/question.html:896
+#: forum/skins/default/templates/question.html:899
msgid "Notify me once a day when there are any new answers"
msgstr ""
-"<strong>Notify me</strong> once a day by email when there are any new "
-"answers or updates"
-#: templates/question.html:384
+#: forum/skins/default/templates/question.html:393
+#: forum/skins/default/templates/question.html:902
msgid "Notify me weekly when there are any new answers"
msgstr ""
-"<strong>Notify me</strong> weekly when there are any new answers or updates"
-#: templates/question.html:389
+#: forum/skins/default/templates/question.html:398
+#: forum/skins/default/templates/question.html:907
#, python-format
msgid ""
"\n"
@@ -2318,171 +2164,215 @@ msgid ""
"(profile_url)s\n"
" "
msgstr ""
-"\n"
-"(note: you can always <a href='%(profile_url)s?"
-"sort=email_subscriptions'>adjust frequency</a> of email updates)"
-#: templates/question.html:396
+#: forum/skins/default/templates/question.html:405
+#: forum/skins/default/templates/question.html:914
msgid "once you sign in you will be able to subscribe for any updates here"
msgstr ""
-"<span class='strong'>Here</span> (once you log in) you will be able to sign "
-"up for the periodic email updates about this question."
-#: templates/question.html:407
+#: forum/skins/default/templates/question.html:416
+#: forum/skins/default/templates/question.html:925
msgid "Your answer"
msgstr ""
-#: templates/question.html:409
+#: forum/skins/default/templates/question.html:418
+#: forum/skins/default/templates/question.html:927
msgid "Be the first one to answer this question!"
msgstr ""
-#: templates/question.html:415
+#: forum/skins/default/templates/question.html:424
+#: forum/skins/default/templates/question.html:933
msgid "you can answer anonymously and then login"
msgstr ""
-"<span class='strong big'>Please start posting your answer anonymously</span> "
-"- your answer will be saved within the current session and published after "
-"you log in or create a new account. Please try to give a <strong>substantial "
-"answer</strong>, for discussions, <strong>please use comments</strong> and "
-"<strong>please do remember to vote</strong> (after you log in)!"
-#: templates/question.html:419
+#: forum/skins/default/templates/question.html:428
+#: forum/skins/default/templates/question.html:937
msgid "answer your own question only to give an answer"
msgstr ""
-"<span class='big strong'>You are welcome to answer your own question</span>, "
-"but please make sure to give an <strong>answer</strong>. Remember that you "
-"can always <strong>revise your original question</strong>. Please "
-"<strong>use comments for discussions</strong> and <strong>please don't "
-"forget to vote :)</strong> for the answers that you liked (or perhaps did "
-"not like)! "
-#: templates/question.html:421
+#: forum/skins/default/templates/question.html:430
+#: forum/skins/default/templates/question.html:939
msgid "please only give an answer, no discussions"
msgstr ""
-"<span class='big strong'>Please try to give a substantial answer</span>. If "
-"you wanted to comment on the question or answer, just <strong>use the "
-"commenting tool</strong>. Please remember that you can always <strong>revise "
-"your answers</strong> - no need to answer the same question twice. Also, "
-"please <strong>don't forget to vote</strong> - it really helps to select the "
-"best questions and answers!"
-#: templates/question.html:457
+#: forum/skins/default/templates/question.html:466
+#: forum/skins/default/templates/question.html:975
msgid "Login/Signup to Post Your Answer"
msgstr ""
-#: templates/question.html:460
+#: forum/skins/default/templates/question.html:469
+#: forum/skins/default/templates/question.html:978
msgid "Answer Your Own Question"
msgstr ""
-#: templates/question.html:462
+#: forum/skins/default/templates/question.html:471
+#: forum/skins/default/templates/question.html:980
msgid "Answer the question"
-msgstr "Post Your Answer"
+msgstr ""
-#: templates/question.html:475
+#: forum/skins/default/templates/question.html:484
+#: forum/skins/default/templates/question.html:993
msgid "Question tags"
-msgstr "Tags"
+msgstr ""
-#: templates/question.html:485
+#: forum/skins/default/templates/question.html:494
+#: forum/skins/default/templates/question.html:1003
msgid "question asked"
-msgstr "Asked"
+msgstr ""
-#: templates/question.html:488
+#: forum/skins/default/templates/question.html:497
+#: forum/skins/default/templates/question.html:1006
msgid "question was seen"
-msgstr "Seen"
+msgstr ""
-#: templates/question.html:488
+#: forum/skins/default/templates/question.html:497
+#: forum/skins/default/templates/question.html:1006
msgid "times"
msgstr ""
-#: templates/question.html:491
+#: forum/skins/default/templates/question.html:500
+#: forum/skins/default/templates/question.html:1009
msgid "last updated"
-msgstr "Last updated"
+msgstr ""
-#: templates/question.html:496
+#: forum/skins/default/templates/question.html:505
+#: forum/skins/default/templates/question.html:1014
msgid "Related questions"
msgstr ""
-#: templates/question_edit.html:5 templates/question_edit.html.py:66
+#: forum/skins/default/templates/question_edit.html:5
+#: forum/skins/default/templates/question_edit.html:66
msgid "Edit question"
msgstr ""
-#: templates/question_edit_tips.html:4
+#: forum/skins/default/templates/question_edit_tips.html:4
msgid "question tips"
-msgstr "Tips"
+msgstr ""
-#: templates/question_edit_tips.html:7
+#: forum/skins/default/templates/question_edit_tips.html:7
msgid "please ask a relevant question"
-msgstr "ask a question relevant to the CNPROG community"
+msgstr ""
-#: templates/question_edit_tips.html:10
+#: forum/skins/default/templates/question_edit_tips.html:10
msgid "please try provide enough details"
-msgstr "provide enough details"
+msgstr ""
-#: templates/question_retag.html:4 templates/question_retag.html.py:53
+#: forum/skins/default/templates/question_retag.html:4
+#: forum/skins/default/templates/question_retag.html:53
msgid "Change tags"
msgstr ""
-#: templates/question_retag.html:40
+#: forum/skins/default/templates/question_retag.html:40
msgid "up to 5 tags, less than 20 characters each"
msgstr ""
-#: templates/question_retag.html:83
+#: forum/skins/default/templates/question_retag.html:83
msgid "Why use and modify tags?"
msgstr ""
-#: templates/question_retag.html:86
+#: forum/skins/default/templates/question_retag.html:86
msgid "tags help us keep Questions organized"
msgstr ""
-#: templates/question_retag.html:94
+#: forum/skins/default/templates/question_retag.html:94
msgid "tag editors receive special awards from the community"
msgstr ""
-#: templates/questions.html:29
+#: forum/skins/default/templates/questions.html:29
+#: forum/skins/default/templates/questions.html:33
+#: forum/skins/default/templates/questions.html:303
msgid "Found by tags"
-msgstr "Tagged questions"
-
-#: templates/questions.html:33
-msgid "Search results"
msgstr ""
-#: templates/questions.html:35
+#: forum/skins/default/templates/questions.html:29
+#: forum/skins/default/templates/questions.html:39
+#: forum/skins/default/templates/questions.html:309
msgid "Found by title"
msgstr ""
-#: templates/questions.html:39 templates/unanswered.html:8
-#: templates/unanswered.html.py:19
-msgid "Unanswered questions"
+#: forum/skins/default/templates/questions.html:29
+#: forum/skins/default/templates/questions.html:45
+#: forum/skins/default/templates/questions.html:315
+msgid "All questions"
msgstr ""
-#: templates/questions.html:41
-msgid "All questions"
+#: forum/skins/default/templates/questions.html:37
+#: forum/skins/default/templates/questions.html:307
+msgid "Search results"
msgstr ""
-#: templates/questions.html:47 templates/unanswered.html:21
-msgid "most recently asked questions"
+#: forum/skins/default/templates/questions.html:43
+#: forum/skins/default/templates/questions.html:313
+#: templates/unanswered.html:8 templates/unanswered.html.py:19
+msgid "Unanswered questions"
msgstr ""
-#: templates/questions.html:48
-msgid "most recently updated questions"
+#: forum/skins/default/templates/questions.html:52
+#: forum/skins/default/templates/questions.html:321
+#: templates/unanswered.html:21
+msgid "most recently asked questions"
msgstr ""
-#: templates/questions.html:48
-msgid "active"
+#: forum/skins/default/templates/questions.html:144
+msgid "Category: "
msgstr ""
-#: templates/questions.html:144
+#: forum/skins/default/templates/questions.html:150
+#: forum/skins/default/templates/questions.html:418
msgid "Did not find anything?"
msgstr ""
-#: templates/questions.html:147
+#: forum/skins/default/templates/questions.html:153
+#: forum/skins/default/templates/questions.html:421
msgid "Did not find what you were looking for?"
msgstr ""
-#: templates/questions.html:149
+#: forum/skins/default/templates/questions.html:155
+#: forum/skins/default/templates/questions.html:423
msgid "Please, post your question!"
msgstr ""
-#: templates/questions.html:163
+#: forum/skins/default/templates/questions.html:170
+#, python-format
+msgid ""
+"\n"
+"\t\t\thave total %(q_num)s questions tagged %(tagname)s\n"
+"\t\t\t"
+msgid_plural ""
+"\n"
+"\t\t\thave total %(q_num)s questions tagged %(tagname)s\n"
+"\t\t\t"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/questions.html:177
+#, python-format
+msgid ""
+"\n"
+"\t\t\t\thave total %(q_num)s questions containing %(searchtitle)s\n"
+"\t\t\t\t"
+msgid_plural ""
+"\n"
+"\t\t\t\thave total %(q_num)s questions containing %(searchtitle)s\n"
+"\t\t\t\t"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/questions.html:183
+#, python-format
+msgid ""
+"\n"
+"\t\t\t\thave total %(q_num)s questions\n"
+"\t\t\t\t"
+msgid_plural ""
+"\n"
+"\t\t\t\thave total %(q_num)s questions\n"
+"\t\t\t\t"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/questions.html:192
+#: forum/skins/default/templates/questions.html:437
#, python-format
msgid ""
"\n"
@@ -2493,15 +2383,10 @@ msgid_plural ""
" have total %(q_num)s questions tagged %(tagname)s\n"
" "
msgstr[0] ""
-"\n"
-"<div class=\"questions-count\">%(q_num)s</div><p>question tagged</p><p><span "
-"class=\"tag\">%(tagname)s</span></p>"
msgstr[1] ""
-"\n"
-"<div class=\"questions-count\">%(q_num)s</div><p>questions tagged</p><div "
-"class=\"tags\"><span class=\"tag\">%(tagname)s</span></div>"
-#: templates/questions.html:171
+#: forum/skins/default/templates/questions.html:200
+#: forum/skins/default/templates/questions.html:445
#, python-format
msgid ""
"\n"
@@ -2514,17 +2399,10 @@ msgid_plural ""
"s in full text\n"
" "
msgstr[0] ""
-"\n"
-"<div class=\"questions-count\">%(q_num)s</div><p>question "
-"containing <strong><span class=\"darkred\">%(searchtitle)s</span></strong></"
-"p>"
msgstr[1] ""
-"\n"
-"<div class=\"questions-count\">%(q_num)s</div><p>questions "
-"containing <strong><span class=\"darkred\">%(searchtitle)s</span></strong></"
-"p>"
-#: templates/questions.html:177
+#: forum/skins/default/templates/questions.html:206
+#: forum/skins/default/templates/questions.html:451
#, python-format
msgid ""
"\n"
@@ -2537,17 +2415,10 @@ msgid_plural ""
"s\n"
" "
msgstr[0] ""
-"\n"
-"<div class=\"questions-count\">%(q_num)s</div><p>question with title "
-"containing <strong><span class=\"darkred\">%(searchtitle)s</span></strong></"
-"p>"
msgstr[1] ""
-"\n"
-"<div class=\"questions-count\">%(q_num)s</div><p>questions with title "
-"containing <strong><span class=\"darkred\">%(searchtitle)s</span></strong></"
-"p>"
-#: templates/questions.html:185
+#: forum/skins/default/templates/questions.html:214
+#: forum/skins/default/templates/questions.html:459
#, python-format
msgid ""
"\n"
@@ -2558,15 +2429,10 @@ msgid_plural ""
" have total %(q_num)s unanswered questions\n"
" "
msgstr[0] ""
-"\n"
-"<div class=\"questions-count\">%(q_num)s</div><p>question without an "
-"accepted answer</p>"
msgstr[1] ""
-"\n"
-"<div class=\"questions-count\">%(q_num)s</div><p>questions without an "
-"accepted answer</p>"
-#: templates/questions.html:191
+#: forum/skins/default/templates/questions.html:220
+#: forum/skins/default/templates/questions.html:465
#, python-format
msgid ""
"\n"
@@ -2577,240 +2443,250 @@ msgid_plural ""
" have total %(q_num)s questions\n"
" "
msgstr[0] ""
-"\n"
-"<div class=\"questions-count\">%(q_num)s</div><p>question</p>"
msgstr[1] ""
-"\n"
-
-"<div class=\"questions-count\">%(q_num)s</div><p>questions<p>"
-#: templates/questions.html:201
+#: forum/skins/default/templates/questions.html:231
+#: forum/skins/default/templates/questions.html:475
msgid "latest questions info"
-msgstr "<strong>Newest</strong> questions are shown first."
+msgstr ""
-#: templates/questions.html:205
+#: forum/skins/default/templates/questions.html:235
+#: forum/skins/default/templates/questions.html:479
msgid "Questions are sorted by the <strong>time of last update</strong>."
msgstr ""
-#: templates/questions.html:206
+#: forum/skins/default/templates/questions.html:236
+#: forum/skins/default/templates/questions.html:480
msgid "Most recently answered ones are shown first."
-msgstr "<strong>Most recently answered</strong> questions are shown first."
+msgstr ""
-#: templates/questions.html:210
+#: forum/skins/default/templates/questions.html:240
+#: forum/skins/default/templates/questions.html:484
msgid "Questions sorted by <strong>number of responses</strong>."
-msgstr "Questions sorted by the <strong>number of answers</strong>."
+msgstr ""
-#: templates/questions.html:211
+#: forum/skins/default/templates/questions.html:241
+#: forum/skins/default/templates/questions.html:485
msgid "Most answered questions are shown first."
-msgstr " "
+msgstr ""
-#: templates/questions.html:215
+#: forum/skins/default/templates/questions.html:245
+#: forum/skins/default/templates/questions.html:489
msgid "Questions are sorted by the <strong>number of votes</strong>."
msgstr ""
-#: templates/questions.html:216
+#: forum/skins/default/templates/questions.html:246
+#: forum/skins/default/templates/questions.html:490
msgid "Most voted questions are shown first."
msgstr ""
-#: templates/questions.html:224 templates/unanswered.html:118
+#: forum/skins/default/templates/questions.html:254
+#: forum/skins/default/templates/questions.html:498
+#: templates/unanswered.html:118
msgid "Related tags"
-msgstr "Tags"
+msgstr ""
-#: templates/questions.html:227 templates/tag_selector.html:10
-#: templates/tag_selector.html.py:27
+#: forum/skins/default/templates/questions.html:264
+#: forum/skins/default/templates/questions.html:501
+#: forum/skins/default/templates/tag_selector.html:10
+#: forum/skins/default/templates/tag_selector.html:27
#, python-format
msgid "see questions tagged '%(tag_name)s'"
msgstr ""
-#: templates/reopen.html:6 templates/reopen.html.py:16
+#: forum/skins/default/templates/reopen.html:6
+#: forum/skins/default/templates/reopen.html:16
msgid "Reopen question"
msgstr ""
-#: templates/reopen.html:19
+#: forum/skins/default/templates/reopen.html:19
msgid "Open the previously closed question"
msgstr ""
-#: templates/reopen.html:22
+#: forum/skins/default/templates/reopen.html:22
msgid "The question was closed for the following reason "
msgstr ""
-#: templates/reopen.html:22
+#: forum/skins/default/templates/reopen.html:22
msgid "reason - leave blank in english"
msgstr ""
-#: templates/reopen.html:22
+#: forum/skins/default/templates/reopen.html:22
msgid "on "
msgstr ""
-#: templates/reopen.html:22
+#: forum/skins/default/templates/reopen.html:22
msgid "date closed"
msgstr ""
-#: templates/reopen.html:29
+#: forum/skins/default/templates/reopen.html:29
msgid "Reopen this question"
msgstr ""
-#: templates/revisions_answer.html:7 templates/revisions_answer.html.py:38
-#: templates/revisions_question.html:8 templates/revisions_question.html:38
+#: forum/skins/default/templates/revisions_answer.html:7
+#: forum/skins/default/templates/revisions_answer.html:38
+#: forum/skins/default/templates/revisions_question.html:8
+#: forum/skins/default/templates/revisions_question.html:38
msgid "Revision history"
msgstr ""
-#: templates/revisions_answer.html:50 templates/revisions_question.html:50
+#: forum/skins/default/templates/revisions_answer.html:50
+#: forum/skins/default/templates/revisions_question.html:50
msgid "click to hide/show revision"
msgstr ""
-#: templates/tag_selector.html:4
+#: forum/skins/default/templates/tag_selector.html:4
msgid "Interesting tags"
msgstr ""
-#: templates/tag_selector.html:14
+#: forum/skins/default/templates/tag_selector.html:14
#, python-format
msgid "remove '%(tag_name)s' from the list of interesting tags"
msgstr ""
-#: templates/tag_selector.html:20 templates/tag_selector.html.py:37
+#: forum/skins/default/templates/tag_selector.html:20
+#: forum/skins/default/templates/tag_selector.html:37
msgid "Add"
msgstr ""
-#: templates/tag_selector.html:21
+#: forum/skins/default/templates/tag_selector.html:21
msgid "Ignored tags"
msgstr ""
-#: templates/tag_selector.html:31
+#: forum/skins/default/templates/tag_selector.html:31
#, python-format
msgid "remove '%(tag_name)s' from the list of ignored tags"
msgstr ""
-#: templates/tag_selector.html:40
+#: forum/skins/default/templates/tag_selector.html:40
msgid "keep ingored questions hidden"
msgstr ""
-#: templates/tags.html:6 templates/tags.html.py:30
+#: forum/skins/default/templates/tags.html:6
+#: forum/skins/default/templates/tags.html:30
msgid "Tag list"
msgstr ""
-#: templates/tags.html:32
+#: forum/skins/default/templates/tags.html:32
msgid "sorted alphabetically"
msgstr ""
-#: templates/tags.html:32
+#: forum/skins/default/templates/tags.html:32
msgid "by name"
msgstr ""
-#: templates/tags.html:33
+#: forum/skins/default/templates/tags.html:33
msgid "sorted by frequency of tag use"
msgstr ""
-#: templates/tags.html:33
+#: forum/skins/default/templates/tags.html:33
msgid "by popularity"
msgstr ""
-#: templates/tags.html:39
+#: forum/skins/default/templates/tags.html:39
msgid "All tags matching query"
msgstr ""
-#: templates/tags.html:39
+#: forum/skins/default/templates/tags.html:39
msgid "all tags - make this empty in english"
msgstr ""
-#: templates/tags.html:42
+#: forum/skins/default/templates/tags.html:42
msgid "Nothing found"
msgstr ""
-#: templates/unanswered.html:114
-#, python-format
-msgid "have %(num_q)s unanswered questions"
-msgstr ""
-"<div class=\"questions-count\">%(num_q)s</div>questions <strong>without "
-"accepted answers</strong>"
-
-#: templates/user_edit.html:6
+#: forum/skins/default/templates/user_edit.html:6
msgid "Edit user profile"
msgstr ""
-#: templates/user_edit.html:19
+#: forum/skins/default/templates/user_edit.html:19
msgid "edit profile"
msgstr ""
-#: templates/user_edit.html:31
+#: forum/skins/default/templates/user_edit.html:31
msgid "image associated with your email address"
msgstr ""
-#: templates/user_edit.html:31
+#: forum/skins/default/templates/user_edit.html:31
#, python-format
msgid "avatar, see %(gravatar_faq_url)s"
-msgstr "<a href='%(gravatar_faq_url)s'>gravatar</a>"
+msgstr ""
-#: templates/user_edit.html:36 templates/user_info.html:56
+#: forum/skins/default/templates/user_edit.html:36
+#: forum/skins/default/templates/user_info.html:56
msgid "Registered user"
msgstr ""
-#: templates/user_edit.html:86 templates/user_email_subscriptions.html:20
+#: forum/skins/default/templates/user_edit.html:43
+msgid "Screen Name"
+msgstr ""
+
+#: forum/skins/default/templates/user_edit.html:86
+#: forum/skins/default/templates/user_email_subscriptions.html:23
msgid "Update"
msgstr ""
-#: templates/user_email_subscriptions.html:8
+#: forum/skins/default/templates/user_email_subscriptions.html:8
msgid "Email subscription settings"
msgstr ""
-#: templates/user_email_subscriptions.html:9
+#: forum/skins/default/templates/user_email_subscriptions.html:9
msgid "email subscription settings info"
msgstr ""
-"<span class='big strong'>Adjust frequency of email updates.</span> Receive "
-"updates on interesting questions by email, <strong><br/>help the community</"
-"strong> by answering questions of your colleagues. If you do not wish to "
-"receive emails - select 'no email' on all items below.<br/>Updates are only "
-"sent when there is any new activity on selected items."
-#: templates/user_email_subscriptions.html:21
+#: forum/skins/default/templates/user_email_subscriptions.html:24
msgid "Stop sending email"
-msgstr "Stop Email"
+msgstr ""
-#: templates/user_info.html:32
+#: forum/skins/default/templates/user_info.html:22
+msgid "karma"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:32
msgid "Moderate this user"
msgstr ""
-#: templates/user_info.html:45
+#: forum/skins/default/templates/user_info.html:45
msgid "update profile"
msgstr ""
-#: templates/user_info.html:60
+#: forum/skins/default/templates/user_info.html:60
msgid "real name"
msgstr ""
-#: templates/user_info.html:65
+#: forum/skins/default/templates/user_info.html:65
msgid "member for"
-msgstr "member since"
+msgstr ""
-#: templates/user_info.html:70
+#: forum/skins/default/templates/user_info.html:70
msgid "last seen"
msgstr ""
-#: templates/user_info.html:76
+#: forum/skins/default/templates/user_info.html:76
msgid "user website"
msgstr ""
-#: templates/user_info.html:82
+#: forum/skins/default/templates/user_info.html:82
msgid "location"
msgstr ""
-#: templates/user_info.html:89
+#: forum/skins/default/templates/user_info.html:89
msgid "age"
msgstr ""
-#: templates/user_info.html:90
+#: forum/skins/default/templates/user_info.html:90
msgid "age unit"
-msgstr "years old"
+msgstr ""
-#: templates/user_info.html:96
+#: forum/skins/default/templates/user_info.html:96
msgid "todays unused votes"
msgstr ""
-#: templates/user_info.html:97
+#: forum/skins/default/templates/user_info.html:97
msgid "votes left"
msgstr ""
-#: templates/user_stats.html:12
+#: forum/skins/default/templates/user_stats.html:12
#, python-format
msgid ""
"\n"
@@ -2823,7 +2699,7 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/user_stats.html:23
+#: forum/skins/default/templates/user_stats.html:23
#, python-format
msgid ""
"\n"
@@ -2836,16 +2712,16 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/user_stats.html:36
+#: forum/skins/default/templates/user_stats.html:36
#, python-format
msgid "the answer has been voted for %(vote_count)s times"
msgstr ""
-#: templates/user_stats.html:36
+#: forum/skins/default/templates/user_stats.html:36
msgid "this answer has been selected as correct"
msgstr ""
-#: templates/user_stats.html:46
+#: forum/skins/default/templates/user_stats.html:46
#, python-format
msgid ""
"\n"
@@ -2856,13 +2732,9 @@ msgid_plural ""
" the answer has been commented %(comment_count)s times\n"
" "
msgstr[0] ""
-"\n"
-"(one comment)"
msgstr[1] ""
-"\n"
-"(%(comment_count)s comments)"
-#: templates/user_stats.html:61
+#: forum/skins/default/templates/user_stats.html:61
#, python-format
msgid ""
"\n"
@@ -2875,23 +2747,23 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/user_stats.html:72
+#: forum/skins/default/templates/user_stats.html:72
msgid "thumb up"
msgstr ""
-#: templates/user_stats.html:73
+#: forum/skins/default/templates/user_stats.html:73
msgid "user has voted up this many times"
msgstr ""
-#: templates/user_stats.html:77
+#: forum/skins/default/templates/user_stats.html:77
msgid "thumb down"
msgstr ""
-#: templates/user_stats.html:78
+#: forum/skins/default/templates/user_stats.html:78
msgid "user voted down this many times"
msgstr ""
-#: templates/user_stats.html:87
+#: forum/skins/default/templates/user_stats.html:87
#, python-format
msgid ""
"\n"
@@ -2904,13 +2776,13 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/user_stats.html:100
+#: forum/skins/default/templates/user_stats.html:100
#, python-format
msgid ""
"see other questions with %(view_user)s's contributions tagged '%(tag_name)s' "
msgstr ""
-#: templates/user_stats.html:115
+#: forum/skins/default/templates/user_stats.html:115
#, python-format
msgid ""
"\n"
@@ -2923,236 +2795,233 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: templates/user_tabs.html:7
+#: forum/skins/default/templates/user_tabs.html:7
msgid "User profile"
msgstr ""
-#: templates/user_tabs.html:16
+#: forum/skins/default/templates/user_tabs.html:7 forum/views/users.py:875
+msgid "overview"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:9 forum/views/users.py:883
+msgid "recent activity"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:12 forum/views/users.py:893
+msgid "comments and answers to others questions"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:13 forum/views/users.py:892
+msgid "responses"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:16
msgid "graph of user reputation"
-msgstr "Graph of user karma"
+msgstr ""
-#: templates/user_tabs.html:17
+#: forum/skins/default/templates/user_tabs.html:17
msgid "reputation history"
-msgstr "karma history"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:20 forum/views/users.py:919
+msgid "user vote record"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:20 forum/views/users.py:918
+msgid "casted votes"
+msgstr ""
-#: templates/user_tabs.html:23
+#: forum/skins/default/templates/user_tabs.html:23
msgid "questions that user selected as his/her favorite"
msgstr ""
-#: templates/user_tabs.html:24
+#: forum/skins/default/templates/user_tabs.html:24
msgid "favorites"
msgstr ""
-#: templates/users.html:6 templates/users.html.py:24
+#: forum/skins/default/templates/user_tabs.html:27 forum/views/users.py:928
+msgid "email subscription settings"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:28 forum/views/users.py:927
+msgid "email subscriptions"
+msgstr ""
+
+#: forum/skins/default/templates/users.html:6
+#: forum/skins/default/templates/users.html:24
msgid "Users"
msgstr ""
-#: templates/users.html:27
+#: forum/skins/default/templates/users.html:26 forum/views/users.py:901
+msgid "reputation"
+msgstr ""
+
+#: forum/skins/default/templates/users.html:27
msgid "recent"
msgstr ""
-#: templates/users.html:28
+#: forum/skins/default/templates/users.html:28
msgid "oldest"
msgstr ""
-#: templates/users.html:29
+#: forum/skins/default/templates/users.html:29
msgid "by username"
msgstr ""
-#: templates/users.html:35
+#: forum/skins/default/templates/users.html:35
#, python-format
msgid "users matching query %(suser)s:"
msgstr ""
-#: templates/users.html:39
+#: forum/skins/default/templates/users.html:39
msgid "Nothing found."
msgstr ""
-#: templates/users_questions.html:11
+#: forum/skins/default/templates/users_questions.html:11
msgid "this questions was selected as favorite"
msgstr ""
-#: templates/users_questions.html:12
+#: forum/skins/default/templates/users_questions.html:12
msgid "thumb-up on"
msgstr ""
-#: templates/users_questions.html:19
+#: forum/skins/default/templates/users_questions.html:19
msgid "thumb-up off"
msgstr ""
-#: templates/users_questions.html:34
+#: forum/skins/default/templates/users_questions.html:34
msgid "this answer has been accepted to be correct"
msgstr ""
-#: templates/authopenid/changeemail.html:3
-#: templates/authopenid/changeemail.html:9
-#: templates/authopenid/changeemail.html:38
+#: forum/skins/default/templates/authopenid/changeemail.html:3
+#: forum/skins/default/templates/authopenid/changeemail.html:9
+#: forum/skins/default/templates/authopenid/changeemail.html:38
msgid "Change email"
-msgstr "Change Email"
+msgstr ""
-#: templates/authopenid/changeemail.html:11
+#: forum/skins/default/templates/authopenid/changeemail.html:11
msgid "Save your email address"
msgstr ""
-#: templates/authopenid/changeemail.html:16
+#: forum/skins/default/templates/authopenid/changeemail.html:16
#, python-format
msgid "change %(email)s info"
msgstr ""
-"<span class=\"strong big\">Enter your new email into the box below</span> if "
-"you'd like to use another email for <strong>update subscriptions</strong>."
-"<br>Currently you are using <strong>%(email)s</strong>"
-#: templates/authopenid/changeemail.html:18
+#: forum/skins/default/templates/authopenid/changeemail.html:18
#, python-format
msgid "here is why email is required, see %(gravatar_faq_url)s"
msgstr ""
-"<span class='strong big'>Please enter your email address in the box below.</"
-"span> Valid email address is required on this Q&amp;A forum. If you like, "
-"you can <strong>receive updates</strong> on interesting questions or entire "
-"forum via email. Also, your email is used to create a unique <a href='%"
-"(gravatar_faq_url)s'><strong>gravatar</strong></a> image for your account. "
-"Email addresses are never shown or otherwise shared with anybody else."
-#: templates/authopenid/changeemail.html:31
+#: forum/skins/default/templates/authopenid/changeemail.html:31
msgid "Your new Email"
msgstr ""
-"<strong>Your new Email:</strong> (will <strong>not</strong> be shown to "
-"anyone, must be valid)"
-#: templates/authopenid/changeemail.html:31
+#: forum/skins/default/templates/authopenid/changeemail.html:31
msgid "Your Email"
msgstr ""
-"<strong>Your Email</strong> (<i>must be valid, never shown to others</i>)"
-#: templates/authopenid/changeemail.html:38
+#: forum/skins/default/templates/authopenid/changeemail.html:38
msgid "Save Email"
msgstr ""
-#: templates/authopenid/changeemail.html:49
+#: forum/skins/default/templates/authopenid/changeemail.html:49
msgid "Validate email"
msgstr ""
-#: templates/authopenid/changeemail.html:52
+#: forum/skins/default/templates/authopenid/changeemail.html:52
#, python-format
msgid "validate %(email)s info or go to %(change_email_url)s"
msgstr ""
-"<span class=\"strong big\">An email with a validation link has been sent to %"
-"(email)s.</span> Please <strong>follow the emailed link</strong> with your "
-"web browser. Email validation is necessary to help insure the proper use of "
-"email on <span class=\"orange\">Q&amp;A</span>. If you would like to use "
-"<strong>another email</strong>, please <a href='%(change_email_url)"
-"s'><strong>change it again</strong></a>."
-#: templates/authopenid/changeemail.html:57
+#: forum/skins/default/templates/authopenid/changeemail.html:57
msgid "Email not changed"
msgstr ""
-#: templates/authopenid/changeemail.html:60
+#: forum/skins/default/templates/authopenid/changeemail.html:60
#, python-format
msgid "old %(email)s kept, if you like go to %(change_email_url)s"
msgstr ""
-"<span class=\"strong big\">Your email address %(email)s has not been changed."
-"</span> If you decide to change it later - you can always do it by editing "
-"it in your user profile or by using the <a href='%(change_email_url)"
-"s'><strong>previous form</strong></a> again."
-#: templates/authopenid/changeemail.html:65
+#: forum/skins/default/templates/authopenid/changeemail.html:65
msgid "Email changed"
msgstr ""
-#: templates/authopenid/changeemail.html:68
+#: forum/skins/default/templates/authopenid/changeemail.html:68
#, python-format
msgid "your current %(email)s can be used for this"
msgstr ""
-"<span class='big strong'>Your email address is now set to %(email)s.</span> "
-"Updates on the questions that you like most will be sent to this address. "
-"Email notifications are sent once a day or less frequently - only when there "
-"are any news."
-#: templates/authopenid/changeemail.html:73
+#: forum/skins/default/templates/authopenid/changeemail.html:73
msgid "Email verified"
msgstr ""
-#: templates/authopenid/changeemail.html:76
+#: forum/skins/default/templates/authopenid/changeemail.html:76
msgid "thanks for verifying email"
msgstr ""
-"<span class=\"big strong\">Thank you for verifying your email!</span> Now "
-"you can <strong>ask</strong> and <strong>answer</strong> questions. Also if "
-"you find a very interesting question you can <strong>subscribe for the "
-"updates</strong> - then will be notified about changes <strong>once a day</"
-"strong> or less frequently."
-#: templates/authopenid/changeemail.html:81
+#: forum/skins/default/templates/authopenid/changeemail.html:81
msgid "email key not sent"
-msgstr "Validation email not sent"
+msgstr ""
-#: templates/authopenid/changeemail.html:84
+#: forum/skins/default/templates/authopenid/changeemail.html:84
#, python-format
msgid "email key not sent %(email)s change email here %(change_link)s"
msgstr ""
-"<span class='big strong'>Your current email address %(email)s has been "
-"validated before</span> so the new key was not sent. You can <a href='%"
-"(change_link)s'>change</a> email used for update subscriptions if necessary."
-#: templates/authopenid/changeopenid.html:4
-#: templates/authopenid/changeopenid.html:30
-#: templates/authopenid/settings.html:34
+#: forum/skins/default/templates/authopenid/changeopenid.html:4
+#: forum/skins/default/templates/authopenid/changeopenid.html:30
+#: forum/skins/default/templates/authopenid/settings.html:34
msgid "Change OpenID"
msgstr ""
-#: templates/authopenid/changeopenid.html:8
+#: forum/skins/default/templates/authopenid/changeopenid.html:8
msgid "Account: change OpenID URL"
msgstr ""
-#: templates/authopenid/changeopenid.html:12
+#: forum/skins/default/templates/authopenid/changeopenid.html:12
msgid ""
"This is where you can change your OpenID URL. Make sure you remember it!"
msgstr ""
-#: templates/authopenid/changeopenid.html:14
-#: templates/authopenid/delete.html:14 templates/authopenid/delete.html:24
+#: forum/skins/default/templates/authopenid/changeopenid.html:14
+#: forum/skins/default/templates/authopenid/delete.html:14
+#: forum/skins/default/templates/authopenid/delete.html:24
msgid "Please correct errors below:"
msgstr ""
-#: templates/authopenid/changeopenid.html:29
+#: forum/skins/default/templates/authopenid/changeopenid.html:29
msgid "OpenID URL:"
msgstr ""
-#: templates/authopenid/changepw.html:5 templates/authopenid/changepw.html:14
-#: templates/authopenid/settings.html:29
+#: forum/skins/default/templates/authopenid/changepw.html:5
+#: forum/skins/default/templates/authopenid/changepw.html:14
+#: forum/skins/default/templates/authopenid/settings.html:29
msgid "Change password"
msgstr ""
-#: templates/authopenid/changepw.html:7
+#: forum/skins/default/templates/authopenid/changepw.html:7
msgid "Account: change password"
-msgstr "Change your password"
+msgstr ""
-#: templates/authopenid/changepw.html:8
+#: forum/skins/default/templates/authopenid/changepw.html:8
msgid "This is where you can change your password. Make sure you remember it!"
msgstr ""
-"<span class='strong'>To change your password</span> please fill out and "
-"submit this form"
-#: templates/authopenid/complete.html:19
+#: forum/skins/default/templates/authopenid/complete.html:19
msgid "Connect your OpenID with this site"
-msgstr "New user signup"
+msgstr ""
-#: templates/authopenid/complete.html:22
+#: forum/skins/default/templates/authopenid/complete.html:22
msgid "Connect your OpenID with your account on this site"
-msgstr "New user signup"
+msgstr ""
-#: templates/authopenid/complete.html:27
+#: forum/skins/default/templates/authopenid/complete.html:27
#, python-format
msgid "register new %(provider)s account info, see %(gravatar_faq_url)s"
msgstr ""
-"<p><span class=\"big strong\">You are here for the first time with your %"
-"(provider)s login.</span> Please create your <strong>screen name</strong> "
-"and save your <strong>email</strong> address. Saved email address will let "
-"you <strong>subscribe for the updates</strong> on the most interesting "
-"questions and will be used to create and retrieve your unique avatar image - "
-"<a href='%(gravatar_faq_url)s'><strong>gravatar</strong></a>.</p>"
-#: templates/authopenid/complete.html:31
+#: forum/skins/default/templates/authopenid/complete.html:31
#, python-format
msgid ""
"%(username)s already exists, choose another name for \n"
@@ -3160,272 +3029,172 @@ msgid ""
"(gravatar_faq_url)s\n"
" "
msgstr ""
-"<p><span class='strong big'>Oops... looks like screen name %(username)s is "
-"already used in another account.</span></p><p>Please choose another screen "
-"name to use with your %(provider)s login. Also, a valid email address is "
-"required on the <span class='orange'>Q&amp;A</span> forum. Your email is "
-"used to create a unique <a href='%(gravatar_faq_url)s'><strong>gravatar</"
-"strong></a> image for your account. If you like, you can <strong>receive "
-"updates</strong> on the interesting questions or entire forum by email. "
-"Email addresses are never shown or otherwise shared with anybody else.</p>"
-#: templates/authopenid/complete.html:35
+#: forum/skins/default/templates/authopenid/complete.html:35
#, python-format
msgid ""
"register new external %(provider)s account info, see %(gravatar_faq_url)s"
msgstr ""
-"<p><span class=\"big strong\">You are here for the first time with your %"
-"(provider)s login.</span></p><p>You can either keep your <strong>screen "
-"name</strong> the same as your %(provider)s login name or choose some other "
-"nickname.</p><p>Also, please save a valid <strong>email</strong> address. "
-"With the email you can <strong>subscribe for the updates</strong> on the "
-"most interesting questions. Email address is also used to create and "
-"retrieve your unique avatar image - <a href='%(gravatar_faq_url)"
-"s'><strong>gravatar</strong></a>.</p>"
-#: templates/authopenid/complete.html:40
-msgid "This account already exists, please use another."
+#: forum/skins/default/templates/authopenid/complete.html:38
+#, python-format
+msgid "register new Facebook connect account info, see %(gravatar_faq_url)s"
msgstr ""
-"<p><span class=\"big strong\">You are here for the first time with your %"
-"(provider)s login.</span> Please create your <strong>screen name</strong> "
-"and save your <strong>email</strong> address. Saved email address will let "
-"you <strong>subscribe for the updates</strong> on the most interesting "
-"questions and will be used to create and retrieve your unique avatar image - "
-"<a href='%(gravatar_faq_url)s'><strong>gravatar</strong></a>.</p>"
+#: forum/skins/default/templates/authopenid/complete.html:42
+msgid "This account already exists, please use another."
+msgstr ""
-#: templates/authopenid/complete.html:55
+#: forum/skins/default/templates/authopenid/complete.html:57
msgid "Sorry, looks like we have some errors:"
msgstr ""
-#: templates/authopenid/complete.html:76
+#: forum/skins/default/templates/authopenid/complete.html:82
msgid "Screen name label"
-msgstr "<strong>Screen Name</strong> (<i>will be shown to others</i>)"
+msgstr ""
-#: templates/authopenid/complete.html:83
+#: forum/skins/default/templates/authopenid/complete.html:89
msgid "Email address label"
msgstr ""
-"<strong>Email Address</strong> (<i>will <strong>not</strong> be shared with "
-"anyone, must be valid</i>)"
-#: templates/authopenid/complete.html:89 templates/authopenid/signup.html:15
-msgid "receive updates motivational blurb"
+#: forum/skins/default/templates/authopenid/complete.html:95
+#: forum/skins/default/templates/authopenid/complete.html:103
+msgid "Tag filter tool will be your right panel, once you log in."
msgstr ""
-"<strong>Receive forum updates by email</strong> - this will help our "
-"community grow and become more useful.<br/>By default <span "
-"class='orange'>Q&amp;A</span> forum sends up to <strong>one email digest per "
-"week</strong> - only when there is anything new.<br/>If you like, please "
-"adjust this now or any time later from your user account."
-#: templates/authopenid/complete.html:91
-msgid "Tag filter tool will be your right panel, once you log in."
+#: forum/skins/default/templates/authopenid/complete.html:96
+#: forum/skins/default/templates/authopenid/signup.html:18
+msgid "receive updates motivational blurb"
msgstr ""
-"<strong>Receive forum updates by email</strong> - this will help our "
-"community grow and become more useful.<br/>By default "
-"<span class='orange'>Q&amp;A</span> forum sends up to <strong>one "
-"email digest per week</strong> - only when there is anything new.<br/>If "
-"you like, please adjust this now or any time later from your user account."
-#: templates/authopenid/complete.html:91
-msgid "create account"
-msgstr "Signup"
+#: forum/skins/default/templates/authopenid/complete.html:100
+#: forum/skins/default/templates/authopenid/signup.html:22
+msgid "please select one of the options above"
+msgstr ""
-#: templates/authopenid/complete.html:92
+#: forum/skins/default/templates/authopenid/complete.html:104
msgid "create account"
-msgstr "Signup"
+msgstr ""
-#: templates/authopenid/complete.html:101
+#: forum/skins/default/templates/authopenid/complete.html:113
msgid "Existing account"
msgstr ""
-#: templates/authopenid/complete.html:102
+#: forum/skins/default/templates/authopenid/complete.html:114
msgid "user name"
msgstr ""
-#: templates/authopenid/complete.html:103
+#: forum/skins/default/templates/authopenid/complete.html:115
msgid "password"
msgstr ""
-#: templates/authopenid/complete.html:108
+#: forum/skins/default/templates/authopenid/complete.html:122
msgid "Register"
msgstr ""
-#: templates/authopenid/complete.html:109 templates/authopenid/signin.html:140
+#: forum/skins/default/templates/authopenid/complete.html:123
+#: forum/skins/default/templates/authopenid/signin.html:151
msgid "Forgot your password?"
msgstr ""
-#: templates/authopenid/confirm_email.txt:2
-msgid "Thank you for registering at our Q&A forum!"
-msgstr ""
-
-#: templates/authopenid/confirm_email.txt:4
-msgid "Your account details are:"
-msgstr ""
-
-#: templates/authopenid/confirm_email.txt:6
-msgid "Username:"
-msgstr ""
-
-#: templates/authopenid/confirm_email.txt:7
-#: templates/authopenid/delete.html:19
-msgid "Password:"
-msgstr ""
-
-#: templates/authopenid/confirm_email.txt:9
-msgid "Please sign in here:"
-msgstr ""
-
-#: templates/authopenid/confirm_email.txt:12
-#: templates/authopenid/email_validation.txt:14
-#: templates/authopenid/sendpw_email.txt:8
-msgid ""
-"Sincerely,\n"
-"Forum Administrator"
-msgstr ""
-"Sincerely,\n"
-"Q&A Forum Administrator"
-
-#: templates/authopenid/delete.html:4 templates/authopenid/settings.html:38
+#: forum/skins/default/templates/authopenid/delete.html:4
+#: forum/skins/default/templates/authopenid/settings.html:38
msgid "Delete account"
msgstr ""
-#: templates/authopenid/delete.html:8
+#: forum/skins/default/templates/authopenid/delete.html:8
msgid "Account: delete account"
msgstr ""
-#: templates/authopenid/delete.html:12
+#: forum/skins/default/templates/authopenid/delete.html:12
msgid ""
"Note: After deleting your account, anyone will be able to register this "
"username."
msgstr ""
-#: templates/authopenid/delete.html:16
+#: forum/skins/default/templates/authopenid/delete.html:16
msgid "Check confirm box, if you want delete your account."
msgstr ""
-#: templates/authopenid/delete.html:31
+#: forum/skins/default/templates/authopenid/delete.html:19
+msgid "Password:"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/delete.html:31
msgid "I am sure I want to delete my account."
msgstr ""
-#: templates/authopenid/delete.html:32
+#: forum/skins/default/templates/authopenid/delete.html:32
msgid "Password/OpenID URL"
msgstr ""
-#: templates/authopenid/delete.html:32
+#: forum/skins/default/templates/authopenid/delete.html:32
msgid "(required for your security)"
msgstr ""
-#: templates/authopenid/delete.html:34
+#: forum/skins/default/templates/authopenid/delete.html:34
msgid "Delete account permanently"
msgstr ""
-#: templates/authopenid/email_validation.txt:2
-msgid "Greetings from the Q&A forum"
-msgstr ""
-
-#: templates/authopenid/email_validation.txt:4
-msgid "To make use of the Forum, please follow the link below:"
-msgstr ""
-
-#: templates/authopenid/email_validation.txt:8
-msgid "Following the link above will help us verify your email address."
-msgstr ""
-
-#: templates/authopenid/email_validation.txt:10
-msgid ""
-"If you beleive that this message was sent in mistake - \n"
-"no further action is needed. Just ingore this email, we apologize\n"
-"for any inconvenience"
-msgstr ""
-
-#: templates/authopenid/external_legacy_login_info.html:4
-#: templates/authopenid/external_legacy_login_info.html:7
+#: forum/skins/default/templates/authopenid/external_legacy_login_info.html:4
+#: forum/skins/default/templates/authopenid/external_legacy_login_info.html:7
msgid "Traditional login information"
msgstr ""
-"<span class='big strong'>Forgot you password? No problems - just get a new "
-"one!</span><br/>Please follow the following steps:<br/>&bull; submit your "
-"user name below and check your email<br/>&bull; <strong>follow the "
-"activation link</strong> for the new password - sent to you by email and "
-"login with the suggested password<br/>&bull; at this you might want to "
-"change your password to something you can remember better"
-#: templates/authopenid/sendpw.html:21
-msgid "Reset password"
-msgstr "Send me a new password"
-
-#: templates/authopenid/external_legacy_login_info.html:12
-msgid "how to login with password through external login website"
+#: forum/skins/default/templates/authopenid/external_legacy_login_info.html:12
+#, python-format
+msgid ""
+"how to login with password through external login website or use %"
+"(feedback_url)s"
msgstr ""
-#: templates/authopenid/sendpw.html:4 templates/authopenid/sendpw.html.py:7
+#: forum/skins/default/templates/authopenid/sendpw.html:4
+#: forum/skins/default/templates/authopenid/sendpw.html:7
msgid "Send new password"
-msgstr "Recover password"
+msgstr ""
-#: templates/authopenid/sendpw.html:10
+#: forum/skins/default/templates/authopenid/sendpw.html:10
msgid "password recovery information"
msgstr ""
-"<span class='big strong'>Forgot you password? No problems - just get a new "
-"one!</span><br/>Please follow the following steps:<br/>&bull; submit your "
-"user name below and check your email<br/>&bull; <strong>follow the "
-"activation link</strong> for the new password - sent to you by email and "
-"login with the suggested password<br/>&bull; at this you might want to "
-"change your password to something you can remember better"
-#: templates/authopenid/sendpw.html:21
+#: forum/skins/default/templates/authopenid/sendpw.html:21
msgid "Reset password"
-msgstr "Send me a new password"
-
-#: templates/authopenid/sendpw.html:22
-msgid "return to login"
msgstr ""
-#: templates/authopenid/sendpw_email.txt:2
-#, python-format
-msgid ""
-"Someone has requested to reset your password on %(site_url)s.\n"
-"If it were not you, it is safe to ignore this email."
-msgstr ""
-
-#: templates/authopenid/sendpw_email.txt:5
-#, python-format
-msgid ""
-"email explanation how to use new %(password)s for %(username)s\n"
-"with the %(key_link)s"
+#: forum/skins/default/templates/authopenid/sendpw.html:22
+msgid "return to login"
msgstr ""
-"To change your password, please follow these steps:\n"
-"* visit this link: %(key_link)s\n"
-"* login with user name %(username)s and password %(password)s\n"
-"* go to your user profile and set the password to something you can remember"
-#: templates/authopenid/settings.html:4
+#: forum/skins/default/templates/authopenid/settings.html:4
msgid "Account functions"
msgstr ""
-#: templates/authopenid/settings.html:30
+#: forum/skins/default/templates/authopenid/settings.html:30
msgid "Give your account a new password."
msgstr ""
-#: templates/authopenid/settings.html:31
+#: forum/skins/default/templates/authopenid/settings.html:31
msgid "Change email "
msgstr ""
-#: templates/authopenid/settings.html:32
+#: forum/skins/default/templates/authopenid/settings.html:32
msgid "Add or update the email address associated with your account."
msgstr ""
-#: templates/authopenid/settings.html:35
+#: forum/skins/default/templates/authopenid/settings.html:35
msgid "Change openid associated to your account"
msgstr ""
-#: templates/authopenid/settings.html:39
+#: forum/skins/default/templates/authopenid/settings.html:39
msgid "Erase your username and all your data from website"
msgstr ""
-#: templates/authopenid/signin.html:5 templates/authopenid/signin.html:21
+#: forum/skins/default/templates/authopenid/signin.html:5
+#: forum/skins/default/templates/authopenid/signin.html:21
msgid "User login"
-msgstr "User login"
+msgstr ""
-#: templates/authopenid/signin.html:28
+#: forum/skins/default/templates/authopenid/signin.html:28
#, python-format
msgid ""
"\n"
@@ -3433,136 +3202,257 @@ msgid ""
"log in\n"
" "
msgstr ""
-"\n"
-"<span class=\"strong big\">Your answer to </span> <i>\"<strong>%(title)s</"
-"strong> %(summary)s...\"</i> <span class=\"strong big\">is saved and will be "
-"posted once you log in.</span>"
-#: templates/authopenid/signin.html:35
+#: forum/skins/default/templates/authopenid/signin.html:35
#, python-format
msgid ""
"Your question \n"
" %(title)s %(summary)s will be posted once you log in\n"
" "
msgstr ""
-"<span class=\"strong big\">Your question</span> <i>\"<strong>%(title)s</"
-"strong> %(summary)s...\"</i> <span class=\"strong big\">is saved and will be "
-"posted once you log in.</span>"
-#: templates/authopenid/signin.html:42
+#: forum/skins/default/templates/authopenid/signin.html:42
msgid "Click to sign in through any of these services."
msgstr ""
-"<p><span class=\"big strong\">Please select your favorite login method below."
-"</span></p><p><font color=\"gray\">External login services use <a href="
-"\"http://openid.net\"><b>OpenID</b></a> technology, where your password "
-"always stays confidential between you and your login provider and you don't "
-"have to remember another one. CNPROG option requires your login name and "
-"password entered here.</font></p>"
-#: templates/authopenid/signin.html:117
+#: forum/skins/default/templates/authopenid/signin.html:128
msgid "Enter your <span id=\"enter_your_what\">Provider user name</span>"
msgstr ""
-"<span class=\"big strong\">Enter your </span><span id=\"enter_your_what\" "
-"class='big strong'>Provider user name</span><br/><span class='grey'>(or "
-"select another login method above)</span>"
-#: templates/authopenid/signin.html:124
+#: forum/skins/default/templates/authopenid/signin.html:135
msgid ""
"Enter your <a class=\"openid_logo\" href=\"http://openid.net\">OpenID</a> "
"web address"
msgstr ""
-"<span class=\"big strong\">Enter your <a class=\"openid_logo\" href=\"http://"
-"openid.net\">OpenID</a> web address</span><br/><span class='grey'>(or choose "
-"another login method above)</span>"
-#: templates/authopenid/signin.html:126 templates/authopenid/signin.html:138
+#: forum/skins/default/templates/authopenid/signin.html:137
+#: forum/skins/default/templates/authopenid/signin.html:149
msgid "Login"
msgstr ""
-#: templates/authopenid/signin.html:129
+#: forum/skins/default/templates/authopenid/signin.html:140
msgid "Enter your login name and password"
msgstr ""
-"<span class='big strong'>Enter your CNPROG login and password</span><br/"
-"><span class='grey'>(or select your OpenID provider above)</span>"
-#: templates/authopenid/signin.html:133
+#: forum/skins/default/templates/authopenid/signin.html:144
msgid "Login name"
msgstr ""
-#: templates/authopenid/signin.html:135
+#: forum/skins/default/templates/authopenid/signin.html:146
msgid "Password"
msgstr ""
-#: templates/authopenid/signin.html:139
+#: forum/skins/default/templates/authopenid/signin.html:150
msgid "Create account"
msgstr ""
-#: templates/authopenid/signin.html:149
+#: forum/skins/default/templates/authopenid/signin.html:160
msgid "Why use OpenID?"
msgstr ""
-#: templates/authopenid/signin.html:152
+#: forum/skins/default/templates/authopenid/signin.html:163
msgid "with openid it is easier"
-msgstr "With the OpenID you don't need to create new username and password."
+msgstr ""
-#: templates/authopenid/signin.html:155
+#: forum/skins/default/templates/authopenid/signin.html:166
msgid "reuse openid"
-msgstr "You can safely re-use the same login for all OpenID-enabled websites."
+msgstr ""
-#: templates/authopenid/signin.html:158
+#: forum/skins/default/templates/authopenid/signin.html:169
msgid "openid is widely adopted"
msgstr ""
-"There are > 160,000,000 OpenID account in use. Over 10,000 sites are OpenID-"
-"enabled."
-#: templates/authopenid/signin.html:161
+#: forum/skins/default/templates/authopenid/signin.html:172
msgid "openid is supported open standard"
-msgstr "OpenID is based on an open standard, supported by many organizations."
+msgstr ""
-#: templates/authopenid/signin.html:166
+#: forum/skins/default/templates/authopenid/signin.html:177
msgid "Find out more"
msgstr ""
-#: templates/authopenid/signin.html:167
+#: forum/skins/default/templates/authopenid/signin.html:178
msgid "Get OpenID"
msgstr ""
-#: templates/authopenid/signup.html:4
+#: forum/skins/default/templates/authopenid/signup.html:4
msgid "Signup"
msgstr ""
-#: templates/authopenid/signup.html:8
+#: forum/skins/default/templates/authopenid/signup.html:8
msgid "Create login name and password"
msgstr ""
-#: templates/authopenid/signup.html:10
+#: forum/skins/default/templates/authopenid/signup.html:10
msgid "Traditional signup info"
msgstr ""
-"<span class='strong big'>If you prefer, create your forum login name and "
-"password here. However</span>, please keep in mind that we also support "
-"<strong>OpenID</strong> login method. With <strong>OpenID</strong> you can "
-"simply reuse your external login (e.g. Gmail or AOL) without ever sharing "
-"your login details with anyone and having to remember yet another password."
-#: templates/authopenid/signup.html:17
+#: forum/skins/default/templates/authopenid/signup.html:25
+msgid ""
+"Please read and type in the two words below to help us prevent automated "
+"account creation."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signup.html:27
msgid "Create Account"
msgstr ""
-#: templates/authopenid/signup.html:19
+#: forum/skins/default/templates/authopenid/signup.html:29
msgid "return to OpenID login"
msgstr ""
-#~ msgid ""
-#~ "\n"
-#~ "\t\t\t\thave total %(q_num)s questions\n"
-#~ "\t\t\t\t"
-#~ msgid_plural ""
-#~ "\n"
-#~ "\t\t\t\thave total %(q_num)s questions\n"
-#~ "\t\t\t\t"
-#~ msgstr[0] ""
-#~ "\n"
-#~ "<div class=\"questions-count\">%(q_num)s</div><p>question</p>"
-#~ msgstr[1] ""
-#~ "\n"
-#~ "<div class=\"questions-count\">%(q_num)s</div><p>questions</p>"
+#: forum/skins/default/templates/fbconnect/xd_receiver.html:5
+#, python-format
+msgid "Connect to %(APP_SHORT_NAME)s with Facebook!"
+msgstr ""
+
+#: forum/templatetags/extra_tags.py:166 forum/templatetags/extra_tags.py:193
+msgid "reputation points"
+msgstr ""
+
+#: forum/templatetags/extra_tags.py:253
+msgid "2 days ago"
+msgstr ""
+
+#: forum/templatetags/extra_tags.py:255
+msgid "yesterday"
+msgstr ""
+
+#: forum/templatetags/extra_tags.py:257
+#, python-format
+msgid "%(hr)d hour ago"
+msgid_plural "%(hr)d hours ago"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/templatetags/extra_tags.py:259
+#, python-format
+msgid "%(min)d min ago"
+msgid_plural "%(min)d mins ago"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/views/users.py:876
+msgid "user profile"
+msgstr ""
+
+#: forum/views/users.py:877
+msgid "user profile overview"
+msgstr ""
+
+#: forum/views/users.py:884
+msgid "recent user activity"
+msgstr ""
+
+#: forum/views/users.py:885
+msgid "profile - recent activity"
+msgstr ""
+
+#: forum/views/users.py:894
+msgid "profile - responses"
+msgstr ""
+
+#: forum/views/users.py:902
+msgid "user reputation in the community"
+msgstr ""
+
+#: forum/views/users.py:903
+msgid "profile - user reputation"
+msgstr ""
+
+#: forum/views/users.py:909
+msgid "favorite questions"
+msgstr ""
+
+#: forum/views/users.py:910
+msgid "users favorite questions"
+msgstr ""
+
+#: forum/views/users.py:911
+msgid "profile - favorite questions"
+msgstr ""
+
+#: forum/views/users.py:920
+msgid "profile - votes"
+msgstr ""
+
+#: forum/views/users.py:929
+msgid "profile - email subscriptions"
+msgstr ""
+
+#: middleware/anon_user.py:33
+#, python-format
+msgid "first time greeting with %(url)s"
+msgstr ""
+
+#: templates/unanswered.html:114
+#, python-format
+msgid "have %(num_q)s unanswered questions"
+msgstr ""
+
+#: utils/forms.py:27
+msgid "this field is required"
+msgstr ""
+
+#: utils/forms.py:42
+msgid "choose a username"
+msgstr ""
+
+#: utils/forms.py:47
+msgid "user name is required"
+msgstr ""
+
+#: utils/forms.py:48
+msgid "sorry, this name is taken, please choose another"
+msgstr ""
+
+#: utils/forms.py:49
+msgid "sorry, this name is not allowed, please choose another"
+msgstr ""
+
+#: utils/forms.py:50
+msgid "sorry, there is no user with this name"
+msgstr ""
+
+#: utils/forms.py:51
+msgid "sorry, we have a serious error - user name is taken by several users"
+msgstr ""
+
+#: utils/forms.py:52
+msgid "user name can only consist of letters, empty space and underscore"
+msgstr ""
+
+#: utils/forms.py:100
+msgid "your email address"
+msgstr ""
+
+#: utils/forms.py:101
+msgid "email address is required"
+msgstr ""
+
+#: utils/forms.py:102
+msgid "please enter a valid email address"
+msgstr ""
+
+#: utils/forms.py:103
+msgid "this email is already used by someone else, please choose another"
+msgstr ""
+
+#: utils/forms.py:128
+msgid "choose password"
+msgstr ""
+
+#: utils/forms.py:129
+msgid "password is required"
+msgstr ""
+
+#: utils/forms.py:132
+msgid "retype password"
+msgstr ""
+
+#: utils/forms.py:133
+msgid "please, retype your password"
+msgstr ""
+
+#: utils/forms.py:134
+msgid "sorry, entered passwords did not match, please try again"
+msgstr ""
diff --git a/osqa.iml b/osqa.iml
new file mode 100755
index 00000000..4e760f0a
--- /dev/null
+++ b/osqa.iml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="jdk" jdkName="Python 2.6.4" jdkType="Python SDK" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module>
+
diff --git a/session_messages/__init__.py b/session_messages/__init__.py
deleted file mode 100644
index 4dd10a6b..00000000
--- a/session_messages/__init__.py
+++ /dev/null
@@ -1,37 +0,0 @@
-"""
-Lightweight session-based messaging system.
-
-Time-stamp: <2009-03-10 19:22:29 carljm __init__.py>
-
-"""
-VERSION = (0, 1, 'pre')
-
-def create_message (request, message):
- """
- Create a message in the current session.
-
- """
- assert hasattr(request, 'session'), "django-session-messages requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."
-
- try:
- request.session['messages'].append(message)
- except KeyError:
- request.session['messages'] = [message]
-
-def get_and_delete_messages (request, include_auth=False):
- """
- Get and delete all messages for current session.
-
- Optionally also fetches user messages from django.contrib.auth.
-
- """
- assert hasattr(request, 'session'), "django-session-messages requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."
-
- messages = request.session.pop('messages', [])
- import logging
-
- if include_auth and request.user.is_authenticated():
- messages.extend(request.user.get_and_delete_messages())
-
- return messages
-
diff --git a/session_messages/context_processors.py b/session_messages/context_processors.py
deleted file mode 100644
index df9840fd..00000000
--- a/session_messages/context_processors.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""
-Context processor for lightweight session messages.
-
-Time-stamp: <2008-07-19 23:16:19 carljm context_processors.py>
-
-"""
-from django.utils.encoding import StrAndUnicode
-
-from session_messages import get_and_delete_messages
-
-def session_messages (request):
- """
- Returns session messages for the current session.
-
- """
- return { 'session_messages': LazyMessages(request) }
-
-class LazyMessages (StrAndUnicode):
- """
- Lazy message container, so messages aren't actually retrieved from
- session and deleted until the template asks for them.
-
- """
- def __init__(self, request):
- self.request = request
-
- def __iter__(self):
- return iter(self.messages)
-
- def __len__(self):
- return len(self.messages)
-
- def __nonzero__(self):
- return bool(self.messages)
-
- def __unicode__(self):
- return unicode(self.messages)
-
- def __getitem__(self, *args, **kwargs):
- return self.messages.__getitem__(*args, **kwargs)
-
- def _get_messages(self):
- if hasattr(self, '_messages'):
- return self._messages
- self._messages = get_and_delete_messages(self.request)
- return self._messages
- messages = property(_get_messages)
-
diff --git a/session_messages/models.py b/session_messages/models.py
deleted file mode 100644
index b67ead6d..00000000
--- a/session_messages/models.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-blank models.py
-"""
diff --git a/settings.py b/settings.py
index 96c20cc3..775bda45 100755
--- a/settings.py
+++ b/settings.py
@@ -10,6 +10,7 @@ SECRET_KEY = '$oo^&_m&qwbib=(_4m_n*zn-d=g#s0he5fx9xonnym#8p6yigm'
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source',
+ 'forum.skins.load_template_source',
# 'django.template.loaders.eggs.load_template_source',
)
@@ -41,7 +42,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
ROOT_URLCONF = 'urls'
TEMPLATE_DIRS = (
- os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
+ os.path.join(os.path.dirname(__file__),'forum','skins').replace('\\','/'),
)
#UPLOAD SETTINGS
diff --git a/templates/content/js/wmd/wmd-min.js b/templates/content/js/wmd/wmd-min.js
deleted file mode 100644
index 85cbd907..00000000
--- a/templates/content/js/wmd/wmd-min.js
+++ /dev/null
@@ -1 +0,0 @@
-var Attacklab=Attacklab||{};Attacklab.wmdBase=function(){var y=top.Attacklab;var E=top.document;var s=top.RegExp;var l=top.navigator;y.Util={};y.Position={};y.Command={};y.Global={};var a=y.Util;var C=y.Position;var h=y.Command;var v=y.Global;v.isIE=/msie/.test(l.userAgent.toLowerCase());v.isIE_5or6=/msie 6/.test(l.userAgent.toLowerCase())||/msie 5/.test(l.userAgent.toLowerCase());v.isIE_7plus=v.isIE&&!v.isIE_5or6;v.isOpera=/opera/.test(l.userAgent.toLowerCase());v.isKonqueror=/konqueror/.test(l.userAgent.toLowerCase());var c="粗体 <strong> Ctrl-B";var f="斜体 <em> Ctrl-I";var z="超链接 <a> Ctrl-L";var u="引用 <blockquote> Ctrl-.";var e="代码 <pre><code> Ctrl-K";var d="图片 <img> Ctrl-G";var q="数字编号列表 <ol> Ctrl-O";var t="项目符号列表 <ul> Ctrl-U";var i="标题 <h1>/<h2> Ctrl-H";var p="水平线 <hr> Ctrl-R";var m="撤销 Ctrl-Z";var j="重做 Ctrl-Y";var B="<p style='margin-top: 0px'><b>输入图片地址</b></p><p>示例:<br />http://www.cnprog.com/images/temp.jpg \"我的截图\"</p>";var D="<p style='margin-top: 0px'><b>输入Web地址</b></p><p>示例:<br />http://www.cnprog.com/ \"我的网站\"</p>";var n='<div>或者上传本地图片:</div><input type="file" name="file-upload" id="file-upload" size="26" onchange="return ajaxFileUpload($(\'#image-url\'));"/><br><img id="loading" src="/content/images/indicator.gif" style="display:none;"/>';var b="http://";var g="http://";var o="images/";var A=500;var x=100;var k="http://wmd-editor.com/";var r="WMD website";var w="_blank";y.PanelCollection=function(){this.buttonBar=E.getElementById("wmd-button-bar");this.preview=E.getElementById("previewer");this.output=E.getElementById("wmd-output");this.input=E.getElementById("editor")};y.panels=undefined;y.ieCachedRange=null;y.ieRetardedClick=false;a.isVisible=function(F){if(window.getComputedStyle){return window.getComputedStyle(F,null).getPropertyValue("display")!=="none"}else{if(F.currentStyle){return F.currentStyle.display!=="none"}}};a.addEvent=function(G,F,H){if(G.attachEvent){G.attachEvent("on"+F,H)}else{G.addEventListener(F,H,false)}};a.removeEvent=function(G,F,H){if(G.detachEvent){G.detachEvent("on"+F,H)}else{G.removeEventListener(F,H,false)}};a.fixEolChars=function(F){F=F.replace(/\r\n/g,"\n");F=F.replace(/\r/g,"\n");return F};a.extendRegExp=function(H,J,G){if(J===null||J===undefined){J=""}if(G===null||G===undefined){G=""}var I=H.toString();var F;I=I.replace(/\/([gim]*)$/,"");F=s.$1;I=I.replace(/(^\/|\/$)/g,"");I=J+I+G;return new s(I,F)};a.createImage=function(F){var H=o+F;var G=E.createElement("img");G.className="wmd-button";G.src=H;return G};a.prompt=function(M,P,H){var I;var F;var K;var J=0;if(arguments.length==4){J=arguments[3]}if(P===undefined){P=""}var L=function(Q){var R=(Q.charCode||Q.keyCode);if(R===27){N(true)}};var N=function(Q){a.removeEvent(E.body,"keydown",L);var R=K.value;if(Q){R=null}else{R=R.replace("http://http://","http://");R=R.replace("http://https://","https://");R=R.replace("http://ftp://","ftp://");if(R.indexOf("http://")===-1&&R.indexOf("ftp://")===-1){R="http://"+R}}I.parentNode.removeChild(I);F.parentNode.removeChild(F);H(R);return false};var G=function(){F=E.createElement("div");F.className="wmd-prompt-background";style=F.style;style.position="absolute";style.top="0";style.zIndex="1000";if(v.isKonqueror){style.backgroundColor="transparent"}else{if(v.isIE){style.filter="alpha(opacity=50)"}else{style.opacity="0.5"}}var Q=C.getPageSize();style.height=Q[1]+"px";if(v.isIE){style.left=E.documentElement.scrollLeft;style.width=E.documentElement.clientWidth}else{style.left="0";style.width="100%"}E.body.appendChild(F)};var O=function(){I=E.createElement("div");I.className="wmd-prompt-dialog";I.style.padding="10px;";I.style.position="fixed";I.style.width="400px";I.style.zIndex="1001";var Q=E.createElement("div");Q.innerHTML=M;Q.style.padding="5px";I.appendChild(Q);var S=E.createElement("form");S.onsubmit=function(){return N(false)};style=S.style;style.padding="0";style.margin="0";style.cssFloat="left";style.width="100%";style.textAlign="center";style.position="relative";I.appendChild(S);K=E.createElement("input");if(J==1){K.id="image-url"}K.type="text";K.value=P;style=K.style;style.display="block";style.width="80%";style.marginLeft=style.marginRight="auto";S.appendChild(K);if(J==1){var R=E.createElement("div");R.innerHTML=n;R.style.padding="5px";S.appendChild(R)}var U=E.createElement("input");U.type="button";U.onclick=function(){return N(false)};U.value="OK";style=U.style;style.margin="10px";style.display="inline";style.width="7em";var T=E.createElement("input");T.type="button";T.onclick=function(){return N(true)};T.value="Cancel";style=T.style;style.margin="10px";style.display="inline";style.width="7em";if(/mac/.test(l.platform.toLowerCase())){S.appendChild(T);S.appendChild(U)}else{S.appendChild(U);S.appendChild(T)}a.addEvent(E.body,"keydown",L);I.style.top="50%";I.style.left="50%";I.style.display="block";if(v.isIE_5or6){I.style.position="absolute";I.style.top=E.documentElement.scrollTop+200+"px";I.style.left="50%"}E.body.appendChild(I);I.style.marginTop=-(C.getHeight(I)/2)+"px";I.style.marginLeft=-(C.getWidth(I)/2)+"px"};G();top.setTimeout(function(){O();var R=P.length;if(K.selectionStart!==undefined){K.selectionStart=0;K.selectionEnd=R}else{if(K.createTextRange){var Q=K.createTextRange();Q.collapse(false);Q.moveStart("character",-R);Q.moveEnd("character",R);Q.select()}}K.focus()},0)};C.getTop=function(H,G){var F=H.offsetTop;if(!G){while(H=H.offsetParent){F+=H.offsetTop}}return F};C.getHeight=function(F){return F.offsetHeight||F.scrollHeight};C.getWidth=function(F){return F.offsetWidth||F.scrollWidth};C.getPageSize=function(){var G,H;var F,K;if(self.innerHeight&&self.scrollMaxY){G=E.body.scrollWidth;H=self.innerHeight+self.scrollMaxY}else{if(E.body.scrollHeight>E.body.offsetHeight){G=E.body.scrollWidth;H=E.body.scrollHeight}else{G=E.body.offsetWidth;H=E.body.offsetHeight}}if(self.innerHeight){F=self.innerWidth;K=self.innerHeight}else{if(E.documentElement&&E.documentElement.clientHeight){F=E.documentElement.clientWidth;K=E.documentElement.clientHeight}else{if(E.body){F=E.body.clientWidth;K=E.body.clientHeight}}}var J=Math.max(G,F);var I=Math.max(H,K);return[J,I,F,K]};y.inputPoller=function(O,H){var F=this;var K=y.panels.input;var G;var I;var L;var J;this.tick=function(){if(!a.isVisible(K)){return}if(K.selectionStart||K.selectionStart===0){var Q=K.selectionStart;var P=K.selectionEnd;if(Q!=G||P!=I){G=Q;I=P;if(L!=K.value){L=K.value;return true}}}return false};var N=function(){if(!a.isVisible(K)){return}if(F.tick()){O()}};var M=function(){J=top.setInterval(N,H)};this.destroy=function(){top.clearInterval(J)};M()};y.undoManager=function(Q){var U=this;var O=[];var M=0;var L="none";var G;var R;var H;var K;var F=function(W,V){if(L!=W){L=W;if(!V){I()}}if(!v.isIE||L!="moving"){H=top.setTimeout(N,1)}else{K=null}};var N=function(){K=new y.TextareaState();R.tick();H=undefined};this.setCommandMode=function(){L="command";I();H=top.setTimeout(N,0)};this.canUndo=function(){return M>1};this.canRedo=function(){if(O[M+1]){return true}return false};this.undo=function(){if(U.canUndo()){if(G){G.restore();G=null}else{O[M]=new y.TextareaState();O[--M].restore();if(Q){Q()}}}L="none";y.panels.input.focus();N()};this.redo=function(){if(U.canRedo()){O[++M].restore();if(Q){Q()}}L="none";y.panels.input.focus();N()};var I=function(){var V=K||new y.TextareaState();if(!V){return false}if(L=="moving"){if(!G){G=V}return}if(G){if(O[M-1].text!=G.text){O[M++]=G}G=null}O[M++]=V;O[M+1]=null;if(Q){Q()}};var P=function(V){var X=false;if(V.ctrlKey||V.metaKey){var W=V.charCode||V.keyCode;var Y=String.fromCharCode(W);switch(Y){case"y":U.redo();X=true;break;case"z":if(!V.shiftKey){U.undo()}else{U.redo()}X=true;break}}if(X){if(V.preventDefault){V.preventDefault()}if(top.event){top.event.returnValue=false}return}};var T=function(V){if(!V.ctrlKey&&!V.metaKey){var W=V.keyCode;if((W>=33&&W<=40)||(W>=63232&&W<=63235)){F("moving")}else{if(W==8||W==46||W==127){F("deleting")}else{if(W==13){F("newlines")}else{if(W==27){F("escape")}else{if((W<16||W>20)&&W!=91){F("typing")}}}}}}};var J=function(){a.addEvent(y.panels.input,"keypress",function(W){if((W.ctrlKey||W.metaKey)&&(W.keyCode==89||W.keyCode==90)){W.preventDefault()}});var V=function(){if(v.isIE||(K&&K.text!=y.panels.input.value)){if(H==undefined){L="paste";I();N()}}};R=new y.inputPoller(V,x);a.addEvent(y.panels.input,"keydown",P);a.addEvent(y.panels.input,"keydown",T);a.addEvent(y.panels.input,"mousedown",function(){F("moving")});y.panels.input.onpaste=V;y.panels.input.ondrop=V};var S=function(){J();N();I()};this.destroy=function(){if(R){R.destroy()}};S()};y.editor=function(O){if(!O){O=function(){}}var L=y.panels.input;var I=0;var P=this;var K;var R;var G;var M;var N;var U=function(W){L.focus();if(W.textOp){if(N){N.setCommandMode()}var Y=new y.TextareaState();if(!Y){return}var Z=Y.getChunks();var V=function(){L.focus();if(Z){Y.setChunks(Z)}Y.restore();O()};var X=W.textOp(Z,V);if(!X){V()}}if(W.execute){W.execute(P)}};var S=function(){if(N){F(document.getElementById("wmd-undo-button"),N.canUndo());F(document.getElementById("wmd-redo-button"),N.canRedo())}};var F=function(V,X){var Y="0px";var Z="-20px";var W="-40px";if(X){V.style.backgroundPosition=V.XShift+" "+Y;V.onmouseover=function(){this.style.backgroundPosition=this.XShift+" "+W};V.onmouseout=function(){this.style.backgroundPosition=this.XShift+" "+Y};if(v.isIE){V.onmousedown=function(){y.ieRetardedClick=true;y.ieCachedRange=document.selection.createRange()}}if(!V.isHelp){V.onclick=function(){if(this.onmouseout){this.onmouseout()}U(this);return false}}}else{V.style.backgroundPosition=V.XShift+" "+Z;V.onmouseover=V.onmouseout=V.onclick=function(){}}};var J=function(){var Z=document.getElementById("wmd-button-bar");var W="0px";var Y="-20px";var ae="-40px";var ak=document.createElement("ul");ak.id="wmd-button-row";ak=Z.appendChild(ak);var ad=document.createElement("li");ad.className="wmd-button";ad.id="wmd-bold-button";ad.title=c;ad.XShift="0px";ad.textOp=h.doBold;F(ad,true);ak.appendChild(ad);var ac=document.createElement("li");ac.className="wmd-button";ac.id="wmd-italic-button";ac.title=f;ac.XShift="-20px";ac.textOp=h.doItalic;F(ac,true);ak.appendChild(ac);var ah=document.createElement("li");ah.className="wmd-spacer";ah.id="wmd-spacer1";ak.appendChild(ah);var ai=document.createElement("li");ai.className="wmd-button";ai.id="wmd-link-button";ai.title=z;ai.XShift="-40px";ai.textOp=function(ap,aq){return h.doLinkOrImage(ap,aq,false)};F(ai,true);ak.appendChild(ai);var al=document.createElement("li");al.className="wmd-button";al.id="wmd-quote-button";al.title=u;al.XShift="-60px";al.textOp=h.doBlockquote;F(al,true);ak.appendChild(al);var am=document.createElement("li");am.className="wmd-button";am.id="wmd-code-button";am.title=e;am.XShift="-80px";am.textOp=h.doCode;F(am,true);ak.appendChild(am);var aa=document.createElement("li");aa.className="wmd-button";aa.id="wmd-image-button";aa.title=d;aa.XShift="-100px";aa.textOp=function(ap,aq){return h.doLinkOrImage(ap,aq,true)};F(aa,true);ak.appendChild(aa);var ag=document.createElement("li");ag.className="wmd-spacer";ag.id="wmd-spacer2";ak.appendChild(ag);var ab=document.createElement("li");ab.className="wmd-button";ab.id="wmd-olist-button";ab.title=q;ab.XShift="-120px";ab.textOp=function(ap,aq){h.doList(ap,aq,true)};F(ab,true);ak.appendChild(ab);var ao=document.createElement("li");ao.className="wmd-button";ao.id="wmd-ulist-button";ao.title=t;ao.XShift="-140px";ao.textOp=function(ap,aq){h.doList(ap,aq,false)};F(ao,true);ak.appendChild(ao);var aj=document.createElement("li");aj.className="wmd-button";aj.id="wmd-heading-button";aj.title=i;aj.XShift="-160px";aj.textOp=h.doHeading;F(aj,true);ak.appendChild(aj);var X=document.createElement("li");X.className="wmd-button";X.id="wmd-hr-button";X.title=p;X.XShift="-180px";X.textOp=h.doHorizontalRule;F(X,true);ak.appendChild(X);var af=document.createElement("li");af.className="wmd-spacer";af.id="wmd-spacer3";ak.appendChild(af);var V=document.createElement("li");V.className="wmd-button";V.id="wmd-undo-button";V.title=m;V.XShift="-200px";V.execute=function(ap){ap.undo()};F(V,true);ak.appendChild(V);var an=document.createElement("li");an.className="wmd-button";an.id="wmd-redo-button";an.title=j;if(/win/.test(l.platform.toLowerCase())){an.title=j}else{an.title="重做 - Ctrl+Shift+Z"}an.XShift="-220px";an.execute=function(ap){ap.redo()};F(an,true);ak.appendChild(an);S()};var H=function(){if(/\?noundo/.test(E.location.href)){y.nativeUndo=true}if(!y.nativeUndo){N=new y.undoManager(function(){O();S()})}J();var W="keydown";if(v.isOpera){W="keypress"}a.addEvent(L,W,function(Y){if(Y.ctrlKey||Y.metaKey){var Z=Y.charCode||Y.keyCode;var X=String.fromCharCode(Z).toLowerCase();if(Z===46){X=""}if(Z===190){X="."}switch(X){case"b":U(document.getElementById("wmd-bold-button"));break;case"i":U(document.getElementById("wmd-italic-button"));break;case"l":U(document.getElementById("wmd-link-button"));break;case".":U(document.getElementById("wmd-quote-button"));break;case"k":U(document.getElementById("wmd-code-button"));break;case"g":U(document.getElementById("wmd-image-button"));break;case"o":U(document.getElementById("wmd-olist-button"));break;case"u":U(document.getElementById("wmd-ulist-button"));break;case"h":U(document.getElementById("wmd-heading-button"));break;case"r":U(document.getElementById("wmd-hr-button"));break;case"y":U(document.getElementById("wmd-redo-button"));break;case"z":if(Y.shiftKey){U(document.getElementById("wmd-redo-button"))}else{U(document.getElementById("wmd-undo-button"))}break;default:return}if(Y.preventDefault){Y.preventDefault()}if(top.event){top.event.returnValue=false}}});a.addEvent(L,"keyup",function(X){if(X.shiftKey&&!X.ctrlKey&&!X.metaKey){var Y=X.charCode||X.keyCode;if(Y===13){fakeButton={};fakeButton.textOp=h.doAutoindent;U(fakeButton)}}});if(L.form){var V=L.form.onsubmit;L.form.onsubmit=function(){Q();if(V){return V.apply(this,arguments)}}}};var Q=function(){if(y.showdown){var V=new y.showdown.converter()}var W=L.value;var X=function(){L.value=W};if(!/markdown/.test(y.wmd_env.output.toLowerCase())){if(V){L.value=V.makeHtml(W);top.setTimeout(X,0)}}return true};this.undo=function(){if(N){N.undo()}};this.redo=function(){if(N){N.redo()}};var T=function(){H()};this.destroy=function(){if(N){N.destroy()}if(G.parentNode){G.parentNode.removeChild(G)}if(L){L.style.marginTop=""}top.clearInterval(M)};T()};y.TextareaState=function(){var F=this;var G=y.panels.input;this.init=function(){if(!a.isVisible(G)){return}this.setInputAreaSelectionStartEnd();this.scrollTop=G.scrollTop;if(!this.text&&G.selectionStart||G.selectionStart===0){this.text=G.value}};this.setInputAreaSelection=function(){if(!a.isVisible(G)){return}if(G.selectionStart!==undefined&&!v.isOpera){G.focus();G.selectionStart=F.start;G.selectionEnd=F.end;G.scrollTop=F.scrollTop}else{if(E.selection){if(E.activeElement&&E.activeElement!==G){return}G.focus();var H=G.createTextRange();H.moveStart("character",-G.value.length);H.moveEnd("character",-G.value.length);H.moveEnd("character",F.end);H.moveStart("character",F.start);H.select()}}};this.setInputAreaSelectionStartEnd=function(){if(G.selectionStart||G.selectionStart===0){F.start=G.selectionStart;F.end=G.selectionEnd}else{if(E.selection){F.text=a.fixEolChars(G.value);var K;if(y.ieRetardedClick&&y.ieCachedRange){K=y.ieCachedRange;y.ieRetardedClick=false}else{K=E.selection.createRange()}var L=a.fixEolChars(K.text);var J="\x07";var I=J+L+J;K.text=I;var M=a.fixEolChars(G.value);K.moveStart("character",-I.length);K.text=L;F.start=M.indexOf(J);F.end=M.lastIndexOf(J)-J.length;var H=F.text.length-a.fixEolChars(G.value).length;if(H){K.moveStart("character",-L.length);while(H--){L+="\n";F.end+=1}K.text=L}this.setInputAreaSelection()}}};this.restore=function(){if(F.text!=undefined&&F.text!=G.value){G.value=F.text}this.setInputAreaSelection();G.scrollTop=F.scrollTop};this.getChunks=function(){var H=new y.Chunks();H.before=a.fixEolChars(F.text.substring(0,F.start));H.startTag="";H.selection=a.fixEolChars(F.text.substring(F.start,F.end));H.endTag="";H.after=a.fixEolChars(F.text.substring(F.end));H.scrollTop=F.scrollTop;return H};this.setChunks=function(H){H.before=H.before+H.startTag;H.after=H.endTag+H.after;if(v.isOpera){H.before=H.before.replace(/\n/g,"\r\n");H.selection=H.selection.replace(/\n/g,"\r\n");H.after=H.after.replace(/\n/g,"\r\n")}this.start=H.before.length;this.end=H.before.length+H.selection.length;this.text=H.before+H.selection+H.after;this.scrollTop=H.scrollTop};this.init()};y.Chunks=function(){};y.Chunks.prototype.findTags=function(G,I){var F=this;var H;if(G){H=a.extendRegExp(G,"","$");this.before=this.before.replace(H,function(J){F.startTag=F.startTag+J;return""});H=a.extendRegExp(G,"^","");this.selection=this.selection.replace(H,function(J){F.startTag=F.startTag+J;return""})}if(I){H=a.extendRegExp(I,"","$");this.selection=this.selection.replace(H,function(J){F.endTag=J+F.endTag;return""});H=a.extendRegExp(I,"^","");this.after=this.after.replace(H,function(J){F.endTag=J+F.endTag;return""})}};y.Chunks.prototype.trimWhitespace=function(F){this.selection=this.selection.replace(/^(\s*)/,"");if(!F){this.before+=s.$1}this.selection=this.selection.replace(/(\s*)$/,"");if(!F){this.after=s.$1+this.after}};y.Chunks.prototype.skipLines=function(H,G,F){if(H===undefined){H=1}if(G===undefined){G=1}H++;G++;var I;var J;this.selection=this.selection.replace(/(^\n*)/,"");this.startTag=this.startTag+s.$1;this.selection=this.selection.replace(/(\n*$)/,"");this.endTag=this.endTag+s.$1;this.startTag=this.startTag.replace(/(^\n*)/,"");this.before=this.before+s.$1;this.endTag=this.endTag.replace(/(\n*$)/,"");this.after=this.after+s.$1;if(this.before){I=J="";while(H--){I+="\\n?";J+="\n"}if(F){I="\\n*"}this.before=this.before.replace(new s(I+"$",""),J)}if(this.after){I=J="";while(G--){I+="\\n?";J+="\n"}if(F){I="\\n*"}this.after=this.after.replace(new s(I,""),J)}};h.prefixes="(?:\\s{4,}|\\s*>|\\s*-\\s+|\\s*\\d+\\.|=|\\+|-|_|\\*|#|\\s*\\[[^\n]]+\\]:)";h.unwrap=function(G){var F=new s("([^\\n])\\n(?!(\\n|"+h.prefixes+"))","g");G.selection=G.selection.replace(F,"$1 $2")};h.wrap=function(G,F){h.unwrap(G);var H=new s("(.{1,"+F+"})( +|$\\n?)","gm");G.selection=G.selection.replace(H,function(I,J){if(new s("^"+h.prefixes,"").test(I)){return I}return J+"\n"});G.selection=G.selection.replace(/\s+$/,"")};h.doBold=function(F,G){return h.doBorI(F,G,2,"strong text")};h.doItalic=function(F,G){return h.doBorI(F,G,1,"emphasized text")};h.doBorI=function(L,J,K,F){L.trimWhitespace();L.selection=L.selection.replace(/\n{2,}/g,"\n");L.before.search(/(\**$)/);var I=s.$1;L.after.search(/(^\**)/);var G=s.$1;var M=Math.min(I.length,G.length);if((M>=K)&&(M!=2||K!=1)){L.before=L.before.replace(s("[*]{"+K+"}$",""),"");L.after=L.after.replace(s("^[*]{"+K+"}",""),"")}else{if(!L.selection&&G){L.after=L.after.replace(/^([*_]*)/,"");L.before=L.before.replace(/(\s?)$/,"");var H=s.$1;L.before=L.before+G+H}else{if(!L.selection&&!G){L.selection=F}var N=K<=1?"*":"**";L.before=L.before+N;L.after=N+L.after}}return};h.stripLinkDefs=function(G,F){G=G.replace(/^[ ]{0,3}\[(\d+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|$)/gm,function(K,L,H,I,J){F[L]=K.replace(/\s*$/,"");if(I){F[L]=K.replace(/["(](.+?)[")]$/,"");return I+J}return""});return G};h.addLinkDef=function(M,I){var F=0;var H={};M.before=h.stripLinkDefs(M.before,H);M.selection=h.stripLinkDefs(M.selection,H);M.after=h.stripLinkDefs(M.after,H);var G="";var L=/(\[(?:\[[^\]]*\]|[^\[\]])*\][ ]?(?:\n[ ]*)?\[)(\d+)(\])/g;var K=function(O){F++;O=O.replace(/^[ ]{0,3}\[(\d+)\]:/," ["+F+"]:");G+="\n"+O};var J=function(P,Q,R,O){if(H[R]){K(H[R]);return Q+F+O}return P};M.before=M.before.replace(L,J);if(I){K(I)}else{M.selection=M.selection.replace(L,J)}var N=F;M.after=M.after.replace(L,J);if(M.after){M.after=M.after.replace(/\n*$/,"")}if(!M.after){M.selection=M.selection.replace(/\n*$/,"")}M.after+="\n\n"+G;return N};h.doLinkOrImage=function(F,G,I){F.trimWhitespace();F.findTags(/\s*!?\[/,/\][ ]?(?:\n[ ]*)?(\[.*?\])?/);if(F.endTag.length>1){F.startTag=F.startTag.replace(/!?\[/,"");F.endTag="";h.addLinkDef(F,null)}else{if(/\n\n/.test(F.selection)){h.addLinkDef(F,null);return}var H=function(L){if(L!==null){F.startTag=F.endTag="";var K=" [999]: "+L;var J=h.addLinkDef(F,K);F.startTag=I?"![":"[";F.endTag="]["+J+"]";if(!F.selection){if(I){F.selection="alt text"}else{F.selection="link text"}}}G()};if(I){a.prompt(B,b,H,1)}else{a.prompt(D,g,H)}return true}};a.makeAPI=function(){y.wmd={};y.wmd.editor=y.editor;y.wmd.previewManager=y.previewManager};a.startEditor=function(){if(y.wmd_env.autostart===false){a.makeAPI();return}var G;var F;var H=function(){y.panels=new y.PanelCollection();F=new y.previewManager();var I=F.refresh;G=new y.editor(I);F.refresh(true)};a.addEvent(top,"load",H)};y.previewManager=function(){var H=this;var V;var F;var N;var M;var S;var O;var I=3000;var P="delayed";var K=function(X,Y){a.addEvent(X,"input",Y);X.onpaste=Y;X.ondrop=Y;a.addEvent(X,"keypress",Y);a.addEvent(X,"keydown",Y);F=new y.inputPoller(Y,A)};var R=function(){var X=0;if(top.innerHeight){X=top.pageYOffset}else{if(E.documentElement&&E.documentElement.scrollTop){X=E.documentElement.scrollTop}else{if(E.body){X=E.body.scrollTop}}}return X};var L=function(){if(!y.panels.preview&&!y.panels.output){return}var Z=y.panels.input.value;if(Z&&Z==S){return}else{S=Z}var Y=new Date().getTime();if(!V&&y.showdown){V=new y.showdown.converter()}if(V){Z=V.makeHtml(Z)}var X=new Date().getTime();M=X-Y;G(Z);O=Z};var U=function(){if(N){top.clearTimeout(N);N=undefined}if(P!=="manual"){var X=0;if(P==="delayed"){X=M}if(X>I){X=I}N=top.setTimeout(L,X)}};var J=function(X){if(X.scrollHeight<=X.clientHeight){return 1}return X.scrollTop/(X.scrollHeight-X.clientHeight)};var W=function(){if(y.panels.preview){y.panels.preview.scrollTop=(y.panels.preview.scrollHeight-y.panels.preview.clientHeight)*J(y.panels.preview)}if(y.panels.output){y.panels.output.scrollTop=(y.panels.output.scrollHeight-y.panels.output.clientHeight)*J(y.panels.output)}};this.refresh=function(X){if(X){S="";L()}else{U()}};this.processingTime=function(){return M};this.output=function(){return O};this.setUpdateMode=function(X){P=X;H.refresh()};var Q=true;var G=function(aa){var X=C.getTop(y.panels.input)-R();if(y.panels.output){if(y.panels.output.value!==undefined){y.panels.output.value=aa;y.panels.output.readOnly=true}else{var Z=aa.replace(/&/g,"&amp;");Z=Z.replace(/</g,"&lt;");y.panels.output.innerHTML="<pre><code>"+Z+"</code></pre>"}}if(y.panels.preview){y.panels.preview.innerHTML=aa}W();if(Q){Q=false;return}var Y=C.getTop(y.panels.input)-R();if(v.isIE){top.setTimeout(function(){top.scrollBy(0,Y-X)},0)}else{top.scrollBy(0,Y-X)}};var T=function(){K(y.panels.input,U);L();if(y.panels.preview){y.panels.preview.scrollTop=0}if(y.panels.output){y.panels.output.scrollTop=0}};this.destroy=function(){if(F){F.destroy()}};T()};h.doAutoindent=function(F,G){F.before=F.before.replace(/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]*\n$/,"\n\n");F.before=F.before.replace(/(\n|^)[ ]{0,3}>[ \t]*\n$/,"\n\n");F.before=F.before.replace(/(\n|^)[ \t]+\n$/,"\n\n");if(/(\n|^)[ ]{0,3}([*+-]|\d+[.])[ \t]+.*\n$/.test(F.before)){if(h.doList){h.doList(F)}}if(/(\n|^)[ ]{0,3}>[ \t]+.*\n$/.test(F.before)){if(h.doBlockquote){h.doBlockquote(F)}}if(/(\n|^)(\t|[ ]{4,}).*\n$/.test(F.before)){if(h.doCode){h.doCode(F)}}};h.doBlockquote=function(F,G){F.selection=F.selection.replace(/^(\n*)([^\r]+?)(\n*)$/,function(L,K,J,I){F.before+=K;F.after=I+F.after;return J});F.before=F.before.replace(/(>[ \t]*)$/,function(J,I){F.selection=I+F.selection;return""});F.selection=F.selection.replace(/^(\s|>)+$/,"");F.selection=F.selection||"Blockquote";if(F.before){F.before=F.before.replace(/\n?$/,"\n")}if(F.after){F.after=F.after.replace(/^\n?/,"\n")}F.before=F.before.replace(/(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*$)/,function(I){F.startTag=I;return""});F.after=F.after.replace(/^(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*)/,function(I){F.endTag=I;return""});var H=function(J){var I=J?"> ":"";if(F.startTag){F.startTag=F.startTag.replace(/\n((>|\s)*)\n$/,function(L,K){return"\n"+K.replace(/^[ ]{0,3}>?[ \t]*$/gm,I)+"\n"})}if(F.endTag){F.endTag=F.endTag.replace(/^\n((>|\s)*)\n/,function(L,K){return"\n"+K.replace(/^[ ]{0,3}>?[ \t]*$/gm,I)+"\n"})}};if(/^(?![ ]{0,3}>)/m.test(F.selection)){h.wrap(F,y.wmd_env.lineLength-2);F.selection=F.selection.replace(/^/gm,"> ");H(true);F.skipLines()}else{F.selection=F.selection.replace(/^[ ]{0,3}> ?/gm,"");h.unwrap(F);H(false);if(!/^(\n|^)[ ]{0,3}>/.test(F.selection)&&F.startTag){F.startTag=F.startTag.replace(/\n{0,2}$/,"\n\n")}if(!/(\n|^)[ ]{0,3}>.*$/.test(F.selection)&&F.endTag){F.endTag=F.endTag.replace(/^\n{0,2}/,"\n\n")}}if(!/\n/.test(F.selection)){F.selection=F.selection.replace(/^(> *)/,function(I,J){F.startTag+=J;return""})}};h.doCode=function(F,G){var I=/\S[ ]*$/.test(F.before);var K=/^[ ]*\S/.test(F.after);if((!K&&!I)||/\n/.test(F.selection)){F.before=F.before.replace(/[ ]{4}$/,function(L){F.selection=L+F.selection;return""});var J=1;var H=1;if(/\n(\t|[ ]{4,}).*\n$/.test(F.before)){J=0}if(/^\n(\t|[ ]{4,})/.test(F.after)){H=0}F.skipLines(J,H);if(!F.selection){F.startTag=" ";F.selection="enter code here"}else{if(/^[ ]{0,3}\S/m.test(F.selection)){F.selection=F.selection.replace(/^/gm," ")}else{F.selection=F.selection.replace(/^[ ]{4}/gm,"")}}}else{F.trimWhitespace();F.findTags(/`/,/`/);if(!F.startTag&&!F.endTag){F.startTag=F.endTag="`";if(!F.selection){F.selection="enter code here"}}else{if(F.endTag&&!F.startTag){F.before+=F.endTag;F.endTag=""}else{F.startTag=F.endTag=""}}}};h.doList=function(Q,J,I){var S=/(\n|^)(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*$/;var R=/^\n*(([ ]{0,3}([*+-]|\d+[.])[ \t]+.*)(\n.+|\n{2,}([*+-].*|\d+[.])[ \t]+.*|\n{2,}[ \t]+\S.*)*)\n*/;var F="-";var N=1;var L=function(){var T;if(I){T=" "+N+". ";N++}else{T=" "+F+" "}return T};var M=function(T){if(I===undefined){I=/^\s*\d/.test(T)}T=T.replace(/^[ ]{0,3}([*+-]|\d+[.])\s/gm,function(U){return L()});return T};Q.findTags(/(\n|^)*[ ]{0,3}([*+-]|\d+[.])\s+/,null);if(Q.before&&!/\n$/.test(Q.before)&&!/^\n/.test(Q.startTag)){Q.before+=Q.startTag;Q.startTag=""}if(Q.startTag){var H=/\d+[.]/.test(Q.startTag);Q.startTag="";Q.selection=Q.selection.replace(/\n[ ]{4}/g,"\n");h.unwrap(Q);Q.skipLines();if(H){Q.after=Q.after.replace(R,M)}if(I==H){return}}var K=1;Q.before=Q.before.replace(S,function(T){if(/^\s*([*+-])/.test(T)){F=s.$1}K=/[^\n]\n\n[^\n]/.test(T)?1:0;return M(T)});if(!Q.selection){Q.selection="List item"}var O=L();var G=1;Q.after=Q.after.replace(R,function(T){G=/[^\n]\n\n[^\n]/.test(T)?1:0;return M(T)});Q.trimWhitespace(true);Q.skipLines(K,G,true);Q.startTag=O;var P=O.replace(/./g," ");h.wrap(Q,y.wmd_env.lineLength-P.length);Q.selection=Q.selection.replace(/\n/g,"\n"+P)};h.doHeading=function(H,I){H.selection=H.selection.replace(/\s+/g," ");H.selection=H.selection.replace(/(^\s+|\s+$)/g,"");if(!H.selection){H.startTag="## ";H.selection="Heading";H.endTag=" ##";return}var J=0;H.findTags(/#+[ ]*/,/[ ]*#+/);if(/#+/.test(H.startTag)){J=s.lastMatch.length}H.startTag=H.endTag="";H.findTags(null,/\s?(-+|=+)/);if(/=+/.test(H.endTag)){J=1}if(/-+/.test(H.endTag)){J=2}H.startTag=H.endTag="";H.skipLines(1,1);var K=J==0?2:J-1;if(K>0){var G=K>=2?"-":"=";var F=H.selection.length;if(F>y.wmd_env.lineLength){F=y.wmd_env.lineLength}H.endTag="\n";while(F--){H.endTag+=G}}};h.doHorizontalRule=function(F,G){F.startTag="----------\n";F.selection="";F.skipLines(2,1,true)}};Attacklab.wmd_env={};Attacklab.account_options={};Attacklab.wmd_defaults={version:1,output:"Markdown",lineLength:40,delayLoad:false};if(!Attacklab.wmd){Attacklab.wmd=function(){Attacklab.loadEnv=function(){var b=function(d){if(!d){return}for(var c in d){Attacklab.wmd_env[c]=d[c]}};b(Attacklab.wmd_defaults);b(Attacklab.account_options);b(top.wmd_options);Attacklab.full=true;var a="bold italic link blockquote code image ol ul heading hr";Attacklab.wmd_env.buttons=Attacklab.wmd_env.buttons||a};Attacklab.loadEnv()};Attacklab.wmd();Attacklab.wmdBase();Attacklab.Util.startEditor()}; \ No newline at end of file
diff --git a/templates/fbconnect/xd_receiver.html b/templates/fbconnect/xd_receiver.html
deleted file mode 100755
index c67c57b7..00000000
--- a/templates/fbconnect/xd_receiver.html
+++ /dev/null
@@ -1 +0,0 @@
-<!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" > <body> <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script> </body> </html>