picfisher 0.2.0 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +122 -0
- data/CHANGELOG.md +23 -0
- data/README.md +1 -1
- data/REQUIREMENTS.md +27 -0
- data/TODO.md +5 -3
- data/exe/picfisher +0 -1
- data/lib/picfisher/downloader.rb +16 -8
- data/lib/picfisher/fishing_boat.rb +10 -1
- data/lib/picfisher/log.rb +14 -11
- data/lib/picfisher/sanitizer.rb +12 -6
- data/lib/picfisher/url_extractor.rb +14 -5
- data/lib/picfisher/version.rb +1 -1
- data/lib/picfisher.rb +43 -16
- metadata +26 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b9de04d8a277e0aa73fe18b4656954e2b5990e855f6d1f566709b71ab0748e2
|
4
|
+
data.tar.gz: bf12cd94fb5f13307d9dd29503ba0fdc640f713ab377c024950b182521a9299d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4b6edaff475b278d2c68a523a76b3301b057144de4d8b4943fe976898dc37bfe63e7dd1034ad5606022bfcbaa239801fcf9a6b7fad61de0716abc3f7bd4e1f0
|
7
|
+
data.tar.gz: 5ab3cd2201cf568a5836131d575c312c391ef928fbce49a26e6573b98fe4efc2b084095018aa66bd788d18aafe34749ddb287e2b4f7b1cecb063d62378449735
|
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
data/REQUIREMENTS.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Getsafe Backend Coding Challenge
|
2
|
+
|
3
|
+
## Task context
|
4
|
+
Imagine you are employed at a hypothetical company called “The Big Picture Corp” where the product department is requesting a tool to download a list of images from a plain text file. For now there are not many requirements from product yet and you only know that they want a simple command line tool for downloading images from a list of urls and storing them on the local harddrive. From the product vision however, it’s already clear that having the functionality of batch downloading images will be important to the product and is likely to be used in several different contexts.
|
5
|
+
|
6
|
+
## Assignment
|
7
|
+
Implement the functionality of downloading images from a given plain text file. Document your solution in this github repository and quickly explain why you think this is a good solution to the given task.
|
8
|
+
|
9
|
+
## Some things to keep in mind
|
10
|
+
- We prefer if you use Ruby, but we’re ok if you use a different language
|
11
|
+
- You can assume that the image urls in a given file are separated by whitespace and can potentially include invalid urls
|
12
|
+
- Your code should be executable through a command line interface (script, rake task, ...)
|
13
|
+
- You can assume your code will be used in production and will also be further developed by other developers over time - therefore make decision accordingly
|
14
|
+
- Try to keep your commits history well organised and clean, like you would do in a pull request for a real task assignment.
|
15
|
+
|
16
|
+
## What we pay attention to
|
17
|
+
1. Does your solution work?
|
18
|
+
2. Is the code clear and maintainable?
|
19
|
+
3. Is the code tested?
|
20
|
+
4. Is your solution documented?
|
21
|
+
5. Have all instructions been followed?
|
22
|
+
|
23
|
+
Bonus: Document your thought process.
|
24
|
+
|
25
|
+
We're here for you in case you have any questions!
|
26
|
+
|
27
|
+
## Above all: have fun!✌🏻
|
data/TODO.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# TODO
|
2
2
|
|
3
|
-
-
|
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
|
-
|
8
|
-
- Allow URLs without image extension. This requires the source
|
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
|
data/exe/picfisher
CHANGED
data/lib/picfisher/downloader.rb
CHANGED
@@ -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
|
-
#
|
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
|
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
|
29
|
+
io_stream = OpenURI.open_uri(url)
|
22
30
|
|
23
|
-
File.
|
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
|
-
#
|
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 [
|
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 [
|
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
|
data/lib/picfisher/sanitizer.rb
CHANGED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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 =
|
7
|
-
IMAGE_EXTENSITONS = %w
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
|
data/lib/picfisher/version.rb
CHANGED
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
|
-
#
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
36
|
-
|
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.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fernando Guillen
|
@@ -10,6 +10,20 @@ bindir: exe
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2024-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.16'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.16'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: open-uri
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,33 +53,33 @@ dependencies:
|
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: 0.13.0
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
56
|
+
name: mocha
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
-
type: :
|
61
|
+
version: '2.3'
|
62
|
+
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '2.3'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
70
|
+
name: rake
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
62
|
-
type: :
|
75
|
+
version: '13.0'
|
76
|
+
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
82
|
+
version: '13.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rubocop
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -73,7 +87,7 @@ dependencies:
|
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '1.21'
|
76
|
-
type: :
|
90
|
+
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
@@ -100,20 +114,6 @@ dependencies:
|
|
100
114
|
- - ">="
|
101
115
|
- !ruby/object:Gem::Version
|
102
116
|
version: 3.23.1
|
103
|
-
- !ruby/object:Gem::Dependency
|
104
|
-
name: mocha
|
105
|
-
requirement: !ruby/object:Gem::Requirement
|
106
|
-
requirements:
|
107
|
-
- - "~>"
|
108
|
-
- !ruby/object:Gem::Version
|
109
|
-
version: '2.3'
|
110
|
-
type: :development
|
111
|
-
prerelease: false
|
112
|
-
version_requirements: !ruby/object:Gem::Requirement
|
113
|
-
requirements:
|
114
|
-
- - "~>"
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
version: '2.3'
|
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:
|
@@ -127,6 +127,7 @@ files:
|
|
127
127
|
- CHANGELOG.md
|
128
128
|
- LICENSE.txt
|
129
129
|
- README.md
|
130
|
+
- REQUIREMENTS.md
|
130
131
|
- Rakefile
|
131
132
|
- TODO.md
|
132
133
|
- exe/picfisher
|
@@ -145,6 +146,7 @@ metadata:
|
|
145
146
|
homepage_uri: https://github.com/fguillen/PicFisher
|
146
147
|
source_code_uri: https://github.com/fguillen/PicFisher
|
147
148
|
changelog_uri: https://github.com/fguillen/PicFisher/blob/main/CHANGELOG.md
|
149
|
+
rubygems_mfa_required: 'true'
|
148
150
|
post_install_message:
|
149
151
|
rdoc_options: []
|
150
152
|
require_paths:
|