tlaw 0.0.2 → 0.1.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -0
- data/CHANGELOG.md +18 -2
- data/README.md +10 -7
- data/examples/demo_base.rb +2 -2
- data/examples/experimental/README.md +3 -0
- data/examples/experimental/afterthedeadline.rb +22 -0
- data/examples/experimental/airvisual.rb +14 -0
- data/examples/experimental/apixu.rb +32 -0
- data/examples/experimental/bing_maps.rb +18 -0
- data/examples/experimental/currencylayer.rb +25 -0
- data/examples/experimental/earthquake.rb +29 -0
- data/examples/experimental/freegeoip.rb +16 -0
- data/examples/experimental/geonames.rb +98 -0
- data/examples/experimental/isfdb.rb +17 -0
- data/examples/experimental/musicbrainz.rb +27 -0
- data/examples/experimental/nominatim.rb +52 -0
- data/examples/experimental/omdb.rb +68 -0
- data/examples/experimental/open_exchange_rates.rb +36 -0
- data/examples/experimental/open_route.rb +27 -0
- data/examples/experimental/open_street_map.rb +16 -0
- data/examples/experimental/quandl.rb +50 -0
- data/examples/experimental/reddit.rb +25 -0
- data/examples/experimental/swapi.rb +27 -0
- data/examples/experimental/tmdb.rb +53 -0
- data/examples/experimental/world_bank.rb +85 -0
- data/examples/experimental/world_bank_climate.rb +77 -0
- data/examples/experimental/wunderground.rb +66 -0
- data/examples/experimental/wunderground_demo.rb +7 -0
- data/examples/forecast_io.rb +16 -16
- data/examples/giphy.rb +4 -4
- data/examples/giphy_demo.rb +1 -1
- data/examples/open_weather_map.rb +64 -60
- data/examples/open_weather_map_demo.rb +4 -4
- data/examples/tmdb_demo.rb +1 -1
- data/examples/urbandictionary_demo.rb +2 -2
- data/lib/tlaw.rb +14 -15
- data/lib/tlaw/api.rb +108 -26
- data/lib/tlaw/api_path.rb +86 -87
- data/lib/tlaw/data_table.rb +15 -10
- data/lib/tlaw/dsl.rb +126 -224
- data/lib/tlaw/dsl/api_builder.rb +47 -0
- data/lib/tlaw/dsl/base_builder.rb +108 -0
- data/lib/tlaw/dsl/endpoint_builder.rb +26 -0
- data/lib/tlaw/dsl/namespace_builder.rb +86 -0
- data/lib/tlaw/endpoint.rb +63 -85
- data/lib/tlaw/formatting.rb +55 -0
- data/lib/tlaw/formatting/describe.rb +86 -0
- data/lib/tlaw/formatting/inspect.rb +52 -0
- data/lib/tlaw/namespace.rb +141 -98
- data/lib/tlaw/param.rb +45 -141
- data/lib/tlaw/param/type.rb +36 -49
- data/lib/tlaw/response_processors.rb +81 -0
- data/lib/tlaw/util.rb +16 -33
- data/lib/tlaw/version.rb +6 -3
- data/tlaw.gemspec +9 -9
- metadata +63 -13
- data/lib/tlaw/param_set.rb +0 -111
- data/lib/tlaw/response_processor.rb +0 -126
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative '../demo_base'
|
2
|
+
#http://docs.themoviedb.apiary.io/#reference/movies/movielatest
|
3
|
+
|
4
|
+
class OMDB < TLAW::API
|
5
|
+
define do
|
6
|
+
base 'http://www.omdbapi.com'
|
7
|
+
param :api_key, field: :apikey, required: true
|
8
|
+
|
9
|
+
SPLIT = ->(v) { v.split(/\s*,\s*/) }
|
10
|
+
|
11
|
+
shared_def :imdb do
|
12
|
+
post_process('imdbRating', &:to_f)
|
13
|
+
post_process('imdbVotes') { |v| v.gsub(',', '').to_i }
|
14
|
+
end
|
15
|
+
|
16
|
+
post_process do |response|
|
17
|
+
response.delete('Response') == 'False' and fail(response['Error'])
|
18
|
+
end
|
19
|
+
|
20
|
+
endpoint :by_id, path: '/?i={imdb_id}' do
|
21
|
+
param :imdb_id, required: true
|
22
|
+
|
23
|
+
param :type, enum: %i[movie series episode]
|
24
|
+
param :year, :to_i, field: :y
|
25
|
+
param :plot, enum: %i[short full]
|
26
|
+
param :tomatoes, enum: [true, false]
|
27
|
+
|
28
|
+
post_process('Released', &Date.method(:parse))
|
29
|
+
post_process('totalSeasons', &:to_i)
|
30
|
+
use_def :imdb
|
31
|
+
end
|
32
|
+
|
33
|
+
endpoint :by_title, path: '/?t={title}' do
|
34
|
+
param :title, required: true
|
35
|
+
|
36
|
+
param :type, enum: %i[movie series episode]
|
37
|
+
param :year, :to_i, field: :y
|
38
|
+
param :plot, enum: %i[short full]
|
39
|
+
param :tomatoes, enum: [true, false]
|
40
|
+
|
41
|
+
post_process('Released', &Date.method(:parse))
|
42
|
+
use_def :imdb
|
43
|
+
|
44
|
+
post_process('Metascore', &:to_i)
|
45
|
+
|
46
|
+
post_process('totalSeasons', &:to_i)
|
47
|
+
|
48
|
+
post_process('Genre', &SPLIT)
|
49
|
+
post_process('Country', &SPLIT)
|
50
|
+
post_process('Writer', &SPLIT)
|
51
|
+
post_process('Actors', &SPLIT)
|
52
|
+
end
|
53
|
+
|
54
|
+
endpoint :search, path: '/?s={search}' do
|
55
|
+
param :search, required: true
|
56
|
+
|
57
|
+
param :type, enum: %i[movie series episode]
|
58
|
+
param :year, :to_i, field: :y
|
59
|
+
param :page, :to_i
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
o = OMDB.new(api_key: ENV.fetch('OMDB'))
|
65
|
+
|
66
|
+
#pp o.by_id("tt0944947")
|
67
|
+
pp o.by_title('Suicide Squad', tomatoes: true, plot: :full)
|
68
|
+
#pp o.search('Game of')['Search'].first
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../demo_base'
|
2
|
+
|
3
|
+
class OpenExchangeRate < TLAW::API
|
4
|
+
define do
|
5
|
+
base 'https://openexchangerates.org/api'
|
6
|
+
|
7
|
+
param :app_id, required: true
|
8
|
+
|
9
|
+
post_process { |h|
|
10
|
+
h['rates'] = h
|
11
|
+
.select { |k, v| k.start_with?('rates.') }
|
12
|
+
.map { |k, v| {'to' => k.sub('rates.', ''), 'rate' => v} }
|
13
|
+
|
14
|
+
h.reject! { |k, v| k.start_with?('rates.') }
|
15
|
+
}
|
16
|
+
post_process 'timestamp', &Time.method(:at)
|
17
|
+
|
18
|
+
endpoint :currencies, path: '/currencies.json'
|
19
|
+
|
20
|
+
endpoint :latest, path: '/latest.json'
|
21
|
+
|
22
|
+
endpoint :historical, path: '/historical/{date}.json' do
|
23
|
+
param :date, :to_date, format: ->(v) { v.strftime('%Y-%m-%d') }
|
24
|
+
end
|
25
|
+
|
26
|
+
endpoint :usage, path: '/usage.json'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
api = OpenExchangeRate.new(app_id: ENV['OPEN_EXCHANGE_RATES'])
|
31
|
+
|
32
|
+
#pp api.latest['rates'].first(3)
|
33
|
+
#pp api.historical(Date.parse('2016-05-01'))['rates'].detect { |r| r['to'] == 'INR' } #, base: 'USD')
|
34
|
+
#pp api.convert(100, 'INR', 'USD')
|
35
|
+
#pp api.usage
|
36
|
+
pp api.latest['rates'].detect { |r| r['to'] == 'INR' }
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative '../demo_base'
|
2
|
+
require 'geo/coord'
|
3
|
+
|
4
|
+
class OpenRouteService < TLAW::API
|
5
|
+
define do
|
6
|
+
base 'https://api.openrouteservice.org'
|
7
|
+
|
8
|
+
param :api_key
|
9
|
+
|
10
|
+
endpoint :directions do
|
11
|
+
post_process { |res|
|
12
|
+
res['route'] = res['routes'].first
|
13
|
+
}
|
14
|
+
param :coordinates, :to_a, keyword: false,
|
15
|
+
format: ->(coords) { coords.map { |c| c.latlng.join(',') }.join('|') }
|
16
|
+
param :profile
|
17
|
+
param :geometry
|
18
|
+
param :geometry_format
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
osm = OpenRouteService.new(api_key: ENV['OPEN_ROUTE_SERVICE'])
|
24
|
+
kharkiv = Geo::Coord.new(50.004444,36.231389)
|
25
|
+
kyiv = Geo::Coord.new(50.450000,30.523333)
|
26
|
+
|
27
|
+
pp osm.directions([kharkiv, kyiv], profile: 'driving-car', geometry_format: 'geojson')['route.segments'].first['steps']
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
$:.unshift 'lib'
|
4
|
+
require 'tlaw'
|
5
|
+
|
6
|
+
class OpenStreetMap < TLAW::API
|
7
|
+
define do
|
8
|
+
base 'http://api.openstreetmap.org/api/0.6'
|
9
|
+
|
10
|
+
endpoint :relation, '/relation/{id}', xml: true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
osm = OpenStreetMap.new
|
15
|
+
|
16
|
+
pp osm.relation(1543125)["osm.relation.tag"].to_a
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
$:.unshift 'lib'
|
4
|
+
require 'tlaw'
|
5
|
+
|
6
|
+
# https://www.quandl.com/docs/api?json#get-data
|
7
|
+
class Quandl < TLAW::API
|
8
|
+
define do
|
9
|
+
base 'https://www.quandl.com/api/v3'
|
10
|
+
|
11
|
+
param :api_key, required: true
|
12
|
+
|
13
|
+
namespace :databases do
|
14
|
+
endpoint :list, path: '.json' do
|
15
|
+
param :per_page, :to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
endpoint :search, '.json?query={query}' do
|
19
|
+
param :query, required: true
|
20
|
+
end
|
21
|
+
|
22
|
+
namespace :[], '/{code}' do
|
23
|
+
endpoint :meta, '.json'
|
24
|
+
endpoint :codes, '/codes.csv'
|
25
|
+
|
26
|
+
namespace :datasets, '/../../datasets/{code}' do
|
27
|
+
endpoint :[], '/{dataset_code}.json' do
|
28
|
+
param :code
|
29
|
+
|
30
|
+
post_process { |h|
|
31
|
+
columns = h['dataset.column_names']
|
32
|
+
h['dataset.data'] = h['dataset.data']
|
33
|
+
.map { |r| columns.zip(r).to_h }
|
34
|
+
}
|
35
|
+
|
36
|
+
post_process_items 'dataset.data' do
|
37
|
+
post_process 'Date', &Date.method(:parse)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
q = Quandl.new(api_key: ENV['QUANDL'])
|
47
|
+
|
48
|
+
#pp q.databases.search('ukraine')['databases'].first
|
49
|
+
pp q.databases['WIKI'].datasets['AAPL', code: 'WIKI']['dataset.data']['Date'].min
|
50
|
+
#pp q.databases['WIKI'].datasets.endpoint(:[]).construct_template
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
$:.unshift 'lib'
|
4
|
+
require 'tlaw'
|
5
|
+
|
6
|
+
class Reddit < TLAW::API
|
7
|
+
define do
|
8
|
+
base 'https://www.reddit.com'
|
9
|
+
|
10
|
+
post_process_items 'data.children' do
|
11
|
+
post_process("data.permalink") { |v| "https://www.reddit.com#{v}" }
|
12
|
+
post_process("data.created", &Time.method(:at))
|
13
|
+
end
|
14
|
+
|
15
|
+
namespace :r, '/r/{subreddit}' do
|
16
|
+
endpoint :new, '/new.json' do
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
r = Reddit.new
|
23
|
+
res = r.r(:ruby).new
|
24
|
+
p res['data.children']['data.ups']
|
25
|
+
p res['data.children']['data.num_comments']
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
$:.unshift 'lib'
|
4
|
+
require 'tlaw'
|
5
|
+
|
6
|
+
class SWAPI < TLAW::API
|
7
|
+
define do
|
8
|
+
base 'http://swapi.co/api'
|
9
|
+
|
10
|
+
namespace :people do
|
11
|
+
endpoint :all, ''
|
12
|
+
endpoint :[], '/{id}/'
|
13
|
+
endpoint :search, '/?search={query}'
|
14
|
+
end
|
15
|
+
|
16
|
+
namespace :species do
|
17
|
+
endpoint :all, ''
|
18
|
+
endpoint :[], '/{id}/'
|
19
|
+
endpoint :search, '/?search={query}'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
s = SWAPI.new
|
25
|
+
|
26
|
+
pp s.people.search('r2')['results'].first
|
27
|
+
pp s.species[2]
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
$:.unshift 'lib'
|
4
|
+
require 'tlaw'
|
5
|
+
|
6
|
+
#http://docs.themoviedb.apiary.io/#reference/movies/movielatest
|
7
|
+
|
8
|
+
class TMDB < TLAW::API
|
9
|
+
define do
|
10
|
+
base 'http://api.themoviedb.org/3'
|
11
|
+
param :api_key, required: true
|
12
|
+
param :language, default: 'en'
|
13
|
+
|
14
|
+
namespace :movies, '/movie' do
|
15
|
+
namespace :[], '/{id}' do
|
16
|
+
param :id, required: true
|
17
|
+
|
18
|
+
endpoint :get, ''
|
19
|
+
|
20
|
+
endpoint :alt_titles
|
21
|
+
|
22
|
+
endpoint :images
|
23
|
+
end
|
24
|
+
|
25
|
+
endpoint :latest
|
26
|
+
endpoint :now_playing do
|
27
|
+
param :page, :to_i, default: 1 # TODO: validate: 1..1000
|
28
|
+
end
|
29
|
+
|
30
|
+
endpoint :upcoming
|
31
|
+
end
|
32
|
+
|
33
|
+
namespace :search do
|
34
|
+
endpoint :movie do
|
35
|
+
param :query, required: true, keyword: false
|
36
|
+
|
37
|
+
#post_process_items 'results', 'release_date', &Date.method(:parse)
|
38
|
+
# TODO: post-process image pathes!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# TODO: should work!
|
43
|
+
#post_process_items 'results', 'release_date', &Date.method(:parse)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
tmdb = TMDB.new(api_key: ENV['TMDB'], language: 'uk')
|
48
|
+
|
49
|
+
#pp tmdb.movies.upcoming['results'].columns(:release_date, :title).to_a
|
50
|
+
#pp tmdb.movies[413898].images
|
51
|
+
#p tmdb.describe
|
52
|
+
#pp tmdb.search.movie('Terminator')['results'].first
|
53
|
+
p tmdb.movies[1187043].get
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
$:.unshift 'lib'
|
4
|
+
require 'tlaw'
|
5
|
+
|
6
|
+
class WorldBank < TLAW::API
|
7
|
+
define do
|
8
|
+
base 'http://api.worldbank.org'
|
9
|
+
|
10
|
+
post_process_replace { |response|
|
11
|
+
if response.is_a?(Array) && response.size == 1 && response.first.is_a?(Hash)
|
12
|
+
response.first
|
13
|
+
elsif response.is_a?(Array) && response.size == 2
|
14
|
+
{'meta' => response.first, 'data' => response.last}
|
15
|
+
else
|
16
|
+
response
|
17
|
+
end
|
18
|
+
}
|
19
|
+
|
20
|
+
post_process_items('data') do
|
21
|
+
post_process 'longitude', &:to_f
|
22
|
+
post_process 'latitude', &:to_f
|
23
|
+
post_process 'value', &:to_f
|
24
|
+
# post_process 'date', &Date.method(:parse)
|
25
|
+
end
|
26
|
+
|
27
|
+
SINGULAR = ->(h) { h['data'].first }
|
28
|
+
|
29
|
+
namespace :countries, '/countries' do
|
30
|
+
endpoint :list, '?format=json' do
|
31
|
+
param :income_level, field: :incomeLevel
|
32
|
+
param :lending_type, field: :lendingType
|
33
|
+
end
|
34
|
+
|
35
|
+
namespace :[], '/{country}' do
|
36
|
+
#param :countries, :to_a, format: ->(c) { c.join(';') }
|
37
|
+
# TODO: splat
|
38
|
+
|
39
|
+
endpoint :get, '?format=json' do
|
40
|
+
#post_process_replace(&SINGULAR)
|
41
|
+
end
|
42
|
+
|
43
|
+
endpoint :indicator, '/indicators/{name}?format=json'
|
44
|
+
# TODO: filter indicator by date
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
namespace :dictionaries, '' do
|
49
|
+
endpoint :topics, '/topics?format=json'
|
50
|
+
#namespace :sources, '/sources?format=json' do
|
51
|
+
|
52
|
+
endpoint :income_levels, '/incomeLevels?format=json'
|
53
|
+
endpoint :lending_types, '/lendingTypes?format=json'
|
54
|
+
|
55
|
+
namespace :indicators do
|
56
|
+
endpoint :list, '?format=json'
|
57
|
+
endpoint :by_topic, '/../topic/{topic_id}/indicator?format=json'
|
58
|
+
endpoint :by_source, '/../source/{source_id}/indicators?format=json'
|
59
|
+
|
60
|
+
endpoint :[], '/{name}?format=json' do
|
61
|
+
post_process_replace(&SINGULAR)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
wb = WorldBank.new
|
69
|
+
|
70
|
+
#pp wb.dictionaries.indicators.list
|
71
|
+
|
72
|
+
#pp wb.sources['data']['name'].reject(&:empty?)
|
73
|
+
#pp wb.countries(income_level: 'LIC')['data']['name'].sort # ['message'].first
|
74
|
+
#pp wb.indicators['NY.GDP.MKTP.CD'] #['data'].first
|
75
|
+
#pp wb.sources[3].indicators #['data']['name']
|
76
|
+
#pp wb.countries['ua'].indicator('NY.GDP.MKTP.CD')['data'].first(5)
|
77
|
+
#pp wb.countries['ua'].get
|
78
|
+
#pp wb.dictionaries.indicators.by_topic(5)['data'].last
|
79
|
+
|
80
|
+
#pp wb.countries.list['data'].to_a
|
81
|
+
#pp wb.countries['us'].indicator("EG.EGY.PRIM.PP.KD")['data'].first(10)
|
82
|
+
|
83
|
+
#pp wb.countries['ukr'].get['data'].first
|
84
|
+
#pp wb.dictionaries.indicators.list
|
85
|
+
pp wb.countries['ukr'].indicator('SP.POP.TOTL')['data'].to_a.first(3)
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
$:.unshift 'lib'
|
4
|
+
require 'tlaw'
|
5
|
+
|
6
|
+
class WorldBankClimate < TLAW::API
|
7
|
+
define do
|
8
|
+
base 'http://climatedataapi.worldbank.org/climateweb/rest/v1'
|
9
|
+
|
10
|
+
{
|
11
|
+
basin: :basinID,
|
12
|
+
country: :country_iso3
|
13
|
+
}.each do |namespace_name, param_name|
|
14
|
+
namespace namespace_name do
|
15
|
+
param param_name, keyword: false, required: true
|
16
|
+
|
17
|
+
{
|
18
|
+
:temperature => 'tas',
|
19
|
+
:precipation => 'pr'
|
20
|
+
}.each do |varname, var|
|
21
|
+
namespace varname, path: '' do
|
22
|
+
{
|
23
|
+
monthly: 'mavg',
|
24
|
+
annual: 'annualavg',
|
25
|
+
monthly_anomaly: 'manom',
|
26
|
+
annual_anomaly: 'annualanom'
|
27
|
+
}.each do |typename, type|
|
28
|
+
endpoint typename, path: "/#{type}/#{var}/{since}/{#{param_name}}.json" do
|
29
|
+
param :since, keyword: true, required: true,
|
30
|
+
enum: {
|
31
|
+
1920 => '1920/1939',
|
32
|
+
1940 => '1940/1959',
|
33
|
+
1960 => '1960/1979',
|
34
|
+
1980 => '1980/1999',
|
35
|
+
2020 => '2020/2039',
|
36
|
+
2040 => '2040/2059',
|
37
|
+
2060 => '2060/2079',
|
38
|
+
2080 => '2080/2099',
|
39
|
+
}
|
40
|
+
|
41
|
+
if typename.to_s.include?('monthly')
|
42
|
+
post_process_replace do |res|
|
43
|
+
{
|
44
|
+
'variable' => res.first['variable'],
|
45
|
+
'fromYear' => res.first['fromYear'],
|
46
|
+
'toYear' => res.first['toYear'],
|
47
|
+
'data' => TLAW::DataTable
|
48
|
+
.from_columns(
|
49
|
+
res.map { |r| r['gcm'] },
|
50
|
+
res.map { |r| r['monthVals'] }
|
51
|
+
)
|
52
|
+
}
|
53
|
+
end
|
54
|
+
else
|
55
|
+
post_process_replace do |res|
|
56
|
+
{
|
57
|
+
'variable' => res.first['variable'],
|
58
|
+
'fromYear' => res.first['fromYear'],
|
59
|
+
'toYear' => res.first['toYear'],
|
60
|
+
'gcm' => res.map { |res| [res['gcm'], res['annualData'].first] }.to_h
|
61
|
+
}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
wbc = WorldBankClimate.new
|
74
|
+
|
75
|
+
pp wbc.country('ukr').temperature.annual(since: 1980)
|
76
|
+
pp wbc.country('ukr').precipation.monthly(since: 1980)['data']
|
77
|
+
|