picfisher 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6b49dc4c4a306ff17087d90b81c875043f63062b1760eb0f481e2968b44dd66
4
- data.tar.gz: 4caafb009411921cef9a4c3c60a8e231072de6a369f6b4e7a5386d636534d241
3
+ metadata.gz: 54dd426f55d53a5b00b37c2b53ec9c942e473e4adf0efa72ba34aabe1b3d8ab1
4
+ data.tar.gz: 5e163219957bc33cdc08cfe9363038c75630113ce2916eff45465002ef61d1fa
5
5
  SHA512:
6
- metadata.gz: 8cb50f69831f0421ec7cda95a942730ebdec12ceadc664a7c65fbba5322ee0c6315b5eefa06440041106756c3ba54c1fcad876c180abf551047b299da09fa2d7
7
- data.tar.gz: 56739738de69a7e0f314815c0665018d516af93cc39451884ae8abe2ac1ba56db02a45cc4e272cab14a9bb32653fbd66e569bc0482999444702bb0ce9b2b8133
6
+ metadata.gz: ca9a1f9a68b39298658df183f7691ea9980242f50200488ac8b9c864cc182540919085b6ffb16ce63a4749f83bfbae2d276c4d795fd19b0f9c1a7e3da359ef8a
7
+ data.tar.gz: 1672ef2e47030c7875d9900479bb50daf52c850af73fb6b505d72cb2f8aebe80d3908b38af6cf2ee7793a2230db61c016e3d2762f63ff9629209a28489000832
data/.rubocop.yml CHANGED
@@ -6,3 +6,125 @@ Style/StringLiterals:
6
6
 
7
7
  Style/StringLiteralsInInterpolation:
8
8
  EnforcedStyle: double_quotes
