Exemple #1
0
 def mock_database_init(self, dbname: str) -> None:
     if dbname == "veekun":
         dbpath = utils.get_config_file(f"{dbname}.sqlite")
         engine = f"sqlite:///{dbpath}"
     else:
         engine = "sqlite://"  # :memory: database
     self.engine = create_engine(engine, future=True)
     self.session_factory = sessionmaker(self.engine, future=True)
     self.Session = scoped_session(self.session_factory)
     database_instances[dbname] = self
Exemple #2
0
async def icon(msg: Message) -> None:
    if len(msg.args) < 1:
        await msg.reply(
            "You can set your Pokémon using "
            f"``{msg.conn.command_character}icon <pokemon>``, "
            "or install the userstyle (https://git.io/JuoFg) "
            "using Stylus (https://add0n.com/stylus.html)."
        )
        return

    search_query = utils.to_id(msg.args[0])
    dex_entry = utils.get_ps_dex_entry(search_query)
    if dex_entry is None or dex_entry["num"] <= 0:
        await msg.reply("Pokémon not found.")
        return

    db = Database.open()
    with db.get_session() as session:
        userid = msg.user.userid
        session.add(d.Users(userid=userid))
        stmt = (
            update(d.Users)
            .filter_by(userid=userid)
            .values(icon=utils.to_id(dex_entry["dex_name"]))
        )
        session.execute(stmt)

        # Update the CSV file
        stmt_csv = (
            select(d.Users.userid, d.Users.icon)
            .where(d.Users.icon.is_not(None))
            .order_by(d.Users.userid)
        )
        with utils.get_config_file("userlist_icons.csv").open(
            "w", encoding="utf-8"
        ) as f:
            f.writelines(
                [f"{userid},{icon}\n" for userid, icon in session.execute(stmt_csv)]
            )

    await msg.reply(
        "Done. Your Pokémon might take up to 24 hours to appear on the userstyle."
    )
Exemple #3
0
async def csv_to_sqlite(conn: Connection) -> None:
    latest_veekun_commit = ""
    try:
        latest_veekun_commit = (subprocess.run(
            [
                "git",
                "rev-list",
                "-1",
                "HEAD",
                "--",
                "data/veekun",
                "databases/veekun.py",
                "tasks/veekun.py",
            ],
            cwd=join(dirname(__file__), ".."),
            capture_output=True,
            check=True,
        ).stdout.decode().strip())
        db = Database.open("veekun")
        with db.get_session() as session:
            stmt = select(v.LatestCommit.commit_id)
            if session.scalar(stmt) == latest_veekun_commit:
                return  # database is already up-to-date, skip rebuild

    except (
            subprocess.SubprocessError,  # generic subprocess error
            FileNotFoundError,  # git is not available
            OperationalError,  # table does not exist
    ):
        pass  # always rebuild on error

    print("Rebuilding veekun database...")

    with open(utils.get_config_file("veekun.sqlite"),
              "wb"):  # truncate database
        pass

    db = Database.open("veekun")

    v.Base.metadata.create_all(db.engine)

    tables_classes = {
        obj.__tablename__: obj
        for name, obj in inspect.getmembers(v) if inspect.isclass(obj)
        and obj.__module__ == v.__name__ and hasattr(obj, "__tablename__")
    }

    with db.get_session() as session:
        if latest_veekun_commit:
            session.add(v.LatestCommit(commit_id=latest_veekun_commit))

        for table in v.Base.metadata.sorted_tables:
            tname = table.key
            file_name = utils.get_data_file("veekun", f"{tname}.csv")
            if isfile(file_name):
                with open(file_name, encoding="utf-8") as f:
                    csv_data = csv.DictReader(f)
                    csv_keys = csv_data.fieldnames

                    if csv_keys is not None:
                        data = [dict(i) for i in csv_data]

                        if hasattr(table.columns, "name_normalized"):
                            for row in data:
                                row["name_normalized"] = utils.to_user_id(
                                    utils.remove_diacritics(row["name"]))

                        if tname == "locations":
                            for row in data:
                                if num := re.search(r"route-(\d+)",
                                                    row["identifier"]):
                                    row["route_number"] = num[1]

                        bulk_insert_stmt = insert(tables_classes[tname])
                        session.execute(bulk_insert_stmt, data)

                        if "identifier" in csv_keys:
                            bulk_update_stmt = (update(
                                tables_classes[tname]).values(
                                    identifier=func.replace(
                                        tables_classes[tname].identifier, "-",
                                        "")).execution_options(
                                            synchronize_session=False))
                            session.execute(bulk_update_stmt)