def shop_all_items(request): ret = { 'shop_brushes': Brush.for_shop(viewer=request.user, request=request), 'shop_colors': Color.for_shop(viewer=request.user), 'color_packs': ColorPack.for_shop(viewer=request.user), 'coin_products': COIN_PRODUCTS, 'brush_products': brush_products(request=request), 'balance': economy.balance(request.user), 'color_packs_header': redis.get('color_packs_header'), 'colors_header': redis.get('colors_header'), 'tabs': [ { 'name': 'colors', 'default': True }, { 'name': 'coins' }, { 'name': 'brushes' }, ], } return ret
def get_latest_before_unjudged_id(): id_ = redis.get('dq:comment_freeze_id') if id_ is None: id_ = 0 id_ = long(id_) earliest_unjudged = QuestComment.all_objects.filter( id__gt=id_, judged=False, ).order_by('id') if earliest_unjudged.exists(): #print 'id',earliest_unjudged[0].id earliest_unjudged_id = earliest_unjudged[0].id latest_before_unjudged = QuestComment.all_objects.filter( #timestamp__lt=earliest_unjudged_ts, id__lt=earliest_unjudged_id, ).order_by('-id') if not latest_before_unjudged.exists(): return new_id = latest_before_unjudged[0].id else: latest = QuestComment.all_objects.all().order_by('-id') if not latest.exists(): return latest = latest[0] new_id = latest.id return new_id
def update(self, fs=None, web=None): """ Renders the footer image and saves it to the filesystem (i.e. S3 in production). `web` is an optional perf optimization. """ from canvas.thumbnailer import generate_thumbnails data = self.render_image().getvalue() footer_meta = generate_thumbnails(data, fs=fs, image_type='footer', filename=self.get_path()) # Update the Content details. content_key = self.comment.reply_content.details_key old_raw_meta = redis.get(content_key) if old_raw_meta: meta = util.loads(old_raw_meta) else: meta = {} meta.update(footer_meta) redis.set(content_key, util.dumps(meta)) self.comment.reply_content.details.force() self.comment.details.force() return meta
def create_gif_content(**kwargs): content = create_content(animated=True, **kwargs) key = 'content:%s:details' % content.id details = util.loads(redis.get(key)) details['original']['animated'] = True redis.set(key, util.dumps(details)) return content
def create_gif_content(**kwargs): content = create_content(**kwargs) key = "content:%s:details" % content.id details = util.loads(redis.get(key)) details["original"]["animated"] = True redis.set(key, util.dumps(details)) return content
def filter_frozen_comments(comments): #TODO pipelining. ts = redis.get('dq:comment_freeze_ts') id_ = redis.get('dq:comment_freeze_id') if ts is None and id_ is None: return comments if ts is not None: ts = float(ts) filtered = [comment for comment in comments if float(comment.timestamp) <= ts] if id_ is not None: id_ = long(id_) filtered = [comment for comment in comments if long(comment.id) <= id_] return filtered
def update_freeze(): id_ = redis.get('dq:comment_freeze_id') if id_ is None: return new_id = get_latest_before_unjudged_id() redis.set('dq:comment_freeze_id', new_id) return new_id
def shop_all_items(request): ret = { 'shop_brushes': Brush.for_shop(viewer=request.user, request=request), 'shop_colors': Color.for_shop(viewer=request.user), 'color_packs': ColorPack.for_shop(viewer=request.user), 'coin_products': COIN_PRODUCTS, 'brush_products': brush_products(request=request), 'balance': economy.balance(request.user), 'color_packs_header': redis.get('color_packs_header'), 'colors_header': redis.get('colors_header'), 'tabs': [ {'name': 'colors', 'default': True}, {'name': 'coins'}, {'name': 'brushes'}, ], } return ret
def whitelisting_paginated(request, after_id=None): freeze_id = redis.get('dq:comment_freeze_id') comments = [] if after_id >= freeze_id: comments = QuestComment.unjudged().filter(id__gt=after_id, ).order_by( 'id')[:knobs.WHITELIST_COMMENTS_PER_PAGE], return r2r_jinja('whitelisting/whitelist_items.html', {'comments': comments}, request)
def archived(cls, select_quests=False): qs = cls.objects if select_quests: qs = qs.select_related('quest') current_quest_id = redis.get('dq:current_scheduled_quest') if current_quest_id: qs = qs.exclude(id=current_quest_id) return qs.exclude(appeared_on__isnull=True).order_by('-appeared_on')
def whitelisting_paginated(request, after_id=None): freeze_id = redis.get('dq:comment_freeze_id') comments = [] if after_id >= freeze_id: comments = QuestComment.unjudged().filter( id__gt=after_id, ).order_by('id')[:knobs.WHITELIST_COMMENTS_PER_PAGE], return r2r_jinja('whitelisting/whitelist_items.html', {'comments': comments}, request)
def whitelisting(request): freeze_id = redis.get('dq:comment_freeze_id') comments = [] if freeze_id is not None: comments = QuestComment.unjudged().filter( id__gte=freeze_id, ).order_by( 'id')[:knobs.WHITELIST_COMMENTS_PER_PAGE] ctx = { 'comments': comments, 'enabled': freeze_id is not None, } return r2r_jinja('whitelisting/whitelisting.html', ctx, request)
def whitelisting(request): freeze_id = redis.get('dq:comment_freeze_id') comments = [] if freeze_id is not None: comments = QuestComment.unjudged().filter( id__gte=freeze_id, ).order_by('id')[:knobs.WHITELIST_COMMENTS_PER_PAGE] ctx = { 'comments': comments, 'enabled': freeze_id is not None, } return r2r_jinja('whitelisting/whitelisting.html', ctx, request)
def update(fs, content, image_type, save_to_db=True): filename = content.details()['original']['name'] # Prevent issues with unicode filenames. filename = filename.encode('ascii') data = fs.read(filename) thumbnailer = Thumbnailer(fs) meta = util.loads(redis.get(content.details_key)) meta.update(thumbnailer.store(data, image_type)) update_metadata(content, meta) if save_to_db: content.save() redis.set(content.details_key, util.dumps(meta)) content.details.force()
def comment_freeze(request): ctx = {} if request.method == 'POST': ts = request.POST['comment_freeze_ts'] if ts: redis.set('dq:comment_freeze_ts', ts) else: redis.delete('dq:comment_freeze_ts') signals.comment_freeze_ts_changed.send(None) ctx['comment_freeze_ts'] = redis.get('dq:comment_freeze_ts') or '' return r2r_jinja('comment_freeze/comment_freeze.html', ctx, request)
def _auto_moderation(cls, author): """ Returns (skip_moderation, curate,) booleans. """ if not author.comments.exists(): return True, True last_drawing = None if author.comments.exists(): last_drawing = author.comments.order_by('-id')[0] if (last_drawing and last_drawing.stickers.filter( type_id=settings.STAR_STICKER_TYPE_ID).count() > knobs.AUTO_MODERATION['stars']): return True, False curate = ((author.userinfo.trusted is None and redis.get('dq:auto_curate')) or author.userinfo.trusted == False) return False, curate
def _auto_moderation(cls, author): """ Returns (skip_moderation, curate,) booleans. """ if not author.comments.exists(): return True, True last_drawing = None if author.comments.exists(): last_drawing = author.comments.order_by("-id")[0] if ( last_drawing and last_drawing.stickers.filter(type_id=settings.STAR_STICKER_TYPE_ID).count() > knobs.AUTO_MODERATION["stars"] ): return True, False curate = (author.userinfo.trusted is None and redis.get("dq:auto_curate")) or author.userinfo.trusted == False return False, curate
def update(fs, content, image_type, save_to_db=True): from drawquest.apps.content_metadata.models import save_content_metadata_from_legacy_dict filename = content.details()['original']['name'] # Prevent issues with unicode filenames. filename = filename.encode('ascii') data = fs.read(filename) thumbnailer = Thumbnailer(fs) meta = util.loads(redis.get(content.details_key)) meta.update(thumbnailer.store(data, image_type)) if save_to_db: content.save() save_content_metadata_from_legacy_dict(content, meta) content.details.force()
def _moderation_context(sections, id_range=None): per_page = knobs.WHITELIST_COMMENTS_PER_PAGE if id_range is not None: from_, to = get_divvy_range(id_range) per_page = knobs.WHITELIST_COMMENTS_PER_PAGE * (to - from_) comments = [] left_per_page = per_page for section in sections: if left_per_page == 0: break incoming_comments = section[:left_per_page] left_per_page -= len(incoming_comments) if id_range is None: comments.extend(list(incoming_comments)) else: comments.extend(list(divvy(incoming_comments, from_, to))) if id_range is not None: comments = divvy(comments, from_, to) try: auto_curate = loads(redis.get('dq:auto_curate')) except TypeError: auto_curate = False min_ago = time.time() - 60 return { 'comments': comments, 'auto_curate_enabled': auto_curate, 'body_class': 'moderation', }
def is_currently_scheduled(self): """ 'currently scheduled' means it's the quest of the day. """ scheduled_quest = ScheduledQuest.objects.get(id=redis.get('dq:current_scheduled_quest')) return scheduled_quest.quest_id == self.id
def get_context_data(self, **kwargs): context = super(_PalettesView, self).get_context_data(**kwargs) context['colors_header'] = redis.get('colors_header') context['color_packs_header'] = redis.get('color_packs_header') return context
def heavy_state_sync(user, app_version=None, app_version_tuple=None, tab_last_seen_timestamps={}): from drawquest.apps.brushes.models import Brush from drawquest.apps.palettes.models import user_palettes, Color twitter_keys = '{}@{}'.format(settings.TWITTER_APP_KEY , settings.TWITTER_APP_SECRET) twitter_keys = twitter_keys[-6:] + twitter_keys[:-6] twitter_keys = swapcase(twitter_keys) ret = { 'realtime_sync': realtime_sync(user), 'user_palettes': user_palettes(user), 'current_quest': current_quest_details(), 'onboarding_quest_id': knobs.ONBOARDING_QUEST_ID, 'sync': twitter_keys, 'tumblr_success_regex': '''<div style="margin-bottom:10px; font-size:40px; color:#777;">Done!</div>''', 'rewards': { 'amounts': knobs.REWARDS, 'copy': { 'quest_of_the_day': _("You drew the Quest of the Day"), 'archived_quest': _("You drew a Quest"), 'first_quest': _("Woo! Your first Quest ever!"), 'streak_3': _("Quest Streak: 3"), 'streak_10': _("Quest Streak: 10"), 'streak_100': _("Epic! 100 straight Quests"), }, 'iphone_copy': { 'archived_quest': _("You drew a Quest"), 'first_quest': _("Your first Quest!"), 'quest_of_the_day': _("Quest of the Day!"), 'streak_10': _("Bonus Streak"), 'streak_100': _("Bonus Streak"), 'streak_3': _("Bonus Streak"), 'personal_share': _("Shared with Facebook"), 'personal_twitter_share': _("Shared with Twitter"), }, }, 'features': { 'invite_from_facebook': True, 'invite_from_twitter': True, 'user_search': True, 'urban_airship_registration_before_auth': True, 'urban_airship_registration': True, }, 'logging': { 'on': True, 'authentication-controller': { 'request-for-me': False, }, 'facebook-controller': { 'open-active-session-with-read-permissions': False, 'request-new-publish-permissions': False, 'request-new-publish-permissions-cancelled': False, 'request-new-read-permissions': False, 'request-new-read-permissions-cancelled': False, }, 'facebook-friends-coordinator': { 'present-requests-dialog': False, 'request-my-friends': False, }, 'http-request': { 'error-auth/login_with_facebook': { 'mute-error-codes': { '403': True, } }, 'error-auth/login_with_twitter': { 'mute-error-codes': { '403': True, } }, 'error-quests/gallery_for_comment': { 'mute-error-codes': { '404': True, } } }, 'private-api': { 'failed-activity/iphone_activities': { 'mute-error-codes': { '1005': True, } } }, 'sharing-controller': { 'present-feed-dialog': False, 'present-share-dialog-with-link': False, }, 'shop-controller': { 'add-payment': False, 'brush-products-request': False, 'coin-products-request': False, }, 'twitter-api-manager': { 'step-1': False, 'step-2': False, }, 'twitter-controller': { 'request-data-cursored-user-ids': False, 'request-data-send-dm': False, 'request-data-unknown': False, 'request-data-users-for-ids': False, }, }, #TODO use settings.LOCALES once that's ready 'supported_languages': ['de', 'en', 'es', 'fr', 'ja', 'ko', 'nl', 'pt', 'ru', 'th', 'zh-Hant', 'zh-Hans'], 'l10n_files_url': None, 'user_colors': list(Color.for_user(user)), 'user_brushes': list(Brush.for_user(user)), 'global_brushes': list(Brush.for_global()), 'comment_view_logging_interval': 10, 'papertrail': { 'host': 'logs.papertrailapp.com', 'port': 27889, 'disabled_logging_points': [], }, 'modals': {}, } if app_version_tuple and app_version_tuple >= (3,): ret['appirater_url'] = 'itms-apps://itunes.apple.com/app/idAPP_ID' else: ret['appirater_url'] = 'itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID' try: ret['color_alert_version'] = int(redis.get('color_alert_version')) except TypeError: ret['color_alert_version'] = 0 if user.is_authenticated(): user_kv_items = user.kv.hgetall() user_kv_items = dict((key, val) for key, val in user_kv_items.items() if key in [ 'saw_update_modal_for_version', 'saw_share_web_profile_modal', 'publish_to_facebook', 'publish_to_twitter', ]) ret.update({ 'user_email': user.email, 'user_profile': user_profile(user.username), 'balance': economy.balance(user), 'completed_quest_ids': completed_quest_ids(user), 'web_profile_privacy': user.kv.web_profile_privacy.get(), 'twitter_privacy': user.kv.twitter_privacy.get(), 'facebook_privacy': user.kv.facebook_privacy.get(), 'user_kv': user_kv_items, 'reminders': { 'invite': 1, }, }) if (app_version and parse_version(knobs.CURRENT_APP_VERSION) > parse_version(app_version)): saw_version = user_kv_items.get('saw_update_modal_for_version') if (saw_version is None or parse_version(saw_version) < parse_version(knobs.CURRENT_APP_VERSION)): ret['modals']['show_update_modal_for_version'] = knobs.CURRENT_APP_VERSION ret['modals']['update_modal_type'] = 'alert' if not user_kv_items.get('saw_share_web_profile_modal'): ret['modals']['show_share_web_profile_modal'] = (user.date_joined <= (datetime.now() - td(days=2)) or user.comments.count() >= 3) ret['tab_badge_type'] = 'flag' if tab_last_seen_timestamps: ret['tab_badges'] = tab_badges(user, last_seen_timestamps=tab_last_seen_timestamps) return ret
def heavy_state_sync(user, app_version=None, app_version_tuple=None, tab_last_seen_timestamps={}): from drawquest.apps.brushes.models import Brush from drawquest.apps.palettes.models import user_palettes, Color twitter_keys = '{}@{}'.format(settings.TWITTER_APP_KEY, settings.TWITTER_APP_SECRET) twitter_keys = twitter_keys[-6:] + twitter_keys[:-6] twitter_keys = swapcase(twitter_keys) ret = { 'realtime_sync': realtime_sync(user), 'user_palettes': user_palettes(user), 'current_quest': current_quest_details(), 'onboarding_quest_id': knobs.ONBOARDING_QUEST_ID, 'sync': twitter_keys, 'tumblr_success_regex': '''<div style="margin-bottom:10px; font-size:40px; color:#777;">Done!</div>''', 'rewards': { 'amounts': knobs.REWARDS, 'copy': { 'quest_of_the_day': _("You drew the Quest of the Day"), 'archived_quest': _("You drew a Quest"), 'first_quest': _("Woo! Your first Quest ever!"), 'streak_3': _("Quest Streak: 3"), 'streak_10': _("Quest Streak: 10"), 'streak_100': _("Epic! 100 straight Quests"), }, 'iphone_copy': { 'archived_quest': _("You drew a Quest"), 'first_quest': _("Your first Quest!"), 'quest_of_the_day': _("Quest of the Day!"), 'streak_10': _("Bonus Streak"), 'streak_100': _("Bonus Streak"), 'streak_3': _("Bonus Streak"), 'personal_share': _("Shared with Facebook"), 'personal_twitter_share': _("Shared with Twitter"), }, }, 'features': { 'invite_from_facebook': True, 'invite_from_twitter': True, 'user_search': True, 'urban_airship_registration_before_auth': True, 'urban_airship_registration': True, }, 'logging': { 'on': True, 'authentication-controller': { 'request-for-me': False, }, 'facebook-controller': { 'open-active-session-with-read-permissions': False, 'request-new-publish-permissions': False, 'request-new-publish-permissions-cancelled': False, 'request-new-read-permissions': False, 'request-new-read-permissions-cancelled': False, }, 'facebook-friends-coordinator': { 'present-requests-dialog': False, 'request-my-friends': False, }, 'http-request': { 'error-auth/login_with_facebook': { 'mute-error-codes': { '403': True, } }, 'error-auth/login_with_twitter': { 'mute-error-codes': { '403': True, } }, 'error-quests/gallery_for_comment': { 'mute-error-codes': { '404': True, } } }, 'private-api': { 'failed-activity/iphone_activities': { 'mute-error-codes': { '1005': True, } } }, 'sharing-controller': { 'present-feed-dialog': False, 'present-share-dialog-with-link': False, }, 'shop-controller': { 'add-payment': False, 'brush-products-request': False, 'coin-products-request': False, }, 'twitter-api-manager': { 'step-1': False, 'step-2': False, }, 'twitter-controller': { 'request-data-cursored-user-ids': False, 'request-data-send-dm': False, 'request-data-unknown': False, 'request-data-users-for-ids': False, }, }, #TODO use settings.LOCALES once that's ready 'supported_languages': [ 'de', 'en', 'es', 'fr', 'ja', 'ko', 'nl', 'pt', 'ru', 'th', 'zh-Hant', 'zh-Hans' ], 'l10n_files_url': None, 'user_colors': list(Color.for_user(user)), 'user_brushes': list(Brush.for_user(user)), 'global_brushes': list(Brush.for_global()), 'comment_view_logging_interval': 10, 'papertrail': { 'host': 'logs.papertrailapp.com', 'port': 27889, 'disabled_logging_points': [], }, 'modals': {}, } if app_version_tuple and app_version_tuple >= (3, ): ret['appirater_url'] = 'itms-apps://itunes.apple.com/app/idAPP_ID' else: ret['appirater_url'] = 'itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID' try: ret['color_alert_version'] = int(redis.get('color_alert_version')) except TypeError: ret['color_alert_version'] = 0 if user.is_authenticated(): user_kv_items = user.kv.hgetall() user_kv_items = dict((key, val) for key, val in user_kv_items.items() if key in [ 'saw_update_modal_for_version', 'saw_share_web_profile_modal', 'publish_to_facebook', 'publish_to_twitter', ]) ret.update({ 'user_email': user.email, 'user_profile': user_profile(user.username), 'balance': economy.balance(user), 'completed_quest_ids': completed_quest_ids(user), 'web_profile_privacy': user.kv.web_profile_privacy.get(), 'twitter_privacy': user.kv.twitter_privacy.get(), 'facebook_privacy': user.kv.facebook_privacy.get(), 'user_kv': user_kv_items, 'reminders': { 'invite': 1, }, }) if (app_version and parse_version(knobs.CURRENT_APP_VERSION) > parse_version(app_version)): saw_version = user_kv_items.get('saw_update_modal_for_version') if (saw_version is None or parse_version(saw_version) < parse_version(knobs.CURRENT_APP_VERSION)): ret['modals'][ 'show_update_modal_for_version'] = knobs.CURRENT_APP_VERSION ret['modals']['update_modal_type'] = 'alert' if not user_kv_items.get('saw_share_web_profile_modal'): ret['modals']['show_share_web_profile_modal'] = ( user.date_joined <= (datetime.now() - td(days=2)) or user.comments.count() >= 3) ret['tab_badge_type'] = 'flag' if tab_last_seen_timestamps: ret['tab_badges'] = tab_badges( user, last_seen_timestamps=tab_last_seen_timestamps) return ret
def quest_of_the_day(request): quest = get_object_or_404(ScheduledQuest, id=redis.get('dq:current_scheduled_quest')).quest return redirect('quest', base36encode(quest.id), slugify(quest.title))
print "id: %s username: %r email: %r" % (user2.id, user2.username, user2.email) ids = ( Comment.all_objects.filter(author=user2) .exclude(reply_content__isnull=True) .values_list("reply_content_id", flat=True) ) num_ids = len(ids) last = time.time() n = 0 total = 0 image_urls = [] all_last = time.time() to_dir = "{}-{}/".format(user2.id, user2.username) for id_ in ids: # [2:3]: details_id = ("content:" + id_ + ":details").encode("ascii") raw = redis.get(details_id) if not raw: continue details = util.loads(raw) try: filename = details["original"]["name"] except KeyError: print "KeyError: ", print details continue to_filename = to_dir + filename.lstrip("original/") try: from_fs.copy_to_other_s3(filename, to_fs, to_filename) except S3ResponseError: continue image_urls.append("http://canvas-export.s3-website-us-east-1.amazonaws.com/" + to_filename)
def current_scheduled_quest(cls): """ The `ScheduledQuest` instance representing the current quest of the day. """ scheduled_quest_id = redis.get('dq:current_scheduled_quest') if scheduled_quest_id: return cls.objects.get(id=scheduled_quest_id)
id_end = 45000 #for user2 in User.objects.filter(id__gte=id_start).exclude(id__gt=id_end).order_by('id').iterator(): for user2 in User.objects.filter(id__in=list(Comment.objects.order_by('-id').values_list('author_id', flat=True).distinct()[:50])).iterator(): #user = User.objects.get(username='******') print "id: %s username: %r email: %r" % (user2.id, user2.username, user2.email) ids = Comment.all_objects.filter(author=user2).exclude(reply_content__isnull=True).values_list('reply_content_id', flat=True) num_ids = len(ids) last = time.time() n = 0 total = 0 image_urls = [] all_last = time.time() to_dir = '{}-{}/'.format(user2.id, user2.username) for id_ in ids:#[2:3]: details_id = ('content:' + id_ + ':details').encode('ascii') raw = redis.get(details_id) if not raw: continue details = util.loads(raw) try: filename = details['original']['name'] except KeyError: print "KeyError: ", print details continue to_filename = to_dir + filename.lstrip('original/') try: from_fs.copy_to_other_s3(filename, to_fs, to_filename) except S3ResponseError: continue image_urls.append('http://canvas-export.s3-website-us-east-1.amazonaws.com/' + to_filename)
def _auto_moderation(cls, author): """ Returns (skip_moderation, curate,) booleans. """ curate = ((author.userinfo.trusted is None and redis.get('dq:auto_curate')) or author.userinfo.trusted == False) return False, curate