diff --git a/.all-contributorsrc b/.all-contributorsrc
index ca614a0..8f287e9 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -113,6 +113,24 @@
"contributions": [
"infra"
]
+ },
+ {
+ "login": "BradleyDS2",
+ "name": "BradleyDS2",
+ "avatar_url": "https://avatars.githubusercontent.com/u/2174921?v=4",
+ "profile": "https://github.com/BradleyDS2",
+ "contributions": [
+ "doc"
+ ]
+ },
+ {
+ "login": "nduja",
+ "name": "Robbo",
+ "avatar_url": "https://avatars.githubusercontent.com/u/69299134?v=4",
+ "profile": "https://github.com/nduja",
+ "contributions": [
+ "code"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/README.md b/README.md
index 1a010dd..53cea05 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ Mango is a self-hosted manga server and reader. Its features include
- Supports nested folders in library
- Automatically stores reading progress
- Thumbnail generation
-- Supports [plugins](https://github.com/hkalexling/mango-plugins) to download from thrid-party sites
+- Supports [plugins](https://github.com/hkalexling/mango-plugins) to download from third-party sites
- The web reader is responsive and works well on mobile, so there is no need for a mobile app
- All the static files are embedded in the binary, so the deployment process is easy and painless
@@ -51,7 +51,7 @@ The official docker images are available on [Dockerhub](https://hub.docker.com/r
### CLI
```
- Mango - Manga Server and Web Reader. Version 0.24.0
+ Mango - Manga Server and Web Reader. Version 0.25.0
Usage:
@@ -80,6 +80,7 @@ base_url: /
session_secret: mango-session-secret
library_path: ~/mango/library
db_path: ~/mango/mango.db
+queue_db_path: ~/mango/queue.db
scan_interval_minutes: 5
thumbnail_generation_interval_hours: 24
log_level: info
@@ -93,17 +94,9 @@ cache_log_enabled: true
disable_login: false
default_username: ""
auth_proxy_header_name: ""
-mangadex:
- base_url: https://mangadex.org
- api_url: https://api.mangadex.org/v2
- download_wait_seconds: 5
- download_retries: 4
- download_queue_db_path: ~/mango/queue.db
- chapter_rename_rule: '[Vol.{volume} ][Ch.{chapter} ]{title|id}'
- manga_rename_rule: '{title}'
```
-- `scan_interval_minutes`, `thumbnail_generation_interval_hours` and `db_optimization_interval_hours` can be any non-negative integer. Setting them to `0` disables the periodic tasks
+- `scan_interval_minutes`, `thumbnail_generation_interval_hours` can be any non-negative integer. Setting them to `0` disables the periodic tasks
- `log_level` can be `debug`, `info`, `warn`, `error`, `fatal` or `off`. Setting it to `off` disables the logging
- You can disable authentication by setting `disable_login` to true. Note that `default_username` must be set to an existing username for this to work.
- By setting `cache_enabled` to `true`, you can enable an experimental feature where Mango caches library metadata to improve page load time. You can further fine-tune the feature with `cache_size_mbs` and `cache_log_enabled`.
@@ -179,6 +172,8 @@ Please check the [development guideline](https://github.com/hkalexling/Mango/wik
 Simon 💻 |
 David Knaack 🚇 |
 i use arch btw 🚇 |
+  BradleyDS2 📖 |
+  Robbo 💻 |
diff --git a/shard.yml b/shard.yml
index 0054a23..44a0924 100644
--- a/shard.yml
+++ b/shard.yml
@@ -1,5 +1,5 @@
name: mango
-version: 0.24.0
+version: 0.25.0
authors:
- Alex Ling
diff --git a/src/config.cr b/src/config.cr
index 41a4cf1..807a74c 100644
--- a/src/config.cr
+++ b/src/config.cr
@@ -4,44 +4,28 @@ class Config
include YAML::Serializable
@[YAML::Field(ignore: true)]
- property path : String = ""
- property host : String = "0.0.0.0"
+ property path = ""
+ property host = "0.0.0.0"
property port : Int32 = 9000
- property base_url : String = "/"
- property session_secret : String = "mango-session-secret"
- property library_path : String = File.expand_path "~/mango/library",
- home: true
- property library_cache_path = File.expand_path "~/mango/library.yml.gz",
- home: true
- property db_path : String = File.expand_path "~/mango/mango.db", home: true
+ property base_url = "/"
+ property session_secret = "mango-session-secret"
+ property library_path = "~/mango/library"
+ property library_cache_path = "~/mango/library.yml.gz"
+ property db_path = "~/mango/mango.db"
+ property queue_db_path = "~/mango/queue.db"
property scan_interval_minutes : Int32 = 5
property thumbnail_generation_interval_hours : Int32 = 24
- property log_level : String = "info"
- property upload_path : String = File.expand_path "~/mango/uploads",
- home: true
- property plugin_path : String = File.expand_path "~/mango/plugins",
- home: true
+ property log_level = "info"
+ property upload_path = "~/mango/uploads"
+ property plugin_path = "~/mango/plugins"
property download_timeout_seconds : Int32 = 30
- property cache_enabled = false
+ property cache_enabled = true
property cache_size_mbs = 50
property cache_log_enabled = true
property disable_login = false
property default_username = ""
property auth_proxy_header_name = ""
property plugin_update_interval_hours : Int32 = 24
- property mangadex = Hash(String, String | Int32).new
-
- @[YAML::Field(ignore: true)]
- @mangadex_defaults = {
- "base_url" => "https://mangadex.org",
- "api_url" => "https://api.mangadex.org/v2",
- "download_wait_seconds" => 5,
- "download_retries" => 4,
- "download_queue_db_path" => File.expand_path("~/mango/queue.db",
- home: true),
- "chapter_rename_rule" => "[Vol.{volume} ][Ch.{chapter} ]{title|id}",
- "manga_rename_rule" => "{title}",
- }
@@singlet : Config?
@@ -59,7 +43,7 @@ class Config
if File.exists? cfg_path
config = self.from_yaml File.read cfg_path
config.path = path
- config.fill_defaults
+ config.expand_paths
config.preprocess
return config
end
@@ -67,7 +51,7 @@ class Config
"Dumping the default config there."
default = self.allocate
default.path = path
- default.fill_defaults
+ default.expand_paths
cfg_dir = File.dirname cfg_path
unless Dir.exists? cfg_dir
Dir.mkdir_p cfg_dir
@@ -77,13 +61,9 @@ class Config
default
end
- def fill_defaults
- {% for hash_name in ["mangadex"] %}
- @{{hash_name.id}}_defaults.map do |k, v|
- if @{{hash_name.id}}[k]?.nil?
- @{{hash_name.id}}[k] = v
- end
- end
+ def expand_paths
+ {% for p in %w(library library_cache db queue_db upload plugin) %}
+ @{{p.id}}_path = File.expand_path @{{p.id}}_path, home: true
{% end %}
end
@@ -98,24 +78,5 @@ class Config
raise "Login is disabled, but default username is not set. " \
"Please set a default username"
end
-
- # `Logger.default` is not available yet
- Log.setup :debug
- unless mangadex["api_url"] =~ /\/v2/
- Log.warn { "It looks like you are using the deprecated MangaDex API " \
- "v1 in your config file. Please update it to " \
- "https://api.mangadex.org/v2 to suppress this warning." }
- mangadex["api_url"] = "https://api.mangadex.org/v2"
- end
- if mangadex["api_url"] =~ /\/api\/v2/
- Log.warn { "It looks like you are using the outdated MangaDex API " \
- "url (mangadex.org/api/v2) in your config file. Please " \
- "update it to https://api.mangadex.org/v2 to suppress this " \
- "warning." }
- mangadex["api_url"] = "https://api.mangadex.org/v2"
- end
-
- mangadex["api_url"] = mangadex["api_url"].to_s.rstrip "/"
- mangadex["base_url"] = mangadex["base_url"].to_s.rstrip "/"
end
end
diff --git a/src/library/library.cr b/src/library/library.cr
index a2dc28d..210912f 100644
--- a/src/library/library.cr
+++ b/src/library/library.cr
@@ -1,9 +1,38 @@
class Library
+ struct ThumbnailContext
+ property current : Int32, total : Int32
+
+ def initialize
+ @current = 0
+ @total = 0
+ end
+
+ def progress
+ if total == 0
+ 0
+ else
+ current / total
+ end
+ end
+
+ def reset
+ @current = 0
+ @total = 0
+ end
+
+ def increment
+ @current += 1
+ end
+ end
+
include YAML::Serializable
getter dir : String, title_ids : Array(String),
title_hash : Hash(String, Title)
+ @[YAML::Field(ignore: true)]
+ getter thumbnail_ctx = ThumbnailContext.new
+
use_default
def save_instance
@@ -24,7 +53,23 @@ class Library
begin
Compress::Gzip::Reader.open path do |content|
- @@default = Library.from_yaml content
+ loaded = Library.from_yaml content
+ # We will have to do a full restart in these cases. Otherwise having
+ # two instances of the library will cause some weirdness.
+ if loaded.dir != Config.current.library_path
+ Logger.fatal "Cached library dir #{loaded.dir} does not match " \
+ "current library dir #{Config.current.library_path}. " \
+ "Deleting cache"
+ delete_cache_and_exit path
+ end
+ if loaded.title_ids.size > 0 &&
+ Storage.default.count_titles == 0
+ Logger.fatal "The library cache is inconsistent with the DB. " \
+ "Deleting cache"
+ delete_cache_and_exit path
+ end
+ @@default = loaded
+ Logger.debug "Library cache loaded"
end
Library.default.register_jobs
rescue e
@@ -39,9 +84,6 @@ class Library
@title_ids = [] of String
@title_hash = {} of String => Title
- @entries_count = 0
- @thumbnails_count = 0
-
register_jobs
end
@@ -262,34 +304,29 @@ class Library
.shuffle!
end
- def thumbnail_generation_progress
- return 0 if @entries_count == 0
- @thumbnails_count / @entries_count
- end
-
def generate_thumbnails
- if @thumbnails_count > 0
+ if thumbnail_ctx.current > 0
Logger.debug "Thumbnail generation in progress"
return
end
Logger.info "Starting thumbnail generation"
entries = deep_titles.flat_map(&.deep_entries).reject &.err_msg
- @entries_count = entries.size
- @thumbnails_count = 0
+ thumbnail_ctx.total = entries.size
+ thumbnail_ctx.current = 0
# Report generation progress regularly
spawn do
loop do
- unless @thumbnails_count == 0
+ unless thumbnail_ctx.current == 0
Logger.debug "Thumbnail generation progress: " \
- "#{(thumbnail_generation_progress * 100).round 1}%"
+ "#{(thumbnail_ctx.progress * 100).round 1}%"
end
# Generation is completed. We reset the count to 0 to allow subsequent
# calls to the function, and break from the loop to stop the progress
# report fiber
- if thumbnail_generation_progress.to_i == 1
- @thumbnails_count = 0
+ if thumbnail_ctx.progress.to_i == 1
+ thumbnail_ctx.reset
break
end
sleep 10.seconds
@@ -303,7 +340,7 @@ class Library
# and CPU
sleep 1.seconds
end
- @thumbnails_count += 1
+ thumbnail_ctx.increment
end
Logger.info "Thumbnail generation finished"
end
diff --git a/src/mango.cr b/src/mango.cr
index b19799f..14603b9 100644
--- a/src/mango.cr
+++ b/src/mango.cr
@@ -7,7 +7,7 @@ require "option_parser"
require "clim"
require "tallboy"
-MANGO_VERSION = "0.24.0"
+MANGO_VERSION = "0.25.0"
# From http://www.network-science.de/ascii/
BANNER = %{
diff --git a/src/queue.cr b/src/queue.cr
index dc15d36..82fdeda 100644
--- a/src/queue.cr
+++ b/src/queue.cr
@@ -118,7 +118,7 @@ class Queue
use_default
def initialize(db_path : String? = nil)
- @path = db_path || Config.current.mangadex["download_queue_db_path"].to_s
+ @path = db_path || Config.current.queue_db_path.to_s
dir = File.dirname @path
unless Dir.exists? dir
Logger.info "The queue DB directory #{dir} does not exist. " \
diff --git a/src/routes/admin.cr b/src/routes/admin.cr
index c78df86..c3692c9 100644
--- a/src/routes/admin.cr
+++ b/src/routes/admin.cr
@@ -66,7 +66,6 @@ struct AdminRouter
end
get "/admin/downloads" do |env|
- mangadex_base_url = Config.current.mangadex["base_url"]
layout "download-manager"
end
diff --git a/src/routes/api.cr b/src/routes/api.cr
index ffed75f..3b33eca 100644
--- a/src/routes/api.cr
+++ b/src/routes/api.cr
@@ -240,7 +240,7 @@ struct APIRouter
}
get "/api/admin/thumbnail_progress" do |env|
send_json env, {
- "progress" => Library.default.thumbnail_generation_progress,
+ "progress" => Library.default.thumbnail_ctx.progress,
}.to_json
end
diff --git a/src/storage.cr b/src/storage.cr
index 4c8cfe7..5622241 100644
--- a/src/storage.cr
+++ b/src/storage.cr
@@ -619,6 +619,20 @@ class Storage
{token, expires}
end
+ def count_titles : Int32
+ count = 0
+ MainFiber.run do
+ get_db do |db|
+ db.query "select count(*) from titles" do |rs|
+ rs.each do
+ count = rs.read Int32
+ end
+ end
+ end
+ end
+ count
+ end
+
def close
MainFiber.run do
unless @db.nil?
diff --git a/src/util/util.cr b/src/util/util.cr
index 11d1a13..e7b1b1a 100644
--- a/src/util/util.cr
+++ b/src/util/util.cr
@@ -163,3 +163,12 @@ def sanitize_filename(str : String) : String
.gsub(/[\177\000-\031\\:\*\?\"<>\|]/, "")
sanitized.size > 0 ? sanitized : random_str
end
+
+def delete_cache_and_exit(path : String)
+ File.delete path
+ Logger.fatal "Invalid library cache deleted. Mango needs to " \
+ "perform a full reset to recover from this. " \
+ "Pleae restart Mango. This is NOT a bug."
+ Logger.fatal "Exiting"
+ exit 1
+end
diff --git a/src/views/download-manager.html.ecr b/src/views/download-manager.html.ecr
index c264177..a8394ff 100644
--- a/src/views/download-manager.html.ecr
+++ b/src/views/download-manager.html.ecr
@@ -24,16 +24,10 @@
|
-
- |
-
|
-
- |
-
|
|