Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.27.0 #322

Merged
merged 68 commits into from
Jul 31, 2022
Merged
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
2865669
Show control after reading at the end in paged mode
Leeingnyo May 12, 2022
0e4169c
Fix preload bug
Leeingnyo May 12, 2022
eac274a
Merge pull request #301 from Leeingnyo/feature/show-control-at-end-in…
hkalexling May 13, 2022
5f59b7e
Merge branch 'dev' into fix/preload-bug
hkalexling May 13, 2022
883e01b
Merge pull request #302 from Leeingnyo/fix/preload-bug
hkalexling May 13, 2022
ea6cbbd
Split Entry and ZippedEntry, Fix to work anyway
Leeingnyo May 14, 2022
10587f4
Implement is_supported_image_file
Leeingnyo May 15, 2022
55ccd92
Implement DirectoryEntry
Leeingnyo May 15, 2022
3b3a073
Scan DirectoryEntry when init and examine
Leeingnyo May 15, 2022
137e84d
Fix caching policy
Leeingnyo May 15, 2022
caf4cfb
Fix Entry.new in YAML::Serializable to support DirectyEntry
Leeingnyo May 15, 2022
9f6be70
Rename Entry.exists? to Entry.examine
Leeingnyo May 15, 2022
3a60286
Run 'crystal tool format'
Leeingnyo May 15, 2022
3da5d9b
Fix contents_signature
Leeingnyo May 15, 2022
0ed5655
Rollback crystal format
Leeingnyo May 15, 2022
f18f6a5
Fix linter issues
hkalexling May 19, 2022
1f5aed6
Rename Entries to ArchiveEntry and DirEntry
Leeingnyo May 20, 2022
238539c
Split files
Leeingnyo May 20, 2022
648cdd7
Add back `zip_path` for backward compatibility
hkalexling May 22, 2022
ae503ae
Remove unnecessary `createtime` method
hkalexling May 22, 2022
82c60cc
Replace puts with Logger.debug
hkalexling May 22, 2022
872e6dc
Better method naming in DirEntry
hkalexling May 22, 2022
e6dbeb6
Use `is_valid?`
hkalexling May 22, 2022
5b23a11
Remove unnecessary `path` method
hkalexling May 22, 2022
2fb6202
Choose correct subclass based on YAML node
hkalexling May 29, 2022
df61870
Fix linter
hkalexling May 29, 2022
39a331c
Avoid not_nil in date_added
hkalexling May 29, 2022
8e4bb99
Add zip_path to API document, add path property
Leeingnyo Jun 3, 2022
9ce8e91
Replace to is_valid?
Leeingnyo Jun 3, 2022
2d97faa
Merge pull request #305 from Leeingnyo/feature/unzipped-entry
hkalexling Jun 5, 2022
d9dce4a
Fix Continue Reading not show missed reading chapter if the latest ch…
torta Jun 5, 2022
30d5ad0
Hide subscribe button when not subscribable
hkalexling Jun 5, 2022
5b58d8a
Clear page when switching plugins
hkalexling Jun 5, 2022
ea35fae
Add jxl support
tr7zw Jun 6, 2022
ae583cf
Workaround for "0 width/height" api responses
tr7zw Jun 7, 2022
be46dd1
Allow config defaults to be sourced from ENV
crainte Jun 15, 2022
bbc0c2c
Fix Dir.contents_signature to detect valid image files added
Leeingnyo Jun 18, 2022
17a9c8e
pass lint
Leeingnyo Jun 18, 2022
a639392
Update comment
hkalexling Jun 18, 2022
44636e0
Merge pull request #310 from torta/feature/greedy-continue-reading
hkalexling Jun 18, 2022
fe440d8
Fix linter issue
hkalexling Jun 18, 2022
31df058
Comment about infinity average ratio
hkalexling Jun 18, 2022
32ce26a
Merge branch 'dev' into jxl-support
hkalexling Jun 18, 2022
3b5e764
Merge pull request #312 from tr7zw/jxl-support
hkalexling Jun 18, 2022
19a8f31
Merge branch 'dev' into fix/rescan-when-files-added
hkalexling Jun 26, 2022
2e91028
Allow config defaults to be sourced from ENV
crainte Jun 15, 2022
f3eb62a
Disable line length warnings
crainte Jun 27, 2022
49425ff
Merge branch 'feature/default-env-vars' of https://github.com/crainte…
hkalexling Jul 3, 2022
f2d6d28
Define properties with macro
hkalexling Jul 3, 2022
b6a1ad8
Merge pull request #314 from crainte/feature/default-env-vars
hkalexling Jul 3, 2022
2d2486a
Merge branch 'dev' into fix/rescan-when-files-added
hkalexling Jul 3, 2022
e7c4123
Merge pull request #315 from Leeingnyo/fix/rescan-when-files-added
hkalexling Jul 3, 2022
405b958
First draft of image fit.
Hiers Jul 5, 2022
db5e99b
Fix in reader.html.ecr.
Hiers Jul 5, 2022
6ddbe8d
Changed setFit function to not have redundant ifs and a better commen…
Hiers Jul 7, 2022
6242836
Fixed right flip panel not being all the way on the right; changed re…
Hiers Jul 13, 2022
dc3ac42
Right flip panels are 1/3 of the rightmost area of the entire screen,…
Hiers Jul 16, 2022
5daeac7
Merge pull request #317 from Hiers/feature/image-fit
hkalexling Jul 17, 2022
75a30a8
Use `myhtml` in plugin helper and add tests (#320)
hkalexling Jul 17, 2022
9fe269a
Disable `plugin_spec.cr` line limit
hkalexling Jul 17, 2022
47af6ee
Merge pull request #321 from hkalexling/fix/plugin-use-html-parser
hkalexling Jul 18, 2022
cb3df43
Merge branch 'dev' into fix/hide-subscribe-btn
hkalexling Jul 18, 2022
98a0c54
Merge pull request #311 from hkalexling/fix/hide-subscribe-btn
hkalexling Jul 18, 2022
bf885a8
Bump version to 0.27.0
hkalexling Jul 18, 2022
7258b3c
Add /manifest.json to static files
phlhg Jul 27, 2022
4c2f802
Fix linter
hkalexling Jul 31, 2022
9ea4ced
Merge pull request #327 from phlhg/fix/static-manifest
hkalexling Jul 31, 2022
7ceb91f
Merge branch 'rc/0.27.0' into dev
hkalexling Jul 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ameba.yml
Original file line number Diff line number Diff line change
@@ -12,3 +12,4 @@ Layout/LineLength:
MaxLength: 80
Excluded:
- src/routes/api.cr
- spec/plugin_spec.cr
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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.26.2
Mango - Manga Server and Web Reader. Version 0.27.0
Usage:
6 changes: 6 additions & 0 deletions public/js/plugin-download.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const component = () => {
return {
plugins: [],
subscribable: false,
info: undefined,
pid: undefined,
chapters: undefined, // undefined: not searched yet, []: empty
@@ -60,6 +61,7 @@ const component = () => {
.then((data) => {
if (!data.success) throw new Error(data.error);
this.info = data.info;
this.subscribable = data.subscribable;
this.pid = pid;
})
.catch((e) => {
@@ -70,6 +72,9 @@ const component = () => {
});
},
pluginChanged() {
this.manga = undefined;
this.chapters = undefined;
this.mid = undefined;
this.loadPlugin(this.pid);
localStorage.setItem("plugin", this.pid);
},
@@ -140,6 +145,7 @@ const component = () => {
if (!query) return;

this.manga = undefined;
this.mid = undefined;
if (this.info.version === 1) {
this.searchChapters(query);
} else {
41 changes: 33 additions & 8 deletions public/js/reader.js
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ const readerComponent = () => {
margin: 30,
preloadLookahead: 3,
enableRightToLeft: false,
fitType: 'vert',

/**
* Initialize the component by fetching the page dimensions
@@ -29,14 +30,16 @@ const readerComponent = () => {
return {
id: i + 1,
url: `${base_url}api/page/${tid}/${eid}/${i+1}`,
width: d.width,
height: d.height,
width: d.width == 0 ? "100%" : d.width,
height: d.height == 0 ? "100%" : d.height,
};
});

const avgRatio = this.items.reduce((acc, cur) => {
// Note: for image types not supported by image_size.cr, the width and height will be 0, and so `avgRatio` will be `Infinity`.
// TODO: support more image types in image_size.cr
const avgRatio = dimensions.reduce((acc, cur) => {
return acc + cur.height / cur.width
}, 0) / this.items.length;
}, 0) / dimensions.length;

console.log(avgRatio);
this.longPages = avgRatio > 2;
@@ -58,11 +61,16 @@ const readerComponent = () => {

// Preload Images
this.preloadLookahead = +(localStorage.getItem('preloadLookahead') ?? 3);
const limit = Math.min(page + this.preloadLookahead, this.items.length + 1);
const limit = Math.min(page + this.preloadLookahead, this.items.length);
for (let idx = page + 1; idx <= limit; idx++) {
this.preloadImage(this.items[idx - 1].url);
}

const savedFitType = localStorage.getItem('fitType');
if (savedFitType) {
this.fitType = savedFitType;
$('#fit-select').val(savedFitType);
}
const savedFlipAnimation = localStorage.getItem('enableFlipAnimation');
this.enableFlipAnimation = savedFlipAnimation === null || savedFlipAnimation === 'true';

@@ -135,7 +143,11 @@ const readerComponent = () => {
const idx = parseInt(this.curItem.id);
const newIdx = idx + (isNext ? 1 : -1);

if (newIdx <= 0 || newIdx > this.items.length) return;
if (newIdx <= 0) return;
if (newIdx > this.items.length) {
this.showControl(idx);
return;
}

if (newIdx + this.preloadLookahead < this.items.length + 1) {
this.preloadImage(this.items[newIdx + this.preloadLookahead - 1].url);
@@ -253,12 +265,20 @@ const readerComponent = () => {
});
},
/**
* Shows the control modal
* Handles clicked image
*
* @param {Event} event - The triggering event
*/
showControl(event) {
clickImage(event) {
const idx = event.currentTarget.id;
this.showControl(idx);
},
/**
* Shows the control modal
*
* @param {number} idx - selected page index
*/
showControl(idx) {
this.selectedIndex = idx;
UIkit.modal($('#modal-sections')).show();
},
@@ -321,6 +341,11 @@ const readerComponent = () => {
this.toPage(this.selectedIndex);
},

fitChanged(){
this.fitType = $('#fit-select').val();
localStorage.setItem('fitType', this.fitType);
},

preloadLookaheadChanged() {
localStorage.setItem('preloadLookahead', this.preloadLookahead);
},
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: mango
version: 0.26.2
version: 0.27.0

authors:
- Alex Ling <[email protected]>
Empty file.
6 changes: 6 additions & 0 deletions spec/asset/plugins/plugin/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "test",
"title": "Test Plugin",
"placeholder": "placeholder",
"wait_seconds": 1
}
21 changes: 19 additions & 2 deletions spec/config_spec.cr
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
require "./spec_helper"

describe Config do
it "creates config if it does not exist" do
with_default_config do |_, path|
it "creates default config if it does not exist" do
with_default_config do |config, path|
File.exists?(path).should be_true
config.port.should eq 9000
end
end

it "correctly loads config" do
config = Config.load "spec/asset/test-config.yml"
config.port.should eq 3000
config.base_url.should eq "/"
end

it "correctly reads config defaults from ENV" do
ENV["LOG_LEVEL"] = "debug"
config = Config.load "spec/asset/test-config.yml"
config.log_level.should eq "debug"
config.base_url.should eq "/"
end

it "correctly handles ENV truthiness" do
ENV["CACHE_ENABLED"] = "false"
config = Config.load "spec/asset/test-config.yml"
config.cache_enabled.should be_false
config.cache_log_enabled.should be_true
config.disable_login.should be_false
end
end
70 changes: 70 additions & 0 deletions spec/plugin_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
require "./spec_helper"

describe Plugin do
describe "helper functions" do
it "mango.text" do
with_plugin do |plugin|
res = plugin.eval <<-JS
mango.text('<a href="https://github.com">Click Me<a>');
JS
res.should eq "Click Me"
end
end

it "mango.text returns empty string when no text" do
with_plugin do |plugin|
res = plugin.eval <<-JS
mango.text('<img src="https://github.com" />');
JS
res.should eq ""
end
end

it "mango.css" do
with_plugin do |plugin|
res = plugin.eval <<-JS
mango.css('<ul><li class="test">A</li><li class="test">B</li><li>C</li></ul>', 'li.test');
JS
res.should eq ["<li class=\"test\">A</li>", "<li class=\"test\">B</li>"]
end
end

it "mango.css returns empty array when no match" do
with_plugin do |plugin|
res = plugin.eval <<-JS
mango.css('<ul><li class="test">A</li><li class="test">B</li><li>C</li></ul>', 'li.noclass');
JS
res.should eq [] of String
end
end

it "mango.attribute" do
with_plugin do |plugin|
res = plugin.eval <<-JS
mango.attribute('<a href="https://github.com">Click Me<a>', 'href');
JS
res.should eq "https://github.com"
end
end

it "mango.attribute returns undefined when no match" do
with_plugin do |plugin|
res = plugin.eval <<-JS
mango.attribute('<div />', 'href') === undefined;
JS
res.should be_true
end
end

# https://github.com/hkalexling/Mango/issues/320
it "mango.attribute handles tags in attribute values" do
with_plugin do |plugin|
res = plugin.eval <<-JS
mango.attribute('<div data-a="<img />" data-b="test" />', 'data-b');
JS
res.should eq "test"
end
end
end
end
8 changes: 8 additions & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ require "../src/queue"
require "../src/server"
require "../src/config"
require "../src/main_fiber"
require "../src/plugin/plugin"

class State
@@hash = {} of String => String
@@ -54,3 +55,10 @@ def with_storage
end
end
end

def with_plugin
with_default_config do
plugin = Plugin.new "test", "spec/asset/plugins"
yield plugin
end
end
66 changes: 43 additions & 23 deletions src/config.cr
Original file line number Diff line number Diff line change
@@ -1,31 +1,51 @@
require "yaml"

class Config
private OPTIONS = {
"host" => "0.0.0.0",
"port" => 9000,
"base_url" => "/",
"session_secret" => "mango-session-secret",
"library_path" => "~/mango/library",
"library_cache_path" => "~/mango/library.yml.gz",
"db_path" => "~/mango.db",
"queue_db_path" => "~/mango/queue.db",
"scan_interval_minutes" => 5,
"thumbnail_generation_interval_hours" => 24,
"log_level" => "info",
"upload_path" => "~/mango/uploads",
"plugin_path" => "~/mango/plugins",
"download_timeout_seconds" => 30,
"cache_enabled" => true,
"cache_size_mbs" => 50,
"cache_log_enabled" => true,
"disable_login" => false,
"default_username" => "",
"auth_proxy_header_name" => "",
"plugin_update_interval_hours" => 24,
}

include YAML::Serializable

@[YAML::Field(ignore: true)]
property path = ""
property host = "0.0.0.0"
property port : Int32 = 9000
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 = "info"
property upload_path = "~/mango/uploads"
property plugin_path = "~/mango/plugins"
property download_timeout_seconds : Int32 = 30
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 path : String = ""

# Go through the options constant above and define them as properties.
# Allow setting the default values through environment variables.
# Overall precedence: config file > environment variable > default value
{% begin %}
{% for k, v in OPTIONS %}
{% if v.is_a? StringLiteral %}
property {{k.id}} : String = ENV[{{k.upcase}}]? || {{ v }}
{% elsif v.is_a? NumberLiteral %}
property {{k.id}} : Int32 = (ENV[{{k.upcase}}]? || {{ v.id }}).to_i
{% elsif v.is_a? BoolLiteral %}
property {{k.id}} : Bool = env_is_true? {{ k.upcase }}, {{ v.id }}
{% else %}
raise "Unknown type in config option: {{ v.class_name.id }}"
{% end %}
{% end %}
{% end %}

@@singlet : Config?

@@ -38,7 +58,7 @@ class Config
end

def self.load(path : String?)
path = "~/.config/mango/config.yml" if path.nil?
path = (ENV["CONFIG_PATH"]? || "~/.config/mango/config.yml") if path.nil?
cfg_path = File.expand_path path, home: true
if File.exists? cfg_path
config = self.from_yaml File.read cfg_path
Loading