9
+
10
+ Gemspec/DateAssignment: # new in 1.10
11
+ Enabled: true
12
+ Gemspec/RequireMFA: # new in 1.23
13
+ Enabled: true
14
+ Layout/LineEndStringConcatenationIndentation: # new in 1.18
15
+ Enabled: true
16
+ Layout/SpaceBeforeBrackets: # new in 1.7
17
+ Enabled: true
18
+ Lint/AmbiguousAssignment: # new in 1.7
19
+ Enabled: true
20
+ Lint/AmbiguousOperatorPrecedence: # new in 1.21
21
+ Enabled: true
22
+ Lint/AmbiguousRange: # new in 1.19
23
+ Enabled: true
24
+ Lint/DeprecatedConstants: # new in 1.8
25
+ Enabled: true
26
+ Lint/DuplicateBranch: # new in 1.3
27
+ Enabled: true
28
+ Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
29
+ Enabled: true
30
+ Lint/EmptyBlock: # new in 1.1
31
+ Enabled: true
32
+ Lint/EmptyClass: # new in 1.3
33
+ Enabled: true
34
+ Lint/EmptyInPattern: # new in 1.16
35
+ Enabled: true
36
+ Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
37
+ Enabled: true
38
+ Lint/LambdaWithoutLiteralBlock: # new in 1.8
39
+ Enabled: true
40
+ Lint/NoReturnInBeginEndBlocks: # new in 1.2
41
+ Enabled: true
42
+ Lint/NumberedParameterAssignment: # new in 1.9
43
+ Enabled: true
44
+ Lint/OrAssignmentToConstant: # new in 1.9
45
+ Enabled: true
46
+ Lint/RedundantDirGlobSort: # new in 1.8
47
+ Enabled: true
48
+ Lint/RefinementImportMethods: # new in 1.27
49
+ Enabled: true
50
+ Lint/RequireRelativeSelfPath: # new in 1.22
51
+ Enabled: true
52
+ Lint/SymbolConversion: # new in 1.9
53
+ Enabled: true
54
+ Lint/ToEnumArguments: # new in 1.1
55
+ Enabled: true
56
+ Lint/TripleQuotes: # new in 1.9
57
+ Enabled: true
58
+ Lint/UnexpectedBlockArity: # new in 1.5
59
+ Enabled: true
60
+ Lint/UnmodifiedReduceAccumulator: # new in 1.1
61
+ Enabled: true
62
+ Lint/UselessRuby2Keywords: # new in 1.23
63
+ Enabled: true
64
+ Naming/BlockForwarding: # new in 1.24
65
+ Enabled: true
66
+ Security/IoMethods: # new in 1.22
67
+ Enabled: true
68
+ Style/ArgumentsForwarding: # new in 1.1
69
+ Enabled: true
70
+ Style/CollectionCompact: # new in 1.2
71
+ Enabled: true
72
+ Style/DocumentDynamicEvalDefinition: # new in 1.1
73
+ Enabled: true
74
+ Style/EndlessMethod: # new in 1.8
75
+ Enabled: true
76
+ Style/FileRead: # new in 1.24
77
+ Enabled: true
78
+ Style/FileWrite: # new in 1.24
79
+ Enabled: true
80
+ Style/HashConversion: # new in 1.10
81
+ Enabled: true
82
+ Style/HashExcept: # new in 1.7
83
+ Enabled: true
84
+ Style/IfWithBooleanLiteralBranches: # new in 1.9
85
+ Enabled: true
86
+ Style/InPatternThen: # new in 1.16
87
+ Enabled: true
88
+ Style/MapToHash: # new in 1.24
89
+ Enabled: true
90
+ Style/MultilineInPatternThen: # new in 1.16
91
+ Enabled: true
92
+ Style/NegatedIfElseCondition: # new in 1.2
93
+ Enabled: true
94
+ Style/NestedFileDirname: # new in 1.26
95
+ Enabled: true
96
+ Style/NilLambda: # new in 1.3
97
+ Enabled: true
98
+ Style/NumberedParameters: # new in 1.22
99
+ Enabled: true
100
+ Style/NumberedParametersLimit: # new in 1.22
101
+ Enabled: true
102
+ Style/OpenStructUse: # new in 1.23
103
+ Enabled: true
104
+ Style/QuotedSymbols: # new in 1.16
105
+ Enabled: true
106
+ Style/RedundantArgument: # new in 1.4
107
+ Enabled: true
108
+ Style/RedundantInitialize: # new in 1.27
109
+ Enabled: true
110
+ Style/RedundantSelfAssignmentBranch: # new in 1.19
111
+ Enabled: true
112
+ Style/SelectByRegexp: # new in 1.22
113
+ Enabled: true
114
+ Style/StringChars: # new in 1.12
115
+ Enabled: true
116
+ Style/SwapValues: # new in 1.1
117
+ Enabled: true
118
+
119
+ Metrics/MethodLength:
120
+ Max: 15
121
+ Exclude:
122
+ - 'test/**/*'
123
+
124
+ Metrics/AbcSize:
125
+ Exclude:
126
+ - 'test/**/*'
127
+
128
+ Layout/LineLength:
129
+ Exclude:
130
+ - 'test/**/*'
data/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.1] - 2024-05-30
9
+
10
+ ### Fixed
11
+
12
+ - Removed development gems from production dependencies
13
+
14
+
15
+ ## [0.2.1] - 2024-05-30
16
+
17
+ ### Added
18
+
19
+ - Show running version in the first log message
20
+
21
+ ### Changed
22
+
23
+ - Rubocop cops application
24
+ - Update TODO.md
25
+
26
+ ### Fixed
27
+
28
+ - Removed outdated comment
29
+
30
+
8
31
  ## [0.2.0] - 2024-05-30
9
32
 
10
33
  ### Added
data/README.md CHANGED
@@ -12,7 +12,7 @@ gem install picfisher
12
12
  ## Usage
13
13
 
14
14
  ```
15
- picfisher [images_file_path] [output_directory_path]
15
+ picfisher <images_file_path> <output_directory_path>
16
16
  ```
17
17
 
18
18
  For example:
data/TODO.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # TODO
2
2
 
3
- - Create the output directory if it doesn't exist. Or add a parameter to allow the user to decide this.
3
+ - If the output directory doesn't exist, create it. We can also add a parameter to allow the user to decide on this.
4
4
  - Check if the Downloader is going to overwrite a file that already exists. Add an option to `force` if not stop with an error.
5
5
  - Add a progress bar for the downloading phase.
6
6
  - Allow multiple concurrent downloads. Add an extra param to decide the number, default `5`
7
- - Add error handling to the Downloader. Many things can be wrong when connecting to the internet.
8
- - Allow URLs without image extension. This requires the source urls file to have a predictable estructure. Or we request all the images and check the media type of the response.
7
+ Add error handling to the Downloader. Many things can be wrong when connecting to the internet.
8
+ - Allow URLs without image extension. This requires the URLs' source file to have a predictable structure. Or we request all the images and check the media type of the response.
9
+ - If we pass an URL instead of a file path, the script will detect it, download the URL, and extract the images from there.
10
+ - Pass Rubocop cops
@@ -1,8 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "open-uri"
2
4
 
