saper 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/saper.svg)](http://badge.fury.io/rb/saper)
|
13
|
+
[![Build Status](https://travis-ci.org/merimond/saper.svg?branch=master)](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
|