|
|
|
@ -5,8 +5,6 @@ const curl = @cImport({
|
|
|
|
|
@cInclude("curl/curl.h");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const zfetch = @import("zfetch");
|
|
|
|
|
const tls = @import("iguanaTLS");
|
|
|
|
|
const uri = @import("uri");
|
|
|
|
|
const json = @import("json");
|
|
|
|
|
|
|
|
|
@ -106,8 +104,6 @@ pub fn main() anyerror!void {
|
|
|
|
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
|
|
|
const alloc = &gpa.allocator;
|
|
|
|
|
|
|
|
|
|
//const key = try std.process.getEnvVarOwned(alloc, "derpikey");
|
|
|
|
|
|
|
|
|
|
var diag = clap.Diagnostic{};
|
|
|
|
|
var args = clap.parse(
|
|
|
|
|
clap.Help,
|
|
|
|
@ -135,7 +131,7 @@ pub fn main() anyerror!void {
|
|
|
|
|
},
|
|
|
|
|
.threading_mode = .SingleThread,
|
|
|
|
|
});
|
|
|
|
|
db.exec(create, .{}, .{}) catch sqliteErrorReport("Couldn't create table", &db);
|
|
|
|
|
db.exec(create, .{}, .{ 0, 0, 0 }) catch sqliteErrorReport("Couldn't create table", &db);
|
|
|
|
|
|
|
|
|
|
if (args.flag("--migrate")) {
|
|
|
|
|
if (args.flag("--yolo")) try db.exec("PRAGMA synchronous=0;", .{}, .{});
|
|
|
|
@ -436,9 +432,9 @@ fn registerID(db: *sqlite.Db, id: u64) !void {
|
|
|
|
|
log.info("Registering ID {d}.", .{id});
|
|
|
|
|
const foo = db.one(
|
|
|
|
|
bool,
|
|
|
|
|
"SELECT true FROM image WHERE eid = ?;",
|
|
|
|
|
"SELECT true FROM image WHERE id = ?;",
|
|
|
|
|
.{},
|
|
|
|
|
.{ .eid = id },
|
|
|
|
|
.{ .id = id },
|
|
|
|
|
) catch {
|
|
|
|
|
sqliteErrorReport("SQLite error while checking if ID already present", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
@ -451,7 +447,7 @@ fn registerID(db: *sqlite.Db, id: u64) !void {
|
|
|
|
|
errdefer db.exec("ROLLBACK;", .{}, .{}) catch {};
|
|
|
|
|
db.exec(
|
|
|
|
|
\\INSERT OR ROLLBACK
|
|
|
|
|
\\ INTO image (eid)
|
|
|
|
|
\\ INTO image (id)
|
|
|
|
|
\\ VALUES (?);
|
|
|
|
|
, .{}, .{ .id = id }) catch {
|
|
|
|
|
sqliteErrorReport("Couldn't insert ID into database.", db);
|
|
|
|
@ -472,9 +468,9 @@ fn storeMetadata(
|
|
|
|
|
log.info("Storing metadata for ID {d}.", .{id});
|
|
|
|
|
const foobar = db.one(
|
|
|
|
|
bool,
|
|
|
|
|
"SELECT true FROM image WHERE eid = ? AND metadata IS NOT NULL;",
|
|
|
|
|
"SELECT true FROM image WHERE id = ? AND metadata IS NOT NULL;",
|
|
|
|
|
.{},
|
|
|
|
|
.{ .eid = id },
|
|
|
|
|
.{ .id = id },
|
|
|
|
|
) catch {
|
|
|
|
|
sqliteErrorReport("SQLite error while checking for metadata precence.", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
@ -491,12 +487,12 @@ fn storeMetadata(
|
|
|
|
|
db.exec(
|
|
|
|
|
\\INSERT OR ROLLBACK
|
|
|
|
|
\\ INTO
|
|
|
|
|
\\ image (eid, metadata)
|
|
|
|
|
\\ image (id, metadata)
|
|
|
|
|
\\ VALUES (?, ?)
|
|
|
|
|
\\ ON CONFLICT (eid)
|
|
|
|
|
\\ ON CONFLICT (id)
|
|
|
|
|
\\ DO UPDATE
|
|
|
|
|
\\ SET metadata=excluded.metadata;
|
|
|
|
|
, .{}, .{ .eid = id, .metadata = metadata }) catch {
|
|
|
|
|
, .{}, .{ .id = id, .metadata = metadata }) catch {
|
|
|
|
|
sqliteErrorReport("Couldn't add metadata for ID {d} to database.", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
@ -505,7 +501,7 @@ fn storeMetadata(
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
db.exec(
|
|
|
|
|
"UPDATE OR ROLLBACK image SET hash_meta = ? WHERE eid = ?",
|
|
|
|
|
"UPDATE OR ROLLBACK image SET hash_meta = ? WHERE id = ?",
|
|
|
|
|
.{},
|
|
|
|
|
.{ hash_buf2[0..], id },
|
|
|
|
|
) catch {
|
|
|
|
@ -528,9 +524,9 @@ fn getMetadata(
|
|
|
|
|
log.info("Downloading metadata for ID {d}.", .{id});
|
|
|
|
|
const foobar = db.one(
|
|
|
|
|
bool,
|
|
|
|
|
"SELECT true FROM image WHERE eid = ? AND metadata IS NOT NULL;",
|
|
|
|
|
"SELECT true FROM image WHERE id = ? AND metadata IS NOT NULL;",
|
|
|
|
|
.{},
|
|
|
|
|
.{ .eid = id },
|
|
|
|
|
.{ .id = id },
|
|
|
|
|
) catch {
|
|
|
|
|
sqliteErrorReport("SQLite error while checking for metadata precence.", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
@ -556,12 +552,12 @@ fn getMetadata(
|
|
|
|
|
db.exec(
|
|
|
|
|
\\INSERT OR ROLLBACK
|
|
|
|
|
\\ INTO
|
|
|
|
|
\\ image (eid, metadata)
|
|
|
|
|
\\ image (id, metadata)
|
|
|
|
|
\\ VALUES (?, ?)
|
|
|
|
|
\\ ON CONFLICT (eid)
|
|
|
|
|
\\ ON CONFLICT (id)
|
|
|
|
|
\\ DO UPDATE
|
|
|
|
|
\\ SET metadata=excluded.metadata;
|
|
|
|
|
, .{}, .{ .eid = id, .metadata = resp.items }) catch {
|
|
|
|
|
, .{}, .{ .id = id, .metadata = resp.items }) catch {
|
|
|
|
|
sqliteErrorReport("Couldn't add metadata for ID {d} to database.", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
@ -570,7 +566,7 @@ fn getMetadata(
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
db.exec(
|
|
|
|
|
"UPDATE OR ROLLBACK image SET hash_meta = ? WHERE eid = ?",
|
|
|
|
|
"UPDATE OR ROLLBACK image SET hash_meta = ? WHERE id = ?",
|
|
|
|
|
.{},
|
|
|
|
|
.{ hash_buf2[0..], id },
|
|
|
|
|
) catch {
|
|
|
|
@ -601,9 +597,9 @@ fn getImage(
|
|
|
|
|
thumb_url: ?[:0]u8,
|
|
|
|
|
},
|
|
|
|
|
alloc,
|
|
|
|
|
"SELECT full_url, thumb_url FROM image WHERE eid = ?",
|
|
|
|
|
"SELECT full_url, thumb_url FROM image WHERE id = ?",
|
|
|
|
|
.{},
|
|
|
|
|
.{ .eid = id },
|
|
|
|
|
.{ .id = id },
|
|
|
|
|
) catch {
|
|
|
|
|
sqliteErrorReport("SQLite error while getting image URLs", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
@ -613,7 +609,7 @@ fn getImage(
|
|
|
|
|
defer alloc.free(url);
|
|
|
|
|
const skipper = db.one(bool,
|
|
|
|
|
\\SELECT true FROM image
|
|
|
|
|
\\ WHERE eid = ? AND image_id IS NOT NULL;
|
|
|
|
|
\\ WHERE id = ? AND image IS NOT NULL;
|
|
|
|
|
, .{}, .{id}) catch {
|
|
|
|
|
sqliteErrorReport("SQLite error while checking if image is already downloaded", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
@ -622,75 +618,83 @@ fn getImage(
|
|
|
|
|
log.info("Image for ID {d} already downloaded.", .{id});
|
|
|
|
|
break :blk;
|
|
|
|
|
}
|
|
|
|
|
defer {
|
|
|
|
|
resp.clearRetainingCapacity();
|
|
|
|
|
std.mem.set(u8, hash_buf[0..], 0);
|
|
|
|
|
std.mem.set(u8, hash_buf2[0..], 0);
|
|
|
|
|
}
|
|
|
|
|
easyFetch(handle, url, resp) catch {
|
|
|
|
|
log.info("Failed to download fullsize image for ID {d}", .{id});
|
|
|
|
|
return error.FATAL;
|
|
|
|
|
};
|
|
|
|
|
try db.exec("BEGIN IMMEDIATE;", .{}, .{});
|
|
|
|
|
errdefer db.exec("ROLLBACK;", .{}, .{}) catch {};
|
|
|
|
|
db.exec(
|
|
|
|
|
"UPDATE OR ROLLBACK image SET image = ? WHERE id = ?",
|
|
|
|
|
.{},
|
|
|
|
|
.{
|
|
|
|
|
.image = resp.items,
|
|
|
|
|
.id = id,
|
|
|
|
|
},
|
|
|
|
|
) catch {
|
|
|
|
|
sqliteErrorReport("Couldn't add image to DB.", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
hashit(resp.items) catch |err| {
|
|
|
|
|
log.err("Couldn't hash image for ID {d}: {s}", .{ id, err });
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
try db.exec("BEGIN IMMEDIATE;", .{}, .{});
|
|
|
|
|
errdefer db.exec("ROLLBACK;", .{}, .{}) catch {};
|
|
|
|
|
try db.exec(
|
|
|
|
|
\\INSERT INTO blob (data, hash)
|
|
|
|
|
\\ VALUES (?, ?);
|
|
|
|
|
, .{}, .{ resp.items, hash_buf2[0..] });
|
|
|
|
|
db.exec(
|
|
|
|
|
\\UPDATE OR ROLLBACK image
|
|
|
|
|
\\ SET image_id = last_insert_rowid() WHERE eid = ?
|
|
|
|
|
,
|
|
|
|
|
"UPDATE OR ROLLBACK image SET hash_full = ? WHERE id = ?",
|
|
|
|
|
.{},
|
|
|
|
|
.{id},
|
|
|
|
|
.{ hash_buf2[0..], id },
|
|
|
|
|
) catch {
|
|
|
|
|
sqliteErrorReport("Couldn't add image to DB.", db);
|
|
|
|
|
sqliteErrorReport("Couldn't set iamge hash", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
db.exec("COMMIT", .{}, .{}) catch {
|
|
|
|
|
sqliteErrorReport("FATAL: couldn't commit database", db);
|
|
|
|
|
return error.FATAL;
|
|
|
|
|
};
|
|
|
|
|
resp.clearRetainingCapacity();
|
|
|
|
|
std.mem.set(u8, hash_buf[0..], 0);
|
|
|
|
|
std.mem.set(u8, hash_buf2[0..], 0);
|
|
|
|
|
}
|
|
|
|
|
if (res.thumb_url) |url| blk: {
|
|
|
|
|
defer alloc.free(url);
|
|
|
|
|
const skipper = db.one(bool,
|
|
|
|
|
\\SELECT true FROM image
|
|
|
|
|
\\ WHERE eid = ? AND thumb_id IS NOT NULL;
|
|
|
|
|
\\ WHERE id = ? AND thumb IS NOT NULL;
|
|
|
|
|
, .{}, .{id}) catch {
|
|
|
|
|
sqliteErrorReport("SQLite error while checking if image is already downloaded", db);
|
|
|
|
|
sqliteErrorReport("SQLite error while checking if thumb is already downloaded", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
if (skipper) |_| {
|
|
|
|
|
log.info("Image for ID {d} already downloaded.", .{id});
|
|
|
|
|
log.info("Thumb for ID {d} already downloaded.", .{id});
|
|
|
|
|
break :blk;
|
|
|
|
|
}
|
|
|
|
|
easyFetch(handle, url, resp) catch {
|
|
|
|
|
log.info("Failed to download fullsize image for ID {d}", .{id});
|
|
|
|
|
return error.FATAL;
|
|
|
|
|
};
|
|
|
|
|
hashit(resp.items) catch |err| {
|
|
|
|
|
log.err("Couldn't hash image for ID {d}: {s}", .{ id, err });
|
|
|
|
|
log.info("Failed to download thumbnail image for ID {d}", .{id});
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
try db.exec("BEGIN IMMEDIATE;", .{}, .{});
|
|
|
|
|
errdefer db.exec("ROLLBACK;", .{}, .{}) catch {};
|
|
|
|
|
try db.exec(
|
|
|
|
|
\\INSERT INTO blob (data, hash)
|
|
|
|
|
\\ VALUES (?, ?);
|
|
|
|
|
, .{}, .{ resp.items, hash_buf2[0..] });
|
|
|
|
|
db.exec(
|
|
|
|
|
\\UPDATE OR ROLLBACK image
|
|
|
|
|
\\ SET thumb_id = last_insert_rowid() WHERE eid = ?
|
|
|
|
|
,
|
|
|
|
|
"UPDATE OR ROLLBACK image SET thumb = ? WHERE id = ?",
|
|
|
|
|
.{},
|
|
|
|
|
.{id},
|
|
|
|
|
.{
|
|
|
|
|
.thumb = resp.items,
|
|
|
|
|
.id = id,
|
|
|
|
|
},
|
|
|
|
|
) catch {
|
|
|
|
|
sqliteErrorReport("Couldn't add image to DB.", db);
|
|
|
|
|
sqliteErrorReport("Couldn't add thumb to DB", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
hashit(resp.items) catch |err| {
|
|
|
|
|
log.err("Couldn't hash thumb for ID {d}: {s}", .{ id, err });
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
db.exec(
|
|
|
|
|
"UPDATE OR ROLLBACK image SET hash_thumb = ? WHERE id = ?",
|
|
|
|
|
.{},
|
|
|
|
|
.{ hash_buf2[0..], id },
|
|
|
|
|
) catch {
|
|
|
|
|
sqliteErrorReport("Couldn't add thumb hash", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|
};
|
|
|
|
|
db.exec("COMMIT", .{}, .{}) catch {
|
|
|
|
@ -708,13 +712,13 @@ fn extractImage(db: *sqlite.Db, id: u64, alloc: *std.mem.Allocator) !void {
|
|
|
|
|
log.info("Extracting image for ID {d}.", .{id});
|
|
|
|
|
const foo = db.oneAlloc(
|
|
|
|
|
struct {
|
|
|
|
|
image: ?[]u8,
|
|
|
|
|
extension: ?[]u8,
|
|
|
|
|
image: ?[:0]u8,
|
|
|
|
|
extension: ?[:0]u8,
|
|
|
|
|
},
|
|
|
|
|
alloc,
|
|
|
|
|
"SELECT blob.data, image.extension FROM blob, image WHERE eid = ? AND image.image_id = blob.id;",
|
|
|
|
|
"SELECT image, extension FROM image WHERE id = ?",
|
|
|
|
|
.{},
|
|
|
|
|
.{id},
|
|
|
|
|
.{ .id = id },
|
|
|
|
|
) catch {
|
|
|
|
|
sqliteErrorReport("SQLite error while reading image", db);
|
|
|
|
|
return error.GO_ON;
|
|
|
|
|