def POST(self): username = None if hasattr(ctx.session, 'username'): username = ctx.session.username else: return web.seeother('/user/register', absolute=True) i = web.input() form = self.form() render = web.template.render( 'templates/', base='layout', globals={ 'session': ctx.session, 'hasattr': hasattr, 'pretty_date': pretty_date}) if not form.validates(): return render.topic.new(form) else: topic = Topic( title=i.title, hashtag=i.hashtag, user_id=ctx.session.user.id) topic.views = 1 tag = db.session.query(Tag).get(i.tag) topic.tags.append(tag) db.session.add(topic) db.session.commit() web.seeother('/topic/%d' % topic.id, absolute=True)
def index(): # board_id = 2 board_id = int(request.args.get('board_id', -1)) if board_id == -1: ms = Topic.all() else: ms = Topic.find_all(board_id=board_id) token = str(uuid.uuid4()) u = current_user() csrf_tokens['token'] = u.id bs = Board.all() return render_template("topic/index.html", ms=ms, token=token, bs=bs, bid=board_id, user=u)
def delete(): id = int(request.args.get('id')) token = request.args.get('token') u = current_user() # 判断 token 是否是我们给的 if token in csrf_tokens and csrf_tokens[token] == u.id: csrf_tokens.pop(token) if u is not None: print('删除 topic 用户是', u, id) Topic.delete(id) return redirect(url_for('.index')) else: abort(404) else: abort(403)
def save(self): """ Overwrite save method to add to Elasticsearch. """ # TODO-2 should we validate the save worked before going to ES? from models.topic import Topic from models.user import User data = json_prep(self.deliver()) topic = Topic.get(id=self['topic_id']) if topic: data['topic'] = json_prep(topic.deliver()) user = User.get(id=self['user_id']) if user: data['user'] = json_prep(user.deliver()) es.index( index='entity', doc_type='post', body=data, id=self['id'], ) return super().save()
def get_unit_route(request, unit_id): """ Get a specific unit given an ID. """ unit = Unit.get_latest_accepted(unit_id) if not unit: return abort(404) # TODO-2 SPLITUP create new endpoints for these instead topics = Topic.list_by_entity_id(unit_id) versions = Unit.get_versions(unit_id) requires = Unit.list_requires(unit_id) required_by = Unit.list_required_by(unit_id) sets = Set.list_by_unit_id(unit_id) return 200, { 'unit': unit.deliver(), # 'unit_parameters': unit.fetch_parameters(), 'topics': [topic.deliver() for topic in topics], 'versions': [version.deliver() for version in versions], 'requires': [require.deliver() for require in requires], 'required_by': [require.deliver() for require in required_by], 'belongs_to': [set_.deliver() for set_ in sets], }
def update_topic_route(request, topic_id): """ Update the topic. - Only the name can be changed. - Only by original author. """ current_user = get_current_user(request) if not current_user: return abort(401) # ## STEP 1) Find existing topic instance ## # topic = Topic.get(id=topic_id) if not topic: return abort(404) if topic['user_id'] != current_user['id']: return abort(403) # ## STEP 2) Limit the scope of changes ## # topic_data = request['params']['topic'] topic_data = pick(topic_data, ('name',)) # ## STEP 3) Validate and save topic instance ## # topic, errors = topic.update(topic_data) if errors: errors = prefix_error_names('topic.', errors) return 400, { 'errors': errors, 'ref': 'k7ItNedf0I0vXfiIUcDtvHgQ', } # ## STEP 4) Return response ## # return 200, {'topic': topic.deliver()}
def get_card_route(request, card_id): """ Get a specific card given an ID. Show all relevant data, but not used for the learning interface. """ card = get_card_by_kind(card_id) if not card: return abort(404) unit = Unit.get_latest_accepted(entity_id=card['unit_id']) if not unit: return abort(404) # TODO-2 SPLITUP create new endpoints for these instead topics = Topic.list_by_entity_id(entity_id=card_id) versions = Card.get_versions(entity_id=card_id) requires = Card.list_requires(entity_id=card_id) required_by = Card.list_required_by(entity_id=card_id) params = CardParameters.get(entity_id=card_id) return 200, { 'card': card.deliver(access='view'), 'card_parameters': params.get_values(), 'unit': unit.deliver(), 'topics': [topic.deliver() for topic in topics], 'versions': [version.deliver() for version in versions], 'requires': [require.deliver() for require in requires], 'required_by': [require.deliver() for require in required_by], }
def get_unit_route(request, unit_id): """ Get a specific unit given an ID. """ db_conn = request["db_conn"] unit = Unit.get_latest_accepted(db_conn, unit_id) if not unit: return abort(404) # TODO-2 SPLITUP create new endpoints for these instead topics = Topic.list_by_entity_id(db_conn, unit_id) versions = Unit.get_versions(db_conn, unit_id) requires = Unit.list_requires(db_conn, unit_id) required_by = Unit.list_required_by(db_conn, unit_id) sets = Set.list_by_unit_id(db_conn, unit_id) return ( 200, { "unit": unit.deliver(), # 'unit_parameters': unit.fetch_parameters(), "topics": [topic.deliver() for topic in topics], "versions": [version.deliver() for version in versions], "requires": [require.deliver() for require in requires], "required_by": [require.deliver() for require in required_by], "belongs_to": [set_.deliver() for set_ in sets], }, )
def post(self): user = users.get_current_user() title = self.request.get("title") content = self.request.get("content") tags = self.request.get("all-tags").split(",") instructor = self.request.get("instructor") if instructor: tags.append(instructor) author = users.get_current_user().nickname() if title and content and tags: topic = Topic.create(title, content, author, tags) topic.subscribers.append(user.email()) topic.put() self.redirect("/topic/" + str(topic.key.id())) the_users = User.query(User.receive_updates==True).fetch() for user in the_users: email = user.email if user.first_name is None: first_name = "" else: first_name = user.first_name if email != users.get_current_user().email(): email_new_topic(first_name, title, topic.key.id(), email) else: self.redirect('/')
def test_list_by_entity_id(db_conn, topics_table): topics_table.insert([{ 'user_id': 'Q', 'name': 'A', 'entity': { 'id': 'A', 'kind': 'card', } }, { 'user_id': 'Q', 'name': 'A', 'entity': { 'id': 'A', 'kind': 'card', } }, { 'user_id': 'Q', 'name': 'A', 'entity': { 'id': 'B', 'kind': 'card', } }]).run(db_conn) topics = Topic.list_by_entity_id('A') assert len(topics) == 2
def post(self, comment_id): comment = Comment.get_by_id(int(comment_id)) comment.deleted = True comment.put() topic = Topic.get_by_id(comment.the_topic_id) topic.num_comments -= 1 topic.put() self.redirect("/topic/" + str(comment.the_topic_id))
def post(self, topic_id): topic = Topic.get_by_id(int(topic_id)) topic.title = self.request.get("title") topic.content = self.request.get("content") topic.tags = self.request.get("all-tags").split(",") topic.updated = datetime.datetime.now() topic.updated_by = users.get_current_user().nickname() topic.put() self.redirect("/topic/" + str(topic_id))
def user_detail(username): u = User.find_by(username=username) user_id = u.id ms = Topic.find_all(user_id=user_id) ms.reverse() rs = Reply.find_all(user_id=user_id) rs.reverse() if u is None: abort(404) else: return render_template('new_profile.html', u=u, ms=ms, rs=rs)
def post(self, topic_id): user = users.get_current_user() author = user.nickname() content = self.request.get("content") post_comment = self.request.get("post-comment") subscribe_button = self.request.get("subscribe-button") if post_comment: if content: comment = Comment.create(author, content, int(topic_id)) Topic.add_comment(int(topic_id), comment.created, comment.author) the_user = "" for usr in User.query(User.email == user.email()).fetch(): the_user = usr topic = Topic.get_by_id(int(topic_id)) subscriber_query = topic.subscribers for email in subscriber_query: if email != user.email(): # don't send email update to the author of the comment email_new_comment(the_user.first_name, Topic.get_by_id(int(topic_id)).title, str(topic_id), email) self.redirect('/topic/' + str(topic_id)) else: self.redirect('/topic/' + str(topic_id)) elif subscribe_button: topic = Topic.get_by_id(int(topic_id)) user = users.get_current_user() user_email = user.email() if user_email in topic.subscribers: topic.subscribers.remove(user_email) else: topic.subscribers.append(user_email) topic.put() self.redirect("/topic/" + str(topic_id))
def get(self, topic_id): user = users.get_current_user() topic = Topic.get_by_id(int(topic_id)) if user.nickname() in ADMINS or user.nickname() == topic.author: args = {} args["topic_title"] = topic.title args["topic_content"] = topic.content args["tags"] = topic.tags self.base_args(user, args) self.render_template("edit-topic.html", args) else: self.redirect('/topic/' + topic_id)
def test_name(db_conn, topics_table): """ Expect a topic to require a name. """ topic, errors = Topic.insert(db_conn, { 'user_id': 'Q', 'entity': { 'id': 'A', 'kind': 'card', } }) assert len(errors) == 1 topic['name'] = 'A' topic, errors = topic.save(db_conn) assert len(errors) == 0
def test_user_id(db_conn, topics_table): """ Expect a topic to require a user id. """ topic, errors = Topic.insert({ 'name': 'A', 'entity': { 'id': 'A', 'kind': 'card', } }) assert len(errors) == 1 topic['user_id'] = 'Q' topic, errors = topic.save() assert len(errors) == 0
def test_entity(db_conn, topics_table): """ Expect a topic to require an entity kind and id. """ topic, errors = Topic.insert({ 'user_id': 'Q', 'name': 'A', }) assert len(errors) == 2 topic['entity'] = { 'id': 'A', 'kind': 'card', } topic, errors = topic.save() assert len(errors) == 0
def get(self, topic_id): user = users.get_current_user() args = {} topic = Topic.get_by_id(int(topic_id)) args["topic"] = topic if user: if user.nickname() in ADMINS: args["admin"]=True if user.email() in topic.subscribers: args["subscribed"] = True self.base_args(user, args) args["comments"] = Comment.query(Comment.deleted==False, Comment.the_topic_id==int(topic_id)).order(Comment.created).fetch() self.render_template("topic.html", args)
def follow_route(request): """ Follow a card, unit, or set. """ # TODO-3 simplify this method. does some of this belong in the model? current_user = get_current_user(request) if not current_user: return abort(401) follow_data = dict(**request['params']) follow_data['user_id'] = current_user['id'] follow = Follow(follow_data) errors = follow.validate() if errors: return 400, { 'errors': errors, 'ref': '4Qn9oWVWiGKvXSONQKHSy1T6' } # Ensure the entity exists TODO-3 should this be a model validation? if follow['entity']['kind'] == 'topic': entity = Topic.get(id=follow['entity']['id']) else: entity = get_latest_accepted(follow['entity']['kind'], follow['entity']['id']) if not entity: return abort(404) # Ensure we don't already follow TODO-3 should this be a model validation? prev = Follow.list(user_id=current_user['id'], entity_id=follow_data['entity']['id']) if prev: return abort(409) follow, errors = follow.save() if errors: return 400, { 'errors': errors, 'ref': 'gKU6wgTItxpKyDs0eAlonCmi', } return 200, {'follow': follow.deliver(access='private')}
def get_set_route(request, set_id): """ Get a specific set given an ID. """ set_ = Set.get_latest_accepted(set_id) if not set_: return abort(404) # TODO-2 SPLITUP create new endpoints for these instead topics = Topic.list_by_entity_id(entity_id=set_id) versions = Set.get_versions(entity_id=set_id) units = set_.list_units() return 200, { 'set': set_.deliver(), # 'set_parameters': set_.fetch_parameters(), 'topics': [topic.deliver() for topic in topics], 'versions': [version.deliver() for version in versions], 'units': [unit.deliver() for unit in units], }
def sitemap_route(request): """ Generate a sitemap so Google can find Sagefy's content. Should be linked to from https://sagefy.org/robots.txt Sitemap: https://sagefy.org/s/sitemap.txt """ # TODO-1 cache in redis db_conn = request['db_conn'] sitemap = defaults | set() # Card, unit, set kinds = {'card': Card, 'unit': Unit, 'set': Set} for kind, Model in kinds.items(): query = Model.start_accepted_query() entities = [Model(data).deliver() for data in query.run(db_conn)] for entity in entities: sitemap.add('https://sagefy.org/{kind}s/{id}'.format( id=entity['entity_id'], kind=kind )) # TODO-2 ...and versions pages # TODO-2 set tree # Topic for topic in Topic.list(db_conn): sitemap.add('https://sagefy.org/topics/{id}'.format(id=topic['id'])) # User users = [deliver_user(user) for user in list_users({}, db_conn)] for user in users: sitemap.add('https://sagefy.org/users/{id}'.format(id=user['id'])) sitemap = '\n'.join(sitemap) return 200, sitemap
def detail(id): u = current_user() m = Topic.get(id) board = Board.one(id=m.board_id) # 传递 topic 的所有 reply 到 页面中 return render_template("topic/detail.html", topic=m, user=u, board=board)
def detail(id): m = Topic.get(id) return render_template("topic/detail.html", topic=m)
def post(self, topic_id): topic = Topic.get_by_id(int(topic_id)) topic.closed=False topic.put() self.redirect("/topic/" + topic_id)
def index(): topics = Topic.all() return render_template("topic/index.html", topics=topics)
def post(self, topic_id): topic = Topic.get_by_id(int(topic_id)) topic.deleted = True topic.put() self.redirect("/")
def get(self, topic_id): user = users.get_current_user() if user.nickname() in ADMINS or user.nickname() == Topic.get_by_id(int(topic_id)).author: args = {} self.base_args(user, args) self.render_template("open-topic.html", args)
def topic_all(user_id): topic_all = Topic.find_all(user_id=ObjectId(user_id)) return render_template("BBS/search.html", ms=topic_all)
def detail(id): m = Topic.get(id) # 传递 topic 的所有 reply 到 页面中 return render_template("topic/detail.html", topic=m)
def test_get_topic_details_handler(self): # GET topic = Topic(title = "New topic", content = "Content of new topic!", author_email = '*****@*****.**') topic.put() get = self.testapp.get('/topic/details/{0}'.format(topic.key.id())) self.assertEqual(get.status_int, 200)
def topic(self): t = Topic.one(id=str(self.title)) return t
def created_topic(user_id): topic = Topic.all(user_id=user_id) topic = sorted(topic, key=lambda m: m.created_time, reverse=True) return topic
def add(): form = request.form user = current_user() Topic.new(form, user_id=user._id) return redirect(url_for("bbs.index"))
def topic(self): # profile.html 中有用到 # Topic 可能为 none, 在 profile 页面中做判断 from models.topic import Topic t = Topic.one(id=self.topic_id) return t
def index(): ms = Topic.all() return render_template("topic/index.html", ms=ms)
def new_chrip(self, title, description): chrip = Topic(author=self.username, title=title, description=description, author_id=self._id) chrip.save_to_mongo()
def detail(id): token = new_csrf_token() topic = Topic.get(id) return render_template("topic/detail.html", token=token, topic=topic)
def new(cls, form, **kwargs): from models.topic import Topic r = super(Reply, cls).new(form, **kwargs) t = Topic.find_by(id=r.topic_id) t.update_replies_id(r.id) return r
def get_chrips(self): return Topic.find_by_author_id(self._id)
def create_post_route(request, topic_id): """ Create a new post on a given topic. Proposal: must include entity (card, unit, or set) information. Vote: must refer to a valid proposal. """ current_user = get_current_user(request) if not current_user: return abort(401) topic = Topic.get(id=topic_id) if not topic: return 404, { 'errors': [{ 'name': 'topic_id', 'message': c('no_topic'), }], 'ref': 'PCSFCxsJtnlP0x9WzbPoKcwM', } # ## STEP 1) Create post (and entity) instances post_data = request['params'].get('post') if not post_data: return 400, { 'errors': [{ 'name': 'post', 'message': 'Missing post data.', }], 'ref': 'ykQpZwJKq54MTCxgkx0p6baW' } post_data = omit(post_data, ('id', 'created', 'modified',)) post_data['user_id'] = current_user['id'] post_data['topic_id'] = topic_id post_ = instance_post_facade(post_data) post_kind = post_['kind'] if post_kind == 'proposal': entity = instance_new_entity(request['params']) entity_kind = get_kind(request['params']) post_['entity_version'] = { 'id': entity['id'], 'kind': entity_kind, } # ## STEP 2) Validate post (and entity) instances errors = prefix_error_names('post.', post_.validate()) if post_kind == 'proposal': errors = errors + prefix_error_names('entity.', entity.validate()) if len(errors): return 400, { 'errors': errors, 'ref': 'tux33ztgFj9ittSpS7WKIkq7' } # ## STEP 3) Save post (and entity) post_.save() if post_kind == 'proposal': entity.save() # ## STEP 4) Add author as a follower Follow.insert({ 'user_id': current_user['id'], 'entity': { 'id': topic['id'], 'kind': 'topic', } }) # TODO-2 also follow the entity # ## STEP 5) Make updates based on proposal / vote status if post_kind == 'proposal': update_entity_status(post_) if post_kind == 'vote': proposal = Proposal.get(id=post_['replies_to_id']) update_entity_status(proposal) # ## STEP 6) Return response return 200, {'post': post_.deliver()}
from models.difficulty import Difficulty import repositories.difficulty_repository as difficulty_repository from models.question import Question import repositories.question_repository as question_repository from models.quiz import Quiz import repositories.quiz_repository as quiz_repository user_topic_repository.delete_all() topic_repository.delete_all() difficulty_repository.delete_all() question_repository.delete_all() quiz_repository.delete_all() topic_00 = Topic("General Knowledge") topic_repository.save(topic_00) topic_01 = Topic("Geography") topic_repository.save(topic_01) topic_02 = Topic("History") topic_repository.save(topic_02) topic_03 = Topic("Sport & Games") topic_repository.save(topic_03) topic_04 = Topic("Science & Nature") topic_repository.save(topic_04) topic_05 = Topic("Literature")
def detail(id): m = Topic.find(id=id) u = User.one(id=m.user_id) # 传递 topic 的所有 reply 到 页面中 return render_template("topic/detail.html", topic=m, user=u)
def detail(id): m = Topic.get(id) t = format_time(m) # 传递 topic 的所有 reply 到 页面中 return render_template("topic/detail.html", topic=m, t=t)
def add(): form = request.form u = current_user() m = Topic.new(form, user_id=u.id) return redirect(url_for('.detail', id=m.id))
def get(self, topic_id): topic = Topic.get_by_id(int(topic_id)) topic.deleted = True topic.put() return self.redirect('/')
def created_topic(user_id): # O(n) ts = Topic.all(user_id=user_id) return ts
def get(self, topic_id): topic = Topic.get_by_id(int(topic_id)) params = {"topic": topic} return self.render_template("delete_topic.html", params=params)
def get_posts_route(request, topic_id): """ Get a reverse chronological listing of posts for given topic. Includes topic meta data and posts (or proposals or votes). Paginates. """ # Is the topic valid? topic = Topic.get(id=topic_id) if not topic: return 404, { 'errors': [{ 'name': 'topic_id', 'message': c('no_topic'), }], 'ref': 'pgnNbqSP1VUWkOYq8MVGPrSS', } # Pull the entity entity_kind = topic['entity']['kind'] entity = get_latest_accepted(entity_kind, topic['entity']['id']) # Pull all kinds of posts posts = get_posts_facade( limit=request['params'].get('limit') or 10, skip=request['params'].get('skip') or 0, topic_id=topic_id ) # For proposals, pull up the proposal entity version # ...then pull up the previous version # ...make a diff between the previous and the proposal entity version diffs = {} entity_versions = {} for post_ in posts: if post_['kind'] == 'proposal': entity_version = entity_versions[post_['id']] = get_version( post_['entity_version']['kind'], post_['entity_version']['id'] ) previous_version = get_version( post_['entity_version']['kind'], entity_version['previous_id'] ) if previous_version: diffs[post_['id']] = object_diff(previous_version.deliver(), entity_version.deliver()) # TODO-2 SPLITUP create new endpoint for this instead users = {} for post_ in posts: user_id = post_['user_id'] if user_id not in users: user = User.get(id=user_id) if user: users[user_id] = { 'name': user['name'], 'avatar': user.get_avatar(48) } # TODO-2 SPLITUP create new endpoints for these instead output = { 'topic': topic.deliver(), 'posts': [p.deliver() for p in posts], 'entity_versions': { p: ev.deliver() for p, ev in entity_versions.items() }, # 'diffs': diffs, TODO-2 this causes a circular dependency 'users': users, } if entity: output[entity_kind] = entity.deliver() return 200, output
def post(self, topic_id): topic = Topic.get_by_id(int(topic_id)) topic.deleted = True topic.put() return self.redirect_to("main-page", topic_id=topic.key.id())
def create_topic_route(request): """ Create a new topic. The first post (or proposal) must be provided. """ current_user = get_current_user(request) if not current_user: return abort(401) # ## STEP 1) Create post and topic (and entity) instances topic_data = request['params'].get('topic') post_data = request['params'].get('post') if not topic_data: return 400, { 'errors': [{ 'name': 'topic', 'message': 'Missing topic data.' }], 'ref': 'zknSd46f2hRNjSjVHCg6YLwN' } if not post_data: return 400, { 'errors': [{ 'name': 'post', 'message': 'Missing post data.' }], 'ref': 'Qki4oWX4nTdNAjYI8z5iNawr' } topic_data = omit(topic_data, ('id', 'created', 'modified')) topic_data['user_id'] = current_user['id'] topic = Topic(topic_data) post_data = omit(post_data, ('id', 'created', 'modified',)) post_data['user_id'] = current_user['id'] post_data['topic_id'] = topic['id'] post_ = instance_post_facade(post_data) post_kind = post_['kind'] if post_kind == 'proposal': entity = instance_new_entity(request['params']) entity_kind = get_kind(request['params']) post_['entity_version'] = { 'id': entity['id'], 'kind': entity_kind, } # ## STEP 2) Validate post and topic (and entity) instances errors = prefix_error_names('topic.', topic.validate()) errors = errors + prefix_error_names('post.', post_.validate()) if post_kind == 'proposal': errors = errors + prefix_error_names('entity.', entity.validate()) if len(errors): return 400, { 'errors': errors, 'ref': 'TAY5pX3ghWBkSIVGTHzpQySa' } # ## STEP 3) Save post and topic (and entity) topic.save() post_.save() if post_kind == 'proposal': entity.save() # ## STEP 4) Add author as a follower Follow.insert({ 'user_id': current_user['id'], 'entity': { 'id': topic['id'], 'kind': 'topic', } }) # TODO-2 also follow the entity automatically IF needed # ## STEP 5) Send out any needed notifications send_notices( entity_id=topic['entity']['id'], entity_kind=topic['entity']['kind'], notice_kind='create_topic', notice_data={ 'user_name': current_user['name'], 'topic_name': topic['name'], 'entity_kind': topic['entity']['kind'], 'entity_name': topic['entity']['id'], } ) # ## STEP 5) Return response return 200, {'topic': topic.deliver(), 'post': post_.deliver()}
def get(self): topics = Topic.query( Topic.deleted == False).order(-Topic.created_at).fetch() params = {"topics": topics} return self.render_template("topics/topics_list.html", params=params)