rubyhexagon 1.1.0 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3b33b5997c2add67eddbfeea3016cc29e5699996b7dc38a2653ed692bbdeb0f
4
- data.tar.gz: d5df5106fef14164a6e33ce3e0b35a80836b2902b299cbc53d574944f32894f6
3
+ metadata.gz: f88455b4dbcc7ad6e9a36d8f377147f71dd116ecce985fcc59d424fc39804ac3
4
+ data.tar.gz: aa44c7453d967144605930ae31899c5851ef7606e38e4de4a2614f6625ffc1bb
5
5
  SHA512:
6
- metadata.gz: a9abec7cf7b10ac58e7c11cf6ad5fb7ed660af4c29153d2cab8082d738345d1f5cc67004d2c3ccc7bf196089a157f0a7f2370f7508309b65a2223df0bb2cfd5b
7
- data.tar.gz: ff325c1d8f244e1ddf40eea8590fa339f5007f848033feb73ef18fe82fe0a5b95db11df3cde327ef2f5583d273eff354707a437e8a2b7d9500ed58f2cb041f89
6
+ metadata.gz: 2073477e49ba4cd8a7abc52d91713365e1eec77dfc9449f9d732c78188e94bd9daf742973a86ee4afd60b5677be6f6c1475672acfc06e777003e392e5fbf80b0
7
+ data.tar.gz: 017dc526b07aeadfecbd128c0578816880fb3145c7bfed57106343b76b0e3444bbd30578c7e2b77ef916b64fe04675132621c40f47d28920b8ea3b1a8563b004
@@ -37,7 +37,7 @@ require 'rubyhexagon/search/tags'
37
37
  # @since 0.4.3
38
38
  module E621
39
39
  MAJOR = 1
40
- MINOR = 1
40
+ MINOR = 2
41
41
  PATCH = 0
42
42
  NAME = 'rubyhexagon'.freeze
43
43
  VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}".freeze
@@ -19,3 +19,9 @@
19
19
  # @author Maxine Michalski
20
20
  # @since 1.0.0
21
21
  class InvalidIDError < StandardError; end
22
+
23
+ # Error class to show that an object misses an important parameter
24
+ #
25
+ # @author Maxine Michalski
26
+ # @since 1.0.0
27
+ class ObjectNotFilledError < StandardError; end
@@ -39,10 +39,12 @@ module E621
39
39
  def initialize(rspec = false)
40
40
  @user_agent = { 'User-Agent' =>
41
41
  "#{E621::NAME}/#{E621::VERSION} (by maxine_red on e621" }
42
- @base = 'https://e621.net'
42
+ @rspec = rspec
43
+ @base = if @rspec || !defined? RSpec then 'https://e621.net'
44
+ else 'spec/data'
45
+ end
43
46
  lock_path = '/tmp/rubyhexagon.lock'
44
47
  @lock_file = File.open(lock_path, 'a')
45
- @rspec = rspec
46
48
  end
47
49
 
48
50
  # @author Maxine Michalski
@@ -58,13 +60,13 @@ module E621
58
60
  # @return [Hash] JSON parsed response.
59
61
  def fetch(noun, action, query)
60
62
  query = query.to_a.map { |q| "#{q.first}=#{q.last}" }.join('&')
63
+ query = "?#{query}" unless query == ''
64
+ uri = "#{@base}/#{noun}/#{action}.json#{query}"
61
65
  lock do
62
66
  if @rspec || !defined? RSpec
63
- JSON.parse(open("#{@base}/#{noun}/#{action}.json?#{query}",
64
- @user_agent).read, symbolize_names: true)
67
+ JSON.parse(open(uri, @user_agent).read, symbolize_names: true)
65
68
  else # In RSpec environment?
66
- JSON.parse(open("spec/data/#{noun}/#{action}.json?#{query}")
67
- .read, symbolize_names: true)
69
+ JSON.parse(open(uri).read, symbolize_names: true)
68
70
  end
69
71
  end
