saper 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/Rakefile +6 -6
- data/bin/saper +17 -36
- data/lib/saper.rb +63 -20
- data/lib/saper/actions/append_with.rb +1 -1
- data/lib/saper/actions/convert_to_html.rb +1 -1
- data/lib/saper/actions/convert_to_json.rb +6 -2
- data/lib/saper/actions/convert_to_markdown.rb +1 -1
- data/lib/saper/actions/convert_to_time.rb +38 -1
- data/lib/saper/actions/convert_to_xml.rb +1 -1
- data/lib/saper/actions/create_atom.rb +6 -2
- data/lib/saper/actions/fetch.rb +3 -2
- data/lib/saper/actions/fetch_with_token.rb +18 -0
- data/lib/saper/actions/find.rb +1 -1
- data/lib/saper/actions/find_first.rb +1 -1
- data/lib/saper/actions/get_attribute.rb +7 -2
- data/lib/saper/actions/get_contents.rb +1 -1
- data/lib/saper/actions/get_text.rb +1 -1
- data/lib/saper/actions/nothing.rb +11 -0
- data/lib/saper/actions/prepend_with.rb +2 -2
- data/lib/saper/actions/remove_after.rb +2 -2
- data/lib/saper/actions/remove_before.rb +2 -2
- data/lib/saper/actions/remove_matching.rb +2 -2
- data/lib/saper/actions/remove_tags.rb +1 -1
- data/lib/saper/actions/replace.rb +1 -1
- data/lib/saper/actions/run_recipe.rb +2 -2
- data/lib/saper/actions/run_recipe_and_save.rb +3 -3
- data/lib/saper/actions/save.rb +2 -2
- data/lib/saper/actions/select_matching.rb +2 -2
- data/lib/saper/actions/set_input.rb +1 -1
- data/lib/saper/actions/skip_tags.rb +1 -1
- data/lib/saper/actions/split.rb +1 -1
- data/lib/saper/arguments/attribute.rb +6 -0
- data/lib/saper/arguments/recipe.rb +12 -6
- data/lib/saper/arguments/service.rb +12 -0
- data/lib/saper/arguments/text.rb +1 -0
- data/lib/saper/arguments/timezone.rb +2 -1
- data/lib/saper/arguments/url.rb +12 -0
- data/lib/saper/arguments/variable.rb +2 -1
- data/lib/saper/arguments/xpath.rb +2 -1
- data/lib/saper/core/action.rb +43 -13
- data/lib/saper/core/argument.rb +30 -14
- data/lib/saper/core/browser.rb +29 -28
- data/lib/saper/core/dsl.rb +14 -16
- data/lib/saper/core/error.rb +1 -1
- data/lib/saper/core/item.rb +2 -2
- data/lib/saper/core/keychain.rb +58 -5
- data/lib/saper/core/namespace.rb +15 -18
- data/lib/saper/core/recipe.rb +53 -12
- data/lib/saper/core/result.rb +72 -0
- data/lib/saper/core/runtime.rb +44 -177
- data/lib/saper/core/stack.rb +57 -0
- data/lib/saper/items/atom.rb +18 -1
- data/lib/saper/items/document.rb +39 -19
- data/lib/saper/items/html.rb +52 -7
- data/lib/saper/items/json.rb +19 -1
- data/lib/saper/items/markdown.rb +14 -4
- data/lib/saper/items/nothing.rb +6 -0
- data/lib/saper/items/text.rb +28 -3
- data/lib/saper/items/time.rb +25 -2
- data/lib/saper/items/url.rb +8 -2
- data/lib/saper/items/xml.rb +51 -11
- data/lib/{lib → saper/patches}/mechanize.rb +0 -0
- data/lib/{lib → saper/patches}/nokogiri.rb +0 -0
- data/lib/saper/version.rb +2 -2
- data/spec/actions/append_with_spec.rb +29 -52
- data/spec/actions/convert_to_html_spec.rb +13 -30
- data/spec/actions/convert_to_json_spec.rb +13 -30
- data/spec/actions/convert_to_markdown_spec.rb +17 -19
- data/spec/actions/convert_to_time_spec.rb +25 -43
- data/spec/actions/convert_to_xml_spec.rb +15 -11
- data/spec/actions/create_atom_spec.rb +11 -19
- data/spec/actions/fetch_spec.rb +3 -8
- data/spec/actions/find_first_spec.rb +38 -40
- data/spec/actions/find_spec.rb +23 -39
- data/spec/actions/get_attribute_spec.rb +30 -3
- data/spec/actions/{get_contents.rb → get_contents_spec.rb} +0 -0
- data/spec/actions/{get_text.rb → get_text_spec.rb} +0 -0
- data/spec/actions/nothing_spec.rb +7 -0
- data/spec/actions/prepend_with_spec.rb +31 -18
- data/spec/actions/{remove_after.rb → remove_after_spec.rb} +0 -0
- data/spec/actions/{remove_before.rb → remove_before_spec.rb} +0 -0
- data/spec/actions/remove_matching_spec.rb +7 -0
- data/spec/actions/remove_tags_spec.rb +7 -0
- data/spec/actions/run_recipe_and_save_spec.rb +7 -0
- data/spec/actions/run_recipe_spec.rb +7 -0
- data/spec/arguments/attribute_spec.rb +7 -0
- data/spec/arguments/recipe_spec.rb +7 -0
- data/spec/arguments/text_spec.rb +7 -0
- data/spec/arguments/timezone_spec.rb +7 -0
- data/spec/arguments/variable_spec.rb +7 -0
- data/spec/arguments/xpath_spec.rb +7 -0
- data/spec/core/action_spec.rb +13 -142
- data/spec/core/argument_spec.rb +38 -71
- data/spec/core/browser_spec.rb +18 -3
- data/spec/core/dsl_spec.rb +1 -1
- data/spec/core/item_spec.rb +1 -1
- data/spec/core/namespace_spec.rb +0 -11
- data/spec/core/recipe_spec.rb +54 -77
- data/spec/core/result_spec.rb +7 -0
- data/spec/core/runtime_spec.rb +20 -151
- data/spec/core/stack_spec.rb +7 -0
- data/spec/integration/simple_invalid_spec.rb +39 -0
- data/spec/integration/simple_valid_spec.rb +39 -0
- data/spec/items/atom_spec.rb +6 -1
- data/spec/items/document_spec.rb +93 -15
- data/spec/items/html_spec.rb +45 -28
- data/spec/items/json_spec.rb +10 -10
- data/spec/items/markdown_spec.rb +24 -3
- data/spec/items/nothing_spec.rb +1 -1
- data/spec/items/text_spec.rb +13 -41
- data/spec/items/time_spec.rb +25 -4
- data/spec/items/url_spec.rb +1 -7
- data/spec/items/xml_spec.rb +46 -39
- data/spec/spec_helper.rb +2 -21
- metadata +63 -60
- data/lib/lib/json_search.rb +0 -54
- data/spec/actions/run_recipe_and_save_spec.tmp.rb +0 -52
- data/spec/actions/run_recipe_spec.tmp.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7aba132c13d3bc80c0034121a49cb2c45841a5c2
|
4
|
+
data.tar.gz: 12e4ca23e2d339a1951e2495f7791444160f3daa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ff6858a582e44d4e61682a014e351d688d9b303870b516a897dd48c50ab66efddd42d3077d2cc87470da4cd4173faeefbc13f3375df214353ce1d17869d13f7
|
7
|
+
data.tar.gz: f8cc29550eaa47a9040fbebbf659dddd627b470dfbcd4d2a42998741d5d4aab187b2b49bcfe813279b2e3eff3989be4fdc0ccb36d47e5e3f9b0a63777cdd0414
|
data/README.md
CHANGED
@@ -9,6 +9,9 @@ Common use scenarios:
|
|
9
9
|
- create an RSS feed for a website or a web application
|
10
10
|
- create an API for a website that doesn't have one
|
11
11
|
|
12
|
+
[](http://badge.fury.io/rb/saper)
|
13
|
+
[](https://travis-ci.org/merimond/saper)
|
14
|
+
|
12
15
|
## Installing
|
13
16
|
|
14
17
|
Make sure you have Ruby and RubyGems, then run:
|
data/Rakefile
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler'
|
3
|
-
require '
|
3
|
+
require 'rake/testtask'
|
4
4
|
require 'yard'
|
5
5
|
|
6
6
|
Bundler.require
|
7
7
|
Bundler::GemHelper.install_tasks
|
8
8
|
|
9
|
-
desc "Run
|
10
|
-
|
11
|
-
|
9
|
+
desc "Run tests"
|
10
|
+
Rake::TestTask.new do |t|
|
11
|
+
t.test_files = FileList['spec/**/*_spec.rb']
|
12
12
|
end
|
13
13
|
|
14
14
|
desc "Generate docs"
|
15
15
|
YARD::Rake::YardocTask.new do |t|
|
16
|
-
t.files
|
16
|
+
t.files = ['lib/saper/**/*.rb']
|
17
17
|
end
|
18
18
|
|
19
|
-
task :default => :
|
19
|
+
task :default => :test
|
data/bin/saper
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
require
|
3
|
+
require_relative "../lib/saper"
|
4
|
+
require "trollop"
|
5
5
|
|
6
6
|
opts = Trollop::options do
|
7
7
|
banner <<-EOS
|
@@ -10,51 +10,32 @@ Usage: saper <filename> [options]
|
|
10
10
|
|
11
11
|
Options are ...
|
12
12
|
EOS
|
13
|
-
opt :
|
14
|
-
opt :
|
13
|
+
opt :recipe, "Recipe name", :type => :string
|
14
|
+
opt :input, "Recipe input", :type => :string
|
15
|
+
opt :agent, "User-Agent", :type => :string
|
16
|
+
opt :keychain, "Keychain file", :type => :string
|
15
17
|
end
|
16
18
|
|
17
|
-
|
18
|
-
Trollop::die "
|
19
|
+
if opts[:recipe].nil?
|
20
|
+
Trollop::die "Recipe name missing"
|
19
21
|
end
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
unless File.exists?(path) && File.file?(path)
|
24
|
-
Trollop::die("File not found")
|
23
|
+
unless ARGV.size == 1
|
24
|
+
Trollop::die "Please specify filename"
|
25
25
|
end
|
26
26
|
|
27
27
|
begin
|
28
|
-
|
29
|
-
rescue
|
30
|
-
Trollop::die("File
|
31
|
-
end
|
32
|
-
|
33
|
-
begin
|
34
|
-
space = Saper::Namespace.parse(data)
|
28
|
+
puts Saper.run_from_file(ARGV.first, opts.delete(:recipe), opts.delete(:input), opts).serialize
|
29
|
+
rescue Errno::ENOENT => e
|
30
|
+
Trollop::die("File not found: %s" % ARGV.first)
|
35
31
|
rescue NoMethodError => e
|
36
32
|
Trollop::die("Invalid command: %s" % e.message.match(/`(\w+)'/)[1])
|
37
|
-
end
|
38
|
-
|
39
|
-
if opts[:recipe].nil?
|
40
|
-
if space.run_by_default.nil?
|
41
|
-
Trollop::die("Recipe name undefined")
|
42
|
-
end
|
43
|
-
opts[:recipe] = space.run_by_default
|
44
|
-
end
|
45
|
-
|
46
|
-
begin
|
47
|
-
recipe = space[opts[:recipe]]
|
48
33
|
rescue Saper::RecipeNotFound => e
|
49
|
-
Trollop::die("
|
34
|
+
Trollop::die("Recipe not found: %s" % opts[:input])
|
50
35
|
rescue Saper::ActionNotFound => e
|
51
36
|
Trollop::die("Invalid action: %s" % e.message)
|
52
37
|
rescue Saper::InvalidArgument => e
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
if opts[:input].nil? && recipe.input_required?
|
57
|
-
Trollop::die("No input specified, action requires %s" % recipe.input_required.inspect)
|
38
|
+
Trollop::die("Invalid action argument")
|
39
|
+
rescue Exception => e
|
40
|
+
puts e.backtrace
|
58
41
|
end
|
59
|
-
|
60
|
-
puts recipe.run(opts[:input]).results
|
data/lib/saper.rb
CHANGED
@@ -1,37 +1,80 @@
|
|
1
1
|
module Saper
|
2
2
|
|
3
|
-
|
4
|
-
Dir[File.dirname(__FILE__) + "/" + dir].each { |file| require file }
|
5
|
-
end
|
6
|
-
|
3
|
+
require 'bundler/setup'
|
7
4
|
require 'reverse_markdown'
|
8
5
|
require 'json'
|
9
6
|
require 'vremya'
|
10
7
|
require 'nokogiri'
|
11
8
|
require 'securerandom'
|
12
9
|
require 'mechanize'
|
10
|
+
require 'jpath'
|
13
11
|
|
14
|
-
require_relative "
|
15
|
-
require_relative "
|
16
|
-
require_relative "lib/nokogiri"
|
17
|
-
|
18
|
-
require_relative "saper/version"
|
12
|
+
require_relative "saper/patches/mechanize"
|
13
|
+
require_relative "saper/patches/nokogiri"
|
19
14
|
require_relative "saper/version"
|
20
|
-
|
21
|
-
require_multiple "saper/items/*.rb"
|
22
|
-
require_relative "saper/core/argument"
|
23
|
-
require_multiple "saper/arguments/*.rb"
|
15
|
+
|
24
16
|
require_relative "saper/core/action"
|
25
|
-
|
26
|
-
require_relative "saper/core/
|
27
|
-
require_relative "saper/core/
|
28
|
-
require_relative "saper/core/type"
|
29
|
-
require_relative "saper/core/recipe"
|
17
|
+
require_relative "saper/core/argument"
|
18
|
+
require_relative "saper/core/browser"
|
19
|
+
require_relative "saper/core/dsl"
|
30
20
|
require_relative "saper/core/error"
|
21
|
+
require_relative "saper/core/item"
|
31
22
|
require_relative "saper/core/keychain"
|
32
|
-
require_relative "saper/core/dsl"
|
33
|
-
require_relative "saper/core/browser"
|
34
23
|
require_relative "saper/core/logger"
|
24
|
+
require_relative "saper/core/namespace"
|
25
|
+
require_relative "saper/core/recipe"
|
26
|
+
require_relative "saper/core/result"
|
35
27
|
require_relative "saper/core/runtime"
|
28
|
+
require_relative "saper/core/stack"
|
29
|
+
require_relative "saper/core/type"
|
30
|
+
|
31
|
+
require_relative "saper/arguments/attribute"
|
32
|
+
require_relative "saper/arguments/recipe"
|
33
|
+
require_relative "saper/arguments/service"
|
34
|
+
require_relative "saper/arguments/text"
|
35
|
+
require_relative "saper/arguments/timezone"
|
36
|
+
require_relative "saper/arguments/url"
|
37
|
+
require_relative "saper/arguments/variable"
|
38
|
+
require_relative "saper/arguments/xpath"
|
39
|
+
|
40
|
+
require_relative "saper/items/atom"
|
41
|
+
require_relative "saper/items/document"
|
42
|
+
require_relative "saper/items/html"
|
43
|
+
require_relative "saper/items/json"
|
44
|
+
require_relative "saper/items/markdown"
|
45
|
+
require_relative "saper/items/nothing"
|
46
|
+
require_relative "saper/items/text"
|
47
|
+
require_relative "saper/items/time"
|
48
|
+
require_relative "saper/items/url"
|
49
|
+
require_relative "saper/items/xml"
|
50
|
+
|
51
|
+
require_relative "saper/actions/append_with"
|
52
|
+
require_relative "saper/actions/convert_to_html"
|
53
|
+
require_relative "saper/actions/convert_to_json"
|
54
|
+
require_relative "saper/actions/convert_to_markdown"
|
55
|
+
require_relative "saper/actions/convert_to_time"
|
56
|
+
require_relative "saper/actions/convert_to_xml"
|
57
|
+
require_relative "saper/actions/create_atom"
|
58
|
+
require_relative "saper/actions/fetch"
|
59
|
+
require_relative "saper/actions/fetch_with_token"
|
60
|
+
require_relative "saper/actions/find"
|
61
|
+
require_relative "saper/actions/find_first"
|
62
|
+
require_relative "saper/actions/get_attribute"
|
63
|
+
require_relative "saper/actions/get_contents"
|
64
|
+
require_relative "saper/actions/get_text"
|
65
|
+
require_relative "saper/actions/nothing"
|
66
|
+
require_relative "saper/actions/prepend_with"
|
67
|
+
require_relative "saper/actions/remove_after"
|
68
|
+
require_relative "saper/actions/remove_before"
|
69
|
+
require_relative "saper/actions/remove_matching"
|
70
|
+
require_relative "saper/actions/remove_tags"
|
71
|
+
require_relative "saper/actions/replace"
|
72
|
+
require_relative "saper/actions/run_recipe"
|
73
|
+
require_relative "saper/actions/run_recipe_and_save"
|
74
|
+
require_relative "saper/actions/save"
|
75
|
+
require_relative "saper/actions/select_matching"
|
76
|
+
require_relative "saper/actions/set_input"
|
77
|
+
require_relative "saper/actions/skip_tags"
|
78
|
+
require_relative "saper/actions/split"
|
36
79
|
|
37
80
|
end
|
@@ -6,10 +6,47 @@ module Saper
|
|
6
6
|
argument :text, :optional => true
|
7
7
|
accepts :text, :returns => :time
|
8
8
|
|
9
|
-
run do |input, format, tz|
|
9
|
+
run do |runtime, input, format, tz|
|
10
|
+
tz = nil if tz && tz.empty?
|
10
11
|
input.to_time(format, tz)
|
11
12
|
end
|
12
13
|
|
14
|
+
# Format elements
|
15
|
+
# %Y - Year with century (can be negative, 4 digits at least)
|
16
|
+
# %C - year / 100 (round down. 20 in 2009)
|
17
|
+
# %y - year % 100 (00..99)
|
18
|
+
# %m - Month of the year, zero-padded (01..12)
|
19
|
+
# %-m - Month of the year, no-padded (1..12)
|
20
|
+
# %B - The full month name (``January'')
|
21
|
+
# %^B - Month name uppercased (``JANUARY'')
|
22
|
+
# %b - Abbreviated month name (``Jan'')
|
23
|
+
# %^b - Abbreviated uppercased month (``JAN'')
|
24
|
+
# %d - Day of the month, zero-padded (01..31)
|
25
|
+
# %-d - Day of the month, no-padded (1..31)
|
26
|
+
# %e - Day of the month, blank-padded ( 1..31)
|
27
|
+
# %j - Day of the year (001..366)
|
28
|
+
# %H - Hour of the day, 24-hour clock, zero-padded (00..23)
|
29
|
+
# %k - Hour of the day, 24-hour clock, blank-padded ( 0..23)
|
30
|
+
# %I - Hour of the day, 12-hour clock, zero-padded (01..12)
|
31
|
+
# %l - Hour of the day, 12-hour clock, blank-padded ( 1..12)
|
32
|
+
# %P - Meridian indicator, lowercase (``am'' or ``pm'')
|
33
|
+
# %p - Meridian indicator, uppercase (``AM'' or ``PM'')
|
34
|
+
# %M - Minute of the hour (00..59)
|
35
|
+
# %S - Second of the minute (00..59)
|
36
|
+
# %L - Millisecond of the second (000..999)
|
37
|
+
# %N - Fractional seconds digits, default is 9 digits (nanosecond)
|
38
|
+
# %z - Time zone as hour and minute offset from UTC (e.g. +0900)
|
39
|
+
# %:z - hour and minute offset from UTC with a colon (e.g. +09:00)
|
40
|
+
# %Z - Time zone abbreviation name
|
41
|
+
# %A - The full weekday name (``Sunday'')
|
42
|
+
# %^A - Weekday, uppercased (``SUNDAY'')
|
43
|
+
# %a - Weekday, abbreviated (``Sun'')
|
44
|
+
# %^a - Weekday, uppercased (``SUN'')
|
45
|
+
# %u - Day of the week (Monday is 1, 1..7)
|
46
|
+
# %w - Day of the week (Sunday is 0, 0..6)
|
47
|
+
# %s - Number of seconds since 1970-01-01 00:00:00 UTC.
|
48
|
+
# %Q - Number of milliseconds since 1970-01-01 00:00:00 UTC.
|
49
|
+
|
13
50
|
end
|
14
51
|
end
|
15
52
|
end
|
@@ -4,8 +4,12 @@ module Saper
|
|
4
4
|
|
5
5
|
accepts :anything, :returns => :atom
|
6
6
|
|
7
|
-
run do |input|
|
8
|
-
|
7
|
+
run do |runtime, input|
|
8
|
+
if runtime.is_a?(Runtime)
|
9
|
+
Items::Atom.new(runtime.variables)
|
10
|
+
else
|
11
|
+
raise RuntimeMissing
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
# Overrides default logic
|
data/lib/saper/actions/fetch.rb
CHANGED
@@ -2,11 +2,12 @@ module Saper
|
|
2
2
|
module Actions
|
3
3
|
class Fetch < Action
|
4
4
|
|
5
|
+
accepts :text, :returns => :document
|
5
6
|
accepts :url, :returns => :document
|
6
7
|
|
7
|
-
run do |input|
|
8
|
+
run do |runtime, input|
|
8
9
|
begin
|
9
|
-
browser.get(input)
|
10
|
+
runtime.browser.get(input)
|
10
11
|
rescue SocketError
|
11
12
|
raise(UnreachableURL, input)
|
12
13
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Saper
|
2
|
+
module Actions
|
3
|
+
class FetchWithToken < Action
|
4
|
+
|
5
|
+
argument :url
|
6
|
+
argument :service
|
7
|
+
|
8
|
+
run do |runtime, input, url, service|
|
9
|
+
begin
|
10
|
+
runtime.browser.post_with_bearer_token(url, input.to_native.to_s, runtime.keychain.token(service))
|
11
|
+
rescue SocketError
|
12
|
+
raise(UnreachableURL, input)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/saper/actions/find.rb
CHANGED
@@ -6,8 +6,13 @@ module Saper
|
|
6
6
|
accepts :xml, :returns => :text
|
7
7
|
accepts :html, :returns => :text
|
8
8
|
|
9
|
-
run do |input, name|
|
10
|
-
input[name]
|
9
|
+
run do |runtime, input, name|
|
10
|
+
value = input[name]
|
11
|
+
if value.nil?
|
12
|
+
Items::Nothing.new
|
13
|
+
else
|
14
|
+
Items::Text.new value
|
15
|
+
end
|
11
16
|
end
|
12
17
|
|
13
18
|
end
|