simple-images-downloader 1.1.0 → 1.1.1

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: 902c3b0e5fe1566296ac139123707162e33ded87accc9ff5705231fb3fa96f4f
4
- data.tar.gz: c2812c8d700ca81d1f29b6a29d0063aef74b9dfd3162c652453733870b8073fe
3
+ metadata.gz: 0e7adf857ef1d9f8490a079e5828b6025d0b44a21ec098bfc0012124c61223a9
4
+ data.tar.gz: 50175489068f5c9c7587b940d0690d335f8787f4e78c3f7ede9b26982b13b1c5
5
5
  SHA512:
6
- metadata.gz: 5501d04aa338c0f992d391d94a5b29e8b63a410938c7a8f31941ed3178b2efa63a6ef84b9bb419f87278880197498367eeb235dea017509c57c708f758f7b4ab
7
- data.tar.gz: 26ba7c6dbd4cfdf1e34750ce6b3f7e99650511ba56597a7c8ab1ee7950c210f7919f0a1104053fcc6195bec822b215678e9c8bc5015fee9d6fc8ae6eb27612e7
6
+ metadata.gz: e205d6d7feb52617f2d526765dd3b3f82509d5cfc2343ca90dbf966966784fa8099cae222904b245ff338d46f5f38883a648d50914c39ec7d3b285af0c6e61a6
7
+ data.tar.gz: 2660f410b9d48c4876e48fd387c69ad12707b29fef9e02ccb453331fc557c42249d0311da6f0df9eafe50e894ce23fa50c7260d2a6b4f091664ab3247b8dbcbe
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.1.1 - 2023-09-30
2
+ - Fixed setting of mime types from configuration. It was using default values instead of the ones set in the configuration
3
+ - Added documentation to classes and methods
4
+
1
5
  ## 1.1.0 - 2023-09-30
2
6
  - Add validation of downloaded content over path validation
3
7
  - Add ability to extend mime types from configuration
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- simple-images-downloader (1.1.0)
4
+ simple-images-downloader (1.1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,11 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # add documentation to this class using YARD
5
+
6
+ # Client class
7
+ # Responsible for opening the URI and handling errors
8
+ #
9
+ # @example
10
+ # SimpleImagesDownloader::Client.new.open(uri)
11
+ #
4
12
  class Client
5
13
  def initialize(options = Configuration::REQUEST_OPTIONS)
6
14
  @options = options
7
15
  end
8
16
 
17
+ # @param uri [URI] URI object
18
+ # @return [StringIO] StringIO object
9
19
  def open(uri)
10
20
  uri.open(@options)
11
21
  rescue OpenURI::HTTPRedirect
@@ -1,6 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # Configuration class
5
+ # @example
6
+ # SimpleImagesDownloader::Configuration.configure do |config|
7
+ # config.destination = './images'
8
+ # config.valid_mime_types = ['image/jpeg', 'image/png']
9
+ # end
10
+ #
11
+ # SimpleImagesDownloader::Configuration.destination
12
+ # # => './images'
13
+ #
14
+ # SimpleImagesDownloader::Configuration.valid_mime_types
15
+ # # => ['image/jpeg', 'image/png']
16
+ #
4
17
  class Configuration
5
18
  include Singleton
6
19
 
@@ -17,16 +30,16 @@ module SimpleImagesDownloader
17
30
  }.freeze
18
31
 
19
32
  # https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types#common_image_file_types
20
- DEFAULT_VALID_MIME_TYPES_MAP = {
21
- 'image/avif' => true,
22
- 'image/gif' => true,
23
- 'image/apng' => true,
24
- 'image/jpg' => true,
25
- 'image/jpeg' => true,
26
- 'image/png' => true,
27
- 'image/svg+xml' => true,
28
- 'image/webp' => true
29
- }.freeze
33
+ DEFAULT_VALID_MIME_TYPES = [
34
+ 'image/avif',
35
+ 'image/gif',
36
+ 'image/apng',
37
+ 'image/jpg',
38
+ 'image/jpeg',
39
+ 'image/png',
40
+ 'image/svg+xml',
41
+ 'image/webp'
42
+ ].freeze
30
43
 
31
44
  DEFAULT_DESTINATION = './'
32
45
 
@@ -34,15 +47,32 @@ module SimpleImagesDownloader
34
47
 
35
48
  def initialize
36
49
  @destination = DEFAULT_DESTINATION
