mirror of https://github.com/getmango/Mango.git
Add `duktape.cr` and the `Plugin` class
This commit is contained in:
parent
a7f4e161de
commit
a812e3ed46
|
@ -20,6 +20,10 @@ shards:
|
||||||
github: crystal-lang/crystal-db
|
github: crystal-lang/crystal-db
|
||||||
version: 0.9.0
|
version: 0.9.0
|
||||||
|
|
||||||
|
duktape:
|
||||||
|
github: jessedoyle/duktape.cr
|
||||||
|
version: 0.20.0
|
||||||
|
|
||||||
exception_page:
|
exception_page:
|
||||||
github: crystal-loot/exception_page
|
github: crystal-loot/exception_page
|
||||||
version: 0.1.4
|
version: 0.1.4
|
||||||
|
@ -36,6 +40,10 @@ shards:
|
||||||
github: jeromegn/kilt
|
github: jeromegn/kilt
|
||||||
version: 0.4.0
|
version: 0.4.0
|
||||||
|
|
||||||
|
myhtml:
|
||||||
|
github: kostya/myhtml
|
||||||
|
version: 1.5.1
|
||||||
|
|
||||||
radix:
|
radix:
|
||||||
github: luislavena/radix
|
github: luislavena/radix
|
||||||
version: 0.3.9
|
version: 0.3.9
|
||||||
|
|
|
@ -27,3 +27,8 @@ dependencies:
|
||||||
github: crystal-ameba/ameba
|
github: crystal-ameba/ameba
|
||||||
clim:
|
clim:
|
||||||
github: at-grandpa/clim
|
github: at-grandpa/clim
|
||||||
|
duktape:
|
||||||
|
github: jessedoyle/duktape.cr
|
||||||
|
version: ~> 0.20.0
|
||||||
|
myhtml:
|
||||||
|
github: kostya/myhtml
|
||||||
|
|
|
@ -16,6 +16,7 @@ class Config
|
||||||
property log_level : String = "info"
|
property log_level : String = "info"
|
||||||
property upload_path : String = File.expand_path "~/mango/uploads",
|
property upload_path : String = File.expand_path "~/mango/uploads",
|
||||||
home: true
|
home: true
|
||||||
|
property plugin_path : String = File.expand_path "~/mango/plugins"
|
||||||
property mangadex = Hash(String, String | Int32).new
|
property mangadex = Hash(String, String | Int32).new
|
||||||
|
|
||||||
@[YAML::Field(ignore: true)]
|
@[YAML::Field(ignore: true)]
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
require "duktape/runtime"
|
||||||
|
require "myhtml"
|
||||||
|
require "http"
|
||||||
|
|
||||||
|
class Plugin
|
||||||
|
class Error < ::Exception
|
||||||
|
end
|
||||||
|
|
||||||
|
class MetadataError < Error
|
||||||
|
end
|
||||||
|
|
||||||
|
class PluginException < Error
|
||||||
|
end
|
||||||
|
|
||||||
|
class SyntaxError < Error
|
||||||
|
end
|
||||||
|
|
||||||
|
{% for name in ["id", "title", "author", "version", "placeholder"] %}
|
||||||
|
getter {{name.id}} = ""
|
||||||
|
{% end %}
|
||||||
|
getter wait_seconds : UInt64 = 0
|
||||||
|
|
||||||
|
def self.list
|
||||||
|
dir = Config.current.plugin_path
|
||||||
|
Dir.children(dir)
|
||||||
|
.select do |f|
|
||||||
|
fp = File.join dir, f
|
||||||
|
File.file?(fp) && File.extname(fp) == ".js"
|
||||||
|
end
|
||||||
|
.map do |f|
|
||||||
|
File.basename f, ".js"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(@path : String)
|
||||||
|
@rt = Duktape::Runtime.new do |sbx|
|
||||||
|
sbx.push_global_object
|
||||||
|
|
||||||
|
sbx.del_prop_string -1, "print"
|
||||||
|
sbx.del_prop_string -1, "alert"
|
||||||
|
sbx.del_prop_string -1, "console"
|
||||||
|
|
||||||
|
def_helper_functions sbx
|
||||||
|
end
|
||||||
|
|
||||||
|
js = File.open @path, &.gets_to_end
|
||||||
|
eval js
|
||||||
|
|
||||||
|
begin
|
||||||
|
data = eval_json "metadata"
|
||||||
|
{% for name in ["id", "title", "author", "version", "placeholder"] %}
|
||||||
|
@{{name.id}} = data[{{name}}].as_s
|
||||||
|
{% end %}
|
||||||
|
@wait_seconds = data["wait_seconds"].as_i.to_u64
|
||||||
|
rescue e
|
||||||
|
raise MetadataError.new "Failed to retrieve metadata from plugin " \
|
||||||
|
"at #{@path}. Error: #{e.message}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def search(query : String)
|
||||||
|
eval_json "search('#{query}')"
|
||||||
|
end
|
||||||
|
|
||||||
|
def select_chapter(id : String)
|
||||||
|
eval_json "selectChapter('#{id}')"
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_page
|
||||||
|
eval_json "nextPage()"
|
||||||
|
end
|
||||||
|
|
||||||
|
private def eval(str)
|
||||||
|
@rt.eval str
|
||||||
|
rescue e : Duktape::SyntaxError
|
||||||
|
raise SyntaxError.new e.message
|
||||||
|
rescue e : Duktape::Error
|
||||||
|
raise Error.new e.message
|
||||||
|
end
|
||||||
|
|
||||||
|
private def eval_json(str)
|
||||||
|
JSON.parse eval(str).as String
|
||||||
|
end
|
||||||
|
|
||||||
|
private def def_helper_functions(sbx)
|
||||||
|
sbx.push_object
|
||||||
|
|
||||||
|
sbx.push_proc LibDUK::VARARGS do |ptr|
|
||||||
|
env = Duktape::Sandbox.new ptr
|
||||||
|
url = env.require_string 0
|
||||||
|
|
||||||
|
headers = HTTP::Headers.new
|
||||||
|
|
||||||
|
if env.get_top == 2
|
||||||
|
env.enum 1, LibDUK::Enum::OwnPropertiesOnly
|
||||||
|
while env.next -1, true
|
||||||
|
k = env.require_string -2
|
||||||
|
v = env.require_string -1
|
||||||
|
headers.add k, v
|
||||||
|
env.pop_2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
res = HTTP::Client.get url, headers
|
||||||
|
body = res.body
|
||||||
|
|
||||||
|
env.push_string body
|
||||||
|
env.call_success
|
||||||
|
end
|
||||||
|
sbx.put_prop_string -2, "get"
|
||||||
|
|
||||||
|
sbx.push_proc 2 do |ptr|
|
||||||
|
env = Duktape::Sandbox.new ptr
|
||||||
|
html = env.require_string 0
|
||||||
|
selector = env.require_string 1
|
||||||
|
|
||||||
|
myhtml = Myhtml::Parser.new html
|
||||||
|
json = myhtml.css(selector).map(&.to_html).to_a.to_json
|
||||||
|
|
||||||
|
env.push_string json
|
||||||
|
env.call_success
|
||||||
|
end
|
||||||
|
sbx.put_prop_string -2, "css"
|
||||||
|
|
||||||
|
sbx.push_proc 1 do |ptr|
|
||||||
|
env = Duktape::Sandbox.new ptr
|
||||||
|
html = env.require_string 0
|
||||||
|
|
||||||
|
myhtml = Myhtml::Parser.new html
|
||||||
|
root = myhtml.root
|
||||||
|
|
||||||
|
str = ""
|
||||||
|
str = root.inner_text if root
|
||||||
|
|
||||||
|
env.push_string str
|
||||||
|
env.call_success
|
||||||
|
end
|
||||||
|
sbx.put_prop_string -2, "innerText"
|
||||||
|
|
||||||
|
sbx.push_proc 1 do |ptr|
|
||||||
|
env = Duktape::Sandbox.new ptr
|
||||||
|
msg = env.require_string 0
|
||||||
|
env.call_success
|
||||||
|
|
||||||
|
raise PluginException.new msg
|
||||||
|
end
|
||||||
|
sbx.put_prop_string -2, "raise"
|
||||||
|
|
||||||
|
sbx.put_prop_string -2, "mango"
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue