wikibase_representable 0.1.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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +18 -0
  3. data/README.md +25 -0
  4. data/Rakefile +10 -0
  5. data/lib/wikibase_representable/model/alias_group_list.rb +16 -0
  6. data/lib/wikibase_representable/model/data_value.rb +25 -0
  7. data/lib/wikibase_representable/model/entity_id.rb +27 -0
  8. data/lib/wikibase_representable/model/entity_id_value.rb +40 -0
  9. data/lib/wikibase_representable/model/item.rb +83 -0
  10. data/lib/wikibase_representable/model/property.rb +64 -0
  11. data/lib/wikibase_representable/model/property_value_snak.rb +34 -0
  12. data/lib/wikibase_representable/model/site_link.rb +28 -0
  13. data/lib/wikibase_representable/model/site_link_list.rb +16 -0
  14. data/lib/wikibase_representable/model/snak_data_value_helper.rb +24 -0
  15. data/lib/wikibase_representable/model/snak_list.rb +16 -0
  16. data/lib/wikibase_representable/model/statement.rb +69 -0
  17. data/lib/wikibase_representable/model/statement_data_value_helper.rb +24 -0
  18. data/lib/wikibase_representable/model/statement_list.rb +24 -0
  19. data/lib/wikibase_representable/model/term.rb +25 -0
  20. data/lib/wikibase_representable/model/term_list.rb +22 -0
  21. data/lib/wikibase_representable/model/time.rb +33 -0
  22. data/lib/wikibase_representable/model/time_value.rb +55 -0
  23. data/lib/wikibase_representable/model.rb +21 -0
  24. data/lib/wikibase_representable/representers/alias_group_list_representer.rb +15 -0
  25. data/lib/wikibase_representable/representers/data_value_representer.rb +15 -0
  26. data/lib/wikibase_representable/representers/entity_id_representer.rb +16 -0
  27. data/lib/wikibase_representable/representers/entity_id_value_representer.rb +18 -0
  28. data/lib/wikibase_representable/representers/item_representer.rb +34 -0
  29. data/lib/wikibase_representable/representers/property_representer.rb +31 -0
  30. data/lib/wikibase_representable/representers/property_value_snak_representer.rb +40 -0
  31. data/lib/wikibase_representable/representers/site_link_list_representer.rb +17 -0
  32. data/lib/wikibase_representable/representers/site_link_representer.rb +16 -0
  33. data/lib/wikibase_representable/representers/snak_list_representer.rb +15 -0
  34. data/lib/wikibase_representable/representers/statement_list_representer.rb +15 -0
  35. data/lib/wikibase_representable/representers/statement_representer.rb +28 -0
  36. data/lib/wikibase_representable/representers/term_list_representer.rb +17 -0
  37. data/lib/wikibase_representable/representers/term_representer.rb +19 -0
  38. data/lib/wikibase_representable/representers/time_representer.rb +19 -0
  39. data/lib/wikibase_representable/representers/time_value_representer.rb +17 -0
  40. data/lib/wikibase_representable/representers.rb +18 -0
  41. data/lib/wikibase_representable/version.rb +5 -0
  42. data/lib/wikibase_representable.rb +4 -0
  43. metadata +195 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e29e8b05d572635fd5ef8182cd5528f79cbd31e0526ab8add032ed1a8d06980a
