Finish downloader

This commit is contained in:
Alex Ling 2020-02-28 17:36:21 +00:00
parent 6bccba16da
commit f11a5cd608

View File

@ -12,10 +12,11 @@ module MangaDex
end end
end end
enum JobStatus enum JobStatus
Pending # 0 Pending # 0
Downloading # 1 Downloading # 1
Error # 2 Error # 2
Completed # 3 Completed # 3
MissingPages # 4
end end
struct Job struct Job
property id : String property id : String
@ -25,12 +26,17 @@ module MangaDex
property status : JobStatus property status : JobStatus
property log : String property log : String
property time : Time property time : Time
private def load_query_result(res : DB::ResultSet) def load_query_result(res : DB::ResultSet)
begin begin
@id, @manga_id, @title, @manga_title, status, @log, time = \ @id = res.read String
res.as {String, String, String, String, Int32, String, Int64} @manga_id = res.read String
@title = res.read String
@manga_title = res.read String
status = res.read Int32
@log = res.read String
time = res.read Int64
@status = JobStatus.new status @status = JobStatus.new status
@time = Time.unix time @time = Time.unix_ms time
return true return true
rescue e rescue e
puts e puts e
@ -45,6 +51,18 @@ module MangaDex
def initialize(@id, @manga_id, @title, @manga_title, @status, @log, def initialize(@id, @manga_id, @title, @manga_title, @status, @log,
@time) @time)
end end
def to_json(json)
json.object do
{% for name in ["id", "manga_id", "title", "manga_title",
"log"] %}
json.field {{name}}, @{{name.id}}
{% end %}
json.field "status", @status.to_s
json.field "time" do
json.number @time.to_unix_ms
end
end
end
end end
class Queue class Queue
def initialize(@path : String) def initialize(@path : String)
@ -56,49 +74,57 @@ module MangaDex
end end
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
begin begin
db.exec "create table queue" \ db.exec "create table if not exists queue" \
"(id string, manga_id string, title text," \ "(id text, manga_id text, title text, manga_title "\
"manga_title text, status integer, log text, time integer)" "text, status integer, log text, time integer)"
db.exec "create unique index id_idx on queue (id)" db.exec "create unique index if not exists id_idx on queue (id)"
db.exec "create index manga_id_idx on queue (manga_id)" db.exec "create index if not exists manga_id_idx on queue (manga_id)"
db.exec "create index status_idx on queue (status)" db.exec "create index if not exists status_idx on queue (status)"
rescue e rescue e
unless e.message == "table queue already exists" puts "Error when checking tables in DB: #{e}"
puts "Error when checking tables in DB: #{e}" raise e
raise e
end
end end
end end
end end
# Returns the earliest job in queue or nil if the job cannot be parsed. # Returns the earliest job in queue or nil if the job cannot be parsed.
# Raises DB::Error if queue is empty # Returns nil if queue is empty
def pop def pop
job = nil
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
res = db.query_one "select * from queue where status = 0 "\ begin
"order by time limit 1" db.query_one "select * from queue where status = 0 "\
job = Job.from_query_result res "or status = 1 order by time limit 1" do |res|
db.exec "delete from queue where id = (select id from queue "\ job = Job.from_query_result res
"where status = 0 order by time limit 1)" end
return job rescue
end
end end
return job
end end
# Push an array of jobs into the queue, and return the number of jobs # Push an array of jobs into the queue, and return the number of jobs
# inserted. Any job already exists in the queue will be ignored. # inserted. Any job already exists in the queue will be ignored.
def push(jobs : Array(Job)) def push(jobs : Array(Job))
start_count = self.count start_count = self.count
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
jobs.each {|job| jobs.each do |job|
db.exec "insert or ignore into queue values "\ db.exec "insert or ignore into queue values "\
"(?, ?, ?, ?, ?, ?, ?)", "(?, ?, ?, ?, ?, ?, ?)",
job.id, job.manga_id, job.title, job.manga_title, job.id, job.manga_id, job.title, job.manga_title,
job.status.to_i, job.log, job.time.to_unix job.status.to_i, job.log, job.time.to_unix_ms
} end
end end
self.count - start_count self.count - start_count
end end
def delete(id) def delete(job : Job)
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
db.exec "delete from queue where id = (?)", id db.exec "delete from queue where id = (?)", job.id
end
end
def get(job : Job)
DB.open "sqlite3://#{@path}" do |db|
db.query_one "select * from queue where id = (?)", id do |res|
job.load_query_result res
end
end end
end end
def delete_status(status : JobStatus) def delete_status(status : JobStatus)
@ -108,8 +134,8 @@ module MangaDex
end end
def count_status(status : JobStatus) def count_status(status : JobStatus)
DB.open "sqlite3://#{@path}" do |db| DB.open "sqlite3://#{@path}" do |db|
return db.query_one "select count(*) from queue where status = (?)", return db.query_one "select count(*) from queue where "\
status.to_i, as: Int32 "status = (?)", status.to_i, as: Int32
end end
end end
def count def count