scb 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6a73a1fdb7a6724a94a2721049039fbf08d737fd
4
+ data.tar.gz: 6272df8f28e9a96cf2211a15a2c2e8f361c828ce
5
+ SHA512:
6
+ metadata.gz: c540e8ea2c2539410f591505121f47d086d5d8d952ac56e72d05c0d6f310dc6dddfbf97a81e4588a1ed510ed3875d2f74eac5ac997e91cc8e25eca2212a53278
7
+ data.tar.gz: ee308c40c529f41eb3e696214d148ea30c4fd3ba89eac01f3e7a5e0df32208ff8f7122311fd9ab9de14846e9ed972efcec36052580a3ed474405a1383b317bd4
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ - jruby-19mode
6
+ - rbx-19mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in scb.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Peter Hellberg
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,131 @@
1
+ # SCB
2
+
3
+ A small API client for the SCB API.
4
+
5
+ You probably want to read the [API\_beskrivning.pdf](http://www.scb.se/Grupp/OmSCB/Dokument/API_beskrivning.pdf) (in Swedish)
6
+
7
+ [![Build Status](https://travis-ci.org/peterhellberg/scb.png?branch=master)](https://travis-ci.org/peterhellberg/scb)
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'scb'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install scb
22
+
23
+ ## Usage
24
+
25
+ It is probably a good idea to take a look in `specs`
26
+
27
+ Configuration of the API client is done automatically, but it is also possible to manually compose the objects:
28
+
29
+ ```ruby
30
+ # Manual composition
31
+ config = SCB::API.config.new
32
+ api = SCB::API.new(config)
33
+ db = SCB::DB.new(api)
34
+ table = db.table('ProdbrEl')
35
+
36
+ # Short form
37
+ table = SCB.table('ProdbrEl')
38
+
39
+ # Liquid renewable energy in 2009
40
+ table.query Bransle: 925, Tid: 2009
41
+ ```
42
+
43
+ ### Configuration
44
+
45
+ Nothing needs to be configured out of the box, but you can change the
46
+ `api_host`, `api_name`, `api_version`, `language`, `database`,
47
+ `http_client` and `json_parser` settings like this:
48
+
49
+ ```ruby
50
+ # English config
51
+ config = SCB::API::Config.new do |c|
52
+ c.language = 'en'
53
+ end
54
+
55
+ # You can also pass a block straight to SCB.api
56
+ SCB.api { |c| c.api_host = 'scb.test' }
57
+ ```
58
+
59
+ ### Database
60
+
61
+ The database is divided into levels/sub-levels and tables.
62
+
63
+ The default language is 'sv' but there is also some data unde 'en'
64
+
65
+ ```ruby
66
+ db = SCB.db
67
+
68
+ # The names of All the top levels
69
+ db.levels.map(&:name)
70
+
71
+ # English levels under
72
+ db.level(BO0303')
73
+
74
+ # The English title of LonArb07Privat
75
+ SCB.db.en.table('LonArb07Privat').title
76
+ ```
77
+
78
+ ### Level
79
+
80
+ The database levels can contain sub-levels or tables. You are probably
81
+ more interested in the actual tables and their data.
82
+
83
+ ```ruby
84
+ # All the levels below BO
85
+ SCB.level('BO').levels
86
+
87
+ # All the tables below HE0110A
88
+ SCB.level('HE0110A').tables
89
+ ```
90
+
91
+ ### Table
92
+
93
+ This is probably where you want to spend most of your time.
94
+
95
+ You can ask the table for possible variables in order to construct your query. I’ve implemented a simplified query format along the lines: `Key: value` where value is automatically turned into an Array if you only want a single value.
96
+
97
+ *Note:* Each value is also turned into a string.
98
+
99
+ ```ruby
100
+ # Database table containing data on electricity production
101
+ table = SCB.table('EltillfM')
102
+
103
+ # URI to the API endpoint for the table
104
+ table.uri
105
+
106
+ # The variable codes for the table
107
+ table.variables.map(&:code)
108
+
109
+ # Query: Wind production in January and February of 2013
110
+ table.query Prodslag: "Vind", Tid: ["2013M01", "2013M02"]
111
+
112
+ # Usage of the Internet
113
+ table = SCB.table('LE0108T05')
114
+
115
+ table.query Tid: 2012, Dem: "25-34"
116
+
117
+ # You can also get the result as a png
118
+ filename = '/tmp/internet_usage_2011.png'
119
+ query = { AnvOmr: 80, Tid: 2011, ContentsCode: "LE0108A2" }
120
+
121
+ table.write_png_query(filename, query)
122
+ ```
123
+ *Note:* `write_png_query` will not overwrite existing files.
124
+
125
+ ## Contributing
126
+
127
+ 1. Fork it
128
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
129
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
130
+ 4. Push to the branch (`git push origin my-new-feature`)
131
+ 5. Create new Pull Request
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ require "rake/testtask"
4
+ require "bundler/gem_tasks"
5
+
6
+ task :default => :spec
7
+
8
+ Rake::TestTask.new(:spec) do |t|
9
+ t.test_files = FileList['spec/**/*_spec.rb']
10
+ end
11
+
12
+ desc "Console"
13
+ task :console do
14
+ exec 'pry -r./lib/scb'
15
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ require "scb/api"
4
+ require "scb/db"
5
+ require "scb/http"
6
+ require "scb/version"
7
+
8
+ module SCB
9
+ class << self
10
+ def api(config = nil)
11
+ API.new(config).tap do |a|
12
+ yield(a.config) if block_given?
13
+ end
14
+ end
15
+
16
+ def db(api = nil)
17
+ @db ||= DB.new(api)
18
+ end
19
+
20
+ def level(name, text = nil, api = nil)
21
+ DB::Level.new(name, text, api = nil)
22
+ end
23
+
24
+ def table(name, api = nil)
25
+ DB::Table.new(name, api)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+
3
+ require 'uri'
4
+
5
+ require_relative "api/config"
6
+
7
+ module SCB
8
+ class API
9
+ attr_accessor :config
10
+
11
+ def initialize(config = nil)
12
+ @config = config || API::Config.new
13
+
14
+ yield(@config) if block_given?
15
+ end
16
+
17
+ def get(path = nil)
18
+ response = http_get(path)
19
+
20
+ if response && response.body
21
+ response.body.force_encoding('UTF-8')
22
+ end
23
+ end
24
+
25
+ def get_and_parse(path = nil)
26
+ load_json get(path)
27
+ end
28
+
29
+ def post(path, query)
30
+ response = http_post path, dump_json(query)
31
+ response_body_without_utf8_bom(query, response)
32
+ end
33
+
34
+ def post_and_parse(path, query)
35
+ query.merge!({ response: { format: "json" }})
36
+ load_json post(path, query)
37
+ end
38
+
39
+ def base_url
40
+ config.base_url
41
+ end
42
+
43
+ def uri(endpoint = nil)
44
+ URI.parse("#{base_url}/#{endpoint}")
45
+ end
46
+
47
+ def load_json(doc)
48
+ config.json_parser.load(doc)
49
+ end
50
+
51
+ def dump_json(obj)
52
+ config.json_parser.dump(obj)
53
+ end
54
+
55
+ private
56
+
57
+ def response_body_without_utf8_bom(query, response)
58
+ if query[:response] && query[:response][:format] == "json"
59
+ # Force the response body to be UTF-8
60
+ body = response.body.force_encoding('UTF-8')
61
+
62
+ # Return the body, stripped of the BOM
63
+ body.sub!(/^\xEF\xBB\xBF/, '')
64
+ else
65
+ response.body
66
+ end
67
+ end
68
+
69
+ def http_get(path)
70
+ config.http_client.get(uri(path))
71
+ end
72
+
73
+ def http_post(path, payload)
74
+ config.http_client.post(uri(path), payload)
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require 'json'
4
+
5
+ module SCB
6
+ class API
7
+ class Config
8
+ attr_accessor :api_host, :api_name, :api_version,
9
+ :language, :database, :http_client, :json_parser
10
+
11
+ def initialize
12
+ @api_host = 'api.scb.se'
13
+ @api_name = 'OV0104'
14
+ @api_version = 'v1/doris'
15
+ @language = 'sv'
16
+ @database = 'ssd'
17
+ @http_client = SCB::HTTP
18
+ @json_parser = JSON
19
+
20
+ yield self if block_given?
21
+ end
22
+
23
+ def base_url
24
+ "http://#{api_host}/#{api_name}/#{api_version}/#{language}/#{database}"
25
+ end
26
+
27
+ def self.language(language)
28
+ new { |c| c.language = language }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "db/level"
4
+ require_relative "db/table"
5
+ require_relative "db/variable"
6
+
7
+ module SCB
8
+ class DB
9
+ attr_accessor :api
10
+
11
+ def initialize(api = nil)
12
+ @api = api || SCB.api
13
+ end
14
+
15
+ def levels(klass = Level)
16
+ @levels ||= data.map do |l|
17
+ klass.new(l["id"], l["text"], api)
18
+ end
19
+ end
20
+
21
+ def level(name, text = nil, klass = Level)
22
+ klass.new(name, text, api)
23
+ end
24
+
25
+ def table(name, klass = Table)
26
+ klass.new(name, api)
27
+ end
28
+
29
+ def uri
30
+ api.uri
31
+ end
32
+
33
+ def en
34
+ language('en')
35
+ end
36
+
37
+ def sv
38
+ language('sv')
39
+ end
40
+
41
+ private
42
+
43
+ def data
44
+ api.get_and_parse
45
+ end
46
+
47
+ def language(language_code)
48
+ api.config.language = language_code
49
+ self
50
+ end
51
+
52
+ class InvalidQuery < RuntimeError
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative '../db'
4
+
5
+ module SCB
6
+ class DB
7
+ class Level
8
+ attr_reader :name, :text, :api
9
+
10
+ def initialize(name, text = nil, api = nil)
11
+ @name = name
12
+ @text = text
13
+ @api = api || SCB.api
14
+ end
15
+
16
+ def levels(klass = Level)
17
+ @levels ||= objects_for_type(klass, "l")
18
+ end
19
+
20
+ def tables(klass = Table)
21
+ @tables ||= objects_for_type(klass, "t")
22
+ end
23
+
24
+ def inspect
25
+ name
26
+ end
27
+
28
+ private
29
+
30
+ def objects_for_type(klass, type)
31
+ data.map { |d|
32
+ klass.new(d["id"], api) if d["type"] == type
33
+ }.compact
34
+ end
35
+
36
+ def data
37
+ @data ||= api.get_and_parse(name) || []
38
+ end
39
+ end
40
+ end
41
+ end