37
- @valid_mime_types = DEFAULT_VALID_MIME_TYPES_MAP.keys
50
+ @valid_mime_types = DEFAULT_VALID_MIME_TYPES
38
51
  end
39
52
 
53
+ # Allows to set valid_mime_types to check against allowed mime types
54
+ #
55
+ # @param value [Array] Array of valid mime types followed by
56
+ # RFC 1341 - MIME (Multipurpose Internet Mail Extensions) format
57
+ # @raise [BaseError] if value is not an Array
58
+ #
40
59
  def valid_mime_types=(value)
41
- raise BaseError, 'valid_mime_types must be an array' unless value.is_a?(Array)
60
+ raise Errors::BaseError, 'valid_mime_types must be an array' unless value.is_a?(Array)
42
61
 
43
62
  @valid_mime_types = value
44
63
  end
45
64
 
65
+ #### Configurable options
66
+ #
67
+ # destination: String, default: './', description: 'Destination folder to put downloaded images'
68
+ # valid_mime_types: Array,
69
+ # default: [
70
+ # 'image/avif', 'image/gif', 'image/apng', 'image/jpg',
71
+ # 'image/jpeg', 'image/png', 'image/svg+xml', 'image/webp'
72
+ # ], description: 'Valid mime types to download'
73
+ #
74
+ # @yield [config] Yields the Configuration object to the block
75
+ #
46
76
  def self.configure
47
77
  yield instance
48
78
  end
@@ -1,18 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # Dispenser class
5
+ # Responsible for moving tempfile to destination directory
6
+ #
7
+ # @example
8
+ # SimpleImagesDownloader::Dispenser.new(tempfile, 'https://example.com/image.jpg').place
9
+ #
4
10
  class Dispenser
5
11
  extend Forwardable
6
12
  include Validatable
7
13
 
8
14
  def_delegator 'SimpleImagesDownloader::Configuration', :destination, :destination_dir
9
15
 
16
+ # @param source [Tempfile] Tempfile object
17
+ # @param remote_path [String] original path of the image from input of SimpleImagesDownloader module
18
+ # @param validators [Array] array of validators for validating the destination directory.
19
+ # Default: [DestinationValidator.new]
10
20
  def initialize(source, remote_path, validators = [DestinationValidator.new])
11
21
  @source = source
12
22
  @remote_path = remote_path
13
23
  @validators = validators
14
24
  end
15
25
 
26
+ # Moves tempfile to destination directory
27
+ #
28
+ # @raise [Errors::BadDestination] if destination directory is not valid
29
+ # @see DestinationValidator
16
30
  def place
17
31
  validate!({ path: destination_dir })
18
32
 
@@ -1,15 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # Downloader class
5
+ # Responsible for downloading images from URI and placing them to the destination folder
6
+ # allows to use custom client and validators for downloading
7
+ #
8
+ # @example
9
+ # SimpleImagesDownloader::Downloader.new(uri).download
10
+ #
4
11
  class Downloader
5
12
  include Validatable
6
13
 
14
+ # @param uri [URI] URI object from which image will be downloaded
15
+ # @param client [Client] Client object for opening the URI. Default: Client.new
16
+ # @param validators [Array] array of validators for validating the response. Default: [MimeTypeValidator.new]
7
17
  def initialize(uri, client = Client.new, validators = [MimeTypeValidator.new])
8
18
  @uri = uri
9
19
  @client = client
10
20
  @validators = validators
11
21
  end
12
22
 
23
+ # Downloads image from URI and places it to the destination folder
24
+ #
25
+ # @raise [Errors::EmptyResponse] if response is empty
26
+ # @raise [Errors::BadMimeType] if response is not an image
27
+ # @see Errors module
28
+ # @see MimeTypeValidator
13
29
  def download
14
30
  puts "Downloading #{@uri}"
15
31
 
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # Errors module
5
+ # Responsible for storing all errors
6
+ #
4
7
  module Errors
5
8
  class BaseError < StandardError; end
6
9
 
@@ -1,11 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # Line class
5
+ # Responsible for parsing the string into URI object
6
+ #
7
+ # @example
8
+ # SimpleImagesDownloader::Line.new('https://example.com/image.jpg').uri
9
+ # # => #<URI::HTTPS https://example.com/image.jpg>
10
+ #
4
11
  class Line
5
12
  def initialize(string)
6
13
  @string = string
7
14
  end
8
15
 
16
+ # @return [URI] URI object
17
+ # @raise [Errors::BadUrl] if string is not a valid URI
18
+ # @see Errors::BadUrl
19
+ #
9
20
  def uri
