def report_exercise_outcome(exercise_outcome, exercise_source, exercise_solving_speed, bookmark_id): """ In the model parlance, an exercise is an entry in a table that logs the performance of an exercise. Every such performance, has a source, and an outcome. :param exercise_outcome: One of: Correct, Retry, Wrong, Typo, Too easy... :param exercise_source: has been assigned to your app by zeeguu :param exercise_solving_speed: in milliseconds :param bookmark_id: the bookmark for which the data is reported :return: """ if not exercise_solving_speed.isdigit(): exercise_solving_speed = 0 try: bookmark = Bookmark.find(bookmark_id) bookmark.report_exercise_outcome(exercise_source, exercise_outcome, exercise_solving_speed, db_session) return "OK" except: traceback.print_exc() return "FAIL"
def test_bookmarks_in_article(self): random_bookmark = BookmarkRule(self.user).bookmark article = random_bookmark.text.article # each bookmark belongs to a random text / article so the # combo of user/article will always result in one bookmark assert 1 == len( Bookmark.find_all_for_user_and_article(self.user, article))
def delete_bookmark(bookmark_id): try: bookmark = Bookmark.find(bookmark_id) db_session.delete(bookmark) db_session.commit() except NoResultFound: return "Inexistent" return "OK"
def report_learned_bookmark(bookmark_id): bookmark = Bookmark.find(bookmark_id) bookmark.report_exercise_outcome( ExerciseSource.TOP_BOOKMARKS_MINI_EXERCISE, ExerciseOutcome.CORRECT, -1, db_session, ) return "OK"
def learned_words(user_id, language_id, from_date: str, to_date: str): query = """ select b.id as bookmark_id, o_uw.word, t_uw.word as translation, b.learned_time from bookmark as b join user_word as o_uw on o_uw.id = b.origin_id join user_word as t_uw on t_uw.id = b.translation_id where b.learned_time > :from_date -- '2021-05-24' and b.learned_time < :to_date -- '2021-06-23' and o_uw.language_id = :language_id -- 2 and b.user_id = :user_id -- 2953 and learned = 1 order by b.learned_time """ results = list_of_dicts_from_query( query, { "user_id": user_id, "from_date": from_date, "to_date": to_date, "language_id": language_id, }, ) for each in results: bookmark = Bookmark.find(each["bookmark_id"]) each["self_reported"] = ( bookmark.sorted_exercise_log().last_exercise().is_too_easy()) each["most_recent_correct_dates"] = bookmark.sorted_exercise_log( ).str_most_recent_correct_dates() return results
def user_article_info(cls, user: User, article: Article, with_content=False, with_translations=True): from zeeguu.core.model import Bookmark # Initialize returned info with the default article info returned_info = article.article_info(with_content=with_content) user_article_info = UserArticle.find(user, article) if not user_article_info: returned_info["starred"] = False returned_info["opened"] = False returned_info["liked"] = None returned_info["translations"] = [] return returned_info returned_info["starred"] = user_article_info.starred is not None returned_info["opened"] = user_article_info.opened is not None returned_info["liked"] = user_article_info.liked if user_article_info.starred: returned_info["starred_time"] = datetime_to_json( user_article_info.starred) if with_translations: translations = Bookmark.find_all_for_user_and_article( user, article) returned_info["translations"] = [ each.serializable_dictionary() for each in translations ] return returned_info
def test_exists(self): random_bookmark = self.user.all_bookmarks()[0] assert Bookmark.exists(random_bookmark)
def test_find_by_user_word_and_text(self): bookmark_should_be = self.user.all_bookmarks()[0] bookmark_to_check = Bookmark.find_by_user_word_and_text( self.user, bookmark_should_be.origin, bookmark_should_be.text) assert bookmark_to_check == bookmark_should_be
def test_find_all_by_user_and_word(self): bookmark_should_be = self.user.all_bookmarks()[0] bookmark_to_check = Bookmark.find_all_by_user_and_word( self.user, bookmark_should_be.origin) assert bookmark_should_be in bookmark_to_check
def test_find(self): bookmark_should_be = self.user.all_bookmarks()[0] bookmark_to_check = Bookmark.find(bookmark_should_be.id) assert bookmark_to_check == bookmark_should_be
def find_all_for_user_and_text(self): bookmark_should_be = self.user.all_bookmarks()[0] bookmark_to_check = Bookmark.find_all_for_text_and_user( bookmark_should_be.text, self.user) assert bookmark_should_be in bookmark_to_check
def get_one_translation(from_lang_code, to_lang_code): """ To think about: - it would also make sense to separate translation from logging; or at least, allow for situations where a translation is not associated with an url... or? - jul 2021 - Bjorn would like to have the possibility of getting a translation without an article; can be done; allow for the articleID to be empty; what would be the downside of that? - hmm. maybe he can simply work with get_multiple_translations :return: json array with translations """ word_str = request.form["word"].strip(punctuation_extended) url = request.form.get("url") title_str = request.form.get("title", "") context = request.form.get("context", "") article_id = request.form.get("articleID", None) if not article_id: # the url comes from elsewhere not from the reader, so we find or create the article article = Article.find_or_create(db_session, url) article_id = article.id minimal_context, query = minimize_context(context, from_lang_code, word_str) # if we have an own / teacher translation that is our first "best guess" # ML: TODO: word translated in the same text / articleID / url should still be considered # as an own translation; currently only if the "context" is the same counts; # which means that translating afslore in a previous paragraph does not count best_guess = get_own_past_translation(flask.g.user, word_str, from_lang_code, to_lang_code, context) if best_guess: likelihood = 1 source = "Own past translation" else: translations = get_next_results( { "from_lang_code": from_lang_code, "to_lang_code": to_lang_code, "url": url, "word": word_str, "title": title_str, "query": query, "context": minimal_context, }, number_of_results=1, ).translations best_guess = translations[0]["translation"] likelihood = translations[0].pop("quality") source = translations[0].pop("service_name") bookmark = Bookmark.find_or_create( db_session, flask.g.user, word_str, from_lang_code, best_guess, to_lang_code, minimal_context, url, title_str, article_id, ) print(bookmark) return json_result({ "translation": best_guess, "bookmark_id": bookmark.id, "source": source, "likelihood": likelihood, })
def test_find_by_specific_user(self): list_should_be = self.user.all_bookmarks() list_to_check = Bookmark.find_by_specific_user(self.user) for b in list_should_be: assert b in list_to_check
def unstar_bookmark(bookmark_id): bookmark = Bookmark.find(bookmark_id) bookmark.starred = False bookmark.update_fit_for_study() db_session.commit() return "OK"
def similar_words_api(bookmark_id): bookmark = Bookmark.find(bookmark_id) return json_result( similar_words(bookmark.origin.word, bookmark.origin.language, flask.g.user))
def all_bookmarks(self, user): from zeeguu.core.model import Bookmark return Bookmark.find_all_for_text_and_user(self, user)
def test_find_all(self): list_should_be = self.user.all_bookmarks() list_to_check = Bookmark.find_all() for b in list_should_be: assert b in list_to_check
def contribute_translation(from_lang_code, to_lang_code): """ User contributes a translation they think is appropriate for a given :param word in :param from_lang_code in a given :param context The :param translation is in :param to_lang_code Together with the two words and the textual context, you must submit also the :param url, :param title of the page where the original word and context occurred. :return: in case of success, the bookmark_id and main translation """ # All these POST params are mandatory word_str = unquote_plus(request.form["word"]) translation_str = request.form["translation"] url = request.form.get("url", "") context_str = request.form.get("context", "") title_str = request.form.get("title", "") # when a translation is added by hand, the servicename_translation is None # thus we set it to MANUAL service_name = request.form.get("servicename_translation", "MANUAL") article_id = None if "articleID" in url: article_id = url.split("articleID=")[-1] url = Article.query.filter_by( id=article_id).one().url.as_canonical_string() elif "articleURL" in url: url = url.split("articleURL=")[-1] elif "article?id=" in url: article_id = url.split("article?id=")[-1] url = Article.query.filter_by( id=article_id).one().url.as_canonical_string() else: # the url comes from elsewhere not from the reader, so we find or create the article article = Article.find_or_create(db_session, url) article_id = article.id # Optional POST param selected_from_predefined_choices = request.form.get( "selected_from_predefined_choices", "") minimal_context, _ = minimize_context(context_str, from_lang_code, word_str) bookmark = Bookmark.find_or_create( db_session, flask.g.user, word_str, from_lang_code, translation_str, to_lang_code, minimal_context, url, title_str, article_id, ) # Inform apimux about translation selection data = { "word_str": word_str, "translation_str": translation_str, "url": url, "context_size": len(context_str), "service_name": service_name, } contribute_trans(data) return json_result(dict(bookmark_id=bookmark.id))