4
+ data.tar.gz: a9ef980b43682ebf929e17d66890af6262d0598903b6db8cadefcfe31b7b30ca
5
+ SHA512:
6
+ metadata.gz: 4e357579f5a6a17f7d3a707faa4704e3939009205157d22d445fc7ec5624db33cfabf27cd17e404e18cd5e9f71707b771cb0a8f1014a33f5ed3823cfca3e8d47
7
+ data.tar.gz: 69001ea25cea8f373d3ddfb503ee6a2f3b56404ea58b7064cb3b8d1775c9a3f4b2861cb6261d9a91fe748cb691e8c3919c9eb56038fb5e81bbe605f1dfe81cd9
data/.rubocop.yml ADDED
@@ -0,0 +1,18 @@
1
+ require:
2
+ - rubocop-rake
3
+ - rubocop-rspec
4
+
5
+ AllCops:
6
+ NewCops: enable
7
+ Gemspec/DevelopmentDependencies:
8
+ EnforcedStyle: gemspec
9
+ Metrics/AbcSize:
10
+ Enabled: false
11
+ Metrics/CyclomaticComplexity:
12
+ Enabled: false
13
+ Metrics/ParameterLists:
14
+ Enabled: false
15
+ RSpec/MultipleMemoizedHelpers:
16
+ Enabled: false
17
+ Style/SafeNavigationChainLength:
18
+ Enabled: false
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # wikibase_representable
2
+
3
+ Provides Wikibase data model classes and support (by way of [representable](https://rubygems.org/gems/representable)) for serializing and deserializing Wikibase data objects to and from JSON.
4
+
5
+ ## Install
6
+ ```sh
7
+ bundle install
8
+ ```
9
+
10
+ ## Example usage
11
+ ```ruby
12
+ # Deserialize an object from JSON
13
+ json = '{"type":"item","id":"Q42","labels":{"en":{"language":"en","value":"Douglas Adams"}}}'
14
+ item = ItemRepresenter.new(Item.new).from_json(json)
15
+ # => #<WikibaseRepresentable::Model::Item:0x0000000...
16
+
17
+ # Serialize an object to JSON
18
+ json = ItemRepresenter.new(item).to_json
19
+ # => "{\"type\":\"item\",\"id\":\"Q42\"...
20
+ ```
21
+
22
+ ## Test (run RSpec and RuboCop)
23
+ ```sh
24
+ bundle exec rake
25
+ ```
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new(:rubocop)
9
+
10
+ task default: %i[spec rubocop]
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Wraps a hash of Term arrays keyed by language code.
6
+ class AliasGroupList < Hash
7
+ def aliases_for_language(language_code)
8
+ fetch(language_code, nil)
9
+ end
10
+
11
+ def aliases_for_language?(language_code)
12
+ key?(language_code)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Object that represents a single data value.
6
+ class DataValue
7
+ attr_accessor :type, :value
8
+
9
+ def initialize(type: nil, value: nil)
10
+ @type = type
11
+ @value = value
12
+ end
13
+
14
+ def ==(other)
15
+ other.is_a?(self.class) &&
16
+ other.type == type &&
17
+ other.value == value
18
+ end
19
+
20
+ def eql?(other)
21
+ self == other
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Data value representing an entity ID data value
6
+ class EntityId
7
+ attr_accessor :id, :numeric_id, :entity_type
8
+
9
+ def initialize(id: nil, numeric_id: nil, entity_type: nil)
10
+ @id = id
11
+ @numeric_id = numeric_id
12
+ @entity_type = entity_type
13
+ end
14
+
15
+ def ==(other)
16
+ other.is_a?(self.class) &&
17
+ id == other.id &&
18
+ entity_type == other.entity_type &&
19
+ numeric_id == other.numeric_id
20
+ end
21
+
22
+ def eql?(other)
23
+ self == other
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wikibase_representable/model/data_value'
4
+
5
+ module WikibaseRepresentable
6
+ module Model
7
+ # Data value representing an entity ID data value
8
+ class EntityIdValue < DataValue
9
+ TYPE = 'wikibase-entityid'
10
+
11
+ def initialize(value: nil)
12
+ super(type: TYPE, value: value)
13
+ end
14
+
15
+ def id
16
+ @value.id
17
+ end
18
+
19
+ def entity_type
20
+ @value.entity_type
21
+ end
22
+
23
+ def numeric_id
24
+ @value.numeric_id
25
+ end
26
+
27
+ def ==(other)
28
+ other.is_a?(self.class) &&
29
+ type == other.type &&
30
+ id == other.id &&
31
+ entity_type == other.entity_type &&
32
+ numeric_id == other.numeric_id
33
+ end
34
+
35
+ def eql?(other)
36
+ self == other
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wikibase_representable/model/alias_group_list'
4
+ require 'wikibase_representable/model/site_link_list'
5
+ require 'wikibase_representable/model/statement_list'
6
+ require 'wikibase_representable/model/term_list'
7
+ require 'wikibase_representable/model/term'
8
+
9
+ module WikibaseRepresentable
10
+ module Model
11
+ # Represents a single Wikibase item.
12
+ # See https://www.mediawiki.org/wiki/Wikibase/DataModel#Items
13
+ class Item
14
+ ENTITY_TYPE = 'item'
15
+
16
+ attr_accessor :type, :id, :labels, :descriptions, :alias_groups, :site_links, :statements
17
+
18
+ def initialize(type: ENTITY_TYPE,
19
+ id: nil,
20
+ labels: TermList.new,
21
+ descriptions: TermList.new,
22
+ alias_groups: AliasGroupList.new,
23
+ site_links: SiteLinkList.new,
24
+ statements: StatementList.new)
25
+ @type = type
26
+ @id = id
27
+ @labels = labels
28
+ @descriptions = descriptions
29
+ @alias_groups = alias_groups
30
+ @site_links = site_links
31
+ @statements = statements
32
+ end
33
+
34
+ def label(language_code)
35
+ @labels.value_for_language(language_code)
36
+ end
37
+
38
+ def statements_by_property_id(property_id)
39
+ @statements.statements_by_property_id(property_id)
40
+ end
41
+
42
+ def statements_by_property_id?(property_id)
43
+ @statements.statements_by_property_id?(property_id)
44
+ end
45
+
46
+ def statement_by_property_id(property_id)
47
+ @statements.statements_by_property_id(property_id)&.first
48
+ end
49
+
50
+ def site_link(site_id)
51
+ @site_links.link_for_site(site_id)
52
+ end
53
+
54
+ def link_to_site?(site_id)
55
+ @site_links.link_for_site?(site_id)
56
+ end
57
+
58
+ def empty?
59
+ @labels.empty? && @descriptions.empty? && @alias_groups.empty? && @site_links.empty? && @statements.empty?
60
+ end
61
+
62
+ def ==(other)
63
+ other.is_a?(self.class) &&
64
+ @type == other.type &&
65
+ @id == other.id &&
66
+ @labels == other.labels &&
67
+ @descriptions == other.descriptions &&
68
+ @alias_groups == other.alias_groups &&
69
+ @site_links == other.site_links &&
70
+ @statements == other.statements
71
+ end
72
+
73
+ def eql?(other)
74
+ self == other
75
+ end
76
+
77
+ alias claims statements
78
+ alias claims_by_property_id statements_by_property_id
79
+ alias claims_by_property_id? statements_by_property_id?
80
+ alias claim_by_property_id statement_by_property_id
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wikibase_representable/model/alias_group_list'
4
+ require 'wikibase_representable/model/statement_list'
5
+ require 'wikibase_representable/model/term_list'
6
+ require 'wikibase_representable/model/term'
7
+
8
+ module WikibaseRepresentable
9
+ module Model
10
+ # Represents a single Wikibase property.
11
+ class Property
12
+ ENTITY_TYPE = 'property'
13
+
14
+ attr_accessor :type, :id, :data_type, :labels, :descriptions, :alias_groups, :statements
15
+
16
+ def initialize(type: ENTITY_TYPE,
17
+ id: nil,
18
+ data_type: nil,
19
+ labels: TermList.new,
20
+ descriptions: TermList.new,
21
+ alias_groups: AliasGroupList.new,
22
+ statements: StatementList.new)
23
+ @type = type
24
+ @data_type = data_type
25
+ @id = id
26
+ @labels = labels
27
+ @descriptions = descriptions
28
+ @alias_groups = alias_groups
29
+ @statements = statements
30
+ end
31
+
32
+ def label(language_code, value)
33
+ @labels.term(Term.new(language_code, value))
34
+ end
35
+
36
+ def description(language_code, value)
37
+ @descriptions.term(Term.new(language_code, value))
38
+ end
39
+
40
+ def aliases(language_code, aliases)
41
+ @alias_groups.aliases_for_language(language_code, aliases)
42
+ end
43
+
44
+ def empty?
45
+ @labels.empty? && @descriptions.empty? && @alias_groups.empty? && @statements.empty?
46
+ end
47
+
48
+ def ==(other)
49
+ other.is_a?(self.class) &&
50
+ @type == other.type &&
51
+ @id == other.id &&
52
+ @data_type == other.data_type &&
53
+ @labels == other.labels &&
54
+ @descriptions == other.descriptions &&
55
+ @alias_groups == other.alias_groups &&
56
+ @statements == other.statements
57
+ end
58
+
59
+ def eql?(other)
60
+ self == other
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Class representing a property value snak.
6
+ # See https://www.mediawiki.org/wiki/Wikibase/DataModel#PropertyValueSnak
7
+ class PropertyValueSnak
8
+ include SnakDataValueHelper
9
+
10
+ SNAK_TYPE = 'value'
11
+
12
+ attr_accessor :type, :property_id, :data_value, :hash
13
+
14
+ def initialize(type: SNAK_TYPE, property_id: nil, data_value: nil, hash: nil)
15
+ @type = type
16
+ @property_id = property_id
17
+ @data_value = data_value
18
+ @hash = hash
19
+ end
20
+
21
+ def ==(other)
22
+ other.is_a?(self.class) &&
23
+ other.type == type &&
24
+ other.property_id == property_id &&
25
+ other.data_value == data_value &&
26
+ other.hash == hash
27
+ end
28
+
29
+ def eql?(other)
30
+ self == other
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Value object representing a link to a page on another site.
6
+ class SiteLink
7
+ attr_accessor :site_id, :page_name, :badges
8
+
9
+ def initialize(site_id: nil, page_name: nil, badges: nil)
10
+ @site_id = site_id
11
+ @page_name = page_name
12
+ @badges = badges
13
+ end
14
+
15
+ def ==(other)
16
+ other.is_a?(self.class) &&
17
+ @site_id == other.site_id &&
18
+ @page_name == other.page_name &&
19
+ @badges.size == other.badges.size &&
20
+ @badges & other.badges == @badges
21
+ end
22
+
23
+ def eql?(other)
24
+ self == other
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Hash of SiteLink objects keyed by site id.
6
+ class SiteLinkList < Hash
7
+ def link_for_site(site_id)
8
+ fetch(site_id, nil)
9
+ end
10
+
11
+ def link_for_site?(site_id)
12
+ key?(site_id)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Convenience methods for grabbing values from snaks
6
+ module SnakDataValueHelper
7
+ def value_type?(type)
8
+ main_snak.data_value.is_a?(type)
9
+ end
10
+
11
+ def data_value
12
+ data_value.value
13
+ end
14
+
15
+ def entity_id_value
16
+ data_value&.value&.id
17
+ end
18
+
19
+ def time_value
20
+ data_value&.value&.time
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Hash of property ID => Snak array.
6
+ class SnakList < Hash
7
+ def snaks_by_property_id(property_id)
8
+ fetch(property_id, nil)
9
+ end
10
+
11
+ def snaks_by_property_id?(property_id)
12
+ key?(property_id)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wikibase_representable/model/snak_list'
4
+
5
+ module WikibaseRepresentable
6
+ module Model
7
+ # Class representing a Wikibase statement.
8
+ # See https://www.mediawiki.org/wiki/Wikibase/DataModel#Statements
9
+ class Statement
10
+ include StatementDataValueHelper
11
+
12
+ TYPE = 'statement'
13
+
14
+ RANK_PREFERRED = 'preferred'
15
+ RANK_NORMAL = 'normal'
16
+ RANK_DEPRECATED = 'deprecated'
17
+
18
+ attr_accessor :main_snak, :type, :qualifiers, :qualifiers_order, :guid, :rank
19
+
20
+ def initialize(main_snak: nil,
21
+ type: TYPE,
22
+ qualifiers: nil,
23
+ qualifiers_order: nil,
24
+ guid: nil,
25
+ rank: RANK_NORMAL)
26
+ @main_snak = main_snak
27
+ @type = type
28
+ @qualifiers = qualifiers
29
+ @qualifiers_order = qualifiers_order
30
+ @guid = guid
31
+ @rank = rank
32
+ end
33
+
34
+ def qualifiers?
35
+ !!qualifiers && !qualifiers.empty?
36
+ end
37
+
38
+ def qualifiers_by_property_id?(property_id)
39
+ qualifiers&.snaks_by_property_id?(property_id)
40
+ end
41
+
42
+ def qualifiers_by_property_id(property_id)
43
+ qualifiers&.snaks_by_property_id(property_id)
44
+ end
45
+
46
+ def qualifier_by_property_id(property_id)
47
+ qualifiers_by_property_id(property_id)&.first
48
+ end
49
+
50
+ def property_id
51
+ @main_snak.property_id
52
+ end
53
+
54
+ def ==(other)
55
+ other.is_a?(self.class) &&
56
+ other.type == @type &&
57
+ other.main_snak == @main_snak &&
58
+ other.qualifiers == @qualifiers &&
59
+ other.qualifiers_order == @qualifiers_order &&
60
+ other.rank == @rank &&
61
+ other.guid == @guid
62
+ end
63
+
64
+ def eql?(other)
65
+ self == other
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Convenience methods for grabbing values from statements' main snaks
6
+ module StatementDataValueHelper
7
+ def value_type?(type)
8
+ main_snak.data_value.is_a?(type)
9
+ end
10
+
11
+ def data_value
12
+ main_snak.data_value.value
13
+ end
14
+
15
+ def entity_id_value
16
+ main_snak.data_value.value.id
17
+ end
18
+
19
+ def time_value
20
+ main_snak.data_value.value.time
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Wraps a hash of Statement arrays keyed by entity id.
6
+ class StatementList < Hash
7
+ def statements_by_property_id(property_id)
8
+ fetch(property_id, nil)
9
+ end
10
+
11
+ def statements_by_property_id?(property_id)
12
+ key?(property_id)
13
+ end
14
+
15
+ def statement_by_property_id(property_id)
16
+ statements_by_property_id(property_id)&.first
17
+ end
18
+
19
+ alias claims_by_property_id statements_by_property_id
20
+ alias claims_by_property_id? statements_by_property_id?
21
+ alias claim_by_property_id statement_by_property_id
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Represents a string value specific to a langugage code.
6
+ class Term
7
+ attr_accessor :language_code, :value
8
+
9
+ def initialize(language_code: nil, value: nil)
10
+ @language_code = language_code
11
+ @value = value
12
+ end
13
+
14
+ def ==(other)
15
+ other.is_a?(self.class) &&
16
+ @language_code == other.language_code &&
17
+ @value == other.value
18
+ end
19
+
20
+ def eql?(other)
21
+ self == other
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'wikibase_representable/model/term'
4
+
5
+ module WikibaseRepresentable
6
+ module Model
7
+ # Wraps a hash of Term objects keyed by language code.
8
+ class TermList < Hash
9
+ def term_for_language(language_code)
10
+ fetch(language_code, nil)
11
+ end
12
+
13
+ def value_for_language(language_code)
14
+ term_for_language(language_code)&.value
15
+ end
16
+
17
+ def term_for_language?(language_code)
18
+ key?(language_code)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WikibaseRepresentable
4
+ module Model
5
+ # Represents a point in time.
6
+ class Time
7
+ attr_accessor :time, :time_zone, :before, :after, :precision, :calendar_model
8
+
9
+ def initialize(time: nil, time_zone: nil, before: nil, after: nil, precision: nil, calendar_model: nil)
10
+ @time = time
11
+ @time_zone = time_zone
12
+ @before = before
13
+ @after = after
14
+ @precision = precision
15
+ @calendar_model = calendar_model
16
+ end
17
+
18
+ def ==(other)
19
+ other.is_a?(self.class) &&
20
+ time == other.time &&
21
+ time_zone == other.time_zone &&
22
+ before == other.before &&
23
+ after == other.after &&
24
+ precision == other.precision &&
25
+ calendar_model == other.calendar_model
26
+ end
27
+
28
+ def eql?(other)
29
+ self == other
30
+ end
31
+ end
32
+ end
33
+ end