diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2012-07-18 04:27:17 -0400 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2012-07-18 04:27:17 -0400 |
commit | 30ab686096a13f720b9229995bfe32cadce256c8 (patch) | |
tree | 7683773cc96c9b78fc480ca2ab010cc74b5a2428 | |
parent | 56adbc140f865053c41a18a48dda47a99937b775 (diff) | |
parent | 2cad0b5d765811aa6001b8dd37a8d66235a278cf (diff) | |
download | askbot-30ab686096a13f720b9229995bfe32cadce256c8.tar.gz askbot-30ab686096a13f720b9229995bfe32cadce256c8.tar.bz2 askbot-30ab686096a13f720b9229995bfe32cadce256c8.zip |
merged master branch and started working on posting into group from the group page
29 files changed, 393 insertions, 277 deletions
diff --git a/askbot/conf/forum_data_rules.py b/askbot/conf/forum_data_rules.py index a94a5f6c..46a1fe08 100644 --- a/askbot/conf/forum_data_rules.py +++ b/askbot/conf/forum_data_rules.py @@ -137,6 +137,17 @@ settings.register( settings.register( livesettings.BooleanValue( FORUM_DATA_RULES, + 'LIMIT_ONE_ANSWER_PER_USER', + default = True, + description = _( + 'Limit one answer per question per user' + ) + ) +) + +settings.register( + livesettings.BooleanValue( + FORUM_DATA_RULES, 'TAGS_ARE_REQUIRED', description = _('Are tags required?'), default = False, diff --git a/askbot/deps/livesettings/models.py b/askbot/deps/livesettings/models.py index 1a57dfc5..71db8acf 100644 --- a/askbot/deps/livesettings/models.py +++ b/askbot/deps/livesettings/models.py @@ -25,14 +25,20 @@ def _safe_get_siteid(site): def find_setting(group, key, site=None): """Get a setting or longsetting by group and key, cache and return it.""" - + siteid = _safe_get_siteid(site) setting = None - + use_db, overrides = get_overrides(siteid) ck = cache_key('Setting', siteid, group, key) - - if use_db: + + grp = overrides.get(group, None) + + if grp and key in grp: + val = grp[key] + setting = ImmutableSetting(key=key, group=group, value=val) + log.debug('Returning overridden: %s', setting) + elif use_db: try: setting = cache_get(ck) @@ -45,10 +51,10 @@ def find_setting(group, key, site=None): # maybe it is a "long setting" try: setting = LongSetting.objects.get(site__id__exact=siteid, key__exact=key, group__exact=group) - + except LongSetting.DoesNotExist: pass - + cache_set(ck, value=setting) else: @@ -57,13 +63,13 @@ def find_setting(group, key, site=None): val = grp[key] setting = ImmutableSetting(key=key, group=group, value=val) log.debug('Returning overridden: %s', setting) - + if not setting: raise SettingNotSet(key, cachekey=ck) return setting -class SettingNotSet(Exception): +class SettingNotSet(Exception): def __init__(self, k, cachekey=None): self.key = k self.cachekey = cachekey @@ -77,22 +83,22 @@ class SettingManager(models.Manager): class ImmutableSetting(object): - + def __init__(self, group="", key="", value="", site=1): self.site = site self.group = group self.key = key self.value = value - + def cache_key(self, *args, **kwargs): return cache_key('OverrideSetting', self.site, self.group, self.key) - + def delete(self): pass - + def save(self, *args, **kwargs): pass - + def __repr__(self): return "ImmutableSetting: %s.%s=%s" % (self.group, self.key, self.value) @@ -120,11 +126,18 @@ class Setting(models.Model, CachedObjectMixin): site = self.site except Site.DoesNotExist: self.site = Site.objects.get_current() - + super(Setting, self).save(force_insert=force_insert, force_update=force_update) - + self.cache_set() - + + def cache_set(self, *args, **kwargs): + val = kwargs.pop('value', self) + key = self.cache_key(*args, **kwargs) + #TODO: fix this with Django's > 1.3 CACHE dict setting support + length = getattr(settings, 'LIVESETTINGS_CACHE_TIMEOUT', settings.CACHE_TIMEOUT) + cache_set(key, value=val, length=length) + class Meta: unique_together = ('site', 'group', 'key') @@ -149,7 +162,7 @@ class LongSetting(models.Model, CachedObjectMixin): def cache_key(self, *args, **kwargs): # note same cache pattern as Setting. This is so we can look up in one check. - # they can't overlap anyway, so this is moderately safe. At the worst, the + # they can't overlap anyway, so this is moderately safe. At the worst, the # Setting will override a LongSetting. return cache_key('Setting', self.site, self.group, self.key) @@ -164,7 +177,14 @@ class LongSetting(models.Model, CachedObjectMixin): self.site = Site.objects.get_current() super(LongSetting, self).save(force_insert=force_insert, force_update=force_update) self.cache_set() - + + def cache_set(self, *args, **kwargs): + val = kwargs.pop('value', self) + key = self.cache_key(*args, **kwargs) + #TODO: fix this with Django's > 1.3 CACHE dict setting support + length = getattr(settings, 'LIVESETTINGS_CACHE_TIMEOUT', settings.CACHE_TIMEOUT) + cache_set(key, value=val, length=length) + class Meta: unique_together = ('site', 'group', 'key') - + diff --git a/askbot/deps/livesettings/overrides.py b/askbot/deps/livesettings/overrides.py index f3dc3355..c2fc09df 100644 --- a/askbot/deps/livesettings/overrides.py +++ b/askbot/deps/livesettings/overrides.py @@ -35,7 +35,7 @@ def get_overrides(siteid=-1): } } - In the settings dict above, the "val" entries must exactly match the format + In the settings dict above, the "val" entries must exactly match the format stored in the database for a setting. Do not use a literal True or an integer, it needs to be the string representation of them. @@ -45,7 +45,7 @@ def get_overrides(siteid=-1): if hasattr(djangosettings, 'LIVESETTINGS_OPTIONS'): if siteid == -1: siteid = _safe_get_siteid(None) - + opts = djangosettings.LIVESETTINGS_OPTIONS if opts.has_key(siteid): opts = opts[siteid] diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index 3d21a907..e33f17e7 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -8,6 +8,8 @@ Development version * Tag moderation (Evgeny) * Editable optional three level category selector for the tags (Evgeny) * Tag editor adding tags as they are typed (Evgeny) +* Optionally allow limiting one answer per question per person (Evgeny) +* Added management command `build_livesettings_cache` (Adolfo) * Welcome email for the case when replying by email is enabled (Evgeny) * Detection of email signature based on the response to the welcome email (Evgeny) * Hide "website" and "about" section of the blocked user profiles diff --git a/askbot/doc/source/management-commands.rst b/askbot/doc/source/management-commands.rst index b96251dc..2755bcf5 100644 --- a/askbot/doc/source/management-commands.rst +++ b/askbot/doc/source/management-commands.rst @@ -80,6 +80,8 @@ The bulk of the management commands fall into this group and will probably be th +---------------------------------+-------------------------------------------------------------+ | `build_thread_summary_cache` | Rebuilds cache for the question summary snippet. | +---------------------------------+-------------------------------------------------------------+ +| `build_livesettings_cache` | Rebuilds cache for the live settings. | ++---------------------------------+-------------------------------------------------------------+ | `delete_contextless_...` | `delete_contextless_badge_award_activities` | | | Deletes Activity objects of type badge award where the | | | related context object is lost. | diff --git a/askbot/exceptions.py b/askbot/exceptions.py index d2d5ddf0..12802e7e 100644 --- a/askbot/exceptions.py +++ b/askbot/exceptions.py @@ -19,6 +19,11 @@ class InsufficientReputation(exceptions.PermissionDenied): """ pass +class AnswerAlreadyGiven(exceptions.PermissionDenied): + """Raised when user attempts to post a second answer + to the same question""" + pass + class DuplicateCommand(exceptions.PermissionDenied): """exception class to indicate that something that can happen only once was attempted for the second time diff --git a/askbot/management/commands/build_livesettings_cache.py b/askbot/management/commands/build_livesettings_cache.py new file mode 100644 index 00000000..1898fc6a --- /dev/null +++ b/askbot/management/commands/build_livesettings_cache.py @@ -0,0 +1,12 @@ +from django.core.management.base import NoArgsCommand + +class Command(NoArgsCommand): + '''Loads livesettings values to cache helping speed up + initial load time for the users''' + + def handle_noargs(self, **options): + from askbot.conf import settings + #Just loads all the settings that way they will be in the cache + for key, value in settings._ConfigSettings__instance.items(): + empty1 = getattr(settings, key) + print 'cache pre-loaded' diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index 166bf0c8..78aa26c1 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -562,9 +562,16 @@ def user_assert_can_post_question(self): ) -def user_assert_can_post_answer(self): +def user_assert_can_post_answer(self, thread = None): """same as user_can_post_question """ + limit_answers = askbot_settings.LIMIT_ONE_ANSWER_PER_USER + if limit_answers and thread.has_answer_by_user(self): + message = _( + 'Sorry, you already gave an answer, please edit it instead.' + ) + raise askbot_exceptions.AnswerAlreadyGiven(message) + self.assert_can_post_question() @@ -848,7 +855,9 @@ def user_assert_can_close_question(self, question = None): def user_assert_can_reopen_question(self, question = None): assert(question.post_type == 'question') + #for some reason rep to reopen own questions != rep to close own q's owner_min_rep_setting = askbot_settings.MIN_REP_TO_REOPEN_OWN_QUESTIONS + min_rep_setting = askbot_settings.MIN_REP_TO_CLOSE_OTHERS_QUESTIONS general_error_message = _( 'Sorry, only administrators, moderators ' @@ -861,15 +870,27 @@ def user_assert_can_reopen_question(self, question = None): 'a minimum reputation of %(min_rep)s is required' ) % {'min_rep': owner_min_rep_setting} + blocked_error_message = _( + 'Sorry, you cannot reopen questions ' + 'because your account is blocked' + ) + + suspended_error_message = _( + 'Sorry, you cannot reopen questions ' + 'because your account is suspended' + ) + _assert_user_can( user = self, post = question, - admin_or_moderator_required = True, owner_can = True, suspended_owner_cannot = True, owner_min_rep_setting = owner_min_rep_setting, + min_rep_setting = min_rep_setting, owner_low_rep_error_message = owner_low_rep_error_message, - general_error_message = general_error_message + general_error_message = general_error_message, + blocked_error_message = blocked_error_message, + suspended_error_message = suspended_error_message ) @@ -1725,7 +1746,7 @@ def user_post_answer( assert(error_message is not None) raise django_exceptions.PermissionDenied(error_message) - self.assert_can_post_answer() + self.assert_can_post_answer(thread = question.thread) if getattr(question, 'post_type', '') != 'question': raise TypeError('question argument must be provided') @@ -2888,6 +2909,10 @@ def send_instant_notifications_about_activity_in_post( ) #send email for all recipients for user in recipients: + + if user.is_blocked(): + continue + reply_address, alt_reply_address = get_reply_to_addresses(user, post) subject_line, body_text = format_instant_notification_email( diff --git a/askbot/models/question.py b/askbot/models/question.py index bc1c45f5..acbfffe0 100644 --- a/askbot/models/question.py +++ b/askbot/models/question.py @@ -565,6 +565,14 @@ class Thread(models.Model): output += answer.format_for_email_as_subthread() return output + def get_answers_by_user(self, user): + """regardless - deleted or not""" + return self.posts.filter(post_type = 'answer', author = user) + + def has_answer_by_user(self, user): + #use len to cache the queryset + return len(self.get_answers_by_user(user)) > 0 + def tagname_meta_generator(self): return u','.join([unicode(tag) for tag in self.get_tag_names()]) @@ -1055,6 +1063,7 @@ class AnonymousQuestion(AnonymousContent): def publish(self,user): added_at = datetime.datetime.now() + #todo: wrong - use User.post_question() instead Thread.objects.create_new( title = self.title, added_at = added_at, diff --git a/askbot/setup_templates/settings.py b/askbot/setup_templates/settings.py index 32af9920..632c4e70 100644 --- a/askbot/setup_templates/settings.py +++ b/askbot/setup_templates/settings.py @@ -181,6 +181,8 @@ INSTALLED_APPS = ( CACHE_BACKEND = 'locmem://' #needed for django-keyedcache CACHE_TIMEOUT = 6000 +#sets a special timeout for livesettings if you want to make them different +LIVESETTINGS_CACHE_TIMEOUT = CACHE_TIMEOUT CACHE_PREFIX = 'askbot' #make this unique CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True #If you use memcache you may want to uncomment the following line to enable memcached based sessions @@ -229,3 +231,4 @@ CSRF_COOKIE_NAME = 'askbot_csrf' STATICFILES_DIRS = ( os.path.join(ASKBOT_ROOT, 'skins'),) RECAPTCHA_USE_SSL = True + diff --git a/askbot/setup_templates/settings.py.mustache b/askbot/setup_templates/settings.py.mustache index 3c3daaa2..18ac214d 100644 --- a/askbot/setup_templates/settings.py.mustache +++ b/askbot/setup_templates/settings.py.mustache @@ -180,6 +180,8 @@ INSTALLED_APPS = ( CACHE_BACKEND = 'locmem://' #needed for django-keyedcache CACHE_TIMEOUT = 6000 +#sets a special timeout for livesettings if you want to make them different +LIVESETTINGS_CACHE_TIMEOUT = CACHE_TIMEOUT CACHE_PREFIX = 'askbot' #make this unique CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True #If you use memcache you may want to uncomment the following line to enable memcached based sessions diff --git a/askbot/skins/common/media/js/utils.js b/askbot/skins/common/media/js/utils.js index 43316da7..da0e029b 100644 --- a/askbot/skins/common/media/js/utils.js +++ b/askbot/skins/common/media/js/utils.js @@ -1,6 +1,10 @@ //var $, scriptUrl, askbotSkin +/** + * attention - this function needs to be retired + * as it cannot accurately give url to the media file + */ var mediaUrl = function(resource){ - return askbot['settings']['static_url'] + askbotSkin + '/' + resource; + return askbot['settings']['static_url'] + 'default' + '/' + resource; }; var cleanUrl = function(url){ diff --git a/askbot/skins/default/media/style/lib_style.less b/askbot/skins/default/media/style/lib_style.less index 63389526..05ab38f5 100644 --- a/askbot/skins/default/media/style/lib_style.less +++ b/askbot/skins/default/media/style/lib_style.less @@ -14,13 +14,12 @@ @body-font:Arial; /* "Trebuchet MS", sans-serif;*/ @sort-font:Georgia, serif; -@main-font:'Yanone Kaffeesatz', Arial, sans-serif; +@main-font:'Open Sans Condensed', Arial, sans-serif; @secondary-font:Arial; /* Buttons */ -.button-style(@w:100px ,@h:20px, @f:14px){ - width:@w; +.button-style(@h:20px, @f:14px){ height:@h; font-size:@f; text-align:center; diff --git a/askbot/skins/default/media/style/style.css b/askbot/skins/default/media/style/style.css index 348eb6b2..7a695825 100644 --- a/askbot/skins/default/media/style/style.css +++ b/askbot/skins/default/media/style/style.css @@ -195,7 +195,7 @@ body.user-messages { text-align: center; background-color: #f5dd69; border-top: #fff 1px solid; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .notify p.notification { margin-top: 6px; @@ -222,7 +222,7 @@ body.user-messages { #header { margin-top: 0px; background: #16160f; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .content-wrapper { /* wrapper positioning class */ @@ -275,12 +275,13 @@ body.user-messages { float: right; /* for #header.with-logo it is modified */ + margin-right: 7px; } #metaNav a { color: #e2e2ae; padding: 0px 0px 0px 35px; height: 25px; - line-height: 30px; + line-height: 25px; margin: 5px 0px 0px 10px; font-size: 18px; font-weight: 100; @@ -337,7 +338,7 @@ body.user-messages { border-bottom: #d3d3c2 1px solid; border-top: #fcfcfc 1px solid; margin-bottom: 10px; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } #secondaryHeader #homeButton { border-right: #afaf9e 1px solid; @@ -359,11 +360,11 @@ body.user-messages { float: left; } #secondaryHeader #scopeWrapper .scope-selector { - font-size: 21px; - color: #5a5a4b; + font-size: 20px; + color: #7a7a6b; height: 55px; line-height: 55px; - margin-left: 24px; + margin-left: 16px; } #secondaryHeader #scopeWrapper .on { background: url(../images/scopearrow.png) no-repeat center bottom; @@ -376,7 +377,7 @@ body.user-messages { display: inline-block; background-color: #fff; - width: 412px; + width: 400px; border: 1px solid #c9c9b5; float: right; height: 42px; @@ -384,21 +385,22 @@ body.user-messages { } #searchBar .searchInput, #searchBar .searchInputCancelable { - font-size: 30px; - height: 40px; + font-size: 26px; + height: 39px; font-weight: 300; background: #FFF; border: 0px; color: #484848; padding-left: 10px; + padding-top: 1px; font-family: Arial; - vertical-align: middle; + vertical-align: top; } #searchBar .searchInput { - width: 352px; + width: 340px; } #searchBar .searchInputCancelable { - width: 317px; + width: 305px; } #searchBar .logoutsearch { width: 337px; @@ -450,14 +452,13 @@ body.anon #searchBar .searchInputCancelable { margin-top: 6px; float: right; text-transform: uppercase; - width: 200px; height: 42px; - font-size: 23px; + font-size: 20px; text-align: center; text-decoration: none; cursor: pointer; color: #4a757f; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; text-shadow: 0px 1px 0px #c6d9dd; -moz-text-shadow: 0px 1px 0px #c6d9dd; -webkit-text-shadow: 0px 1px 0px #c6d9dd; @@ -478,6 +479,9 @@ body.anon #searchBar .searchInputCancelable { -webkit-box-shadow: 1px 1px 2px #636363; -moz-box-shadow: 1px 1px 2px #636363; box-shadow: 1px 1px 2px #636363; + width: 200px; + /* to match width of sidebar */ + } #askButton:hover { background-color: #cde5e9; @@ -522,7 +526,7 @@ body.anon #searchBar .searchInputCancelable { .box p { margin-bottom: 4px; color: #707070; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .box p.info-box-follow-up-links { text-align: right; @@ -539,7 +543,7 @@ body.anon #searchBar .searchInputCancelable { color: #656565; padding-right: 10px; margin-bottom: 10px; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; width: 190px; } .box h3 { @@ -547,7 +551,7 @@ body.anon #searchBar .searchInputCancelable { font-size: 18px; text-align: left; font-weight: normal; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; padding-left: 0px; } .box .contributorback { @@ -556,12 +560,10 @@ body.anon #searchBar .searchInputCancelable { .box label { color: #707070; font-size: 15px; - display: block; - float: right; + vertical-align: bottom; + display: inline; text-align: left; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; - width: 80px; - margin-right: 18px; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .box #displayTagFilterControl label, .box #emailTagFilterControl label { @@ -594,7 +596,7 @@ body.anon #searchBar .searchInputCancelable { .box .inputs #ignoredTagInput, .box .inputs #subscribedTagInput, .box .inputs #ab-tag-search { - width: 156px; + width: 152px; padding-left: 5px; border: #c9c9b5 1px solid; height: 25px; @@ -609,14 +611,13 @@ body.anon #searchBar .searchInputCancelable { border: 0; font-weight: bold; margin-top: -2px; - width: 30px; height: 27px; font-size: 14px; text-align: center; text-decoration: none; cursor: pointer; color: #4a757f; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; text-shadow: 0px 1px 0px #c6d9dd; -moz-text-shadow: 0px 1px 0px #c6d9dd; -webkit-text-shadow: 0px 1px 0px #c6d9dd; @@ -672,14 +673,13 @@ body.anon #searchBar .searchInputCancelable { font-weight: normal; margin-top: 3px; display: block; - width: 120px; height: 34px; font-size: 21px; text-align: center; text-decoration: none; cursor: pointer; color: #4a757f; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; text-shadow: 0px 1px 0px #c6d9dd; -moz-text-shadow: 0px 1px 0px #c6d9dd; -webkit-text-shadow: 0px 1px 0px #c6d9dd; @@ -702,6 +702,7 @@ body.anon #searchBar .searchInputCancelable { box-shadow: 1px 1px 2px #636363; margin: 0 auto; padding: 0; + width: 130px; } .box a.followed:hover, .box a.follow:hover { @@ -740,7 +741,7 @@ body.anon #searchBar .searchInputCancelable { text-align: center; } .box .notify-sidebar #question-subscribe-sidebar { - margin: 7px 0 0 3px; + margin: 0 0 0 3px; } .users-page .box label { display: inline; @@ -877,20 +878,20 @@ body.anon #searchBar .searchInputCancelable { /* ----- Headline, containing number of questions and tags selected, check main_page/headline.html ----- */ #questionCount { font-weight: bold; - font-size: 23px; + font-size: 20px; color: #7ea9b3; width: 200px; float: left; - margin-bottom: 8px; + margin-bottom: 6px; padding-top: 6px; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } #listSearchTags { float: left; margin-top: 3px; color: #707070; font-size: 16px; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } ul#searchTags { margin-left: 10px; @@ -904,7 +905,7 @@ ul#searchTags { margin: 5px 0 10px 0; padding: 0px; float: left; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .search-tips a { text-decoration: underline; @@ -918,28 +919,26 @@ ul#searchTags { padding: 0; width: 100%; } -.main-page #question-list { - margin-top: 10px; -} .short-summary { position: relative; filter: inherit; - padding: 10px; + padding: 10px 0 3px 0; border-bottom: 1px solid #DDDBCE; margin-bottom: 1px; overflow: hidden; - width: 710px; + width: 733px; float: left; - background: url(../images/summary-background.png) repeat-x; + /*background: url(../images/summary-background.png) repeat-x;*/ + } .short-summary h2 { - font-size: 24px; + font-size: 20px; font-weight: normal; line-height: 26px; padding-left: 0; - margin-bottom: 6px; + margin-bottom: 7px; display: block; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .short-summary a { color: #464646; @@ -964,12 +963,12 @@ ul#searchTags { .short-summary .counts { float: right; margin: 4px 0 0 5px; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .short-summary .counts .item-count { padding: 0px 5px 0px 5px; font-size: 25px; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .short-summary .counts .votes div, .short-summary .counts .views div, @@ -981,7 +980,7 @@ ul#searchTags { color: #646464; } .short-summary .tags { - margin-top: 0; + margin: 0 0 0 1px; } .short-summary .votes, .short-summary .answers, @@ -1179,6 +1178,10 @@ ul.tags.marked-tags li, ul#ab-user-tags li { width: 160px; margin: 5px; + margin-left: 0; +} +.tags-page ul.tags { + margin-left: 5px; } ul#related-tags li { margin: 0 5px 8px 0; @@ -1284,7 +1287,7 @@ ul#related-tags li { /* ----- Ask and Edit Question Form template----- */ .section-title { color: #7ea9b3; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; font-weight: bold; font-size: 24px; } @@ -1373,14 +1376,13 @@ ul#related-tags li { float: left; font-weight: normal; margin-top: 3px; - width: 160px; height: 34px; font-size: 21px; text-align: center; text-decoration: none; cursor: pointer; color: #4a757f; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; text-shadow: 0px 1px 0px #c6d9dd; -moz-text-shadow: 0px 1px 0px #c6d9dd; -webkit-text-shadow: 0px 1px 0px #c6d9dd; @@ -1560,11 +1562,11 @@ ul#related-tags li { /* ----- Question template ----- */ .question-page h1 { padding-top: 0px; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .question-page h1 a { color: #464646; - font-size: 30px; + font-size: 26px; font-weight: normal; line-height: 1; } @@ -1573,12 +1575,12 @@ ul#related-tags li { clear: both; padding: 3px 0 0 23px; font-size: 15px; - width: 110px; + width: 130px; background-position: center left; margin-left: 0px !important; } .question-page p.rss a { - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; vertical-align: top; } .question-page .question-content { @@ -1592,7 +1594,7 @@ ul#related-tags li { } .question-page #question-table, .question-page .answer-table { - margin: 6px 0 6px 0; + margin: 8px 0 6px 0; border-spacing: 0px; width: 670px; padding-right: 10px; @@ -1743,7 +1745,7 @@ ul#related-tags li { } .question-page #questionCount { float: left; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; line-height: 15px; } .question-page .question-img-upvote, @@ -1792,7 +1794,7 @@ ul#related-tags li { color: #7ea9b3; width: 200px; float: left; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .question-page .comments { font-size: 12px; @@ -1855,14 +1857,13 @@ ul#related-tags li { .question-page .comments button { line-height: 25px; margin-bottom: 5px; - width: 100px; height: 27px; font-size: 12px; text-align: center; text-decoration: none; cursor: pointer; color: #4a757f; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; text-shadow: 0px 1px 0px #c6d9dd; -moz-text-shadow: 0px 1px 0px #c6d9dd; -webkit-text-shadow: 0px 1px 0px #c6d9dd; @@ -2035,8 +2036,8 @@ ul#related-tags li { float: left; text-align: center; padding-top: 2px; - margin: 10px 10px 0px 3px; - /* smalls IE fixes */ + margin: 0px 10px 0px 3px; + /* small IE fixes */ *margin: 0; *height: 210px; @@ -2046,15 +2047,16 @@ ul#related-tags li { cursor: pointer; } .question-page .vote-number { - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; - padding: 0px 0 5px 0; + font-family: 'Open Sans Condensed', Arial, sans-serif; + padding: 2px 0 5px 0; font-size: 25px; font-weight: bold; color: #777; } .question-page .vote-buttons .notify-sidebar { text-align: left; - width: 120px; + width: 130px; + margin-top: 7px; } .question-page .vote-buttons .notify-sidebar label { vertical-align: top; @@ -2124,7 +2126,7 @@ ul#related-tags li { margin-top: 10px; } .question-page #fmanswer h2 { - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; color: #7ea9b3; font-size: 24px; } @@ -2245,14 +2247,13 @@ ul#related-tags li { .user-profile-page input.submit { font-weight: normal; margin: 5px 0px; - width: 100px; height: 26px; font-size: 15px; text-align: center; text-decoration: none; cursor: pointer; color: #4a757f; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; text-shadow: 0px 1px 0px #c6d9dd; -moz-text-shadow: 0px 1px 0px #c6d9dd; -webkit-text-shadow: 0px 1px 0px #c6d9dd; @@ -2341,14 +2342,13 @@ ul#related-tags li { #local_login_buttons .submit-b, #password-fs .submit-b, #openid-fs .submit-b { - width: 100px; height: 24px; font-size: 15px; text-align: center; text-decoration: none; cursor: pointer; color: #4a757f; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; text-shadow: 0px 1px 0px #c6d9dd; -moz-text-shadow: 0px 1px 0px #c6d9dd; -webkit-text-shadow: 0px 1px 0px #c6d9dd; @@ -2492,7 +2492,7 @@ a:hover.medal { } .user-profile-page h2 { padding: 10px 0px 10px 0px; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } .user-details { font-size: 13px; @@ -2517,14 +2517,13 @@ a:hover.medal { font-weight: bold; line-height: 26px; margin-top: -2px; - width: 100px; height: 26px; font-size: 14px; text-align: center; text-decoration: none; cursor: pointer; color: #4a757f; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; text-shadow: 0px 1px 0px #c6d9dd; -moz-text-shadow: 0px 1px 0px #c6d9dd; -webkit-text-shadow: 0px 1px 0px #c6d9dd; @@ -2579,13 +2578,13 @@ a:hover.medal { display: none; } .count { - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; font-size: 200%; font-weight: 700; color: #777777; } .scoreNumber { - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; font-size: 35px; font-weight: 800; color: #777; @@ -2696,7 +2695,7 @@ a:hover.medal { color: #525252; } .revision h3 { - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; font-size: 21px; padding-left: 0px; } @@ -2803,7 +2802,7 @@ ins { padding: 6px 0 0 0; background: #16160f; font-size: 16px; - font-family: 'Yanone Kaffeesatz', Arial, sans-serif; + font-family: 'Open Sans Condensed', Arial, sans-serif; } #ground p { margin-bottom: 0; @@ -3375,6 +3374,9 @@ p.signup_p { padding: 0; margin-top: -3px; } +.user-profile-page ul.tags { + margin-left: 5px; +} .userList { font-size: 13px; } @@ -3518,7 +3520,6 @@ body.anon.lang-es #searchBar .searchInputCancelable { margin: 0 5px 3px 0; } .group-wiki .follow-toggle.group-join-btn { - width: 150px; margin: 4px auto 10px auto; display: block; } diff --git a/askbot/skins/default/media/style/style.less b/askbot/skins/default/media/style/style.less index bfb567bb..916312d8 100644 --- a/askbot/skins/default/media/style/style.less +++ b/askbot/skins/default/media/style/style.less @@ -269,12 +269,13 @@ body.user-messages { #metaNav {/* Top Navigation bar containing links for tags, people and badges, check widgets/header.html */ float: right;/* for #header.with-logo it is modified */ + margin-right: 7px; a { color: #e2e2ae; padding: 0px 0px 0px 35px; height: 25px; - line-height: 30px; + line-height: 25px; margin:5px 0px 0px 10px; font-size: 18px; font-weight: 100; @@ -367,11 +368,11 @@ body.user-messages { } .scope-selector{ - font-size:21px; - color:#5a5a4b; + font-size:20px; + color:#7a7a6b; height:55px; line-height:55px; - margin-left:24px + margin-left:16px } .on{ background:url(../images/scopearrow.png) no-repeat center bottom; @@ -384,32 +385,33 @@ body.user-messages { } #searchBar { /* Main search form , check widgets/search_bar.html */ - display:inline-block; + display: inline-block; background-color: #fff; - width:412px; + width: 400px; border: 1px solid #c9c9b5; float:right; height:42px; margin:6px 0px 0px 15px; .searchInput, .searchInputCancelable{ - font-size: 30px; - height: 40px; + font-size: 26px; + height: 39px; font-weight:300; background:#FFF; border:0px; color:#484848; padding-left:10px; + padding-top: 1px; font-family:@body-font; - vertical-align: middle; + vertical-align: top; } .searchInput,{ - width: 352px; + width: 340px; } .searchInputCancelable { - width: 317px; + width: 305px; } .logoutsearch { @@ -471,7 +473,8 @@ body.anon { margin-top:6px; float:right; text-transform:uppercase; - .button-style(200px, 42px, 23px); + .button-style(42px, 20px); + width: 200px;/* to match width of sidebar */ } #askButton:hover{ @@ -545,12 +548,10 @@ body.anon { label { color: @info-text; font-size:15px; - display: block; - float: right; + vertical-align: bottom; + display: inline; text-align:left; font-family:@main-font; - width:80px; - margin-right:18px; } #displayTagFilterControl label, @@ -586,7 +587,7 @@ body.anon { #ignoredTagInput, #subscribedTagInput, #ab-tag-search { - width:156px; + width:152px; padding-left:5px; border:#c9c9b5 1px solid; height:25px; @@ -601,7 +602,7 @@ body.anon { border:0; font-weight:bold; margin-top:-2px; - .button-style(30px, 27px, 14px); + .button-style(27px, 14px); .rounded-corners(4px); } #interestingTagAdd:hover, @@ -626,8 +627,9 @@ body.anon { font-weight:normal; margin-top:3px; display:block; - .button-style(120px,34px,21px); + .button-style(34px,21px); .center; + width: 130px; } a.followed:hover, a.follow:hover{ @@ -658,7 +660,7 @@ body.anon { /* notify by email box */ .notify-sidebar #question-subscribe-sidebar { - margin: 7px 0 0 3px; + margin: 0 0 0 3px; } } @@ -672,7 +674,7 @@ body.anon { font-size:16px; border-bottom:#cccccc 1px solid; font-size:13px; - + strong{ float:right; padding-right:10px; @@ -680,16 +682,23 @@ body.anon { } .questions-related { word-wrap: break-word; - + p { line-height: 20px; - padding: 4px 0px 4px 0px; + padding: 4px 0px 9px 0px; font-size: 16px; font-weight:normal; border-bottom:#cccccc 1px solid; } - a{ + p:first-child { + margin-top: -4px; + } + p:last-child { + border: none; + } + a { font-size:13px; + line-height: 1.3; } } /* tips and markdown help are widgets for ask template */ @@ -812,12 +821,12 @@ body.anon { #questionCount{ font-weight:bold; - font-size:23px; + font-size:20px; color:@section-title; width:200px; float:left; - margin-bottom:8px; - padding-top:6px; + margin-bottom:6px; + padding-top: 6px; font-family:@main-font; } @@ -860,27 +869,23 @@ ul#searchTags { width: 100%; } -.main-page #question-list { - margin-top: 10px; -} - .short-summary { position: relative; filter: inherit; - padding: 10px; + padding: 10px 0 3px 0; border-bottom: 1px solid #DDDBCE; margin-bottom:1px; overflow: hidden; - width: 710px; + width: 733px; float: left; - background: url(../images/summary-background.png) repeat-x; - + /*background: url(../images/summary-background.png) repeat-x;*/ + h2 { - font-size: 24px; + font-size: 20px; font-weight:normal; line-height: 26px; padding-left: 0; - margin-bottom:6px; + margin-bottom:7px; display:block; font-family:@main-font; } @@ -934,7 +939,7 @@ ul#searchTags { } .tags { - margin-top: 0; + margin: 0 0 0 1px; } .votes, .answers, .favorites, .views { @@ -1427,7 +1432,7 @@ ul#related-tags li { float: left; font-weight:normal; margin-top:3px; - .button-style(160px,34px,21px); + .button-style(34px,21px); margin-right:7px; } @@ -1593,14 +1598,14 @@ ul#related-tags li { h1{ padding-top:0px; - font-family:@main-font; - } - - h1 a{ - color:@question-link; - font-size:30px; - font-weight:normal; - line-height:1; + font-family:@main-font; + + a { + color:@question-link; + font-size:26px; + font-weight:normal; + line-height:1; + } } p.rss { @@ -1608,7 +1613,7 @@ ul#related-tags li { clear:both; padding: 3px 0 0 23px; font-size: 15px; - width:110px; + width:130px; background-position:center left; margin-left:0px !important; } @@ -1617,7 +1622,7 @@ ul#related-tags li { font-family:@main-font; vertical-align: top; } - + .question-content{ float:right; width:682px; @@ -1637,7 +1642,7 @@ ul#related-tags li { #question-table, .answer-table { - margin: 6px 0 6px 0; + margin: 8px 0 6px 0; border-spacing: 0px; width: 670px; padding-right:10px; @@ -1781,7 +1786,7 @@ ul#related-tags li { .tabBar{ width:100%; } - + #questionCount{ float:left; font-family:@main-font; @@ -1816,9 +1821,6 @@ ul#related-tags li { #fmanswer_button{ margin:8px 0px; } - #fmanswer_button.answer-own-question { - width: 150px; - } .question-img-favorite:hover { background: url(../images/vote-favorite-on.png) } @@ -1901,7 +1903,7 @@ ul#related-tags li { button{ line-height:25px; margin-bottom:5px; - .button-style(100px, 27px, 12px); + .button-style(27px, 12px); font-family:@body-font; font-weight:bold; } @@ -1955,9 +1957,9 @@ ul#related-tags li { margin: -3px 0px 0px -2px; } .content { - margin-bottom: 7px; + margin-bottom: 7px; } - + .comment-votes { float: left; width: 37px; @@ -2063,7 +2065,7 @@ ul#related-tags li { .vote-number { font-family: @main-font; - padding: 0px 0 5px 0; + padding: 2px 0 5px 0; font-size: 25px; font-weight: bold; color: #777; @@ -2071,10 +2073,11 @@ ul#related-tags li { .vote-buttons .notify-sidebar { text-align: left; - width:120px; - } - .vote-buttons .notify-sidebar label { - vertical-align: top; + width:130px; + margin-top: 7px; + label { + vertical-align: top; + } } .tabBar-answer{ @@ -2091,7 +2094,7 @@ ul#related-tags li { .accepted-answer { background-color: #f7fecc; border-bottom-color: #9BD59B; - + .vote-buttons { width:27px; margin-right:10px; @@ -2253,7 +2256,7 @@ ul#related-tags li { input.submit{ font-weight:normal; margin:5px 0px; - .button-style(100px,26px,15px); + .button-style(26px,15px); font-family:@body-font; } input.submit:hover{ @@ -2284,7 +2287,7 @@ ul#related-tags li { width:200px; } .submit-b{ - .button-style(100px,24px,15px); + .button-style(24px,15px); font-family:@body-font; font-weight:bold; padding-right:10px; @@ -2442,7 +2445,7 @@ a:hover.medal { font-weight:bold; line-height:26px; margin-top:-2px; - .button-style(100px,26px,14px); + .button-style(26px,14px); } .follow-toggle:hover, .submit:hover { @@ -3514,7 +3517,6 @@ body.anon.lang-es { margin: 0 5px 3px 0; } .follow-toggle.group-join-btn { - width: 150px; margin: 4px auto 10px auto; display: block; } diff --git a/askbot/skins/default/templates/macros.html b/askbot/skins/default/templates/macros.html index 499acf41..4204d362 100644 --- a/askbot/skins/default/templates/macros.html +++ b/askbot/skins/default/templates/macros.html @@ -6,23 +6,6 @@ >{% if icon == False %}{% if site_label %}{{ site_label }}{% else %}{{ site }}{% endif %}{% endif %}</a> {%- endmacro -%} -{%- macro follow_toggle(follow, name, alias, id) -%} - {# follow - boolean; name - object type name; alias - e.g. users name; id - object id #} - <div - class="follow-toggle follow-user-toggle" - id="follow-{{ name|escape }}-{{ id }}" - > - {% if follow %} - <div class="follow">{% trans %}follow {{alias}}{% endtrans %}</div> - {% else %} - <div class="unfollow"> - <div class="unfollow-red">{% trans %}unfollow {{alias}}{% endtrans %}</div> - <div class="unfollow-green">{% trans %}following {{alias}}{% endtrans %}</div> - </div> - {% endif %} - </div> -{%- endmacro -%} - {%- macro inbox_post_snippet(response, inbox_section) -%} <div id="re_{{response.id}}" class="re{% if response.is_new %} new highlight{% else %} seen{% endif %}"> <input type="checkbox" /> @@ -534,8 +517,8 @@ answer {% if answer.accepted() %}accepted-answer{% endif %} {% if answer.author_ {%- macro follow_toggle(follow, name, alias, id) -%} {# follow - boolean; name - object type name; alias - e.g. users name; id - object id #} <div - class="follow-toggle" - id="follow-{{ name }}-{{ id }}" + class="follow-toggle follow-user-toggle" + id="follow-{{ name|escape }}-{{ id }}" > {% if follow %} <div class="follow">{% trans %}follow {{alias}}{% endtrans %}</div> diff --git a/askbot/skins/default/templates/meta/bottom_scripts.html b/askbot/skins/default/templates/meta/bottom_scripts.html index 093283f8..6c132203 100644 --- a/askbot/skins/default/templates/meta/bottom_scripts.html +++ b/askbot/skins/default/templates/meta/bottom_scripts.html @@ -42,33 +42,36 @@ </script> {% endif %} <script type="text/javascript"> -{% if active_tab != "tags" and active_tab != "users" %} $(document).ready(function(){ - if (Modernizr.history) { - // history management works! - } else { - // no history support :( - //hash = unescape(window.location.hash).replace('#','').split("?")[0] - hash = History.unescapeHash(window.location.hash).replace('#','').split("?")[0] - if (hash.substring(0,11)==askbot['urls']['questions']){ - url = hash - }else{ - url = askbot['urls']['questions']+hash - } - if (hash !== ''){ - window.location = 'http://'+window.location.host+url - } - } - + {% if active_tab == 'questions' %} + if (Modernizr.history) { + // history management works! + } else { + // no history support :( + //hash = unescape(window.location.hash).replace('#','').split("?")[0] + {# todo: fix this evil code!!! #} + var hash = History.unescapeHash(window.location.hash).replace('#','').split("?")[0]; + var questions_url = askbot['urls']['questions']; + if (hash.substring(0, questions_url.length) === questions_url) { + var url = hash; + } else { + var url = questions_url + hash; + } + if (hash !== '' && hash !== undefined && url !== undefined){ + {# was this causing strange redirects in IE??? #} + window.location = 'http://' + window.location.host + url; + } + } + {% endif %} // focus input on the search bar endcomment - {% if active_tab != "ask" %} + {% if active_tab in ('users', 'questions', 'tags') %} $('#keywords').focus(); - {% else %} + {% elif active_tab == 'ask' %} $('#id_title').focus(); + {% else %} + animateHashes(); {% endif %} - animateHashes(); }); -{% endif %} {% if user_messages %} $('#validate_email_alert').click(function(){notify.close(true)}) notify.show(); diff --git a/askbot/skins/default/templates/meta/html_head_stylesheets.html b/askbot/skins/default/templates/meta/html_head_stylesheets.html index 0d2ba463..8977f152 100644 --- a/askbot/skins/default/templates/meta/html_head_stylesheets.html +++ b/askbot/skins/default/templates/meta/html_head_stylesheets.html @@ -1,4 +1,5 @@ {% if settings.ASKBOT_CSS_DEVEL == False %} + <link href="{{"/style/style.css"|media }}" rel="stylesheet" type="text/css" /> {% else %} <link href="{{"/style/style.less"|media }}" rel="stylesheet/less" type="text/css" /> @@ -7,7 +8,7 @@ {% if settings.USE_LOCAL_FONTS %} {% include "meta/fonts.html" %} {% else %} - <link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:300,400,700' rel='stylesheet' type='text/css'> + <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:400,700&subset=latin,cyrillic-ext,latin-ext' rel='stylesheet' type='text/css'> {% endif %} {{ skin.get_extra_css_link() }} {% if settings.USE_CUSTOM_CSS %} diff --git a/askbot/skins/default/templates/question/content.html b/askbot/skins/default/templates/question/content.html index 58b1bcca..66b3014b 100644 --- a/askbot/skins/default/templates/question/content.html +++ b/askbot/skins/default/templates/question/content.html @@ -3,11 +3,6 @@ {# ==== BEGIN: question/question_card.html ==== #} {% include "question/question_card.html" %} {# ==== END: question/question_card.html ==== #} -{% if thread.closed %} - {# ==== START: question/closed_question_info.html ==== #} - {% include "question/closed_question_info.html" %} - {# ==== END: question/closed_question_info.html ==== #} -{% endif %} {% if answers %} <div class="clean"></div> @@ -34,8 +29,21 @@ {% endif %} {# ==== START: question/new_answer_form.html ==== #} -{% include "question/new_answer_form.html" %} -{# ==== END: question/new_answer_form.html ==== #} -{% if request.user == question.author %}{# this is outside the form on purpose #} - <input type="button" class="submit after-editor answer-own-question" id="fmanswer_button" value="{% trans %}Answer Your Own Question{% endtrans %}"/> -{%endif%} +{# buttons below cannot be cached yet #} +{% if user_already_gave_answer %} + <a + class="submit" + href="{% url "edit_answer" previous_answer.id %}" + >{% trans %}Edit Your Previous Answer{% endtrans %}</a> + <span>{% trans %}(only one answer per question is allowed){% endtrans %}</span> +{% else %} + {% include "question/new_answer_form.html" %} +{% endif %} +{% if question.closed == False and request.user == question.author %}{# this is outside the form on purpose #} +<input + type="button" + class="submit after-editor answer-own-question" + id="fmanswer_button" + value="{% trans %}Answer Your Own Question{% endtrans %}" +/> +{% endif %} diff --git a/askbot/skins/default/templates/question/javascript.html b/askbot/skins/default/templates/question/javascript.html index f0d6ed3a..e76849c9 100644 --- a/askbot/skins/default/templates/question/javascript.html +++ b/askbot/skins/default/templates/question/javascript.html @@ -1,37 +1,35 @@ -{% if not thread.closed %} - <script type='text/javascript' src='{{"/js/editor.js"|media}}'></script> - <script type='text/javascript'> - {% if settings.ENABLE_MATHJAX or settings.MARKUP_CODE_FRIENDLY %} - var codeFriendlyMarkdown = true; - {% else %} - var codeFriendlyMarkdown = false; - {% endif %} - var maxCommentLength = {{settings.MAX_COMMENT_LENGTH}}; - askbot['urls']['postComments'] = '{% url post_comments %}'; - askbot['urls']['editComment'] = '{% url edit_comment %}'; - askbot['urls']['deleteComment'] = '{% url delete_comment %}'; - askbot['urls']['getComment'] = '{% url get_comment %}'; - askbot['urls']['question_url_template'] = scriptUrl + '{{ 'question/'|transurl }}{{ "{{QuestionID}}/{{questionSlug}}" }}';{# yes it needs to be that whacky #} - askbot['urls']['vote_url_template'] = scriptUrl + '{{ 'questions/'|transurl }}{{ "{{QuestionID}}/" }}{{ 'vote/'|transurl }}'; - askbot['urls']['user_signin'] = '{{ settings.LOGIN_URL }}'; - askbot['urls']['swap_question_with_answer'] = '{% url swap_question_with_answer %}'; - askbot['urls']['upvote_comment'] = '{% url upvote_comment %}'; - askbot['urls']['delete_post'] = '{% url delete_post %}'; - askbot['urls']['get_html_template'] = '{% url get_html_template %}'; - askbot['messages']['addComment'] = '{% trans %}post a comment{% endtrans %}'; - {% if settings.SAVE_COMMENT_ON_ENTER %} - askbot['settings']['saveCommentOnEnter'] = true; - {% else %} - askbot['settings']['saveCommentOnEnter'] = false; - {% endif %} - askbot['settings']['tagSource'] = '{{ settings.TAG_SOURCE }}'; - </script> - {% if settings.EDITOR_TYPE == 'markdown' %} - <script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script> - <script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script> +<script type='text/javascript' src='{{"/js/editor.js"|media}}'></script> +<script type='text/javascript'> + {% if settings.ENABLE_MATHJAX or settings.MARKUP_CODE_FRIENDLY %} + var codeFriendlyMarkdown = true; {% else %} - {% include "meta/tinymce.html" %} + var codeFriendlyMarkdown = false; {% endif %} + var maxCommentLength = {{settings.MAX_COMMENT_LENGTH}}; + askbot['urls']['postComments'] = '{% url post_comments %}'; + askbot['urls']['editComment'] = '{% url edit_comment %}'; + askbot['urls']['deleteComment'] = '{% url delete_comment %}'; + askbot['urls']['getComment'] = '{% url get_comment %}'; + askbot['urls']['question_url_template'] = scriptUrl + '{{ 'question/'|transurl }}{{ "{{QuestionID}}/{{questionSlug}}" }}';{# yes it needs to be that whacky #} + askbot['urls']['vote_url_template'] = scriptUrl + '{{ 'questions/'|transurl }}{{ "{{QuestionID}}/" }}{{ 'vote/'|transurl }}'; + askbot['urls']['user_signin'] = '{{ settings.LOGIN_URL }}'; + askbot['urls']['swap_question_with_answer'] = '{% url swap_question_with_answer %}'; + askbot['urls']['upvote_comment'] = '{% url upvote_comment %}'; + askbot['urls']['delete_post'] = '{% url delete_post %}'; + askbot['urls']['get_html_template'] = '{% url get_html_template %}'; + askbot['messages']['addComment'] = '{% trans %}post a comment{% endtrans %}'; + {% if settings.SAVE_COMMENT_ON_ENTER %} + askbot['settings']['saveCommentOnEnter'] = true; + {% else %} + askbot['settings']['saveCommentOnEnter'] = false; + {% endif %} + askbot['settings']['tagSource'] = '{{ settings.TAG_SOURCE }}'; +</script> +{% if settings.EDITOR_TYPE == 'markdown' %} + <script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script> + <script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script> +{% else %} + {% include "meta/tinymce.html" %} {% endif %} <script type='text/javascript' src='{{"/js/jquery.validate.min.js"|media}}'></script> <script type='text/javascript' src='{{"/js/post.js"|media}}'></script> diff --git a/askbot/skins/default/templates/question/question_card.html b/askbot/skins/default/templates/question/question_card.html index dd52ea0f..c787bf34 100644 --- a/askbot/skins/default/templates/question/question_card.html +++ b/askbot/skins/default/templates/question/question_card.html @@ -25,6 +25,12 @@ } })(); </script> + {% if thread.closed %} + <div class="clearfix"></div> + {# ==== START: question/closed_question_info.html ==== #} + {% include "question/closed_question_info.html" %} + {# ==== END: question/closed_question_info.html ==== #} + {% endif %} {% include "question/question_comments.html" %} </div> diff --git a/askbot/skins/default/templates/reopen.html b/askbot/skins/default/templates/reopen.html index 52d926ce..4ddd6f31 100644 --- a/askbot/skins/default/templates/reopen.html +++ b/askbot/skins/default/templates/reopen.html @@ -9,8 +9,8 @@ <span class="big">{{ question.get_question_title()|escape }}</span> </a> </p> -<p>{% trans %}This question has been closed by - <a href="{{closed_by_profile_url}}">{{closed_by_username|escape}}</a> +<p>{% trans username = closed_by_username|escape %}This question has been closed by + <a href="{{closed_by_profile_url}}">{{username}}</a> {% endtrans %} </p> <p> diff --git a/askbot/skins/default/templates/revisions.html b/askbot/skins/default/templates/revisions.html index aa1996a9..a0531b80 100644 --- a/askbot/skins/default/templates/revisions.html +++ b/askbot/skins/default/templates/revisions.html @@ -79,8 +79,7 @@ $("#nav_questions").attr('className',"on"); $('div.revision div[id^=rev-header-]').bind('click', function(){ var revId = this.id.substr(11); - toggleRev(revId); - + toggleRev(revId); }); lanai.highlightSyntax(); }); @@ -88,13 +87,13 @@ function toggleRev(id) { var arrow = $("#rev-arrow-" + id); var visible = arrow.attr("src").indexOf("hide") > -1; - var path = mediaUrl( - "media/images/expander-arrow-" + - (visible ? "show" : "hide") + - ".gif" + - "?v={{settings.MEDIA_RESOURCE_REVISION}}" - ); - arrow.attr("src", path); + if (visible) { + var image_path = '{{ "/images/expander-arrow-show.gif"|media }}'; + } else { + var image_path = '{{ "/images/expander-arrow-hide.gif"|media }}'; + } + image_path = image_path + "?v={{settings.MEDIA_RESOURCE_REVISION}}"; + arrow.attr("src", image_path); $("#rev-body-" + id).slideToggle("fast"); } </script> diff --git a/askbot/skins/default/templates/widgets/ask_button.html b/askbot/skins/default/templates/widgets/ask_button.html index 31448b73..a27f3b2c 100644 --- a/askbot/skins/default/templates/widgets/ask_button.html +++ b/askbot/skins/default/templates/widgets/ask_button.html @@ -2,5 +2,8 @@ {% if not search_state %} {# get empty SearchState() if there's none #} {% set search_state=search_state|get_empty_search_state %} {% endif %} - <a id="askButton" href="{{ search_state.full_ask_url() }}">{% trans %}Ask Your Question{% endtrans %}</a> + <a + id="askButton" + href="{{ search_state.full_ask_url() }}{% if group %}&group={{ group.id }}{% endif %}" + >{% trans %}Ask Your Question{% endtrans %}</a> {% endif %} diff --git a/askbot/tests/badge_tests.py b/askbot/tests/badge_tests.py index dbb37dde..b66eadcc 100644 --- a/askbot/tests/badge_tests.py +++ b/askbot/tests/badge_tests.py @@ -68,7 +68,8 @@ class BadgeTests(AskbotTestCase): self.assert_have_badge(badge_key, recipient = self.u2, expected_count = 1) #post another question and check that there are no new badges - answer2 = self.post_answer(user = self.u2, question = question) + question2 = self.post_question(user = self.u1) + answer2 = self.post_answer(user = self.u2, question = question2) answer2.score = min_score - 1 answer2.save() self.u1.upvote(answer2) @@ -269,7 +270,8 @@ class BadgeTests(AskbotTestCase): answer = self.post_answer(user = self.u2, question = question) self.u1.accept_best_answer(answer) self.assert_have_badge('scholar', recipient = self.u1) - answer2 = self.post_answer(user = self.u2, question = question) + question2 = self.post_question(user = self.u1) + answer2 = self.post_answer(user = self.u2, question = question2) self.u1.accept_best_answer(answer2) self.assert_have_badge( 'scholar', diff --git a/askbot/tests/permission_assertion_tests.py b/askbot/tests/permission_assertion_tests.py index 2f746ef9..8061bdb8 100644 --- a/askbot/tests/permission_assertion_tests.py +++ b/askbot/tests/permission_assertion_tests.py @@ -447,9 +447,9 @@ class ReopenQuestionPermissionAssertionTests(utils.AskbotTestCase): ) - def test_high_rep_nonowner_cannot_reopen(self): + def test_high_rep_nonowner_can_reopen(self): self.other_user.reputation = 1000000 - self.assert_cannot_reopen(user = self.other_user) + self.assert_can_reopen(user = self.other_user) def test_low_rep_admin_can_reopen(self): self.other_user.set_admin_status() @@ -482,7 +482,7 @@ class ReopenQuestionPermissionAssertionTests(utils.AskbotTestCase): self.assert_cannot_reopen(user = self.other_user) class EditQuestionPermissionAssertionTests(utils.AskbotTestCase): - + def setUp(self): self.create_user() self.create_user(username = 'other_user') diff --git a/askbot/views/readers.py b/askbot/views/readers.py index b37cacb2..467282e5 100644 --- a/askbot/views/readers.py +++ b/askbot/views/readers.py @@ -470,7 +470,7 @@ def question(request, id):#refactor - long subroutine. display question body, an user_post_id_list = [ id for id in post_to_author if post_to_author[id] == request.user.id ] - + #resolve page number and comment number for permalinks show_comment_position = None if show_comment: @@ -535,7 +535,7 @@ def question(request, id):#refactor - long subroutine. display question body, an is_cacheable = False elif show_comment_position > askbot_settings.MAX_COMMENTS_TO_SHOW: is_cacheable = False - + answer_form = AnswerForm( initial = { 'wiki': question_post.wiki and askbot_settings.WIKI_ON, @@ -547,6 +547,16 @@ def question(request, id):#refactor - long subroutine. display question body, an request.user.is_authenticated() and request.user.can_post_comment() ) + user_already_gave_answer = False + previous_answer = None + if request.user.is_authenticated(): + if askbot_settings.LIMIT_ONE_ANSWER_PER_USER: + for answer in answers: + if answer.author == request.user: + user_already_gave_answer = True + previous_answer = answer + break + data = { 'is_cacheable': False,#is_cacheable, #temporary, until invalidation fix 'long_time': const.LONG_TIME,#"forever" caching @@ -561,6 +571,8 @@ def question(request, id):#refactor - long subroutine. display question body, an 'user_votes': user_votes, 'user_post_id_list': user_post_id_list, 'user_can_post_comment': user_can_post_comment,#in general + 'user_already_gave_answer': user_already_gave_answer, + 'previous_answer': previous_answer, 'tab_id' : answer_sort_method, 'favorited' : favorited, 'similar_threads' : thread.get_similar_threads(), diff --git a/askbot/views/users.py b/askbot/views/users.py index c15e665b..9012a048 100644 --- a/askbot/views/users.py +++ b/askbot/views/users.py @@ -81,7 +81,7 @@ def show_users(request, by_group = False, group_id = None, group_slug = None): except models.Tag.DoesNotExist: raise Http404 if group_slug == slugify(group.name): - users = models.User.objects.filter( + users = users.filter( group_memberships__group__id = group_id ) if request.user.is_authenticated(): @@ -99,7 +99,6 @@ def show_users(request, by_group = False, group_id = None, group_slug = None): } ) return HttpResponseRedirect(group_page_url) - is_paginated = True diff --git a/askbot/views/writers.py b/askbot/views/writers.py index 58584b94..2dee9c37 100644 --- a/askbot/views/writers.py +++ b/askbot/views/writers.py @@ -24,6 +24,7 @@ from django.core import exceptions from django.conf import settings from django.views.decorators import csrf +from askbot import exceptions as askbot_exceptions from askbot import forms from askbot import models from askbot.conf import settings as askbot_settings @@ -523,6 +524,10 @@ def answer(request, id):#process a new answer timestamp = update_time, ) return HttpResponseRedirect(answer.get_absolute_url()) + except askbot_exceptions.AnswerAlreadyGiven, e: + request.user.message_set.create(message = unicode(e)) + answer = question.thread.get_answers_by_user(request.user)[0] + return HttpResponseRedirect(answer.get_absolute_url()) except exceptions.PermissionDenied, e: request.user.message_set.create(message = unicode(e)) else: |