def test_mark_failed(monkeypatch): runner = CliRunner() with runner.isolated_filesystem(): db_path = Path.cwd() / "db.sqlite3" copyfile(Path(__file__).parent / "test.db", db_path) monkeypatch.setattr("pixi.database.DATABASE_PATH", db_path) illustration = mock.Mock( id=99, user=mock.Mock(account="azuline"), title="cat whiskers", ) mark_failed(illustration) with database() as (conn, cursor): cursor.execute( """ SELECT id FROM failed WHERE id = ? AND artist = ? AND title = ? """, ( 99, "azuline", "cat whiskers", ), ) assert cursor.fetchone()["id"] == 99
def test_failed(monkeypatch): runner = CliRunner() with runner.isolated_filesystem(): db_path = Path.cwd() / "db.sqlite3" copyfile(Path(__file__).parent / "test.db", db_path) monkeypatch.setattr("pixi.database.DATABASE_PATH", db_path) with database() as (conn, cursor): cursor.execute( """ INSERT INTO FAILED (id, artist, title, time) VALUES (?, ?, ?, ?) """, ( 20, "testing", "illustration", "2019-01-01T01:23:45-04:00", ), ) result = runner.invoke(failed) assert result.output == ( "Jan 01, 2019 01:23:45 | testing - illustration\n" "URL: https://www.pixiv.net/member_illust.php?mode=medium" "&illust_id=20\n\n")
def test_get_version_empty_table(monkeypatch): with CliRunner().isolated_filesystem(): monkeypatch.setattr("pixi.database.DATABASE_PATH", Path.cwd() / "db.sqlite3") with database() as (conn, cursor): cursor.execute("CREATE TABLE versions (version INTEGER PRIMARY KEY)") conn.commit() assert 0 == _get_version()
def test_database_contextmanager(monkeypatch): with CliRunner().isolated_filesystem(): monkeypatch.setattr("pixi.database.DATABASE_PATH", Path.cwd() / "db.sqlite3") with database() as (conn, cursor): cursor.execute("CREATE TABLE ham(id INTEGER PRIMARY KEY)") cursor.execute("INSERT INTO ham (id) VALUES (1)") conn.commit() cursor.execute("SELECT id FROM ham") assert cursor.fetchone()[0] == 1
def clear_failed(illustration_id): with database() as (conn, cursor): cursor.execute( """ DELETE FROM failed WHERE id = ? """, (illustration_id, ), ) conn.commit()
def wipe(table): """Wipe the saved history of downloaded illustrations.""" tables = ["downloaded", "failed"] if table == "all" else [table] with database() as (conn, cursor): for t in tables: _confirm_table_wipe(t) cursor.execute(f"DELETE FROM {t}") click.echo(f"Wiped the {t} table.") conn.commit()
def test_wipe_single(_, monkeypatch): runner = CliRunner() with runner.isolated_filesystem(): db_path = Path.cwd() / "db.sqlite3" copyfile(Path(__file__).parent / "test.db", db_path) monkeypatch.setattr("pixi.database.DATABASE_PATH", db_path) with database() as (conn, cursor): cursor.execute('INSERT INTO downloaded (id, path) VALUES (1, "a")') cursor.execute( 'INSERT INTO FAILED (id, artist, title) VALUES (1, "a", "b")') conn.commit() runner.invoke(wipe, "--table=failed") with database() as (conn, cursor): cursor.execute("SELECT 1 FROM downloaded") assert cursor.fetchone() cursor.execute("SELECT 1 FROM failed") assert not cursor.fetchone()
def check_duplicate(illustration_id): with database() as (conn, cursor): cursor.execute( """ SELECT path FROM downloaded WHERE id = ? """, (illustration_id, ), ) row = cursor.fetchone() if row: raise DuplicateImage(row["path"])
def record_download(illustration_id, path): with database() as (conn, cursor): cursor.execute( """ INSERT OR IGNORE INTO downloaded (id, path) VALUES (?, ?) """, ( illustration_id, path, ), ) conn.commit()
def mark_failed(illustration): with database() as (conn, cursor): cursor.execute( """ INSERT OR IGNORE INTO failed (id, artist, title) VALUES (?, ?, ?) """, ( illustration.id, illustration.user.account, illustration.title, ), ) conn.commit()
def test_wipe_failed(confirm, monkeypatch): runner = CliRunner() with runner.isolated_filesystem(): db_path = Path.cwd() / "db.sqlite3" copyfile(Path(__file__).parent / "test.db", db_path) monkeypatch.setattr("pixi.database.DATABASE_PATH", db_path) confirm.side_effect = click.Abort with database() as (conn, cursor): cursor.execute('INSERT INTO downloaded (id, path) VALUES (1, "a")') cursor.execute( 'INSERT INTO FAILED (id, artist, title) VALUES (1, "a", "b")') conn.commit() result = runner.invoke(wipe, "--table=all") assert isinstance(result.exception, SystemExit) with database() as (conn, cursor): cursor.execute("SELECT 1 FROM downloaded") assert cursor.fetchone() cursor.execute("SELECT 1 FROM failed") assert cursor.fetchone()
def test_migrate(calculate, monkeypatch): runner = CliRunner() with runner.isolated_filesystem(): fake_mig = Path.cwd() / "0001.sql" with fake_mig.open("w") as f: f.write("INSERT INTO test (id) VALUES (29)") monkeypatch.setattr("pixi.database.DATABASE_PATH", Path.cwd() / "db.sqlite3") with database() as (conn, cursor): cursor.execute("CREATE TABLE test (id INTEGER PRIMARY KEY)") cursor.execute( "CREATE TABLE versions (version INTEGER PRIMARY KEY)") conn.commit() calculate.return_value = [Migration(path=fake_mig, version=9)] runner.invoke(migrate) with database() as (conn, cursor): cursor.execute("SELECT version FROM versions") assert 9 == cursor.fetchone()[0] cursor.execute("SELECT id FROM test") assert 29 == cursor.fetchone()[0]
def test_clear_failed(monkeypatch): runner = CliRunner() with runner.isolated_filesystem(): db_path = Path.cwd() / "db.sqlite3" copyfile(Path(__file__).parent / "test.db", db_path) monkeypatch.setattr("pixi.database.DATABASE_PATH", db_path) with database() as (conn, cursor): cursor.execute( """ INSERT INTO failed (id, artist, title) VALUES (?, ?, ?) """, ( 99, "azuline", "cat whiskers", ), ) clear_failed(99) with database() as (conn, cursor): cursor.execute("SELECT 1 FROM failed WHERE id = ?", (99, )) assert not cursor.fetchone()
def migrate(): """Upgrade the database to the latest migration.""" migrations_needed = calculate_migrations_needed() if not migrations_needed: click.echo("Database is up to date.") sys.exit(1) with database() as (conn, cursor): for mig in migrations_needed: with mig.path.open() as sql: cursor.executescript(sql.read()) cursor.execute( "INSERT INTO versions (version) VALUES (?)", (mig.version, ), ) conn.commit()
def test_check_duplicate_negative(monkeypatch): runner = CliRunner() with runner.isolated_filesystem(): db_path = Path.cwd() / "db.sqlite3" copyfile(Path(__file__).parent / "test.db", db_path) monkeypatch.setattr("pixi.database.DATABASE_PATH", db_path) with database() as (conn, cursor): cursor.execute( """ INSERT INTO downloaded (id, path) VALUES (?, ?) """, ( 99, "/haha/a/path", ), ) check_duplicate(98)
def failed(): """View illustrations that failed to download.""" with database() as (conn, cursor): cursor.execute(""" SELECT id, artist, title, time FROM failed ORDER BY time DESC """) for row in cursor.fetchall(): time = datetime.fromisoformat( row["time"]).strftime("%b %d, %Y %H:%M:%S") click.echo(f'{time} | {row["artist"]} - {row["title"]}') click.echo( "URL: https://www.pixiv.net/member_illust.php?mode=medium" f'&illust_id={row["id"]}\n')
def test_record_download(monkeypatch): runner = CliRunner() with runner.isolated_filesystem(): db_path = Path.cwd() / "db.sqlite3" copyfile(Path(__file__).parent / "test.db", db_path) monkeypatch.setattr("pixi.database.DATABASE_PATH", db_path) record_download(99, "/haha/a/path") with database() as (conn, cursor): cursor.execute( """ SELECT id FROM downloaded WHERE id = ? AND path = ? """, ( 99, "/haha/a/path", ), ) assert cursor.fetchone()["id"] == 99
def test_create_nonexistent_database(monkeypatch): with CliRunner().isolated_filesystem(): monkeypatch.setattr("pixi.database.DATABASE_PATH", Path.cwd() / "db.sqlite3") create_database_if_nonexistent() with database() as (conn, cursor): cursor.execute("SELECT version FROM versions")