def dialog_post_api_fetch(post_id, route): try: post_id = int(post_id) except: return _error("Ungültige Anfrage, bitte im globalen Forum melden.") cuser = muser.getCurrentUser() if not cuser.isLoggedIn(): return _error("Nur angemeldete Benutzer können Beiträge melden.") if not mforum.Article.exists(post_id): return _error("Beitrag nicht gefunden.") post = mforum.Article(post_id) live = bool(request.values.get("live", 0)) if live: if post.isClosed() or post.isDeleted(): return "<div style='color: #c00; font-family: \"Open Sans\", Arial, sans-serif'>Beitrag ist bereits geschlossen oder gelöscht.</div>" if route not in ["flagging/closure/duplicate", "closure/duplicate"]: return "<div style='color: #c00; font-family: \"Open Sans\", Arial, sans-serif'>Ein Fehler ist aufgetreten. Bitte im <a href='/f/0' target='_blank' style='color: #600; font-weight: bold;'>globalen Forum</a> melden.</div>" search = request.values.get("search", "").strip() if search == "": return "" id = None if search.startswith("#"): try: id = int(search[1:]) except: id = None if not mforum.Article.exists(id): id = None if id: data = mforum.Article(id) return render_template("forum/raw_qna.html", data=data) else: return "<div style='font-family: \"Open Sans\", Arial, sans-serif'>Bitte wähle ein Suchergebnis aus der Liste rechts.</div>" else: if post.isClosed() or post.isDeleted(): return "[]" if route not in ["flagging/closure/duplicate", "closure/duplicate"]: return "[]" search = request.values.get("search", "").strip() if search == "": return "[]" forum = mforum.Forum(post.getDetail("forumID")) data = forum.getArticles(search, "score")[:80] data = [{ "id": k.id, "title": k.getHTMLTitle(), "score": k.getScore(), "tags": k.getTags(), "closed": k.isClosed() } for k in data if not k.isDeleted()] return jsonify(data[:10])
def tools_forum_flags_action(id): cuser = muser.getCurrentUser() if not cuser.isMod(): abort(404) flagged = mreviews.CustomQueue.getItemData(id) flagged = dict(flagged) if not flagged or (flagged["item_type"] != "forum.question" and flagged["item_type"] != "forum.answer"): abort(404) if flagged["item_type"] == "forum.question": flagged["post"] = mforum.Article(flagged["item_id"]) elif flagged["item_type"] == "forum.answer": flagged["post"] = mforum.Answer(flagged["item_id"]) if flagged["state"] == 0: flags = request.json["flags"] for f in flags: mreviews.CustomQueue.manageFlag(id, f, request.json["result"], request.json["response"]) if mreviews.CustomQueue.getItemOpenFlagsCount(id) == 0: return "{ok:last}" return "{ok}" return "{ok:last}"
def tools_forum_flags_item(id): cuser = muser.getCurrentUser() if not cuser.isMod(): abort(404) flagged = mreviews.CustomQueue.getItemData(id) flagged = dict(flagged) if not flagged or (flagged["item_type"] != "forum.question" and flagged["item_type"] != "forum.answer"): abort(404) if flagged["item_type"] == "forum.question": flagged["post"] = mforum.Article(flagged["item_id"]) elif flagged["item_type"] == "forum.answer": flagged["post"] = mforum.Answer(flagged["item_id"]) flags = mreviews.CustomQueue.getItemFlags(id) def _prepare(d): d = dict(d) d["flagger"] = muser.User.from_id(d["flagger_id"]) return d flags = list(map(_prepare, flags)) has_open_flags = mreviews.CustomQueue.getItemOpenFlagsCount(id) != 0 return render_template("tools/forum_flag_item.html", title="Werkzeuge - Beitragsmeldungen", thispage="tools", item=flagged, flags=flags, has_open_flags=has_open_flags)
def _prepare(d): d = dict(d) if d["item_type"] == "forum.question": d["post"] = mforum.Article(d["item_id"]) elif d["item_type"] == "forum.answer": d["post"] = mforum.Answer(d["item_id"]) return d
def dialog_post_api(post_id, route): try: post_id = int(post_id) except: return _error("Ungültige Anfrage, bitte im globalen Forum melden.") cuser = muser.getCurrentUser() if not cuser.isLoggedIn(): return _error("Nur angemeldete Benutzer können Beiträge melden.") if not mforum.Article.exists(post_id): return _error("Beitrag nicht gefunden.") post = mforum.Article(post_id) if post.isDeleted() or post.getDetail("author") == cuser.id: r = "post_own_or_deleted" elif post.isClosed(): r = "post_closed" elif cuser.may("forum_closeQuestion"): r = "post_close_priv" else: r = "post_no_close_priv" if route.startswith("mod"): r = "post" return _dialog(r, route)
def tools_forum_flags_finish(id): cuser = muser.getCurrentUser() if not cuser.isMod(): abort(404) flagged = mreviews.CustomQueue.getItemData(id) flagged = dict(flagged) if not flagged or (flagged["item_type"] != "forum.question" and flagged["item_type"] != "forum.answer"): abort(404) if flagged["item_type"] == "forum.question": flagged["post"] = mforum.Article(flagged["item_id"]) elif flagged["item_type"] == "forum.answer": flagged["post"] = mforum.Answer(flagged["item_id"]) if flagged["state"] == 0: mreviews.CustomQueue.completeReview(id) return "{ok}"
def unit_submit(unit_id, course_id, unit_label=None, course_label=None): if not mcourses.Courses.exists(course_id) or not mcourses.Units.exists( unit_id) or muser.require_login() or muser.getCurrentUser( ).isDisabled(): abort(404) course = mcourses.Courses(course_id) unit = mcourses.Units(unit_id) cuser = muser.getCurrentUser() if unit.getType() == "quiz": MAX_SCORE = 0 TOTAL_SCORE = 0 RESULT_DATA = {} data = request.json master = unit.getJSON() k = 0 for i in master: k += 1 if i["type"] == "text-answer": MAX_SCORE += int(i["data"]["points"]) if str(k) in list(data.keys()): _ = data[str(k)] if _.lower() in [x.lower() for x in i["data"]["correct"]]: TOTAL_SCORE += int(i["data"]["points"]) RESULT_DATA[k] = ({ "max": i["data"]["points"], "sum": i["data"]["points"], "selection": _, "correct": i["data"]["correct"] }) else: RESULT_DATA[k] = ({ "max": i["data"]["points"], "sum": 0, "selection": _, "correct": i["data"]["correct"] }) elif i["type"] == "multiple-choice": MAX_SCORE += int(i["data"]["points"]) if str(k) in list(data.keys()): _ = data[str(k)] if i["data"]["choices"][int(_)].startswith("*"): TOTAL_SCORE += int(i["data"]["points"]) RESULT_DATA[k] = ({ "max": i["data"]["points"], "sum": i["data"]["points"], "selection": _, "correct": i["data"]["choices"] }) else: RESULT_DATA[k] = ({ "max": i["data"]["points"], "sum": 0, "selection": _, "correct": i["data"]["choices"] }) elif i["type"] == "multiple-answer": MAX_SCORE += int(i["data"]["points"]) if str(k) in list(data.keys()): _ = data[str(k)] total = float(len(i["data"]["choices"])) correct = 0 Zid = 0 for Z in i["data"]["choices"]: if Z.startswith("*") == (Zid in [int(x) for x in _]): correct += 1 Zid += 1 pts = (correct / total) * int(i["data"]["points"]) pts = round(pts, 1) TOTAL_SCORE += pts RESULT_DATA[k] = ({ "max": i["data"]["points"], "sum": pts, "selection": _, "correct": i["data"]["choices"] }) unit.addViewData( cuser, json.dumps({ "result": RESULT_DATA, "max": MAX_SCORE, "sum": TOTAL_SCORE })) return "{ok}" elif unit.getType() == "pinboard": aid = int(unit.getJSON()) if aid == 0: abort(500) else: a = mforum.Article(aid) data = request.json answer = mforum.Answer.createNew(a.getDetail("forumID"), aid, data["comment"], muser.User(-1)) answer.addRevision(data["comment"], cuser, "Ursprüngliche Version") a.setDetail("last_activity_date", time.time()) answer.setDetail("last_activity_date", time.time()) answer.setDetail("creation_date", time.time()) return "{ok}" abort(500)
def unit_show(unit_id, course_id, unit_label=None, course_label=None): if not mcourses.Courses.exists(course_id) or not mcourses.Units.exists( unit_id): abort(404) course = mcourses.Courses(course_id) unit = mcourses.Units(unit_id) cuser = muser.getCurrentUser() if course.getLabel() != course_label: x = url_for("unit_show", course_id=course_id, course_label=course.getLabel(), unit_id=unit_id, unit_label=unit_label if unit_label else unit.getLabel()) return redirect(x) if unit.getLabel() != unit_label: return redirect( url_for("unit_show", course_id=course_id, course_label=course_label, unit_id=unit_id, unit_label=unit.getLabel())) if course.getDetail("state") == 0 and not ( cuser.isMod() or course.getCourseRole(cuser) >= 2): abort(403) if unit.isDisabled() and not (cuser.isMod() or course.getCourseRole(cuser) >= 3): abort(403) course.setLastVisitedUnitId(cuser, unit.id) if unit.getType() == "info": if cuser.isLoggedIn() and not cuser.isDisabled(): unit.addViewData(cuser, None) return render_template('courses/units/info.html', title=course.getTitle() + " - " + unit.getTitle(), thispage="courses", course=course, data=unit) elif unit.getType() == "extvideo": if cuser.isLoggedIn() and not cuser.isDisabled(): unit.addViewData(cuser, None) return render_template('courses/units/extvideo.html', title=course.getTitle() + " - " + unit.getTitle(), thispage="courses", course=course, data=unit) elif unit.getType() == "syllabus": if cuser.isLoggedIn() and not cuser.isDisabled(): unit.addViewData(cuser, None) return render_template('courses/units/syllabus.html', title=course.getTitle() + " - " + unit.getTitle(), thispage="courses", course=course, data=unit) elif unit.getType() == "survey": if cuser.isLoggedIn() and not cuser.isDisabled(): unit.addViewData(cuser, None) s = msurvey.Survey(unit.getJSON()["survey"]) return render_template('courses/units/survey.html', title=course.getTitle() + " - " + unit.getTitle(), thispage="courses", course=course, data=unit, survey=s) elif unit.getType() == "quiz": try: return render_template('courses/units/quiz.html', title=course.getTitle() + " - " + unit.getTitle(), thispage="courses", course=course, data=unit, int=int) except Exception as e: if request.values.get("re-submit", 0) == "true": raise e data = {"re-submit": "true", "submission-error": "incomplete"} return redirect( url_for("unit_show", course_id=course_id, course_label=course_label, unit_id=unit_id, unit_label=unit.getLabel(), **data)) elif unit.getType() == "pinboard": aid = int(unit.getJSON()) if aid == 0: a = None else: a = mforum.Article(aid) if cuser.isLoggedIn() and not cuser.isDisabled(): unit.addViewData(cuser, None) return render_template('courses/units/pinboard.html', title=course.getTitle() + " - " + unit.getTitle(), thispage="courses", course=course, data=unit, post=a) abort(500)
def user_activity_page(id, name=None): try: id = int(id) except: abort(404) if muser.User.exists(id): user = muser.User.from_id(id) cuser = muser.getCurrentUser() mt = user.getDetail("mergeto") if mt and not cuser.isMod(): return redirect(url_for("user_edit_page", id=mt)) if user.isDeleted(): if not cuser.isMod(): abort(404) else: return redirect(url_for("user_deleted_page", id=id)) if name != user.getDetail("name"): return redirect( url_for("user_activity_page", id=id, name=user.getDetail("name"))) else: if request.values.get("page", "summary") == "summary": return render_template("user/activity/summary.html", data=user, thispage="user", title="Aktivität " + user.getHTMLName(False), courses=mcourses.Courses) elif request.values.get("page", "summary") == "courses": return render_template( "user/activity/courses.html", data=user, thispage="user", title="Kurse von " + user.getHTMLName(False), mcourses=mcourses.Courses, mproposals=mproposal.Proposal, prs=mpull_requests.PullRequest.getByUser(user.id, None)) elif request.values.get("page", "summary") == "forum": return render_template("user/activity/forum.html", data=user, thispage="user", title="Forenbeiträge von " + user.getHTMLName(False), mquestions=mforum.Article, manswers=mforum.Answer, mquestion=lambda x: mforum.Article(x)) elif request.values.get("page", "summary") == "reputation": return render_template("user/activity/reputation.html", data=user, thispage="user", title="Reputation von " + user.getHTMLName(False)) elif request.values.get("page", "summary") == "badges": return render_template("user/activity/badges.html", data=user, thispage="user", title="Abzeichen von " + user.getHTMLName(False), getCollectedBadges=mbadges.Badge.byUser) elif request.values.get("page", "summary") == "flags": if user.id != cuser.id and not cuser.isMod(): abort(403) closure_filter = request.values.get("closure", "all") closure_data = mreviews.PostClosure.getFromUser(user) cd = [] closure_helpful = closure_pending = closure_declined = closure_total = 0 for row in closure_data: closure_total += 1 if row["state"] == 0: closure_pending += 1 if closure_filter not in ["all", "pending"]: continue elif row["state"] > 0: closure_helpful += 1 if closure_filter not in ["all", "helpful"]: continue elif row["state"] == -2: closure_declined += 1 if closure_filter not in ["all", "declined"]: continue row["item"] = mforum.Article(row["item_id"]) cd.append(row) post_deletion_filter = request.values.get( "post_deletion", "all") post_deletion_data = mreviews.PostDeletion.getFromUser(user) pdd = [] post_deletion_helpful = post_deletion_pending = post_deletion_declined = post_deletion_total = 0 for row in post_deletion_data: post_deletion_total += 1 if row["state"] == 0: post_deletion_pending += 1 if post_deletion_filter not in ["all", "pending"]: continue elif row["state"] > 0: post_deletion_helpful += 1 if post_deletion_filter not in ["all", "helpful"]: continue elif row["state"] == -2: post_deletion_declined += 1 if post_deletion_filter not in ["all", "declined"]: continue row["item"] = mforum.Article(row["item_id"]) pdd.append(row) custom_filter = request.values.get("custom", "all") custom_data = mreviews.CustomQueue.getFromUser(user) customd = [] custom_helpful = custom_pending = custom_declined = custom_total = 0 for row in custom_data: custom_total += 1 if row["state"] == 0: custom_pending += 1 if custom_filter not in ["all", "pending"]: continue elif row["state"] > 0: custom_helpful += 1 if custom_filter not in ["all", "helpful"]: continue elif row["state"] == -2: custom_declined += 1 if custom_filter not in ["all", "declined"]: continue if row["item_type"] == "forum.question": row["item"] = mforum.Article(row["item_id"]) elif row["item_type"] == "forum.answer": row["item"] = mforum.Answer(row["item_id"]) elif row["item_type"] == "user": row["item"] = muser.User.from_id(row["item_id"]) customd.append(row) return render_template( "user/activity/flags.html", data=user, closure_flags=cd, post_deletion_flags=pdd, custom_flags=customd, thispage="user", title="Meldungen von " + user.getHTMLName(False), closure_helpful=closure_helpful, closure_pending=closure_pending, closure_declined=closure_declined, closure_total=closure_total, post_deletion_helpful=post_deletion_helpful, post_deletion_pending=post_deletion_pending, post_deletion_declined=post_deletion_declined, post_deletion_total=post_deletion_total, custom_helpful=custom_helpful, custom_pending=custom_pending, custom_declined=custom_declined, custom_total=custom_total) else: abort(404) else: abort(404)