Add Cmd::Pull
This commit is contained in:
parent
880eb64897
commit
e01d64b4a2
8 changed files with 127 additions and 155 deletions
|
@ -16,12 +16,12 @@ AllCops:
|
|||
- bin/*
|
||||
|
||||
##
|
||||
# Enabled cops
|
||||
# Enabled
|
||||
Style/FrozenStringLiteralComment:
|
||||
Enabled: true
|
||||
|
||||
##
|
||||
# Disabled cops
|
||||
# Disabled
|
||||
Layout/MultilineMethodCallIndentation:
|
||||
Enabled: false
|
||||
Layout/ArgumentAlignment:
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
#!/usr/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "json"
|
||||
root_dir = File.realpath(File.join(__dir__, ".."))
|
||||
lib_dir = File.join(root_dir, "lib", "quran-json")
|
||||
require File.join(lib_dir, "quran", "json")
|
||||
|
||||
##
|
||||
# Provide short access to 'Quran::JSON::Cmd::Pull'
|
||||
include Quran::JSON
|
||||
|
||||
##
|
||||
# Utils
|
||||
|
@ -18,22 +24,11 @@ end
|
|||
##
|
||||
# main
|
||||
def main(argv)
|
||||
root_dir = File.realpath(File.join(__dir__, ".."))
|
||||
lib_dir = File.join(root_dir, "lib", "quran-json")
|
||||
libexec_dir = File.join(root_dir, "libexec", "quran-json")
|
||||
share_dir = File.join(root_dir, "share", "quran-json", "data")
|
||||
sources = JSON.parse(File.binread(File.join(share_dir, "sources.json")))
|
||||
require File.join(lib_dir, "quran", "json")
|
||||
|
||||
case argv[0]
|
||||
when "pull"
|
||||
cli = Quran::JSON::Pull.cli(argv[1..])
|
||||
sources.each do |locale, source|
|
||||
case cli.locale
|
||||
when locale
|
||||
wait spawn(libexec_dir, source["http"]["hostname"], *argv[1..])
|
||||
end
|
||||
end
|
||||
cmd = Cmd::Pull.new(argv[1..])
|
||||
source = Ryo.find(cmd.sources) { _1 == cmd.options.locale }
|
||||
wait spawn(cmd.libexec_dir, source[cmd.options.locale]["http"]["hostname"], *argv[1..])
|
||||
else
|
||||
warn "Usage: quran-json pull [OPTIONS]"
|
||||
end
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
module Quran
|
||||
module JSON
|
||||
require_relative "json/cmd"
|
||||
require_relative "json/pull"
|
||||
require_relative "json/cmd/pull"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,6 +25,14 @@ module Quran::JSON::Cmd
|
|||
File.join(quran_dir, options.locale)
|
||||
end
|
||||
|
||||
def libexec_dir
|
||||
File.join(root_dir, "libexec", "quran-json")
|
||||
end
|
||||
|
||||
def sources
|
||||
@sources ||= Ryo.from JSON.parse(File.binread(File.join(data_dir, "sources.json")))
|
||||
end
|
||||
|
||||
def line
|
||||
@line ||= IO::Line.new($stdout)
|
||||
end
|
||||
|
|
95
lib/quran-json/quran/json/cmd/pull.rb
Normal file
95
lib/quran-json/quran/json/cmd/pull.rb
Normal file
|
@ -0,0 +1,95 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Quran::JSON::Cmd
|
||||
class Pull
|
||||
require "ryo"
|
||||
require "json"
|
||||
require "net/http"
|
||||
require "fileutils"
|
||||
require "optparse"
|
||||
include Quran::JSON::Cmd
|
||||
include FileUtils
|
||||
|
||||
attr_reader :options,
|
||||
:source,
|
||||
:http
|
||||
|
||||
def self.parse_cli(argv)
|
||||
op = nil
|
||||
result = Ryo({locale: "en", replace: false, update: false})
|
||||
OptionParser.new(nil, 22, " " * 2) do |o|
|
||||
op = o
|
||||
op.banner = "Usage: quran-json pull [OPTIONS]"
|
||||
cli_options.each { op.on(*_1) }
|
||||
end.parse(argv, into: result)
|
||||
result
|
||||
rescue
|
||||
puts op.help
|
||||
exit
|
||||
end
|
||||
|
||||
def self.cli_options
|
||||
[
|
||||
["-l", "--locale LOCALE", "A locale (eg 'en')"],
|
||||
["-r", "--replace", "Replace existing JSON files"],
|
||||
["-u", "--update", "Replace surah metadata"]
|
||||
]
|
||||
end
|
||||
|
||||
def initialize(argv)
|
||||
@options = self.class.parse_cli(argv)
|
||||
@source = sources[options.locale]
|
||||
@http = Net::HTTP.new(source.http.hostname, 443).tap { _1.use_ssl = true }
|
||||
end
|
||||
|
||||
def pull_surah(surah_no)
|
||||
pull format(source.http.path, {surah_no:})
|
||||
end
|
||||
|
||||
def pull_ayah(surah_no, ayah_no)
|
||||
pull format(source.http.path, {surah_no:, ayah_no:})
|
||||
end
|
||||
|
||||
def write(surah_no, rows)
|
||||
mkdir_p(locale_dir)
|
||||
rows[0] = Ryo.table_of(metadata[surah_no - 1])
|
||||
write_json File.join(locale_dir, "#{surah_no}.json"), rows
|
||||
end
|
||||
|
||||
def update(surah_no)
|
||||
rows = read_json File.join(locale_dir, "#{surah_no}.json")
|
||||
write(surah_no, rows)
|
||||
end
|
||||
|
||||
def keepalive
|
||||
http.start
|
||||
yield
|
||||
ensure
|
||||
http.finish
|
||||
end
|
||||
|
||||
##
|
||||
# @return [Boolean]
|
||||
# Returns true when a surah shouldn't be replaced, or updated
|
||||
def keep?(surah_no)
|
||||
exist?(surah_no) and [options.replace, options.update].all? { _1.equal?(false) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def exist?(surah_no)
|
||||
File.exist? File.join(locale_dir, "#{surah_no}.json")
|
||||
end
|
||||
|
||||
def pull(req_path)
|
||||
res = http.get(req_path)
|
||||
case res
|
||||
when Net::HTTPOK
|
||||
res
|
||||
else
|
||||
##
|
||||
# TODO: Handle error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,122 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Quran::JSON::Pull
|
||||
require "ryo"
|
||||
require "json"
|
||||
require "net/http"
|
||||
require "fileutils"
|
||||
require "optparse"
|
||||
include Quran::JSON::Cmd
|
||||
include FileUtils
|
||||
|
||||
attr_reader :options,
|
||||
:source,
|
||||
:http
|
||||
|
||||
def self.cli(argv)
|
||||
op = nil
|
||||
result = Ryo({locale: "en", replace: false, update: false})
|
||||
OptionParser.new(nil, 22, " " * 2) do |o|
|
||||
op = o
|
||||
op.banner = "Usage: quran-json pull [OPTIONS]"
|
||||
cli_options.each { op.on(*_1) }
|
||||
end.parse(argv, into: result)
|
||||
result
|
||||
rescue
|
||||
puts op.help
|
||||
exit
|
||||
end
|
||||
|
||||
def self.cli_options
|
||||
[
|
||||
[
|
||||
"-l", "--locale LOCALE",
|
||||
"ar, en, pt, fa, nl, fr, or it (default: en)"
|
||||
],
|
||||
[
|
||||
"-r", "--replace",
|
||||
"Replace existing JSON files (default: no)"
|
||||
],
|
||||
[
|
||||
"-u", "--update",
|
||||
"Replace surah metadata with an updated copy (implies -r, default: no)"
|
||||
]
|
||||
]
|
||||
end
|
||||
|
||||
def initialize(options)
|
||||
@options = options
|
||||
@source = sources[options.locale]
|
||||
@http = Net::HTTP.new(source.http.hostname, 443).tap { _1.use_ssl = true }
|
||||
end
|
||||
|
||||
def pull_surah(surah_no)
|
||||
pull path(vars(binding))
|
||||
end
|
||||
|
||||
def pull_ayah(surah_no, ayah_no)
|
||||
pull path(vars(binding))
|
||||
end
|
||||
|
||||
def write(surah_no, rows)
|
||||
mkdir_p(locale_dir)
|
||||
rows[0] = Ryo.table_of(metadata[surah_no - 1])
|
||||
write_json File.join(locale_dir, "#{surah_no}.json"), rows
|
||||
end
|
||||
|
||||
def update(surah_no)
|
||||
rows = read_json File.join(locale_dir, "#{surah_no}.json")
|
||||
write(surah_no, rows)
|
||||
end
|
||||
|
||||
def keepalive
|
||||
http.start
|
||||
yield
|
||||
ensure
|
||||
http.finish
|
||||
end
|
||||
|
||||
##
|
||||
# @return [Boolean]
|
||||
# Returns true when a surah shouldn't be replaced, or updated
|
||||
def keep?(surah_no)
|
||||
exist?(surah_no) and [options.replace, options.update].all? { _1.equal?(false) }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def path(vars)
|
||||
format source.http.path, source.http.vars.map { [_1.to_sym, vars[_1.to_sym]] }.to_h
|
||||
end
|
||||
|
||||
def exist?(surah_no)
|
||||
File.exist? File.join(locale_dir, "#{surah_no}.json")
|
||||
end
|
||||
|
||||
def headers
|
||||
@headers ||= {
|
||||
"user-agent" => "quran-json (https://github.com/ReflectsLight/quran-json#readme)"
|
||||
}
|
||||
end
|
||||
|
||||
def pull(req_path)
|
||||
res = http.get(req_path, headers)
|
||||
case res
|
||||
when Net::HTTPOK
|
||||
res
|
||||
else
|
||||
##
|
||||
# TODO: Handle error
|
||||
end
|
||||
end
|
||||
|
||||
def vars(binding)
|
||||
binding.local_variables.map do
|
||||
[_1.to_sym, binding.local_variable_get(_1)]
|
||||
end.to_h
|
||||
end
|
||||
|
||||
def sources
|
||||
@sources ||= Ryo.from read_json(File.join(data_dir, "sources.json"))
|
||||
end
|
||||
end
|
|
@ -6,6 +6,10 @@ require File.join(lib_dir, "quran", "json")
|
|||
require "optparse"
|
||||
require "nokogiri"
|
||||
|
||||
##
|
||||
# Provide short access to 'Quran::JSON::Cmd::Pull'
|
||||
include Quran::JSON
|
||||
|
||||
##
|
||||
# Grep for ayah content
|
||||
def grep(res)
|
||||
|
@ -14,16 +18,10 @@ def grep(res)
|
|||
el.text.gsub(/[0-9]/, "")
|
||||
end
|
||||
|
||||
##
|
||||
# CLI parser
|
||||
def parse_cli(argv)
|
||||
Quran::JSON::Pull.cli(argv)
|
||||
end
|
||||
|
||||
##
|
||||
# main
|
||||
def main(argv)
|
||||
cmd = Quran::JSON::Pull.new parse_cli(argv)
|
||||
cmd = Cmd::Pull.new(argv)
|
||||
cmd.keepalive do
|
||||
1.upto(114) do |surah_no|
|
||||
if cmd.keep?(surah_no)
|
||||
|
@ -32,7 +30,7 @@ def main(argv)
|
|||
cmd.update(surah_no)
|
||||
else
|
||||
rows = [nil]
|
||||
ayah_count = cmd.metadata[surah_no].ayahs
|
||||
ayah_count = cmd.metadata[surah_no - 1].ayahs
|
||||
1.upto(ayah_count) do |ayah_no|
|
||||
res = cmd.pull_ayah(surah_no, ayah_no)
|
||||
rows.push([ayah_no, grep(res)])
|
||||
|
|
|
@ -6,6 +6,10 @@ require File.join(lib_dir, "quran", "json")
|
|||
require "optparse"
|
||||
require "nokogiri"
|
||||
|
||||
##
|
||||
# Provide short access to 'Quran::JSON::Cmd::Pull'
|
||||
include Quran::JSON
|
||||
|
||||
##
|
||||
# Grep for ayah content
|
||||
def grep(res)
|
||||
|
@ -15,16 +19,10 @@ def grep(res)
|
|||
html.css(sel).map { _1.text.strip.gsub(/^[0-9]+\.\s*/, "") }
|
||||
end
|
||||
|
||||
##
|
||||
# CLI parser
|
||||
def parse_cli(argv)
|
||||
Quran::JSON::Pull.cli(argv)
|
||||
end
|
||||
|
||||
##
|
||||
# main
|
||||
def main(argv)
|
||||
cmd = Quran::JSON::Pull.new parse_cli(argv)
|
||||
cmd = Cmd::Pull.new(argv)
|
||||
cmd.keepalive do
|
||||
1.upto(114) do |surah_no|
|
||||
if cmd.keep?(surah_no)
|
||||
|
|
Loading…
Reference in a new issue