3
5
  module PicFisher
6
+ # Downloads an image from an URL
4
7
  module Downloader
5
- # TODO: We need to add error handling here
8
+ # Downloads an image from an URL
9
+ # @param url [String]
10
+ # @param output_path [String]
11
+ # @return [nil]
12
+ # @raise [PicFisher::Error]
13
+ # @example
14
+ # PicFisher::Downloader.download("https://example.com/image_in_internet.png", "OUTPUT_PATH")
15
+ # PicFisher::Downloader.download("https://example.com/not_existing.png", "OUTPUT_PATH")
6
16
  def self.download(url, output_path)
7
17
  PicFisher::Log.debug("Fishing #{url} to #{output_path}")
8
18
 
@@ -11,18 +21,16 @@ module PicFisher
11
21
  rescue OpenURI::HTTPError => e
12
22
  message = "Failed to fish #{url}: #{e}"
13
23
  PicFisher::Log.error(message)
14
- raise PicFisher::Error.new(message)
24
+ raise PicFisher::Error, message
15
25
  end
16
26
  end
17
27
 
18
- private
19
-
20
28
  def self._dowload(url, output_path)
21
- io_stream = OpenURI::open_uri(url)
29
+ io_stream = OpenURI.open_uri(url)
22
30
 
23
- File.open(output_path, "wb") do |f|
24
- f.write(io_stream.read)
25
- end
31
+ File.binwrite(output_path, io_stream.read)
26
32
  end
33
+
34
+ private_class_method :_dowload
27
35
  end
28
36
  end
@@ -1,6 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PicFisher
4
+ # Extracts the image urls from the given file and download them to the given directory
2
5
  module FishingBoat
3
- # REVIEW: we could use keyword params if we see it adds readability
6
+ # Extracts the image urls from the given file and download them to the given directory
7
+ # @param images_file_path [String]
8
+ # @param output_directory_path [String]
9
+ # @return [nil]
10
+ # @raise [PicFisher::Error]
11
+ # @example
12
+ # PicFisher::FishingBoat.fish("images.txt","~/Downloads/fished_images")
4
13
  def self.fish(images_file_path, output_directory_path)
5
14
  PicFisher::Log.info("Fishing from #{images_file_path} to #{output_directory_path}")
6
15
 
data/lib/picfisher/log.rb CHANGED
@@ -1,25 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PicFisher
4
+ # Print a message to the console
5
+ # @param debug_level [Symbol]
6
+ # @return [nil]
7
+ # @example
8
+ # PicFisher::Log.debug("message")
9
+ # PicFisher::Log.info("message")
10
+ # PicFisher::Log.error("message")
2
11
  module Log
3
12
  def self.debug(message)
4
- if ["debug"].include? debug_level
5
- output(:debug, message)
6
- end
13
+ output(:debug, message) if ["debug"].include? debug_level
7
14
  end
8
15
 
9
16
  def self.info(message)
10
- if ["debug", "info"].include? debug_level
11
- output(:info, message)
12
- end
17
+ output(:info, message) if %w[debug info].include? debug_level
13
18
  end
14
19
 
15
20
  def self.error(message)
16
- if ["debug", "info", "error"].include? debug_level
17
- output(:error, message)
18
- end
21
+ output(:error, message) if %w[debug info error].include? debug_level
19
22
  end
20
23
 
21
- private
22
-
23
24
  def self.output(level, message)
24
25
  final_message = "PicFisher [#{level.upcase}] #{message}"
25
26
  Kernel.puts(final_message)
@@ -28,5 +29,7 @@ module PicFisher
28
29
  def self.debug_level
29
30
  ENV["DEBUG_LEVEL"] || "info" # default is info
30
31
  end
32
+
33
+ private_class_method :debug_level
31
34
  end
32
35
  end
@@ -1,19 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PicFisher
4
+ # Sanitizes an image url
2
5
  module Sanitizer
6
+ # Sanitizes an image url
7
+ # @param url [String]
8
+ # @return [String]
9
+ # @example
10
+ # PicFisher::Sanitizer.sanitize_image_url("https://example.com/image_in_internet.png")
3
11
  def self.sanitize_image_url(url)
4
12
  filename_extension = File.extname(url)
5
13
  filename_extension_escaped = Regexp.escape(filename_extension) # to escape the dot "."
6
14
  result =
7
15
  url
8
- .sub(/#{filename_extension_escaped}$/, "")
9
- .gsub(/[^\w\s-]+/, "_")
10
- .gsub(/(^|\b\s)\s+($|\s?\b)/, "\\1\\2")
11
- .gsub(/\s+/, "_")
16
+ .sub(/#{filename_extension_escaped}$/, "")
17
+ .gsub(/[^\w\s-]+/, "_")
18
+ .gsub(/(^|\b\s)\s+($|\s?\b)/, "\\1\\2")
19
+ .gsub(/\s+/, "_")
12
20
 
13
21
  result = "#{result}#{filename_extension}"
14
-
15
22
  PicFisher::Log.debug("Sanitizing url '#{url}': #{result}")
16
-
17
23
  result
18
24
  end
19
25
  end
@@ -1,17 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "uri"
2
4
 
3
5
  module PicFisher
6
+ # Extracts image urls from a string
4
7
  module URLExtractor
5
8
  # NOTE: using URI.regexp(["http", "https"]) didn't work for me
6
- URL_REGEX = /https?:\/\/[^\s,]+/
7
- IMAGE_EXTENSITONS = %w(.jpg .jpeg .png .gif .webp .bmp .ico .svg .tiff or .tif .psd .raw .cr2 .nrw .arw .dng .nef .orf .sr2 .raf .tif .tiff .djvu)
9
+ URL_REGEX = %r{https?://[^\s,]+}
10
+ IMAGE_EXTENSITONS = %w[.jpg .jpeg .png .gif .webp .bmp .ico .svg .tiff or .tif .psd .raw .cr2 .nrw .arw .dng .nef
11
+ .orf .sr2 .raf .tif .tiff .djvu].freeze
8
12
 
13
+ # Extracts image urls from a string
14
+ # @param string [String]
15
+ # @return [Array<String>]
16
+ # @example
17
+ # PicFisher::URLExtractor.extract("https://example.com/image_in_internet.png, https://example.com/another.png")
9
18
  def self.extract(string)
10
19
  result =
11
20
  string
12
- .scan(URL_REGEX)
13
- .select { |url| url.end_with?(*IMAGE_EXTENSITONS) }
14
- .uniq
21
+ .scan(URL_REGEX)
22
+ .select { |url| url.end_with?(*IMAGE_EXTENSITONS) }
23
+ .uniq
15
24
 
16
25
  PicFisher::Log.debug("Extracted urls: #{result.join("|")}")
17
26
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PicFisher
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.2"
5
5
  end
data/lib/picfisher.rb CHANGED
@@ -7,32 +7,59 @@ require_relative "picfisher/downloader"
7
7
  require_relative "picfisher/fishing_boat"
8
8
  require_relative "picfisher/log"
9
9
 
10
+ # Extracts the image urls from the given file and download them to the given directory
10
11
  module PicFisher
11
12
  class Error < StandardError; end
12
13
 
13
- # REVIEW: we could use keyword params if we see it adds readability
14
+ # Extracts the image urls from the given file and download them to the given directory
15
+ # @param images_file_path [String]
16
+ # @param output_directory_path [String]
17
+ # @return [nil]
18
+ # @raise [PicFisher::Error]
19
+ # @example
20
+ # PicFisher.fish("images.txt","~/Downloads/fished_images")
14
21
  def self.fish(images_file_path, output_directory_path)
15
- PicFisher::Log.info "PicFisher is running..."
22
+ PicFisher::Log.info "PicFisher [#{PicFisher::VERSION}] is running..."
16
23
 
17
- if images_file_path.nil? || output_directory_path.nil?
18
- message = "Use: picfisher [images_file_path] [output_directory_path]"
19
- PicFisher::Log.error(message)
20
- raise PicFisher::Error.new(message)
24
+ run_validations(images_file_path, output_directory_path)
25
+
26
+ PicFisher::FishingBoat.fish(images_file_path, output_directory_path)
27
+ PicFisher::Log.info "PicFisher is finished!"
28
+ end
29
+
30
+ class << self
31
+ private
32
+
33
+ def run_validations(images_file_path, output_directory_path)
34
+ validate_paths(images_file_path, output_directory_path)
35
+ validate_origin_exists(images_file_path)
36
+ validate_output_exists(output_directory_path)
21
37
  end
22
38
 
23
- if !File.exist?(images_file_path)
24
- message = "File not found: #{images_file_path}"
25
- PicFisher::Log.error(message)
26
- raise PicFisher::Error.new(message)
39
+ # rubocop:disable Style/GuardClause
40
+ def validate_paths(images_file_path, output_directory_path)
41
+ if images_file_path.nil? || output_directory_path.nil?
42
+ message = "Use: picfisher <images_file_path> <output_directory_path>"
43
+ PicFisher::Log.error(message)
44
+ raise PicFisher::Error, message
45
+ end
27
46
  end
28
47
 
29
- if !Dir.exist?(output_directory_path)
30
- message = "Directory not found: #{output_directory_path}"
31
- PicFisher::Log.error(message)
32
- raise PicFisher::Error.new(message)
48
+ def validate_origin_exists(images_file_path)
49
+ unless File.exist?(images_file_path)
50
+ message = "File not found: #{images_file_path}"
51
+ PicFisher::Log.error(message)
52
+ raise PicFisher::Error, message
53
+ end
33
54
  end
34
55
 
35
- PicFisher::FishingBoat.fish(images_file_path, output_directory_path)
36
- PicFisher::Log.info "PicFisher is finished!"
56
+ def validate_output_exists(output_directory_path)
57
+ unless Dir.exist?(output_directory_path)
58
+ message = "Directory not found: #{output_directory_path}"
59
+ PicFisher::Log.error(message)
60
+ raise PicFisher::Error, message
61
+ end
62
+ end
63
+ # rubocop:enable Style/GuardClause
37
64
  end
38
65
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picfisher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernando Guillen
@@ -11,109 +11,109 @@ cert_chain: []
11
11
  date: 2024-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: open-uri
14
+ name: minitest
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.4.1
19
+ version: '5.16'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.4.1
26
+ version: '5.16'
27
27
  - !ruby/object:Gem::Dependency
28
- name: uri
28
+ name: open-uri
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.13.0
33
+ version: 0.4.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.13.0
40
+ version: 0.4.1
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake
42
+ name: uri
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '13.0'
47
+ version: 0.13.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '13.0'
54
+ version: 0.13.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: minitest
56
+ name: mocha
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '5.16'
62
- type: :runtime
61
+ version: '2.3'
62
+ type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '5.16'
68
+ version: '2.3'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rubocop
70
+ name: webmock
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.21'
76
- type: :runtime
75
+ version: '3.23'
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 3.23.1
79
+ type: :development
77
80
  prerelease: false
78
81
  version_requirements: !ruby/object:Gem::Requirement
79
82
  requirements:
80
83
  - - "~>"
81
84
  - !ruby/object:Gem::Version
82
- version: '1.21'
85
+ version: '3.23'
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 3.23.1
83
89
  - !ruby/object:Gem::Dependency
84
- name: webmock
90
+ name: rubocop
85
91
  requirement: !ruby/object:Gem::Requirement
86
92
  requirements:
87
93
  - - "~>"
88
94
  - !ruby/object:Gem::Version
89
- version: '3.23'
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- version: 3.23.1
95
+ version: '1.21'
93
96
  type: :development
94
97
  prerelease: false
95
98
  version_requirements: !ruby/object:Gem::Requirement
96
99
  requirements:
97
100
  - - "~>"
98
101
  - !ruby/object:Gem::Version
99
- version: '3.23'
100
- - - ">="
101
- - !ruby/object:Gem::Version
102
- version: 3.23.1
102
+ version: '1.21'
103
103
  - !ruby/object:Gem::Dependency
104
- name: mocha
104
+ name: rake
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: '2.3'
109
+ version: '13.0'
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '2.3'
116
+ version: '13.0'
117
117
  description: Reading all the image URLs from a given text file and download them to
118
118
  a given directory.
119
119
  email:
@@ -145,6 +145,7 @@ metadata:
145
145
  homepage_uri: https://github.com/fguillen/PicFisher
146
146
  source_code_uri: https://github.com/fguillen/PicFisher
147
147
  changelog_uri: https://github.com/fguillen/PicFisher/blob/main/CHANGELOG.md
148
+ rubygems_mfa_required: 'false'
148
149
  post_install_message:
149
150
  rdoc_options: []
150
151
  require_paths: