locabulary 0.2.0 → 0.3.0
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/.hound.yml +46 -0
- data/.rspec +1 -0
- data/.rubocop_todo.yml +21 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/README.md +8 -1
- data/Rakefile +37 -4
- data/data/administrative_units.json +374 -806
- data/lib/locabulary/exceptions.rb +25 -0
- data/lib/locabulary/items/administrative_unit.rb +65 -0
- data/lib/locabulary/items/base.rb +105 -0
- data/lib/locabulary/items.rb +32 -0
- data/lib/locabulary/json_creator.rb +105 -0
- data/lib/locabulary/schema.rb +11 -20
- data/lib/locabulary/version.rb +3 -0
- data/lib/locabulary.rb +67 -88
- data/locabulary.gemspec +8 -2
- data/script/update_data_files.sh +7 -2
- metadata +97 -4
- data/script/json_creator.rb +0 -129
@@ -0,0 +1,25 @@
|
|
1
|
+
module Locabulary
|
2
|
+
# Container for all exceptions in the Locabulary ecosystem
|
3
|
+
module Exceptions
|
4
|
+
class RuntimeError < ::RuntimeError
|
5
|
+
end
|
6
|
+
|
7
|
+
# There is a problem with the hierarchy; A child is being defined without a defined parent.
|
8
|
+
class MissingHierarchicalParentError < RuntimeError
|
9
|
+
attr_reader :predicate_name, :error
|
10
|
+
def initialize(predicate_name, error)
|
11
|
+
@predicate_name = predicate_name
|
12
|
+
@error = error
|
13
|
+
super("Expected #{predicate_name.inspect} to have a welformed tree. Error: #{error}")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# There is a problem with the hierarchy; Instead of a tree we have a multitude of trees
|
18
|
+
class TooManyHierarchicalRootsError < RuntimeError
|
19
|
+
attr_reader :predicate_name, :roots
|
20
|
+
def initialize(predicate_name, roots)
|
21
|
+
super("Expected fewer root slugs for #{predicate_name.inspect}. Roots encountered: #{roots.inspect}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'locabulary/exceptions'
|
2
|
+
require 'locabulary/items/base'
|
3
|
+
|
4
|
+
module Locabulary
|
5
|
+
module Items
|
6
|
+
# Responsible for exposing the data structure logic of the Administrative Units
|
7
|
+
#
|
8
|
+
# @see ./data/administrative_units.json
|
9
|
+
class AdministrativeUnit < Locabulary::Items::Base
|
10
|
+
configure do |config|
|
11
|
+
config.attribute_names = [
|
12
|
+
:predicate_name, :term_label, :term_uri, :description, :grouping, :classification, :affiliation, :default_presentation_sequence,
|
13
|
+
:homepage, :activated_on, :deactivated_on
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
# [String] What is the URL of the homepage. Please note the term_uri is reserved for something that is more resolvable by machines.
|
18
|
+
# And while the homepage may look resolvable, it is not as meaningful for longterm preservation.
|
19
|
+
attr_reader :homepage
|
20
|
+
attr_reader :classification
|
21
|
+
attr_reader :grouping
|
22
|
+
attr_reader :affiliation
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_writer :homepage, :classification, :grouping, :affiliation
|
27
|
+
|
28
|
+
public
|
29
|
+
|
30
|
+
def initialize(*args)
|
31
|
+
super
|
32
|
+
@children = []
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :children
|
36
|
+
|
37
|
+
HIERARCHY_SEPARATOR = '::'.freeze
|
38
|
+
def slugs
|
39
|
+
term_label.split(HIERARCHY_SEPARATOR)
|
40
|
+
end
|
41
|
+
|
42
|
+
def parent_slugs
|
43
|
+
slugs[0..-2]
|
44
|
+
end
|
45
|
+
|
46
|
+
def parent_term_label
|
47
|
+
parent_slugs.join(HIERARCHY_SEPARATOR)
|
48
|
+
end
|
49
|
+
|
50
|
+
def root_slug
|
51
|
+
slugs[0]
|
52
|
+
end
|
53
|
+
|
54
|
+
def selectable?
|
55
|
+
children.count == 0
|
56
|
+
end
|
57
|
+
|
58
|
+
def selectable_label
|
59
|
+
slugs[1..-1].join(HIERARCHY_SEPARATOR)
|
60
|
+
end
|
61
|
+
|
62
|
+
alias selectable_id id
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'dry/configurable'
|
2
|
+
module Locabulary
|
3
|
+
module Items
|
4
|
+
# A singular item in the controlled vocubulary.
|
5
|
+
# @see https://en.wikipedia.org/wiki/Resource_Description_Framework
|
6
|
+
class Base
|
7
|
+
extend Dry::Configurable
|
8
|
+
|
9
|
+
setting :attribute_names, [
|
10
|
+
:predicate_name, :term_label, :term_uri, :deposit_label, :description, :grouping, :affiliation, :default_presentation_sequence,
|
11
|
+
:activated_on, :deactivated_on
|
12
|
+
].freeze
|
13
|
+
|
14
|
+
def attribute_names
|
15
|
+
self.class.config.attribute_names
|
16
|
+
end
|
17
|
+
|
18
|
+
# [String] the trait for a given subject that we are describing by way of the term_label/term_uri
|
19
|
+
attr_reader :predicate_name
|
20
|
+
|
21
|
+
# [String] the human friendly version of the meaning for this given trait
|
22
|
+
# @note For the time being, please regard the term_label as immutable; If you need a modification, deactivate this one and activate a
|
23
|
+
# new one
|
24
|
+
attr_reader :term_label
|
25
|
+
|
26
|
+
# [String] the machine friendly version of the meaning for this given trait
|
27
|
+
# @note For the time being, please regard the term_uri as immutable; If you need a modification, deactivate this one and activate a
|
28
|
+
# new one
|
29
|
+
attr_reader :term_uri
|
30
|
+
|
31
|
+
# [String] a side-car of more exhaustive information related to this particular term
|
32
|
+
attr_reader :description
|
33
|
+
|
34
|
+
# [Date] When was this particular item activated
|
35
|
+
attr_reader :activated_on
|
36
|
+
|
37
|
+
# [Date] When was this particular item deactivated
|
38
|
+
attr_reader :deactivated_on
|
39
|
+
|
40
|
+
# [Integer, nil] What is the order in which
|
41
|
+
# @see Locabulary::Item#presentation_sequence for details on how this is calculated
|
42
|
+
attr_reader :default_presentation_sequence
|
43
|
+
|
44
|
+
# @deprecated
|
45
|
+
attr_reader :deposit_label
|
46
|
+
|
47
|
+
# @deprecated
|
48
|
+
attr_reader :grouping
|
49
|
+
|
50
|
+
# @deprecated
|
51
|
+
attr_reader :affiliation
|
52
|
+
|
53
|
+
def initialize(attributes = {})
|
54
|
+
attribute_names.each do |key|
|
55
|
+
value = attributes.fetch(key) { attributes.fetch(key.to_s, nil) }
|
56
|
+
send("#{key}=", value)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_h
|
61
|
+
attribute_names.each_with_object({}) do |key, mem|
|
62
|
+
mem[key.to_s] = send(key) unless send(key).to_s.strip == ''
|
63
|
+
mem
|
64
|
+
end
|
65
|
+
end
|
66
|
+
alias as_json to_h
|
67
|
+
|
68
|
+
def to_persistence_format_for_fedora
|
69
|
+
return term_uri unless term_uri.to_s.strip == ''
|
70
|
+
term_label
|
71
|
+
end
|
72
|
+
alias id to_persistence_format_for_fedora
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
attr_writer(*config.attribute_names)
|
77
|
+
|
78
|
+
def predicate_name=(input)
|
79
|
+
@predicate_name = input.to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
def default_presentation_sequence=(input)
|
83
|
+
@default_presentation_sequence = input.to_s.strip == '' ? nil : input.to_i
|
84
|
+
end
|
85
|
+
|
86
|
+
public
|
87
|
+
|
88
|
+
include Comparable
|
89
|
+
|
90
|
+
def <=>(other)
|
91
|
+
predicate_name_sort = predicate_name <=> other.predicate_name
|
92
|
+
return predicate_name_sort unless predicate_name_sort == 0
|
93
|
+
presentation_sequence_sort = presentation_sequence <=> other.presentation_sequence
|
94
|
+
return presentation_sequence_sort unless presentation_sequence_sort == 0
|
95
|
+
term_label <=> other.term_label
|
96
|
+
end
|
97
|
+
|
98
|
+
SORT_SEQUENCE_FOR_NIL = 100_000_000
|
99
|
+
private_constant :SORT_SEQUENCE_FOR_NIL
|
100
|
+
def presentation_sequence
|
101
|
+
default_presentation_sequence || SORT_SEQUENCE_FOR_NIL
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'locabulary/items/base'
|
2
|
+
require 'hanami/utils/string'
|
3
|
+
module Locabulary
|
4
|
+
# A container for the various types of Locabulary Items
|
5
|
+
module Items
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# @api public
|
9
|
+
# @since 0.2.1
|
10
|
+
def build(options = {})
|
11
|
+
predicate_name = options.fetch(:predicate_name) { options.fetch('predicate_name') }
|
12
|
+
builder_for(predicate_name: predicate_name).call(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @api public
|
16
|
+
# @since 0.2.1
|
17
|
+
#
|
18
|
+
# @param options [Hash]
|
19
|
+
# @option predicate_name [String] Used for lookup of the correct Locabulary::Item type
|
20
|
+
def builder_for(options = {})
|
21
|
+
predicate_name = options.fetch(:predicate_name)
|
22
|
+
possible_class_name_for_predicate_name = Hanami::Utils::String.new(predicate_name).singularize.classify
|
23
|
+
klass = begin
|
24
|
+
Items.const_get(possible_class_name_for_predicate_name)
|
25
|
+
rescue NameError
|
26
|
+
Items::Base
|
27
|
+
end
|
28
|
+
klass.method(:new)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
require 'locabulary/items/administrative_unit'
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require "google/api_client"
|
2
|
+
require "google_drive"
|
3
|
+
require 'highline/import'
|
4
|
+
require 'locabulary'
|
5
|
+
require 'locabulary/items'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
module Locabulary
|
9
|
+
# Responsible for capturing predicate_name from a given source and writing it to a file
|
10
|
+
class JsonCreator
|
11
|
+
def initialize(document_key, predicate_name, data_fetcher = default_data_fetcher)
|
12
|
+
@document_key = document_key
|
13
|
+
@predicate_name = predicate_name
|
14
|
+
@output_filepath = Locabulary.filename_for_predicate_name(predicate_name: predicate_name)
|
15
|
+
@data_fetcher = data_fetcher
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :document_key, :predicate_name, :data_fetcher, :spreadsheet_data, :json_data
|
19
|
+
attr_accessor :output_filepath
|
20
|
+
|
21
|
+
def create_or_update
|
22
|
+
rows = data_fetcher.call(document_key)
|
23
|
+
data = extract_data_from(rows)
|
24
|
+
convert_to_json(data)
|
25
|
+
end
|
26
|
+
|
27
|
+
# :nocov:
|
28
|
+
def write_to_file
|
29
|
+
File.open(output_filepath, "w") do |f|
|
30
|
+
f.puts json_data
|
31
|
+
end
|
32
|
+
end
|
33
|
+
# :nocov:
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def extract_data_from(rows)
|
38
|
+
spreadsheet_data = []
|
39
|
+
header = rows[0]
|
40
|
+
rows[1..-1].each do |row|
|
41
|
+
# The activated_on is a present hack reflecting a previous value
|
42
|
+
row_data = { "predicate_name" => predicate_name, "activated_on" => "2015-07-22", "default_presentation_sequence" => nil }
|
43
|
+
row.each_with_index do |cell, index|
|
44
|
+
row_data[header[index]] = cell unless cell.to_s.strip == ''
|
45
|
+
end
|
46
|
+
spreadsheet_data << row_data
|
47
|
+
end
|
48
|
+
spreadsheet_data
|
49
|
+
end
|
50
|
+
|
51
|
+
def default_data_fetcher
|
52
|
+
->(document_key) { GoogleSpreadsheet.new(document_key).all_rows }
|
53
|
+
end
|
54
|
+
|
55
|
+
def convert_to_json(data)
|
56
|
+
json_array = data.map do |row|
|
57
|
+
Locabulary::Items.build(row).to_h
|
58
|
+
end
|
59
|
+
@json_data = JSON.pretty_generate("predicate_name" => predicate_name, "values" => json_array)
|
60
|
+
end
|
61
|
+
|
62
|
+
# :nocov:
|
63
|
+
# Responsible for interacting with Google Sheets and retrieiving relevant information
|
64
|
+
class GoogleSpreadsheet
|
65
|
+
attr_reader :access_token, :document_key, :session
|
66
|
+
|
67
|
+
private :session
|
68
|
+
|
69
|
+
def initialize(document_key)
|
70
|
+
@document_key = document_key
|
71
|
+
configure_oauth!
|
72
|
+
@session = GoogleDrive.login_with_oauth(access_token)
|
73
|
+
end
|
74
|
+
|
75
|
+
def configure_oauth!
|
76
|
+
client = Google::APIClient.new
|
77
|
+
auth = client.authorization
|
78
|
+
auth.client_id = client_secrets.fetch('client_id')
|
79
|
+
auth.client_secret = client_secrets.fetch('client_secret')
|
80
|
+
auth.scope = ["https://www.googleapis.com/auth/drive.readonly"]
|
81
|
+
auth.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
|
82
|
+
puts "\n Open the following URL, login with your credentials and get the authorization code \n\n #{auth.authorization_uri}\n\n"
|
83
|
+
auth.code = ask('Authorization Code: ')
|
84
|
+
auth.fetch_access_token!
|
85
|
+
@access_token = auth.access_token
|
86
|
+
end
|
87
|
+
|
88
|
+
def all_rows
|
89
|
+
session.spreadsheet_by_key(document_key).worksheets[0].rows
|
90
|
+
end
|
91
|
+
|
92
|
+
def client_secrets
|
93
|
+
@secrets ||= YAML.load(File.open(File.join(secrets_path)))
|
94
|
+
end
|
95
|
+
|
96
|
+
def secrets_path
|
97
|
+
if File.exist? File.join(File.dirname(__FILE__), '../../config/client_secrets.yml')
|
98
|
+
File.join(File.dirname(__FILE__), '../../config/client_secrets.yml')
|
99
|
+
else
|
100
|
+
File.join(File.dirname(__FILE__), '../../config/client_secrets.example.yml')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/locabulary/schema.rb
CHANGED
@@ -2,26 +2,17 @@ require 'dry/validation'
|
|
2
2
|
require 'dry/validation/schema'
|
3
3
|
|
4
4
|
module Locabulary
|
5
|
-
|
6
|
-
|
7
|
-
key(:
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
value.optional(:affiliation) { |affiliation| affiliation.none? | affiliation.str? }
|
17
|
-
value.optional(:default_presentation_sequence) do |default_presentation_sequence|
|
18
|
-
default_presentation_sequence.none? | default_presentation_sequence.int?
|
19
|
-
end
|
20
|
-
value.key(:activated_on) { |activated_on| activated_on.format?(/\A\d{4}-\d{2}-\d{2}\Z/) }
|
21
|
-
value.optional(:deactivated_on) { |deactivated_on| deactivated_on.none? | deactivated_on.format?(/\A\d{4}-\d{2}-\d{2}\Z/) }
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
5
|
+
# Responsible for providing a defined and clear schema for each of the locabulary items.
|
6
|
+
Schema = Dry::Validation.Schema do
|
7
|
+
key(:predicate_name).required(format?: /\A[a-z_]+\Z/)
|
8
|
+
key(:values).each do
|
9
|
+
key(:term_label).required(:str?)
|
10
|
+
optional(:description).maybe(:str?)
|
11
|
+
optional(:grouping).maybe(:str?)
|
12
|
+
optional(:affiliation).maybe(:str?)
|
13
|
+
optional(:default_presentation_sequence).maybe(:int?)
|
14
|
+
key(:activated_on).required(format?: /\A\d{4}-\d{2}-\d{2}\Z/)
|
15
|
+
optional(:deactivated_on).maybe(format?: /\A\d{4}-\d{2}-\d{2}\Z/)
|
25
16
|
end
|
26
17
|
end
|
27
18
|
end
|
data/lib/locabulary.rb
CHANGED
@@ -1,43 +1,12 @@
|
|
1
1
|
require 'date'
|
2
2
|
require 'json'
|
3
|
+
require 'locabulary/exceptions'
|
4
|
+
require 'locabulary/items'
|
3
5
|
|
4
6
|
# @since 0.1.0
|
5
7
|
module Locabulary
|
6
|
-
VERSION='0.2.0'.freeze
|
7
8
|
DATA_DIRECTORY = File.expand_path("../../data/", __FILE__).freeze
|
8
9
|
|
9
|
-
class RuntimeError < ::RuntimeError
|
10
|
-
end
|
11
|
-
|
12
|
-
class Item
|
13
|
-
include Comparable
|
14
|
-
ATTRIBUTE_NAMES = [:predicate_name, :term_label, :term_uri, :deposit_label, :description, :grouping, :affiliation, :default_presentation_sequence, :activated_on, :deactivated_on].freeze
|
15
|
-
|
16
|
-
attr_reader(*ATTRIBUTE_NAMES)
|
17
|
-
|
18
|
-
def initialize(attributes={})
|
19
|
-
ATTRIBUTE_NAMES.each do |key|
|
20
|
-
value = attributes.fetch(key) { attributes.fetch(key.to_s, nil) }
|
21
|
-
send("#{key}=", value)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
SORT_SEQUENCE_FOR_NIL = 100_000_000
|
26
|
-
def <=>(other)
|
27
|
-
value = presentation_sequence <=> other.presentation_sequence
|
28
|
-
return value unless value == 0
|
29
|
-
term_label <=> other.term_label
|
30
|
-
end
|
31
|
-
|
32
|
-
def presentation_sequence
|
33
|
-
default_presentation_sequence || SORT_SEQUENCE_FOR_NIL
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
attr_writer(*ATTRIBUTE_NAMES)
|
39
|
-
end
|
40
|
-
|
41
10
|
module_function
|
42
11
|
|
43
12
|
# @api public
|
@@ -50,25 +19,68 @@ module Locabulary
|
|
50
19
|
def active_items_for(options = {})
|
51
20
|
predicate_name = options.fetch(:predicate_name)
|
52
21
|
as_of = options.fetch(:as_of) { Date.today }
|
22
|
+
builder = Items.builder_for(predicate_name: predicate_name)
|
53
23
|
active_cache[predicate_name] ||= begin
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
24
|
+
collector = []
|
25
|
+
with_active_extraction_for(predicate_name, as_of) do |data|
|
26
|
+
collector << builder.call(data.merge('predicate_name' => predicate_name))
|
27
|
+
end
|
28
|
+
collector.sort
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @api public
|
33
|
+
# @since 0.2.0
|
34
|
+
def active_hierarchical_root(options = {})
|
35
|
+
predicate_name = options.fetch(:predicate_name)
|
36
|
+
as_of = options.fetch(:as_of) { Date.today }
|
37
|
+
builder = Items.builder_for(predicate_name: predicate_name)
|
38
|
+
active_hierarchical_root_cache[predicate_name] ||= begin
|
39
|
+
items = []
|
40
|
+
hierarchy_graph_keys = {}
|
41
|
+
top_level_slugs = Set.new
|
42
|
+
with_active_extraction_for(predicate_name, as_of) do |data|
|
43
|
+
item = builder.call(data.merge('predicate_name' => predicate_name))
|
44
|
+
items << item
|
45
|
+
top_level_slugs << item.root_slug
|
46
|
+
hierarchy_graph_keys[item.term_label] = item
|
47
|
+
end
|
48
|
+
associate_parents_and_childrens_for(hierarchy_graph_keys, items, predicate_name)
|
49
|
+
raise Exceptions::TooManyHierarchicalRootsError.new(predicate_name, top_level_slugs.to_a) if top_level_slugs.size > 1
|
50
|
+
hierarchy_graph_keys.fetch(top_level_slugs.first)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def associate_parents_and_childrens_for(hierarchy_graph_keys, items, predicate_name)
|
55
|
+
items.each do |item|
|
56
|
+
begin
|
57
|
+
hierarchy_graph_keys.fetch(item.parent_term_label).children << item unless item.parent_slugs.empty?
|
58
|
+
rescue KeyError => error
|
59
|
+
raise Exceptions::MissingHierarchicalParentError.new(predicate_name, error)
|
60
|
+
end
|
70
61
|
end
|
71
62
|
end
|
63
|
+
private :associate_parents_and_childrens_for
|
64
|
+
|
65
|
+
def with_active_extraction_for(predicate_name, as_of)
|
66
|
+
filename = filename_for_predicate_name(predicate_name: predicate_name)
|
67
|
+
json = JSON.parse(File.read(filename))
|
68
|
+
json.fetch('values').each do |data|
|
69
|
+
yield(data) if data_is_active?(data, as_of)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
private :with_active_extraction_for
|
73
|
+
|
74
|
+
def data_is_active?(data, as_of)
|
75
|
+
activated_on = Date.parse(data.fetch('activated_on'))
|
76
|
+
return false unless activated_on < as_of
|
77
|
+
deactivated_on_value = data.fetch('deactivated_on', nil)
|
78
|
+
return true if deactivated_on_value.nil?
|
79
|
+
deactivated_on = Date.parse(deactivated_on_value)
|
80
|
+
return false unless deactivated_on >= as_of
|
81
|
+
true
|
82
|
+
end
|
83
|
+
private :data_is_active?
|
72
84
|
|
73
85
|
# @api public
|
74
86
|
# @since 0.1.0
|
@@ -87,27 +99,12 @@ module Locabulary
|
|
87
99
|
active_items_for(predicate_name: predicate_name).map(&:term_label)
|
88
100
|
end
|
89
101
|
|
90
|
-
|
91
|
-
# @api public
|
92
|
-
def active_nested_labels_for(options = {})
|
93
|
-
format_active_items_for(active_labels_for(options))
|
94
|
-
end
|
95
|
-
|
96
|
-
# @api public
|
97
|
-
def properties_for_uri(options = {})
|
98
|
-
predicate_name = options.fetch(:predicate_name)
|
99
|
-
term_uri = options.fetch(:term_uri)
|
100
|
-
object = active_items_for(predicate_name: predicate_name).detect { |obj| obj.term_uri == term_uri }
|
101
|
-
return object. if object
|
102
|
-
term_uri
|
103
|
-
end
|
104
|
-
|
105
102
|
# @api private
|
106
103
|
def filename_for_predicate_name(options = {})
|
107
104
|
predicate_name = options.fetch(:predicate_name)
|
108
105
|
filename = File.join(DATA_DIRECTORY, "#{File.basename(predicate_name)}.json")
|
109
106
|
return filename if File.exist?(filename)
|
110
|
-
raise Locabulary::RuntimeError, "Unable to find predicate_name: #{predicate_name}"
|
107
|
+
raise Locabulary::Exceptions::RuntimeError, "Unable to find predicate_name: #{predicate_name}"
|
111
108
|
end
|
112
109
|
|
113
110
|
# @api private
|
@@ -116,31 +113,13 @@ module Locabulary
|
|
116
113
|
end
|
117
114
|
|
118
115
|
# @api private
|
119
|
-
def
|
120
|
-
@
|
116
|
+
def active_hierarchical_root_cache
|
117
|
+
@active_hierarchical_root_cache ||= {}
|
121
118
|
end
|
122
119
|
|
123
120
|
# @api private
|
124
|
-
def
|
125
|
-
|
126
|
-
|
127
|
-
key, value = build_key_and_value(item)
|
128
|
-
root[key] ||= []
|
129
|
-
root[key] << value
|
130
|
-
end
|
131
|
-
root
|
132
|
-
end
|
133
|
-
|
134
|
-
# @api private
|
135
|
-
def build_key_and_value(text)
|
136
|
-
text_array = text.split(/(::)/)
|
137
|
-
return text, text if text_array.size == 1
|
138
|
-
return text, text_array.last if text_array.size == 3
|
139
|
-
key = ""
|
140
|
-
(0..(text_array.size-3)).each do |index|
|
141
|
-
key << text_array[index]
|
142
|
-
end
|
143
|
-
value = text_array.last
|
144
|
-
return key, value
|
121
|
+
def reset_active_cache!
|
122
|
+
@active_cache = nil
|
123
|
+
@active_hierarchical_root_cache = nil
|
145
124
|
end
|
146
125
|
end
|
data/locabulary.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'locabulary'
|
4
|
+
require 'locabulary/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "locabulary"
|
@@ -20,12 +20,18 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.license = 'APACHE2'
|
21
21
|
|
22
22
|
spec.add_dependency "json", "~> 1.8"
|
23
|
+
spec.add_dependency "dry-configurable"
|
24
|
+
spec.add_dependency "hanami-utils"
|
23
25
|
|
24
26
|
spec.add_development_dependency "dry-validation"
|
25
27
|
spec.add_development_dependency "bundler"
|
26
|
-
spec.add_development_dependency "
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
spec.add_development_dependency "rspec-its"
|
27
30
|
spec.add_development_dependency "rake", "~> 10.0"
|
28
31
|
spec.add_development_dependency 'google_drive'
|
29
32
|
spec.add_development_dependency 'highline'
|
30
33
|
spec.add_development_dependency "activesupport", "~>4.0"
|
34
|
+
spec.add_development_dependency "rubocop"
|
35
|
+
spec.add_development_dependency "simplecov"
|
36
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
31
37
|
end
|
data/script/update_data_files.sh
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby -U
|
2
|
+
if !ENV.key?('BUNDLE_GEMFILE')
|
3
|
+
$stderr.puts "You need to call the command via `bundle exec script/#{File.basename(__FILE__)}`"
|
4
|
+
$stderr.puts "You will also need to make sure you have valid information in ./config/client_secrets.example.yml."
|
5
|
+
abort(1)
|
6
|
+
end
|
2
7
|
|
3
|
-
|
8
|
+
require 'locabulary/json_creator'
|
4
9
|
|
5
10
|
puts "Updating Administrative Units"
|
6
|
-
json_creator = JsonCreator.new "1oBW5FCTtYXsUi8roBiMRBLFY3dXamhTqy-kiG2rqu5Q", "administrative_units"
|
11
|
+
json_creator = Locabulary::JsonCreator.new "1oBW5FCTtYXsUi8roBiMRBLFY3dXamhTqy-kiG2rqu5Q", "administrative_units"
|
7
12
|
json_creator.create_or_update
|
8
13
|
json_creator.write_to_file
|