10
21
  URI.parse(@string)
11
22
  rescue URI::Error
@@ -1,7 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # Runner class
5
+ # Responsible for invoking interface to download images from file
6
+ #
7
+ # @example
8
+ # SimpleImagesDownloader::Runner.invoke('./urls.txt')
9
+ #
4
10
  class Runner
11
+ # Allows to invoke interface to download images from file
5
12
  def self.invoke
6
13
  raise SimpleImagesDownloader::Errors::MissingFileArgumentError if ARGV.size.zero?
7
14
 
@@ -1,14 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # SourceFile class
5
+ # Responsible for opening the file of URLs and validating it
6
+ #
7
+ # @example
8
+ # SimpleImagesDownloader::SourceFile.new('./urls.txt').each_line do |line|
9
+ # puts line
10
+ # end
11
+ #
4
12
  class SourceFile
5
13
  include Validatable
6
14
 
15
+ # @param path [String] path to file
16
+ # @param validators [Array] array of validators
7
17
  def initialize(path, validators = [FilePersistanceValidator.new, FileAccessibilityValidator.new])
8
18
  @path = path
9
19
  @validators = validators
10
20
  end
11
21
 
22
+ # @yield [line] passes each line of file to block
23
+ # @yieldparam line [String] line of file
12
24
  def each_line(&block)
13
25
  validate!({ path: @path })
14
26
 
@@ -1,9 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # StringIOToTempfile module
5
+ # Responsible for converting StringIO to Tempfile
6
+ #
7
+ # @example
8
+ # SimpleImagesDownloader::StringioToTempfile.convert(stringio)
9
+ # # => #<Tempfile:0x00007f9b9c0b3a38>
10
+ #
4
11
  module StringioToTempfile
5
12
  module_function
6
13
 
14
+ # @param stringio [StringIO] StringIO object
15
+ # @return [Tempfile] Tempfile object
7
16
  def convert(stringio)
8
17
  tempfile = Tempfile.new(binmode: true)
9
18
 
@@ -2,7 +2,16 @@
2
2
 
3
3
  module SimpleImagesDownloader
4
4
  module Validatable
5
+ # DestinationValidator class
6
+ # Responsible for validating destination path
7
+ #
8
+ # @example
9
+ # SimpleImagesDownloader::DestinationValidator.new.validate({ path: './images' })
10
+ #
5
11
  class DestinationValidator < Validator
12
+ # @param options [Hash] hash with path to destination directory
13
+ # @raise [Errors::DestinationIsNotDirectory] if destination is not directory
14
+ # @raise [Errors::DestinationIsNotWritable] if destination is not writable
6
15
  def validate(options)
7
16
  path = options[:path]
8
17
 
@@ -2,7 +2,15 @@
2
2
 
3
3
  module SimpleImagesDownloader
4
4
  module Validatable
5
+ # FileAccessibilityValidator class
6
+ # Responsible for validating file accessibility
7
+ #
8
+ # @example
9
+ # SimpleImagesDownloader::FileAccessibilityValidator.new.validate({ path: './urls.txt' })
10
+ #
5
11
  class FileAccessibilityValidator < Validator
12
+ # @param options [Hash] hash with path to file
13
+ # @raise [Errors::PermissionsError] if file is not readable
6
14
  def validate(options)
7
15
  return if File.readable?(options[:path])
8
16
 
@@ -2,7 +2,15 @@
2
2
 
3
3
  module SimpleImagesDownloader
4
4
  module Validatable
5
+ # FilePersistanceValidator class
6
+ # Responsible for validating file persistance
7
+ #
8
+ # @example
9
+ # SimpleImagesDownloader::FilePersistanceValidator.new.validate({ path: './urls.txt' })
10
+ #
5
11
  class FilePersistanceValidator < Validator
12
+ # @param options [Hash] hash with path to file
13
+ # @raise [Errors::MissingFileError] if file does not exist
6
14
  def validate(options)
7
15
  return if File.exist?(options[:path])
8
16
 
@@ -2,25 +2,40 @@
2
2
 
3
3
  module SimpleImagesDownloader
4
4
  module Validatable
5
+ # MimeTypeValidator class
6
+ # Responsible for validating mime type of file
7
+ #
8
+ # @example
9
+ # SimpleImagesDownloader::MimeTypeValidator.new.validate({ path: './image.jpg', io: StringIO.new })
10
+ #
5
11
  class MimeTypeValidator < Validator
