ruby-tapas-downloader 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/License.txt +13 -0
- data/README.md +46 -0
- data/bin/ruby-tapas-downloader +12 -0
- data/config/urls.yml +3 -0
- data/lib/ruby-tapas-downloader.rb +30 -0
- data/lib/ruby_tapas_downloader/cli.rb +45 -0
- data/lib/ruby_tapas_downloader/config.rb +8 -0
- data/lib/ruby_tapas_downloader/downloadable.rb +7 -0
- data/lib/ruby_tapas_downloader/downloadables.rb +9 -0
- data/lib/ruby_tapas_downloader/downloadables/catalog.rb +34 -0
- data/lib/ruby_tapas_downloader/downloadables/episode.rb +51 -0
- data/lib/ruby_tapas_downloader/downloadables/file.rb +39 -0
- data/lib/ruby_tapas_downloader/extractor.rb +7 -0
- data/lib/ruby_tapas_downloader/extractors.rb +9 -0
- data/lib/ruby_tapas_downloader/extractors/catalog.rb +22 -0
- data/lib/ruby_tapas_downloader/extractors/episode.rb +20 -0
- data/lib/ruby_tapas_downloader/extractors/files.rb +17 -0
- data/lib/ruby_tapas_downloader/feed_fetcher.rb +29 -0
- data/lib/ruby_tapas_downloader/login.rb +46 -0
- data/lib/ruby_tapas_downloader/version.rb +3 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5cca06220dad1b22ec9ac237334ff1f860674e68
|
4
|
+
data.tar.gz: a9392d4d857a3fcd85257c9cdcb5bae7532e9f0a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 00ebe03a4463feb0b9168118b0cbdc2ef66cafb3ccc14f6316a3fe17463fa40368b9d585019644e4aaf0fa1d5409149e722e61920315babff495164d2772caf8
|
7
|
+
data.tar.gz: 5d10b7bcb522279593ccf512b002b614d3aea17eb78a64d62cd2d6fe49c6f22da9ecbbac3e763baa4fcf5369edfd266d84378e0819564f7daf7c0809286ae28e
|
data/License.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
2
|
+
Version 2, December 2004
|
3
|
+
|
4
|
+
Copyright (C) 2013 Leandro Facchinetti <leafac@gmail.com>
|
5
|
+
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
7
|
+
copies of this license document, and changing it is allowed as long
|
8
|
+
as the name is changed.
|
9
|
+
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
data/README.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
Ruby Tapas Downloader
|
2
|
+
=====================
|
3
|
+
|
4
|
+
[Ruby Tapas][ruby-tapas] is a great series of screencasts by
|
5
|
+
[Avdi Grimm][avdi-grimm]. You should totally check it out if you don't already
|
6
|
+
know it!
|
7
|
+
|
8
|
+
There's only one problem with Ruby Tapas, in my opinion: there's no way to
|
9
|
+
watch it via straming. One can only download episodes, which soon becomes
|
10
|
+
tedious.
|
11
|
+
|
12
|
+
Enters Ruby Tapas Downloader! It downloads all episodes and attachments,
|
13
|
+
organizes them for later use and keeps an easy to use index of episodes.
|
14
|
+
|
15
|
+
Installation
|
16
|
+
------------
|
17
|
+
|
18
|
+
```bash
|
19
|
+
$ gem install ruby-tapas-downloader
|
20
|
+
```
|
21
|
+
|
22
|
+
Usage
|
23
|
+
-----
|
24
|
+
|
25
|
+
```bash
|
26
|
+
$ ruby-tapas-downloader <email> <password> <download-path>
|
27
|
+
```
|
28
|
+
|
29
|
+
Warning
|
30
|
+
-------
|
31
|
+
|
32
|
+
Except for a few episodes, Ruby Tapas is a paid screencast. Therefore, assert
|
33
|
+
that you don't redistribute the downloaded material. Ruby Tapas Downloader is
|
34
|
+
only an utility tool and doesn't substitute the subscription.
|
35
|
+
|
36
|
+
You should do no evil!
|
37
|
+
|
38
|
+
Thanks
|
39
|
+
------
|
40
|
+
|
41
|
+
Thanks Avdi Grimm for putting all this great material out the door!
|
42
|
+
|
43
|
+
I learn a lot from you.
|
44
|
+
|
45
|
+
[ruby-tapas]: http://www.rubytapas.com/
|
46
|
+
[avdi-grimm]: http://devblog.avdi.org/
|
data/config/urls.yml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'rss'
|
4
|
+
require 'rexml/document'
|
5
|
+
require 'set'
|
6
|
+
require 'cgi'
|
7
|
+
require 'logger'
|
8
|
+
|
9
|
+
module RubyTapasDownloader
|
10
|
+
class << self
|
11
|
+
# The Logger for RubyTapasDownloader.
|
12
|
+
attr_writer :logger
|
13
|
+
|
14
|
+
# @return [Logger] the Logger for RubyTapasDownloader
|
15
|
+
def logger
|
16
|
+
@logger ||= Logger.new STDOUT
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'bundler/setup'
|
22
|
+
require 'mechanize'
|
23
|
+
|
24
|
+
require_relative 'ruby_tapas_downloader/downloadables'
|
25
|
+
|
26
|
+
require_relative 'ruby_tapas_downloader/extractors'
|
27
|
+
|
28
|
+
require_relative 'ruby_tapas_downloader/config'
|
29
|
+
require_relative 'ruby_tapas_downloader/login'
|
30
|
+
require_relative 'ruby_tapas_downloader/feed_fetcher'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative '../ruby-tapas-downloader'
|
2
|
+
|
3
|
+
# The Command Line Interface for Ruby Tapas Downloader.
|
4
|
+
class RubyTapasDownloader::CLI
|
5
|
+
# @param email [String] the e-mail for the user.
|
6
|
+
# @param password [String] the password for the user.
|
7
|
+
# @param download_path [String] the path in which the download is performed.
|
8
|
+
def initialize email, password, download_path
|
9
|
+
@email = email
|
10
|
+
@password = password
|
11
|
+
@download_path = download_path
|
12
|
+
end
|
13
|
+
|
14
|
+
# Perform complete download procedure.
|
15
|
+
def download
|
16
|
+
create_agent
|
17
|
+
login
|
18
|
+
fetch_feed
|
19
|
+
create_catalog
|
20
|
+
download_catalog
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def create_agent
|
26
|
+
@agent = Mechanize.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def login
|
30
|
+
RubyTapasDownloader::Login.new(@agent, @email, @password).login
|
31
|
+
end
|
32
|
+
|
33
|
+
def fetch_feed
|
34
|
+
@feed = RubyTapasDownloader::FeedFetcher.new(@agent, @email, @password)
|
35
|
+
.fetch
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_catalog
|
39
|
+
@catalog = RubyTapasDownloader::Extractors::Catalog.new.extract @feed
|
40
|
+
end
|
41
|
+
|
42
|
+
def download_catalog
|
43
|
+
@catalog.download @download_path, @agent
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Catalog is the set of all Ruby Tapas Episodes.
|
2
|
+
class RubyTapasDownloader::Downloadables::Catalog <
|
3
|
+
RubyTapasDownloader::Downloadable
|
4
|
+
|
5
|
+
# @return [Set<RubyTapasDownloader::Downloadables::Episode>] the Episodes.
|
6
|
+
attr_reader :episodes
|
7
|
+
|
8
|
+
def initialize episodes
|
9
|
+
@episodes = episodes
|
10
|
+
end
|
11
|
+
|
12
|
+
# Download the Catalog.
|
13
|
+
#
|
14
|
+
# @param basepath [String] the path to place download.
|
15
|
+
# @param agent [Mechanize] the Mechanize agent.
|
16
|
+
def download basepath, agent
|
17
|
+
RubyTapasDownloader.logger.info 'Starting download of catalog in ' \
|
18
|
+
"`#{ basepath }'..."
|
19
|
+
FileUtils.mkdir_p basepath
|
20
|
+
episodes.each { |episode| episode.download basepath, agent }
|
21
|
+
end
|
22
|
+
|
23
|
+
def == other
|
24
|
+
episodes == other.episodes
|
25
|
+
end
|
26
|
+
|
27
|
+
def eql? other
|
28
|
+
episodes.eql? other.episodes
|
29
|
+
end
|
30
|
+
|
31
|
+
def hash
|
32
|
+
episodes.hash
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# An Ruby Tapas Episode.
|
2
|
+
class RubyTapasDownloader::Downloadables::Episode <
|
3
|
+
RubyTapasDownloader::Downloadable
|
4
|
+
|
5
|
+
# @return [String] the title of the Episode.
|
6
|
+
attr_reader :title
|
7
|
+
|
8
|
+
# @return [String] the link to the Episode.
|
9
|
+
attr_reader :link
|
10
|
+
|
11
|
+
# @return [Set<RubyTapasDownloader::Downloadables::File>] the Set of Files
|
12
|
+
# for that episode.
|
13
|
+
attr_reader :files
|
14
|
+
|
15
|
+
def initialize title, link, files
|
16
|
+
@title = title
|
17
|
+
@link = link
|
18
|
+
@files = files
|
19
|
+
end
|
20
|
+
|
21
|
+
# Clean title to be used in path names.
|
22
|
+
#
|
23
|
+
# @return [String] the sanitized title.
|
24
|
+
def sanitized_title
|
25
|
+
@sanitized_title ||= title.downcase.gsub(/[^\w<>#?!$]+/, '-')
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# Download the Episode.
|
30
|
+
#
|
31
|
+
# @param (see: RubyTapasDownloader::Downloadables::Catalog#download)
|
32
|
+
def download basepath, agent
|
33
|
+
episode_path = File.join basepath, sanitized_title
|
34
|
+
RubyTapasDownloader.logger.info 'Starting download of episode ' \
|
35
|
+
"`#{ title }' in `#{ episode_path }'..."
|
36
|
+
FileUtils.mkdir_p episode_path
|
37
|
+
files.each { |file| file.download episode_path, agent }
|
38
|
+
end
|
39
|
+
|
40
|
+
def == other
|
41
|
+
title == other.title && link == other.link && files == other.files
|
42
|
+
end
|
43
|
+
|
44
|
+
def eql? other
|
45
|
+
title.eql?(other.title) && link.eql?(other.link) && files.eql?(other.files)
|
46
|
+
end
|
47
|
+
|
48
|
+
def hash
|
49
|
+
title.hash + link.hash + files.hash
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# The File resource of an Episode.
|
2
|
+
class RubyTapasDownloader::Downloadables::File <
|
3
|
+
RubyTapasDownloader::Downloadable
|
4
|
+
|
5
|
+
# @return [String] the name of the File.
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
# @return [String] the link to download the File.
|
9
|
+
attr_reader :link
|
10
|
+
|
11
|
+
def initialize name, link
|
12
|
+
@name = name
|
13
|
+
@link = link
|
14
|
+
end
|
15
|
+
|
16
|
+
# Download the File.
|
17
|
+
#
|
18
|
+
# @param (see: RubyTapasDownloader::Downloadables::Catalog#download)
|
19
|
+
def download basepath, agent
|
20
|
+
FileUtils.mkdir_p basepath
|
21
|
+
|
22
|
+
file_path = File.join(basepath, name)
|
23
|
+
RubyTapasDownloader.logger.info "Starting download of file `#{ name }' " \
|
24
|
+
"in `#{ file_path }'..."
|
25
|
+
agent.download link, file_path unless File.exists? file_path
|
26
|
+
end
|
27
|
+
|
28
|
+
def == other
|
29
|
+
name == other.name && link == other.link
|
30
|
+
end
|
31
|
+
|
32
|
+
def eql? other
|
33
|
+
name.eql?(other.name) && link.eql?(other.link)
|
34
|
+
end
|
35
|
+
|
36
|
+
def hash
|
37
|
+
name.hash + link.hash
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Extract an Catalog from an Feed.
|
2
|
+
class RubyTapasDownloader::Extractors::Catalog < RubyTapasDownloader::Extractor
|
3
|
+
# @param episode_extractor [RubyTapasDownloader::Extractors::Episode] the
|
4
|
+
# Episode Extractor.
|
5
|
+
def initialize episode_extractor =
|
6
|
+
RubyTapasDownloader::Extractors::Episode.new
|
7
|
+
@episode_extractor = episode_extractor
|
8
|
+
end
|
9
|
+
|
10
|
+
# @param feed [RSS::Rss] the feed extracted with `RSS::Parser.parse`.
|
11
|
+
# @return [RubyTapasDownloader::Downloadables::Catalog] the Catalog extracted
|
12
|
+
# from feed.
|
13
|
+
def extract feed
|
14
|
+
episodes = Set.new
|
15
|
+
|
16
|
+
feed.items.each { |item|
|
17
|
+
episodes << @episode_extractor.extract(item)
|
18
|
+
}
|
19
|
+
|
20
|
+
RubyTapasDownloader::Downloadables::Catalog.new episodes
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Extract an Episode from an Feed Item.
|
2
|
+
class RubyTapasDownloader::Extractors::Episode < RubyTapasDownloader::Extractor
|
3
|
+
# @param files_extractor [RubyTapasDownloader::Extractors::Files] the
|
4
|
+
# Files Extractor.
|
5
|
+
def initialize files_extractor = RubyTapasDownloader::Extractors::Files.new
|
6
|
+
@files_extractor = files_extractor
|
7
|
+
end
|
8
|
+
|
9
|
+
# @param item [RSS::Rss::Channel::Item] the feed item extracted with
|
10
|
+
# `feed.items[i]`.
|
11
|
+
# @return [RubyTapasDownloader::Downloadables::Episode] the Episode extracted
|
12
|
+
# from feed item.
|
13
|
+
def extract item
|
14
|
+
title = CGI.unescapeHTML item.title
|
15
|
+
link = item.link
|
16
|
+
files = @files_extractor.extract item.description
|
17
|
+
|
18
|
+
RubyTapasDownloader::Downloadables::Episode.new title, link, files
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Extract a Set of Files from an Feed Item Description.
|
2
|
+
class RubyTapasDownloader::Extractors::Files < RubyTapasDownloader::Extractor
|
3
|
+
# @param item_description [String] the feed item description extracted with
|
4
|
+
# `feed.items[i].description`.
|
5
|
+
# @return [Set<RubyTapasDownloader::Downloadables::File>] the Set of Files
|
6
|
+
# extracted from feed item description.
|
7
|
+
def extract item_description
|
8
|
+
files = Set.new
|
9
|
+
document = REXML::Document.new item_description
|
10
|
+
document.elements.each("/div[@class='blog-entry']/ul/li/a") { |element|
|
11
|
+
name = element.text
|
12
|
+
link = element.attribute('href').to_s
|
13
|
+
files << RubyTapasDownloader::Downloadables::File.new(name, link)
|
14
|
+
}
|
15
|
+
files
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Fetches feed from Ruby Tapas.
|
2
|
+
class RubyTapasDownloader::FeedFetcher
|
3
|
+
# @return [Mechanize] the Mechanize agent.
|
4
|
+
attr_reader :agent
|
5
|
+
|
6
|
+
# @return [String] the e-mail for the user.
|
7
|
+
attr_reader :email
|
8
|
+
|
9
|
+
# @return [String] the password for the user.
|
10
|
+
attr_reader :password
|
11
|
+
|
12
|
+
def initialize agent, email, password
|
13
|
+
@agent = agent
|
14
|
+
@email = email
|
15
|
+
@password = password
|
16
|
+
end
|
17
|
+
|
18
|
+
# Fetch feed from Ruby Tapas.
|
19
|
+
#
|
20
|
+
# @return [RSS::Rss] the feed for Ruby Tapas.
|
21
|
+
def fetch
|
22
|
+
RubyTapasDownloader.logger.info 'Fetching episodes feed...'
|
23
|
+
|
24
|
+
feed_url = RubyTapasDownloader::Config.urls[:feed]
|
25
|
+
|
26
|
+
agent.add_auth feed_url, email, password
|
27
|
+
RSS::Parser.parse agent.get(feed_url).body
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Perform Login in Ruby Tapas.
|
2
|
+
#
|
3
|
+
# Login must be performed before any attempt to download files.
|
4
|
+
class RubyTapasDownloader::Login
|
5
|
+
# @return [Mechanize] the Mechanize agent.
|
6
|
+
attr_reader :agent
|
7
|
+
|
8
|
+
# @return [String] the e-mail for the user.
|
9
|
+
attr_reader :email
|
10
|
+
|
11
|
+
# @return [String] the password for the user.
|
12
|
+
attr_reader :password
|
13
|
+
|
14
|
+
def initialize agent, email, password
|
15
|
+
@agent = agent
|
16
|
+
@email = email
|
17
|
+
@password = password
|
18
|
+
end
|
19
|
+
|
20
|
+
# Perform login.
|
21
|
+
def login
|
22
|
+
RubyTapasDownloader.logger.info 'Logging in...'
|
23
|
+
request_login_page
|
24
|
+
fill_login_form
|
25
|
+
submit_login_form
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def request_login_page
|
31
|
+
@page = agent.get RubyTapasDownloader::Config.urls.fetch(:login)
|
32
|
+
end
|
33
|
+
|
34
|
+
def fill_login_form
|
35
|
+
login_form.username = email
|
36
|
+
login_form.password = password
|
37
|
+
end
|
38
|
+
|
39
|
+
def submit_login_form
|
40
|
+
login_form.submit
|
41
|
+
end
|
42
|
+
|
43
|
+
def login_form
|
44
|
+
@page.forms.first
|
45
|
+
end
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-tapas-downloader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Leandro Facchinetti
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: mechanize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry-debugger
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.2'
|
55
|
+
description: It downloads all episodes and attachments, organizes them for later use
|
56
|
+
and keeps an easy to use index of episodes.
|
57
|
+
email: ruby-tapas-downloader@leafac.com
|
58
|
+
executables:
|
59
|
+
- ruby-tapas-downloader
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files:
|
62
|
+
- README.md
|
63
|
+
files:
|
64
|
+
- License.txt
|
65
|
+
- README.md
|
66
|
+
- bin/ruby-tapas-downloader
|
67
|
+
- config/urls.yml
|
68
|
+
- lib/ruby-tapas-downloader.rb
|
69
|
+
- lib/ruby_tapas_downloader/cli.rb
|
70
|
+
- lib/ruby_tapas_downloader/config.rb
|
71
|
+
- lib/ruby_tapas_downloader/downloadable.rb
|
72
|
+
- lib/ruby_tapas_downloader/downloadables.rb
|
73
|
+
- lib/ruby_tapas_downloader/downloadables/catalog.rb
|
74
|
+
- lib/ruby_tapas_downloader/downloadables/episode.rb
|
75
|
+
- lib/ruby_tapas_downloader/downloadables/file.rb
|
76
|
+
- lib/ruby_tapas_downloader/extractor.rb
|
77
|
+
- lib/ruby_tapas_downloader/extractors.rb
|
78
|
+
- lib/ruby_tapas_downloader/extractors/catalog.rb
|
79
|
+
- lib/ruby_tapas_downloader/extractors/episode.rb
|
80
|
+
- lib/ruby_tapas_downloader/extractors/files.rb
|
81
|
+
- lib/ruby_tapas_downloader/feed_fetcher.rb
|
82
|
+
- lib/ruby_tapas_downloader/login.rb
|
83
|
+
- lib/ruby_tapas_downloader/version.rb
|
84
|
+
homepage: https://github.com/leafac/ruby-tapas-downloader
|
85
|
+
licenses:
|
86
|
+
- wtfpl
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.2.2
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Downloader for Avdi Grimm Ruby Tapas
|
108
|
+
test_files: []
|