def find_or_create( cls, session, user, _origin: str, _origin_lang: str, _translation: str, _translation_lang: str, _context: str, _url: str, _url_title: str, article_id: int, ): """ if the bookmark does not exist, it creates it and returns it if it exists, it ** updates the translation** and returns the bookmark object :param _origin: :param _context: :param _url: :return: """ origin_lang = Language.find_or_create(_origin_lang) translation_lang = Language.find_or_create(_translation_lang) origin = UserWord.find_or_create(session, _origin, origin_lang) article = Article.query.filter_by(id=article_id).one() url = Url.find_or_create(session, article.url.as_string(), _url_title) context = Text.find_or_create(session, _context, origin_lang, url, article) translation = UserWord.find_or_create(session, _translation, translation_lang) now = datetime.now() try: # try to find this bookmark bookmark = Bookmark.find_by_user_word_and_text(user, origin, context) # update the translation bookmark.translation = translation except sqlalchemy.orm.exc.NoResultFound as e: bookmark = cls(origin, translation, user, context, now) except Exception as e: raise e session.add(bookmark) session.commit() return bookmark
def modify_user_language(): """ This endpoint is for modifying a user language. It tries to find the user_language, and otherwise create it. It then sets all the parameters given. :return: "OK" in case of success """ language_id = int(request.form.get("language_id", "")) try: language_reading = int(request.form.get("language_reading", "")) except: language_reading = None try: language_exercises = int(request.form.get("language_exercises", "")) except: language_exercises = None try: language_level = int(request.form.get("language_level", "")) except: language_level = None language_object = Language.find_by_id(language_id) user_language = UserLanguage.find_or_create(session, flask.g.user, language_object) if language_reading is not None: user_language.reading_news = language_reading if language_exercises is not None: user_language.doing_exercises = language_exercises if language_level is not None: user_language.declared_level = language_level session.add(user_language) session.commit() return "OK"
def find_or_create(cls, session, user: User, _url, _title: str, _language): """ create a new object and add it to the db if it's not already there otherwise retrieve the existing object and update in case of creation, the created object is incomplete \ """ language = Language.find(_language) url = Url.find_or_create(session, _url, _title) try: return cls.query.filter_by(user=user, url=url).one() except NoResultFound: try: new = cls(user, url, _title, language) session.add(new) session.commit() return new except Exception as e: from sentry_sdk import capture_exception capture_exception(e) print("seems we avoided a race condition") session.rollback() return cls.query.filter_by(user=user, url=url).one()
def test_languages_exists(self): language_should_be = LanguageRule().random try: language_to_check = Language.find(language_should_be.code) except NoResultFound: assert False, "No Language found in database" assert language_should_be.code == language_to_check.code \ and language_should_be.name == language_to_check.name
def __create_new_language(cls, language_id): language_name = cls.languages.get(language_id) if language_name is None: raise KeyError new_language = Language(language_id, language_name) cls.save(new_language) return new_language
def create_anonymous(cls, uuid, password, learned_language_code=None, native_language_code=None): """ :param uuid: :param password: :param learned_language_code: :param native_language_code: :return: """ # since the DB must have an email we generate a fake one fake_email = uuid + cls.ANONYMOUS_EMAIL_DOMAIN if learned_language_code is not None: try: learned_language = Language.find_or_create( learned_language_code) except NoResultFound as e: learned_language = None else: learned_language = None if native_language_code is not None: try: native_language = Language.find_or_create(native_language_code) except NoResultFound as e: native_language = None else: native_language = None new_user = cls(fake_email, uuid, password, learned_language=learned_language, native_language=native_language) return new_user
def get_interesting_reading_languages(): """ 'Interesting languages' are defined as languages the user isn't subscribed to already and thus might subscribe to. :return: a json list with languages the user isn't reading yet. every language in this list is a dictionary with the following info: id = unique id of the language; language = <unicode string> """ all_languages = Language.available_languages() all_languages.sort(key=lambda x: x.name) learned_languages = Language.all_reading_for_user(flask.g.user) interesting_languages = [] for lan in all_languages: if lan not in learned_languages: interesting_languages.append(lan.as_dictionary()) return json_result(interesting_languages)
def __init__(self, email, name, password, learned_language=None, native_language=None, invitation_code=None, cohort=None): self.email = email self.name = name self.update_password(password) self.learned_language = learned_language or Language.default_learned() self.native_language = native_language or Language.default_native_language( ) self.invitation_code = invitation_code self.cohort = cohort # Add the learned language to user languages and set reading_news to True # so that the user has articles in the reader when opening it for the first time. from zeeguu_core.model import UserLanguage UserLanguage(self, learned_language or Language.default_learned(), reading_news=True)
def get_reading_languages(): """ A user might be subscribed to multiple languages at once. This endpoint returns them as a list. :return: a json list with languages for which the user is registered; every language in this list is a dictionary with the following info: id = unique id of the language; language = <unicode string> """ all_user_languages = [] reading_languages = Language.all_reading_for_user(flask.g.user) for lan in reading_languages: all_user_languages.append(lan.as_dictionary()) return json_result(all_user_languages)
def get_or_create_language(cls, language_id): try: return Language.find(language_id) except (NoResultFound, OperationalError, ObjectDeletedError): return cls.__create_new_language(language_id)
def find_or_create(cls, session, _url: str, language=None, sleep_a_bit=False): """ If not found, download and extract all the required info for this article. :param url: :return: """ from zeeguu_core.model import Url, Article, Language import newspaper url = Url.extract_canonical_url(_url) try: found = cls.find(url) if found: return found art = newspaper.Article(url=url) art.download() art.parse() if art.text == '': raise Exception("Newspaper got empty article from: " + url) if sleep_a_bit: import time from random import randint print("GOT: " + url) sleep_time = randint(3, 33) print( f"sleeping for {sleep_time}s... so we don't annoy our friendly servers" ) time.sleep(sleep_time) if not language: if art.meta_lang == '': art.meta_lang = detect(art.text) zeeguu_core.log(f"langdetect: {art.meta_lang} for {url}") language = Language.find_or_create(art.meta_lang) # Create new article and save it to DB url_object = Url.find_or_create(session, url) new_article = Article( url_object, art.title, ', '.join(art.authors), art.text[ 0: 32000], # any article longer than this will be truncated... art.summary, None, None, language) session.add(new_article) session.commit() return new_article except sqlalchemy.exc.IntegrityError or sqlalchemy.exc.DatabaseError: for i in range(10): try: session.rollback() u = cls.find(url) print("Found article by url after recovering from race") return u except: print("Exception of second degree in article..." + str(i)) time.sleep(0.3) continue break
def find_for_language_id(cls, language_code): language = Language.find(language_code) return cls.query.filter(cls.language == language).all()
this has been added, one can run the 'tag_existing_articles' script to tag them. """ import zeeguu_core from zeeguu_core.model.topic import Topic from zeeguu_core.model.language import Language from zeeguu_core.model.localized_topic import LocalizedTopic session = zeeguu_core.db.session count = 0 TOPICS = ["Sport", "Health", "Technology", "Politics", "Science", "Culture", "Travel", "Food"] LANGUAGES = [Language.find("es"), Language.find("fr"), Language.find("nl"), Language.find("de") , Language.find("en"), Language.find("it")] SPANISH_TOPICS = [["Sport", "juego sport deporte"], ["Salud", "salud hospital"] , ["Technologia", "tech technologia"], ["Politica", "politica diplomatico"], ["Ciencia", "ciencia"] , ["Cultura", "cultura"], ["Viaje", "viaje viajes"], ["Comida", "comida alimento"]] FRENCH_TOPICS = [["Sport", "sport divertissement jouer"], ["Sante", "sante hopital"] , ["Technologie", "tech technologie"], ["Politique", "politique politologie"], ["Science", "science savoir"] , ["Culture", "culture"], ["Voyage", "voyager voyage"], ["Aliments", "nourriture aliments"]] DUTCH_TOPICS = [["Sport", "sport spel"], ["Gezondheid", "gezondheid ziekenhuis gezond"] , ["Technologie", "tech technologie"], ["Politiek", "politiek politisch"], ["Wetenschap", "wetenschap"] , ["Cultuur", "cultuur cultureel"], ["Reizen", "reizen reis"], ["Eten", "eten voedsel eet"]] GERMAN_TOPICS = [["Sport", "sport sportart spielart abart"], ["Gesundheit", "gesundheit gesundheitszustand"] , ["Technologie", "technologie technik"], ["Politik", "politik politologie"], ["Wissenschaft", "wissenschaft"] , ["Kultur", "kultur bildung"], ["Reise", "reise reisen"], ["Essen", "lebensmittel essen"]] ENGLISH_TOPICS = [["Sport", "sport playing"], ["Health", "health hospital healthy"] , ["Technology", "tech technology"], ["Politics", "politics politic"], ["Science", "science scientist"]
def set_native_language(self, code): self.native_language = Language.find(code)
def set_learned_language(self, code): self.learned_language = Language.find(code)