reddit_image_downloader 0.0.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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +109 -0
- data/Rakefile +1 -0
- data/bin/reddit_image_downloader +7 -0
- data/lib/reddit_image_downloader.rb +21 -0
- data/lib/reddit_image_downloader/option_parser.rb +78 -0
- data/lib/reddit_image_downloader/processor.rb +59 -0
- data/lib/reddit_image_downloader/version.rb +3 -0
- data/reddit_image_downloader.gemspec +28 -0
- metadata +154 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Brendan Loudermilk
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# RedditImageDownloader
|
2
|
+
|
3
|
+
RedditImageDownloader is a command line tool written in Ruby for downloading
|
4
|
+
images from any subreddit on reddit.com.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
The tool is available on RubyGems:
|
9
|
+
|
10
|
+
$ gem install reddit_image_downloader
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
Use the `reddit_image_downloader` command to download images. Specify one or
|
15
|
+
more of the options below to customize your query.
|
16
|
+
|
17
|
+
$ reddit_image_downloader [options]
|
18
|
+
|
19
|
+
### Specifying subreddit(s)
|
20
|
+
|
21
|
+
You must use `--subreddits` (shorthand `-r`) to specify one or more subreddits
|
22
|
+
as a comma-separated list. The following example will download the top images
|
23
|
+
[/r/EarthPorn][earthporn] and [/r/awww][awww].
|
24
|
+
|
25
|
+
$ reddit_image_downloader -r EarthPorn,awww
|
26
|
+
|
27
|
+
### Downloading to a specific path
|
28
|
+
|
29
|
+
By default, the command will download all images into the current working
|
30
|
+
directory of your shell. You can override this behavior with the
|
31
|
+
`--destination` (shorthand `-d`) option. The following example will download
|
32
|
+
images from [/r/Earthporn][earthporn] to your desktop.
|
33
|
+
|
34
|
+
$ reddit_image_downloader -r EarthPorn -d ~/Desktop
|
35
|
+
|
36
|
+
### Requiring minimum dimensions
|
37
|
+
|
38
|
+
You may choose to only download images which meet minimum width and height
|
39
|
+
requirements with the `--min-width` (shorthand `-x`) and `--min-height`
|
40
|
+
(shorthand `-y`) options respectively. The following example will download
|
41
|
+
images from [/r/EarthPorn][earthporn] *only* if they are 1920x1080.
|
42
|
+
|
43
|
+
$ reddit_image_downloader -r EarthPorn -x 1920 -y 1080
|
44
|
+
|
45
|
+
You may choose to only specify one dimension, as well.
|
46
|
+
|
47
|
+
$ reddit_image_downloader -r EarthPorn -y 1080
|
48
|
+
|
49
|
+
### Choosing a page
|
50
|
+
|
51
|
+
You may choose to download images from either one the of "top" (default),
|
52
|
+
"new", or "controversial" pages with the `--page` (shorthand `-p`) option. The
|
53
|
+
following example will download new images from [/r/awww][awww].
|
54
|
+
|
55
|
+
$ reddit_image_downloader -r awww -p new
|
56
|
+
|
57
|
+
### Purging old images
|
58
|
+
|
59
|
+
The initial use case for this tool was to manage a folder for wallpaper
|
60
|
+
images. The `--max-age` (shorthand `-a`) option can be used to purge images
|
61
|
+
older than a specified number of days. The following example will download
|
62
|
+
images from [/r/awww][awww] then delete any images that were downloaded more
|
63
|
+
than 14 days ago.
|
64
|
+
|
65
|
+
$ reddit_image_downloader -r awww -a 14
|
66
|
+
|
67
|
+
### Need help?
|
68
|
+
|
69
|
+
You can use the `--help` (shorthand `-h`) option to see a list of all the
|
70
|
+
available options and a short description of each. The following example shows
|
71
|
+
the help message:
|
72
|
+
|
73
|
+
$ reddit_image_downloader -h
|
74
|
+
|
75
|
+
## Contributing
|
76
|
+
|
77
|
+
1. Fork it
|
78
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
79
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
80
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
81
|
+
5. Create new Pull Request
|
82
|
+
|
83
|
+
[earthporn]: http://reddit.com/r/EarthPorn
|
84
|
+
[awww]: http://reddit.com/r/awww
|
85
|
+
|
86
|
+
## License
|
87
|
+
|
88
|
+
Copyright (c) 2013 Brendan Loudermilk
|
89
|
+
|
90
|
+
MIT License
|
91
|
+
|
92
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
93
|
+
a copy of this software and associated documentation files (the
|
94
|
+
"Software"), to deal in the Software without restriction, including
|
95
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
96
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
97
|
+
permit persons to whom the Software is furnished to do so, subject to
|
98
|
+
the following conditions:
|
99
|
+
|
100
|
+
The above copyright notice and this permission notice shall be
|
101
|
+
included in all copies or substantial portions of the Software.
|
102
|
+
|
103
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
104
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
105
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
106
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
107
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
108
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
109
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Stdlib
|
2
|
+
require "optparse"
|
3
|
+
require "ostruct"
|
4
|
+
|
5
|
+
# Gems
|
6
|
+
require "snoo"
|
7
|
+
require "mechanize"
|
8
|
+
require "dimensions"
|
9
|
+
|
10
|
+
# Development Gems
|
11
|
+
if ENV["DEV"]
|
12
|
+
require "pry"
|
13
|
+
end
|
14
|
+
|
15
|
+
# Self
|
16
|
+
require "reddit_image_downloader/version"
|
17
|
+
require "reddit_image_downloader/option_parser"
|
18
|
+
require "reddit_image_downloader/processor"
|
19
|
+
|
20
|
+
module RedditImageDownloader
|
21
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module RedditImageDownloader
|
2
|
+
module OptionParser
|
3
|
+
PAGES = %W[top new controversial]
|
4
|
+
|
5
|
+
DEFAULT_OPTIONS = {
|
6
|
+
show_help: false,
|
7
|
+
subreddits: [],
|
8
|
+
min_width: 0,
|
9
|
+
min_height: 0,
|
10
|
+
destination: Dir.pwd,
|
11
|
+
max_age: nil,
|
12
|
+
page: :top,
|
13
|
+
}
|
14
|
+
|
15
|
+
BANNER = "Usage: reddit_image_downloader [options]"
|
16
|
+
|
17
|
+
SUBREDDIT_FORMATS = %W[-r --subreddits=SUB1,SUB2]
|
18
|
+
SUBREDDIT_DESC = "List of subreddits to download from"
|
19
|
+
|
20
|
+
PATH_FORMATS = %W[-d --destination=PATH]
|
21
|
+
PATH_DESC = "Path to download images to (defaults to current directory)"
|
22
|
+
|
23
|
+
WIDTH_FORMATS = %W[-x --min-width=WIDTH]
|
24
|
+
WIDTH_DESC = "Only download images at least WIDTH wide"
|
25
|
+
|
26
|
+
HEIGHT_FORMATS = %W[-y --min-height=HEIGHT]
|
27
|
+
HEIGHT_DESC = "Only download images at least HEIGHT tall"
|
28
|
+
|
29
|
+
PAGE_FORMATS = %W[-p --page=PAGE]
|
30
|
+
PAGE_DESC = "Page to download (top [default], new, controversial)"
|
31
|
+
|
32
|
+
DAYS_FORMATS = %W[-a --max-age=DAYS]
|
33
|
+
DAYS_DESC = "Purge files in destination folder older than DAYS days"
|
34
|
+
|
35
|
+
HELP_FORMATS = %W[-h --help]
|
36
|
+
HELP_DESC = "Show this message"
|
37
|
+
|
38
|
+
def self.parse(args)
|
39
|
+
options = DEFAULT_OPTIONS.dup
|
40
|
+
|
41
|
+
parser = ::OptionParser.new do |parser|
|
42
|
+
parser.banner = BANNER
|
43
|
+
|
44
|
+
parser.on(*SUBREDDIT_FORMATS, Array, SUBREDDIT_DESC) do |subreddits|
|
45
|
+
options[:subreddits] += subreddits
|
46
|
+
end
|
47
|
+
|
48
|
+
parser.on(*PATH_FORMATS, PATH_DESC) do |destination|
|
49
|
+
options[:destination] = destination
|
50
|
+
end
|
51
|
+
|
52
|
+
parser.on(*WIDTH_FORMATS, Integer, WIDTH_DESC) do |min_width|
|
53
|
+
options[:min_width] = min_width
|
54
|
+
end
|
55
|
+
|
56
|
+
parser.on(*HEIGHT_FORMATS, Integer, HEIGHT_DESC) do |min_height|
|
57
|
+
options[:min_height] = min_height
|
58
|
+
end
|
59
|
+
|
60
|
+
parser.on(*PAGE_FORMATS, PAGES, PAGE_DESC) do |page|
|
61
|
+
options[:page] = page
|
62
|
+
end
|
63
|
+
|
64
|
+
parser.on(*DAYS_FORMATS, Integer, DAYS_DESC) do |days|
|
65
|
+
options[:max_age] = days
|
66
|
+
end
|
67
|
+
|
68
|
+
parser.on_tail(*HELP_FORMATS, HELP_DESC) do
|
69
|
+
options[:show_help] = true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
parser.parse!(args)
|
74
|
+
|
75
|
+
options
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RedditImageDownloader
|
2
|
+
class Processor < Struct.new(:options)
|
3
|
+
def self.process!(options)
|
4
|
+
new(options).process!
|
5
|
+
end
|
6
|
+
|
7
|
+
def process!
|
8
|
+
listings.each do |listing|
|
9
|
+
download = agent.get(listing["url"])
|
10
|
+
|
11
|
+
if download.is_a?(Mechanize::Image)
|
12
|
+
reader = Dimensions::Reader.new
|
13
|
+
|
14
|
+
reader << download.body
|
15
|
+
|
16
|
+
if reader.width > options[:min_width] && reader.height > options[:min_height]
|
17
|
+
filename = "#{listing["id"]}.#{reader.type}"
|
18
|
+
destination = File.join(options[:destination], filename)
|
19
|
+
|
20
|
+
unless File.exists?(destination)
|
21
|
+
download.save(destination)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if options[:max_age]
|
28
|
+
file_query = File.join(options[:destination], "*")
|
29
|
+
|
30
|
+
Dir[file_query].each do |file|
|
31
|
+
age = Time.now - File.ctime(file)
|
32
|
+
days_old = age / (24 * 3600)
|
33
|
+
|
34
|
+
if days_old > options[:max_age]
|
35
|
+
File.delete(file)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def listings
|
44
|
+
options[:subreddits].map do |subreddit|
|
45
|
+
client.get_listing(subreddit: subreddit, page: options[:page]).parsed_response["data"]["children"]
|
46
|
+
end.flatten.map do |listing|
|
47
|
+
listing["data"]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def client
|
52
|
+
@client ||= Snoo::Client.new
|
53
|
+
end
|
54
|
+
|
55
|
+
def agent
|
56
|
+
@agent ||= Mechanize.new
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'reddit_image_downloader/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "reddit_image_downloader"
|
8
|
+
spec.version = RedditImageDownloader::VERSION
|
9
|
+
spec.authors = ["Brendan Loudermilk"]
|
10
|
+
spec.email = ["brendan@gophilosophie.com"]
|
11
|
+
spec.description = %q{Download images from Reddit}
|
12
|
+
spec.summary = %q{Download images from Reddit}
|
13
|
+
spec.homepage = "https://github.com/bloudermilk/reddit_image_downloader"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "pry", "~> 0.9.12.2"
|
24
|
+
|
25
|
+
spec.add_dependency "snoo", "~> 0.1.2"
|
26
|
+
spec.add_dependency "mechanize", "~> 2.7.2"
|
27
|
+
spec.add_dependency "dimensions", "~> 1.2.0"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: reddit_image_downloader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Brendan Loudermilk
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-10-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
prerelease: false
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.3'
|
21
|
+
none: false
|
22
|
+
type: :development
|
23
|
+
name: bundler
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '1.3'
|
29
|
+
none: false
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
prerelease: false
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
none: false
|
38
|
+
type: :development
|
39
|
+
name: rake
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
none: false
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.9.12.2
|
53
|
+
none: false
|
54
|
+
type: :development
|
55
|
+
name: pry
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.9.12.2
|
61
|
+
none: false
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.1.2
|
69
|
+
none: false
|
70
|
+
type: :runtime
|
71
|
+
name: snoo
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.1.2
|
77
|
+
none: false
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ~>
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 2.7.2
|
85
|
+
none: false
|
86
|
+
type: :runtime
|
87
|
+
name: mechanize
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ~>
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 2.7.2
|
93
|
+
none: false
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ~>
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 1.2.0
|
101
|
+
none: false
|
102
|
+
type: :runtime
|
103
|
+
name: dimensions
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ~>
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: 1.2.0
|
109
|
+
none: false
|
110
|
+
description: Download images from Reddit
|
111
|
+
email:
|
112
|
+
- brendan@gophilosophie.com
|
113
|
+
executables:
|
114
|
+
- reddit_image_downloader
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- .gitignore
|
119
|
+
- Gemfile
|
120
|
+
- LICENSE.txt
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- bin/reddit_image_downloader
|
124
|
+
- lib/reddit_image_downloader.rb
|
125
|
+
- lib/reddit_image_downloader/option_parser.rb
|
126
|
+
- lib/reddit_image_downloader/processor.rb
|
127
|
+
- lib/reddit_image_downloader/version.rb
|
128
|
+
- reddit_image_downloader.gemspec
|
129
|
+
homepage: https://github.com/bloudermilk/reddit_image_downloader
|
130
|
+
licenses:
|
131
|
+
- MIT
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
none: false
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ! '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
none: false
|
148
|
+
requirements: []
|
149
|
+
rubyforge_project:
|
150
|
+
rubygems_version: 1.8.25
|
151
|
+
signing_key:
|
152
|
+
specification_version: 3
|
153
|
+
summary: Download images from Reddit
|
154
|
+
test_files: []
|