imgfetcha 0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 85a525ae878b7bdb3a04929960bae1c2a346efaca5774a1a78b51cdbf003259e
4
+ data.tar.gz: cc85354908698f73e8b7d96a9c4343f1394df2cf2fd97c69edf7242fe0549c91
5
+ SHA512:
6
+ metadata.gz: 55c26e1b660266ff2949c4a220e855ef5530edb6f3261d1fd5c19075d36387184d30d636b8323d1f867726de68535a16df8a0a45db195f7ccd35ab51898a1a2a
7
+ data.tar.gz: 61577dcbe5f68f9ad96c9c4c2aebfcf61fc7a031774e854cb27e21169dd9f640512e48813e354abf6ee9d94a90ad4e6be2b47eb983ee23f4cead0c21ee212a95
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'imgfetcha'
3
+
4
+ begin
5
+ Imgfetcha.run
6
+ end
@@ -0,0 +1,22 @@
1
+ require 'imgfetcha/version'
2
+ require 'imgfetcha/arg_parser'
3
+ require 'imgfetcha/file_reader'
4
+ require 'imgfetcha/batch_fetcher'
5
+ require 'imgfetcha/errors/input_file_not_specified_error'
6
+ require 'imgfetcha/errors/no_urls_found_error'
7
+
8
+ module Imgfetcha
9
+ def self.run
10
+ parser = ArgParser.new
11
+ options = parser.run
12
+
13
+ reader = FileReader.new(options)
14
+ reader.run
15
+
16
+ downloader = BatchFetcher.new(reader.result, options)
17
+ downloader.run
18
+ rescue StandardError, NotImplementedError => e
19
+ puts e.class, e.message
20
+ puts e.backtrace if options[:verbose]
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ require 'optparse'
2
+
3
+ module Imgfetcha
4
+ class ArgParser
5
+ attr_accessor :result
6
+
7
+ def initialize
8
+ @result = {}
9
+ end
10
+
11
+ def run
12
+ execute_parser
13
+ @result
14
+ end
15
+
16
+ private
17
+
18
+ # rubocop:disable Metrics/MethodLength
19
+ def execute_parser
20
+ OptionParser.new do |opts|
21
+ opts.banner = 'Usage: imgfetcha -i INPUT_FILE -o OUTPUT_DIRECTORY'
22
+
23
+ opts.on('-v', '--[no-]verbose', 'Run verbosely') do |v|
24
+ @result[:verbose] = v
25
+ end
26
+
27
+ opts.on('-i INPUT_FILE', '--input=INPUT_FILE', 'Specify input file') do |i|
28
+ @result[:input_file] = i
29
+ end
30
+
31
+ opts.on('-o OUTPUT_DIRECTORY', '--output=OUTPUT_DIRECTORY', 'Specify output directory') do |o|
32
+ @result[:output_dir] = o
33
+ end
34
+
35
+ opts.on('-V', '--version', 'Print version') do
36
+ puts Imgfetcha::VERSION
37
+ exit
38
+ end
39
+
40
+ opts.on('-h', '--help', 'Print this help') do
41
+ puts opts
42
+ exit
43
+ end
44
+ end.parse!
45
+ end
46
+ # rubocop:enable Metrics/MethodLength
47
+ end
48
+ end
@@ -0,0 +1,69 @@
1
+ require 'open-uri'
2
+ require 'mime/types'
3
+
4
+ module Imgfetcha
5
+ class BatchFetcher
6
+ # NOTE: 'bin' stands for `application/octet-stream`
7
+ VALID_TYPES = %w[jpeg jpg png gif heic bin].freeze
8
+
9
+ attr_reader :urls, :output_dir, :result
10
+
11
+ def initialize(urls, options)
12
+ @urls = urls
13
+ @output_dir = options[:output_dir] || Dir.pwd
14
+ @verbose = options[:verbose]
15
+ end
16
+
17
+ def run
18
+ @result = batch_download
19
+ puts "\nDownloaded #{@result.count} images"
20
+ @result
21
+ end
22
+
23
+ private
24
+
25
+ def batch_download
26
+ urls.map.with_index do |url, i|
27
+ print_progress(url, i)
28
+ temp_file = URI.open(url)
29
+ type = detect_type(temp_file)
30
+
31
+ next unless validate_type(type)
32
+
33
+ write_file(temp_file: temp_file, name: file_name(url, temp_file))
34
+ url
35
+ end.compact
36
+ end
37
+
38
+ # Get basename from a URL
39
+ def file_name(url, file)
40
+ name = File.basename(URI.parse(url).path)
41
+ # Append type if valid types aren't contained in the name
42
+ name += ".#{detect_type(file)}" unless VALID_TYPES.any? { |type| name.include?(type) }
43
+
44
+ name
45
+ end
46
+
47
+ def write_file(temp_file:, name:)
48
+ File.open("#{@output_dir}/#{name}", 'wb') do |f|
49
+ f.write(temp_file.read) ? print('OK') : print('ERROR')
50
+ end
51
+ end
52
+
53
+ def detect_type(file)
54
+ content_type = file.meta['content-type']
55
+ MIME::Types[content_type].first.preferred_extension
56
+ end
57
+
58
+ def validate_type(type)
59
+ return true if VALID_TYPES.include?(type)
60
+
61
+ print("ERROR: Type #{type} is invalid")
62
+ false
63
+ end
64
+
65
+ def print_progress(url, index)
66
+ print "\n[#{index + 1}/#{@urls.count}] Downloading #{url} "
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ module Imgfetcha
2
+ class FileReader
3
+ class InputFileNotSpecifiedError < StandardError
4
+ attr_reader :message
5
+
6
+ def initialize
7
+ @message = "Input file was not specified. Please provide the input file with '-i INPUT_FILE'"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Imgfetcha
2
+ class FileReader
3
+ class NoUrlsFoundError < StandardError
4
+ attr_reader :message
5
+
6
+ def initialize
7
+ @message = "The input file doesn't seem to have any valid URLs"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ module Imgfetcha
2
+ class FileReader
3
+ attr_reader :input_file, :result
4
+
5
+ def initialize(options)
6
+ @input_file = options[:input_file]
7
+ @verbose = options[:verbose]
8
+ end
9
+
10
+ def run
11
+ read_file
12
+ filter_urls
13
+ report_results if @verbose
14
+ @result
15
+ end
16
+
17
+ private
18
+
19
+ def read_file
20
+ raise InputFileNotSpecifiedError unless @input_file
21
+
22
+ # Expand path so that Dir#chdir would understand paths relative to home
23
+ @contents = File.read(File.expand_path(@input_file)).split
24
+ end
25
+
26
+ def filter_urls
27
+ @result = @contents.select { |url| URI.parse(url).is_a?(URI::HTTP) }
28
+ raise NoUrlsFoundError if @result.empty?
29
+
30
+ # TODO: group valid and unvalid URLs, warn about invalid ones
31
+
32
+ @result
33
+ end
34
+
35
+ def report_results
36
+ puts "Found #{@result.count} URLs in #{@contents.count} lines:"
37
+ puts @result
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module Imgfetcha
2
+ VERSION = '0.2.0'.freeze
3
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: imgfetcha
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - ston1x
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-07-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mime-types
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.13.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.13.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.9.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.9.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.88.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.88.0
69
+ description: Uses input file as a list of URLs and downloads all the images
70
+ email:
71
+ - stoianovnk@gmail.com
72
+ executables:
73
+ - imgfetcha
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - bin/imgfetcha
78
+ - lib/imgfetcha.rb
79
+ - lib/imgfetcha/arg_parser.rb
80
+ - lib/imgfetcha/batch_fetcher.rb
81
+ - lib/imgfetcha/errors/input_file_not_specified_error.rb
82
+ - lib/imgfetcha/errors/no_urls_found_error.rb
83
+ - lib/imgfetcha/file_reader.rb
84
+ - lib/imgfetcha/version.rb
85
+ homepage: https://github.com/ston1x/imgfetcha
86
+ licenses:
87
+ - MIT
88
+ metadata:
89
+ allowed_push_host: https://rubygems.org
90
+ homepage_uri: https://github.com/ston1x/imgfetcha
91
+ source_code_uri: https://github.com/ston1x/imgfetcha
92
+ changelog_uri: https://github.com/ston1x/imgfetcha
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: 2.3.0
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.1.2
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Ruby gem that takes an input of image URLs and downloads them in batch
112
+ test_files: []