70
72
  end
@@ -69,14 +69,30 @@ module E621
69
69
  posts
70
70
  end
71
71
 
72
+ # @author Maxine Michalski
73
+ #
74
+ # Fetch popular posts by day, week or month
75
+ #
76
+ # @param timespan [Symbol] can be :day, :week or :month
77
+ # @raise ArgumentError if no valid symbol is given
78
+ #
79
+ # @return [Array<Post>]
80
+ def self.popular(timespan = :day)
81
+ unless %i[day week month].include?(timespan)
82
+ raise ArgumentError, "Unknown time span: #{timespan}"
83
+ end
84
+ API.new.fetch('post', "popular_by_#{timespan}", {}).map do |post|
85
+ Post.new(post[:id]).show(post)
86
+ end
87
+ end
88
+
72
89
  # @author Maxine Michalski
73
90
  #
74
91
  # Helper function for deleted posts
75
92
  #
76
93
  # @return [Array<Post>] array of deleted posts
77
94
  def self.fetch_deleted(page)
78
- api = API.new
79
- api.fetch('post', 'deleted_index', page: page).map do |post|
95
+ API.new.fetch('post', 'deleted_index', page: page).map do |post|
80
96
  DeletedPost.new(post[:id], post[:delreason])
81
97
  end
82
98
  end
@@ -88,8 +104,7 @@ module E621
88
104
  #
89
105
  # @return [Array<Post>] array of posts
90
106
  def self.fetch_posts(parameters)
91
- api = API.new
92
- api.fetch('post', 'index', parameters).map do |data|
107
+ API.new.fetch('post', 'index', parameters).map do |data|
93
108
  Post.new(data[:id]).show(data)
94
109
  end
95
110
  end
@@ -33,7 +33,7 @@ module E621
33
33
  # @param name [String] name pattern to search tags with
34
34
  # @param limit [Integer] number of tags to return. This has a hard limit
35
35
  # of 500
36
- # @param after_id [Integer] only look for tags after this ID
36
+ # @param page [Integer] page to retieve
37
37
  #
38
38
  # @return [Array<Tag>] array of tags
39
39
  def self.list(name, limit = 500, page = 1)
@@ -48,18 +48,90 @@ module E621
48
48
  t
49
49
  end
50
50
 
51
+ # @author Maxine Michalski
52
+ #
53
+ # Retrieve information about implicated tags.
54
+ # @param name [String] name pattern to search tags with
55
+ # @param page [Integer] page to retrieve
56
+ #
57
+ # @raise ObjectNotFilledError if no name is present
58
+ #
59
+ # @return [Array<Tag>] array of implicated tags for this tag
60
+ def self.implications(name, page = 1)
61
+ params = { implied_to: name, page: page }
62
+ tags = fetch_implications(params)
63
+ while block_given? && tags != []
64
+ tags.each { |tag| yield tag unless tag.nil? }
65
+ tags = fetch_implications(params)
66
+ params[:page] += 1
67
+ end
68
+ tags.compact
69
+ end
70
+
71
+ # @author Maxine Michalski
72
+ #
73
+ # Retrieve information about aliased tags.
74
+ # @param name [String] name pattern to search tags with
75
+ # @param page [Integer] page to retrieve
76
+ #
77
+ # @raise ObjectNotFilledError if no name is present
78
+ #
79
+ # @return [Array<Tag>] array of implicated tags for this tag
80
+ def self.aliases(name, page = 1)
81
+ params = { aliased_to: name, approved: true, page: page }
82
+ tags = fetch_aliases(params)
83
+ while block_given? && tags != []
84
+ tags.each { |tag| yield tag unless tag.nil? }
85
+ tags = fetch_aliases(params)
86
+ params[:page] += 1
87
+ end
88
+ tags.compact
89
+ end
90
+
51
91
  # @author Maxine Michalski
52
92
  #
53
93
  # Helper function to get Tag data
54
94
  #
55
95
  # @return [Array<Tag>] array of tags
56
96
  def self.fetch_tags(params)
57
- api = API.new
58
- api.fetch('tag', 'index', params).map do |data|
97
+ API.new.fetch('tag', 'index', params).map do |data|
59
98
  Tag.new(data[:id]).show(data)
60
99
  end
61
100
  end
62
101
  private_class_method :fetch_tags
102
+
103
+ # @author Maxine Michalski
104
+ #
105
+ # Helper function to fetch implicated tags
106
+ #
107
+ # @param params [Hash] parameter for API call
108
+ #
109
+ # @return [Array<Tag>] array of implicated tags
110
+ def self.fetch_implications(params)
111
+ tag_params = { name: params[:implied_to], order: :date, limit: 1,
112
+ page: 1 }
113
+ implied_tag = fetch_tags(tag_params).first
114
+ API.new.fetch('tag_implication', 'index', params).map do |tag|
115
+ if tag[:consequent_id] == implied_tag.id && !tag[:pending]
116
+ Tag.new(tag[:predicate_id])
117
+ end
118
+ end
119
+ end
120
+ private_class_method :fetch_implications
121
+
122
+ # @author Maxine Michalski
123
+ #
124
+ # Helper function to fetch aliased tags
125
+ #
126
+ # @param params [Hash] parameter for API call
127
+ #
128
+ # @return [Array<Tag>] array of implicated tags
129
+ def self.fetch_aliases(params)
130
+ API.new.fetch('tag_alias', 'index', params).map do |tag|
131
+ Tag.new(tag[:alias_id])
132
+ end
133
+ end
134
+ private_class_method :fetch_aliases
63
135
  end
64
136
  end
65
137
  end
@@ -38,7 +38,7 @@ module E621
38
38
  #
39
39
  # @raise InvalidIDError
40
40
  #
41
- # @param tag [Integer] tag data, fetched from e621
41
+ # @param id [Integer] tag data, fetched from e621
42
42
  #
43
43
  # @return the object
44
44
  def initialize(id)
@@ -50,19 +50,29 @@ module E621
50
50
 
51
51
  # @author Maxine Michalski
52
52
  #
53
- # Bang method to fill tag data. If data is already available at creation,
54
- # use the initializer!
53
+ # Bang method to fill tag data.
54
+ # @notice If the optional parameter is not given, this method makes an API
55
+ # call.
56
+ #
57
+ # @param tag [Hash] optional parameter with API call information
58
+ #
59
+ # @return [NilClass]
55
60
  def show!(tag = nil)
56
61
  tag = API.new.fetch('tag', 'show', id: @id) if tag.nil?
57
62
  @name = tag[:name]
58
63
  @count = tag[:count].to_i
59
64
  @type = (Type.new(tag[:type], tag[:type_locked]) unless tag[:type].nil?)
65
+ nil
60
66
  end
61
67
 
62
68
  # @author Maxine Michalski
63
69
  #
64
- # Bang method to fill tag data. If data is already available at creation,
65
- # use the initializer!
70
+ # Method to return a properly filled Tag object.
71
+ # @note This makes an additional API call if no argument is given
72
+ #
73
+ # @param tag [Hash] optional parameter, if information are ready
74
+ #
75
+ # @return [Tag] Tag filled with all information
66
76
  def show(tag = nil)
67
77
  new_tag = Tag.new(@id)
68
78
  new_tag.show!(tag)
@@ -76,7 +86,9 @@ module E621
76
86
  # @note If there is only a an ID set with one argument, then only compare
77
87
  # IDs
78
88
  #
79
- # @return [TrueClass, FalseClass]
89
+ # @param other [Object] object that should be compared
90
+ #
91
+ # @return [TrueClass, FalseClass] test result of comparison
80
92
  def ==(other)
81
93
  return false unless other.is_a?(Tag)
82
94
  if @name.nil? || other.name.nil?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyhexagon
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maxine Michalski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-26 00:00:00.000000000 Z
11
+ date: 2018-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json