6
12
  extend Forwardable
7
13
 
8
14
  def_delegator 'SimpleImagesDownloader::Configuration', :valid_mime_types, :valid_mime_types
9
15
 
16
+ # Validates mime type of file. The mime types are taken from file Configuration
17
+ #
18
+ # @param options [Hash] hash with path to file and io object. Example: { path: './image.jpg', io: StringIO }
19
+ # @raise [Errors::BadMimeType] if mime type is not valid
20
+ # @see Configuration::DEFAULT_VALID_MIME_TYPES to see default valid mime types or add your own
10
21
  def validate(options)
11
22
  path = options[:path]
12
23
  io = options[:io]
13
24
 
14
25
  mime_type = mime_type_of(io)
15
26
 
16
- return if Configuration::DEFAULT_VALID_MIME_TYPES_MAP[mime_type]
27
+ return if SimpleImagesDownloader::Configuration.valid_mime_types.include?(mime_type)
17
28
 
18
29
  raise Errors::BadMimeType.new(path, mime_type)
19
30
  end
20
31
 
21
32
  private
22
33
 
23
- # Taken from Shrine https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/determine_mime_type.rb#L94
34
+ # Returns mime type of file. Uses UNIX file command
35
+ #
36
+ # @see https://github.com/shrinerb/shrine/blob/master/lib/shrine/plugins/determine_mime_type.rb#L94
37
+ # @param io [IO] io object
38
+ # @return [String] mime type of file
24
39
  def mime_type_of(io)
25
40
  Open3.popen3('file --mime-type --brief -') do |stdin, stdout, stderr, thread|
26
41
  copy_stream(from: io, to: stdin.binmode)
@@ -2,6 +2,8 @@
2
2
 
3
3
  module SimpleImagesDownloader
4
4
  module Validatable
5
+ # Validator class
6
+ # Responsible for defining interface for validators
5
7
  class Validator
6
8
  def validate(_value)
7
9
  raise NotImplementedError, 'must be implemented in subclass'
@@ -1,7 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
+ # Validatable module
5
+ # Responsible for validating the object using array of validators
6
+ #
7
+ # @example
8
+ # class SourceFile
9
+ # include Validatable
10
+ #
11
+ # def initialize(path, validators = [FilePersistanceValidator.new, FileAccessibilityValidator.new])
12
+ # @path = path
13
+ # @validators = validators
14
+ # end
15
+ #
16
+ # def each_line(&block)
17
+ # validate!({ path: @path })
18
+ # # ...
19
+ # end
20
+ # end
4
21
  module Validatable
22
+ # @param value [Object] value to validate
23
+ # @raise [Errors::<Particular>Error] if value is not valid
5
24
  def validate!(value)
6
25
  (@validators ||= []).each { |validator| validator.validate(value) }
7
26
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleImagesDownloader
4
- VERSION = '1.1.0'
4
+ # gem version
5
+ VERSION = '1.1.1'
5
6
  end
@@ -25,15 +25,31 @@ require_relative 'simple_images_downloader/downloader'
25
25
  require_relative 'simple_images_downloader/strategies/from_file_strategy'
26
26
  require_relative 'simple_images_downloader/strategies/from_url_strategy'
27
27
 
28
+ # SimpleImagesDownloader module
29
+ # It is a main module of the gem
30
+ # It is responsible for providing interface to download images from file or url
31
+ #
32
+ # @example
33
+ # SimpleImagesDownloader.from_file('./urls.txt')
34
+ # SimpleImagesDownloader.from_url('https://example.com/image.jpg')
35
+ #
28
36
  module SimpleImagesDownloader
37
+ # Downloads images from file by taking urls from it. Places images to the destination folder set in configuration
38
+ #
39
+ # @param path [String] path to file with urls
29
40
  def self.from_file(path)
30
41
  SimpleImagesDownloader::Strategies::FromFileStrategy.new(path).process
31
42
  end
32
43
 
44
+ # Downloads image from url. Places image to the destination folder set in configuration
45
+ #
46
+ # @param url [String] url of image
33
47
  def self.from_url(url)
34
48
  SimpleImagesDownloader::Strategies::FromUrlStrategy.new(url).process
35
49
  end
36
50
 
51
+ # Returns root path of the gem. It is used for testing purposes
52
+ # @return [String] root path of the gem
37
53
  def self.root
38
54
  File.dirname __dir__
39
55
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple-images-downloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - IlkhamGaysin