def delete_cardbox(_id): box = CardBox.fetch(db, _id) if not box: flash('Invalid Cardbox ID.', 'error') return redirect(url_for('index')) if box._id not in current_user.cardboxs: flash('You can only delete cardboxes that you own.', 'error') return redirect(url_for('show_box', _id=_id)) form = ConfirmationForm() form.submit.label.text = 'Delete' message = 'Are you sure you want to delete CardBox ' + box.name + '?' if form.is_submitted(): CardBox.delete(db, _id) current_user.cardboxs.remove(box._id) current_user.store(db) User.update_score(db, current_user._id) flash("Successfully removed CardBox") return redirect( url_for('huge_list', foption='owner', fterm=current_user._id)) return render_template('_confirm.html', message=message, address='show_box', add_kwargs={'_id': _id}, form=form)
def add_cardbox(): if not request.is_json: abort(404) # already returns dictionary payload = request.get_json() req = ('username', 'password', 'tags', 'content', 'name') if not payload or not all(r in payload for r in req): abort(404) if User.exists(db, payload['username']): user = User.fetch(db, payload['username']) if not user.check_password(payload['password']): abort(404) new_box = CardBox(CardBox.gen_card_id(), name=payload['name'], owner=user._id, rating=0, tags=payload['tags'], content=payload['content']) new_box.store(db) user.cardboxs.append(new_box._id) user.store(db) return 'OK'
def confirm_challenge(user_id, box_id): box = CardBox.fetch(db, box_id) if not box: flash('Invalid Cardbox ID.', 'error') return redirect(url_for('challenge_user', _id=user_id)) if user_id == current_user._id: flash('You can not even challenge yourself. Nice try.', 'error') return redirect(url_for('user_list')) user = User.fetch(db, user_id) if not user: flash('Invalid User ID.', 'error') return redirect(url_for('user_list')) form = ConfirmationForm() form.submit.label.text = 'Challenge' message = 'Challenge ' + user_id + ' to duel ' + box.name + '?' if form.is_submitted(): challenge.challenge(db, current_user._id, user._id, box._id) flash('Challenge request sent!') return redirect(url_for('challenge_list', requests='sent')) return render_template('_confirm.html', message=message, address='challenge_user', add_kwargs={'_id': user_id}, form=form)
def download_cardbox(_id: str): box = CardBox.fetch(db, _id) if not box: abort(404) return jsonify(vars(box))
def preview_box(_id): box = CardBox.fetch(db, _id) if not box: flash('Invalid Cardbox ID.', 'error') return redirect(url_for('huge_list')) return render_template('preview_box.html', box=box)
def show_box(_id): box = CardBox.fetch(db, _id) if not box: flash('Invalid Cardbox ID.', 'error') return redirect(url_for('huge_list')) owned = box.owner == current_user._id return render_template('show_box.html', box=box, owned=owned)
def download_cardbox(_id: str): box = CardBox.fetch(db, _id) if not box: abort(404) content = Card.fetch_content_to_list(db, _id) vars_box = vars(box) vars_box['content'] = content # use flask jsonify to create valid json response return jsonify(vars_box)
def rate_cardbox(_id): box = CardBox.fetch(db, _id) if not box: flash('Invalid Cardbox ID.', 'error') return redirect(url_for('index')) if box.increment_rating(db, current_user): User.update_score(db, box.owner) flash('Successfully rated. Thank you for your appreciation! :3') return redirect(url_for('show_box', _id=_id)) flash("Already rated. Don't try to fool us!", 'error') return redirect(url_for('show_box', _id=_id))
def show_user(_id): if not User.exists(db, _id): flash('Invalid User Name.' 'Be the first User to have this name! :D', 'error') return redirect(url_for('index')) score = User.update_score(db, _id) user = User.fetch(db, _id) picture_filepath = utils.profile_img_path(app, user._id) # <-- Showcase --> showcase = dict(info=False, cardbox=False, rank=False) infocase = user.showcase if infocase['show_info']: showcase['info'] = infocase['info'] if infocase['show_cardbox']: box = CardBox.fetch(db, infocase['cardbox']) if box: showcase['cardbox'] = box else: showcase['cardbox'] = 'string' if infocase['show_rank']: showcase['rank'] = user.get_rank(db) # <-- my own profile? --> if user._id == current_user._id: return render_template('show_user_myself.html', user=user, showcase=showcase, picture_filepath=picture_filepath, score=score, active='profile') return render_template('show_user.html', user=user, active='community', picture_filepath=picture_filepath, showcase=showcase, score=score, following=current_user.is_following(_id))
def challenge(db, challenger_id, challenged_id, box_id): new_duel_id = gen_duel_id() box = CardBox.fetch(db, box_id) content = Card.fetch_content(db, box_id) vs_dict = dict(duel_id=new_duel_id, challenger=challenger_id, challenged=challenged_id, box_id=box_id, box_name=box.name, box_content=content, started=False, finish_time=None, winner='') db.hset(TABLE_VS, new_duel_id, json.dumps(vs_dict)) db.rpush(challenger_id + CHALLENGE_SUFFIX, new_duel_id) db.rpush(challenged_id + CHALLENGE_SUFFIX, new_duel_id) return new_duel_id
def update_score(db, _id) -> int: user = User.fetch(db, _id) score_likes = 0 boxes = CardBox.fetch_multiple(db, user.cardboxs) for box in boxes: score_likes = score_likes + box.rating score_followers = 0 users = User.fetch_all(db) for u in users: if u.is_following(user._id): score_followers += 1 score_boxes = len(user.cardboxs) score = (user.offline_score + score_likes * 100 + score_followers * 200 + score_boxes * 100) db.zadd(TABLE_SCORE, {_id: score}) return score
def challenge_user(_id): if _id == current_user._id: flash('You can not even challenge yourself. Nice try.', 'error') return redirect(url_for('user_list')) args = request.args # <-- receive parameters --> sort_key = args.get('sort') sort_direction = args.get('direction') page = args.get('page') filter_option = args.get('foption') filter_term = args.get('fterm') # <-- validate parameters and set fallback values --> sort_key_possible = ('name', 'owner', 'rating') sort_key = sort_key if sort_key in sort_key_possible else 'rating' sort_direction_possible = ('desc', 'asc') sort_direction = (sort_direction if sort_direction in sort_direction_possible else 'desc') sort_direction_bool = sort_direction == 'desc' filter_option_possible = ('name', 'owner') filter_option = (filter_option if filter_option in filter_option_possible else 'name') # filter_term: filter only applied if non-empty string given (None case) # TODO: filter_term validation analogous to tags/user input sanitization page = page or 1 # equals 1 if None; else: stays the same try: page = int(page) except ValueError: page = 1 # <-- filter form --> form = ChallengeFilterForm() if form.validate_on_submit(): filter_option = form.option.data filter_term = form.term.data kwargs = {key: value for key, value in args.items()} kwargs.update(sort=sort_key, direction=sort_direction, foption=filter_option, fterm=filter_term, page=1) return redirect(url_for('challenge_user', _id=_id, **kwargs)) form.term.data = filter_term form.option.data = filter_option cardboxes = CardBox.fetch_all(db) # <-- filter process --> # checks for filter_option = 'name', 'owner' if term is part of string if filter_term: if filter_option == 'name' or filter_option == 'owner': cardboxes = [ box for box in cardboxes if filter_term.lower() in getattr(box, filter_option).lower() ] else: cardboxes = [ box for box in cardboxes if filter_term in getattr(box, filter_option) ] # <-- sort process --> def _sort_key_of(box): if sort_key == 'name': return box.name.lower() if sort_key == 'owner': return box.owner.lower() return getattr(box, sort_key) if cardboxes: cardboxes.sort(key=_sort_key_of, reverse=sort_direction_bool) # <-- pagination --> per_page = 50 cardbox_count = len(cardboxes) page_range = utils.page_range(total_count=cardbox_count, per_page=per_page) page = (page if page in page_range else 1) pagination = utils.Pagination(parent=cardboxes, page=page, per_page=per_page, total_count=cardbox_count) # <-- standard values--> kwargs = {key: value for key, value in args.items()} kwargs.update(sort=sort_key, direction=sort_direction, foption=filter_option, fterm=filter_term, page=page, _id=_id) # <-- creation of dynamic content --> pag_kwargs = dict(pagination=pagination, endpoint='challenge_user', prev='<', next='>', ellipses='...', size='lg', args=kwargs) def partner_id_producer(item): return _id wrapper = utils.TableItemWrapper(dict(partner_id=partner_id_producer)) table = ChooseBoxTable(wrapper(pagination.items), _id, sort_reverse=sort_direction_bool, sort_by=sort_key) return render_template('challenge.html', _id=_id, table=table, filter_form=form, pagination_kwargs=pag_kwargs, active='versus')
def user_settings(): # <-- Change profile picture --> picture_form = PictureForm() if picture_form.submit.data and picture_form.validate_on_submit(): filename = utils.sha1_of(current_user._id) + '.jpg' filepath = os.path.join(app.static_folder, 'img', filename) utils.save_file_field_img(picture_form.picture, filepath) flash('Successfully changed profile picture!') return (redirect(url_for('user_settings'))) elif picture_form.submit.data and picture_form.is_submitted(): for message in picture_form.picture.errors: flash(message, category='error') return (redirect(url_for('user_settings'))) picture_filepath = utils.profile_img_path(app, current_user._id) # <-- Change Showcase --> boxes = CardBox.fetch_multiple(db, current_user.cardboxs) showcase_form = ShowcaseForm() choices = [(b._id, b.name) for b in boxes] choices = [('', '---')] + choices showcase_form.cardbox_input.choices = choices if (showcase_form.submit_showcase.data and showcase_form.validate_on_submit()): new_showcase = dict(info=showcase_form.info_input.data, cardbox=showcase_form.cardbox_input.data, show_info=showcase_form.check_info.data, show_cardbox=showcase_form.check_cardbox.data, show_rank=showcase_form.check_rank.data) current_user.showcase = new_showcase current_user.store(db) flash('Showcase adjusted!') return redirect(url_for('user_settings')) showcase_form.check_info.data = current_user.showcase['show_info'] showcase_form.info_input.data = current_user.showcase['info'] showcase_form.check_cardbox.data = current_user.showcase['show_cardbox'] showcase_form.cardbox_input.data = current_user.showcase['cardbox'] showcase_form.check_rank.data = current_user.showcase['show_rank'] showcase_form.rank_token.data = current_user.get_rank(db) # <-- Change Password --> password_form = ChangePasswordForm() if (password_form.submit_password.data and password_form.validate_on_submit()): if not current_user.check_password(password_form.old_password.data): flash('Old passwort not correct.', 'error') return redirect(url_for('user_settings')) current_user.set_password(password_form.new_password.data) current_user.store(db) flash('Successfully changed password!') return redirect(url_for('user_settings')) return render_template('profile_settings.html', user=current_user, picture_form=picture_form, showcase_form=showcase_form, password_form=password_form, picture_filepath=picture_filepath)
def add_cardbox(): if not request.is_json: print('not json') abort(404) # already returns dictionary payload = request.get_json() # <-- validate payload --> req = ('username', 'password', 'tags', 'content', 'name', 'info') if not payload or not all(r in payload for r in req): print('missing key in payload') abort(404) # None check if any(payload[key] is None for key in req): print('key is None') abort(404) # type check if not all([ isinstance(payload['tags'], list), isinstance(payload['name'], str), isinstance(payload['info'], str) ]): print('key wrong type') abort(404) if any(' ' in tag for tag in payload['tags']): print('whitespace in tag') abort(404) # <-- validate content --> if not isinstance(payload['content'], list): print('content not list') abort(404) attrs = ('question', 'answers', 'correct_answer', 'explanation') if not all(a in _dict for a in attrs for _dict in payload['content']): print('missing key in card') abort(404) number_of_answers = 3 for card in payload['content']: q, a, ca, e = (card['question'], card['answers'], card['correct_answer'], card['explanation']) if not isinstance(q, str) or not isinstance(e, str): abort(404) if not (isinstance(a, list) and len(a) == number_of_answers): abort(404) if not (isinstance(ca, int) and ca in range(number_of_answers)): abort(404) # check authorization if User.exists(db, payload['username']): user = User.fetch(db, payload['username']) if not user.check_password(payload['password']): print('unauthorized') abort(404) cardbox_id = CardBox.gen_card_id() # 'Update'-Function boxes = CardBox.fetch_multiple(db, user.cardboxs) for box in boxes: if box.name == payload['name']: cardbox_id = box._id break else: user.cardboxs.append(cardbox_id) # store content in separate redis table Card.save_content(db, cardbox_id, payload['content']) # create CardBox object for metadata new_box = CardBox(cardbox_id, name=payload['name'], owner=user._id, rating=0, info=payload['info'], tags=payload['tags']) new_box.store(db) user.store(db) User.update_score(db, user._id) return 'OK'
def huge_list(): args = request.args sort_key = args.get('sort') or 'rating' sort_direction = args.get('direction') page = int(args.get('page')) if args.get('page') else 1 if not sort_direction: sort_direction = True else: sort_direction = sort_direction == 'desc' filter_option = args.get('foption') filter_term = args.get('fterm') form = FilterForm() if form.validate_on_submit(): filter_option = form.option.data filter_term = form.term.data kwargs = {key: value for key, value in args.items()} kwargs.update(foption=filter_option, fterm=filter_term, page=1) return redirect(url_for('huge_list', **kwargs)) form.term.data = filter_term filter_option = filter_option or 'tags' form.option.data = filter_option def sort_key_of(box): if sort_key == 'name': return box.name.lower() if sort_key == 'owner': return box.owner.lower() return getattr(box, sort_key) cardboxes = CardBox.fetch_all(db) if filter_term: cardboxes = [ c for c in cardboxes if filter_term in getattr(c, filter_option) ] if sort_key and cardboxes and hasattr(cardboxes[0], sort_key): cardboxes.sort(key=sort_key_of, reverse=sort_direction) else: sort_key = None pagination = utils.Pagination(parent=cardboxes, page=page, per_page=50, total_count=len(cardboxes)) kwargs = {key: value for key, value in args.items()} kwargs.update(page=page, foption=filter_option, direction=sort_direction) pag_kwargs = dict(pagination=pagination, endpoint='huge_list', prev='<', next='>', ellipses='...', size='lg', args=kwargs) table = CardBoxTable(pagination.items, sort_reverse=sort_direction, sort_by=sort_key) return render_template('huge_list.html', table=table, filter_form=form, pagination_kwargs=pag_kwargs)