addic7ed_downloader 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/console +3 -0
- data/exe/addic7ed +103 -0
- data/lib/addic7ed_downloader/common.rb +5 -5
- data/lib/addic7ed_downloader/search.rb +20 -23
- data/lib/addic7ed_downloader/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d5010c8960bd6a47416839f748b667d317ca962
|
4
|
+
data.tar.gz: e8457ab07b0a71d956ddf1bb0930b879b4b098ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c3e8788e8906148eb9aa9d1b5e8103d2b3070477a5534283098eeb0d85e3c0120f7c4e4991b272aaf1953c677cef9f5f2b586ee3affc7e6000d15b929372f2c
|
7
|
+
data.tar.gz: a98a926cc5a8ab0a3d0f6adf9500c1e1135cf593df09a1b4c7943452f58c07fa6f5af2b29e74122e0fb3010eb119fe2c6e4c46126331902b4463a22010913714
|
data/bin/console
CHANGED
@@ -5,6 +5,9 @@ require 'addic7ed_downloader'
|
|
5
5
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
filename = "frasier s01e01 Pilot.mkv"
|
9
|
+
filename = 'Game.of.Thrones.S06E03.Oathbreaker.1080p.WEB-DL.DD5.1.H264-NTb[rartv].mkv'
|
10
|
+
search = Addic7edDownloader::Search.by_filename(filename)
|
8
11
|
|
9
12
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
13
|
require 'pry'
|
data/exe/addic7ed
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w( .. lib ))
|
3
|
+
|
4
|
+
require 'addic7ed_downloader'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'highline'
|
7
|
+
require 'optparse'
|
8
|
+
|
9
|
+
options = {
|
10
|
+
rename: true,
|
11
|
+
language: 'en',
|
12
|
+
path: './'
|
13
|
+
}
|
14
|
+
|
15
|
+
optparse = OptionParser.new do |opts|
|
16
|
+
opts.banner = 'Usage: addic7ed [options] <search or video file>'
|
17
|
+
|
18
|
+
opts.on('-y', '--auto-download', 'Download best result without confirmation') do
|
19
|
+
options[:auto] = true
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on('-L', '--list', 'List languages.') do
|
23
|
+
puts 'Available languages:'
|
24
|
+
Addic7edDownloader::LANGUAGES.each { |key, value| puts "#{key}:\t#{value[:name]}" }
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on('-l LANGUAGE', '--language LANGUAGE', 'Language code to look subtitles for (default: English)') do |l|
|
29
|
+
options[:language] = l
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on('-n', '--no-rename', "Don't automatically rename subtitles if the file exists") do
|
33
|
+
options[:rename] = false
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on('-p PATH', '--path PATH', 'Path to save the file') do |p|
|
37
|
+
options[:path] = p
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on('-v', '--version', 'Print version and exit') do
|
41
|
+
puts "addic7ed v#{Addic7edDownloader::VERSION}"
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
46
|
+
puts opts
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
end.parse!
|
50
|
+
|
51
|
+
# Join arguments to create the search term
|
52
|
+
options[:search] = optparse.join(' ')
|
53
|
+
|
54
|
+
# main program
|
55
|
+
begin
|
56
|
+
cli = HighLine.new
|
57
|
+
HighLine.colorize_strings # Monkey patch String for cli colors
|
58
|
+
|
59
|
+
# Valid search?
|
60
|
+
if options[:search].empty?
|
61
|
+
cli.say 'Please choose a file or type a search'.red
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
|
65
|
+
# Search subtitle
|
66
|
+
search = Addic7edDownloader::Search.by_filename(options[:search], lang: options[:language])
|
67
|
+
|
68
|
+
# Results found?
|
69
|
+
if search.nil?
|
70
|
+
cli.say 'Error parsing the file or search'.red
|
71
|
+
exit
|
72
|
+
elsif search.results.empty?
|
73
|
+
cli.say 'No subtitles found'.red
|
74
|
+
exit
|
75
|
+
end
|
76
|
+
|
77
|
+
# Choose
|
78
|
+
if options[:auto]
|
79
|
+
subtitles = search.find_best_subtitle
|
80
|
+
else
|
81
|
+
cli.say "Search results for #{search}. Choose the file:"
|
82
|
+
subtitles = cli.choose(*search.results) do |menu|
|
83
|
+
menu.default = '1'
|
84
|
+
menu.select_by = :index
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Download subtitle
|
89
|
+
sub_file = search.download_subtitle(subtitles, options[:path])
|
90
|
+
|
91
|
+
# Rename file to match the video if it exists
|
92
|
+
if options[:rename] && File.exist?(options[:search])
|
93
|
+
# Extract video filename without extension
|
94
|
+
filename = File.basename(options[:search], File.extname(options[:search]))
|
95
|
+
FileUtils.mv(sub_file, "#{filename}#{File.extname(sub_file)}")
|
96
|
+
end
|
97
|
+
|
98
|
+
cli.say 'Subtitle downloaded successfully!'.green
|
99
|
+
rescue Interrupt, EOFError
|
100
|
+
cli.say 'Interrupted!'.red
|
101
|
+
rescue SocketError
|
102
|
+
cli.say "Couldn't perform action. Are you online?".red
|
103
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module Addic7edDownloader
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
TAGS_REGEXP =
|
6
|
-
TAGS_FILTER_REGEXP = /(?<!WEB)-(?!DL)|[\.\s\(\)\[\]]+/
|
2
|
+
# Assuming: "SHOWNAME - SEASON&EPISODE - TAGS"
|
3
|
+
SEASON_EPISODE_REGEXP = /s(?<season>\d{1,2})e(?<episode>\d{1,2})|(?<season>\d{1,2})x(?<episode>\d{1,2})/i
|
4
|
+
SHOWNAME_REGEXP = /(?<showname>[\w\s\.]+?)[\s\.-]*?#{SEASON_EPISODE_REGEXP}/i
|
5
|
+
TAGS_REGEXP = /#{SEASON_EPISODE_REGEXP}[\s\.-]?(?<tags>.*)/i # Get the end of file
|
6
|
+
TAGS_FILTER_REGEXP = /(?<!WEB)-(?!DL)|[\.\s\(\)\[\]]+/i # Filter '-', but not 'WEB-DL'
|
7
7
|
|
8
8
|
# Ripped from gem addic7ed (Check them out!)
|
9
9
|
LANGUAGES = {
|
@@ -6,37 +6,34 @@ module Addic7edDownloader
|
|
6
6
|
BASE_URL = 'http://www.addic7ed.com'.freeze
|
7
7
|
DEFAULTS = {
|
8
8
|
lang: 'en',
|
9
|
-
tags: []
|
10
|
-
path: './'
|
9
|
+
tags: []
|
11
10
|
}.freeze
|
12
11
|
|
13
12
|
attr_accessor :showname, :season, :episode, :lang, :tags, :path
|
14
13
|
|
15
14
|
def self.by_filename(filename, options = {})
|
16
|
-
showname = filename[SHOWNAME_REGEXP,
|
17
|
-
season = filename[
|
18
|
-
episode = filename[
|
19
|
-
options[:tags] = filename[TAGS_REGEXP,
|
20
|
-
|
21
|
-
new(showname, season, episode, options)
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.by_string(search_string, options = {})
|
25
|
-
showname = search_string[SHOWNAME_REGEXP, 1].strip
|
26
|
-
season = search_string[SEASON_REGEXP, 1].to_i
|
27
|
-
episode = search_string[EPISODE_REGEXP, 1].to_i
|
28
|
-
options[:tags] = options[:filename][TAGS_REGEXP, 1].split(TAGS_FILTER_REGEXP) if options[:filename]
|
15
|
+
showname = filename[SHOWNAME_REGEXP, :showname].strip
|
16
|
+
season = filename[SEASON_EPISODE_REGEXP, :season].to_i
|
17
|
+
episode = filename[SEASON_EPISODE_REGEXP, :episode].to_i
|
18
|
+
options[:tags] = filename[TAGS_REGEXP, :tags].split(TAGS_FILTER_REGEXP)
|
29
19
|
|
30
20
|
new(showname, season, episode, options)
|
21
|
+
rescue NoMethodError
|
22
|
+
# Failed to parse
|
23
|
+
nil
|
31
24
|
end
|
32
25
|
|
33
26
|
def initialize(showname, season, episode, options = {})
|
34
|
-
@showname = showname
|
27
|
+
@showname = showname.tr('.', ' ')
|
35
28
|
@season = season.to_i
|
36
29
|
@episode = episode.to_i
|
37
30
|
|
38
31
|
opts = DEFAULTS.merge(options)
|
39
|
-
@lang, @tags
|
32
|
+
@lang, @tags = opts.values_at(:lang, :tags)
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
"#{@showname.split.map(&:capitalize).join(' ')} #{sprintf('%02dx%02d', @season, @episode)}"
|
40
37
|
end
|
41
38
|
|
42
39
|
def results
|
@@ -57,11 +54,11 @@ module Addic7edDownloader
|
|
57
54
|
results.first
|
58
55
|
end
|
59
56
|
|
60
|
-
def download_best
|
61
|
-
download_subtitle(find_best_subtitle)
|
57
|
+
def download_best(path = './')
|
58
|
+
download_subtitle(find_best_subtitle, path)
|
62
59
|
end
|
63
60
|
|
64
|
-
def download_subtitle(subtitle)
|
61
|
+
def download_subtitle(subtitle, path = './')
|
65
62
|
return unless subtitle
|
66
63
|
|
67
64
|
# Addic7ed needs the correct Referer to be set
|
@@ -72,8 +69,9 @@ module Addic7edDownloader
|
|
72
69
|
|
73
70
|
raise unless response.headers['content-type'].include? 'text/srt'
|
74
71
|
|
72
|
+
# Get file name from headers
|
75
73
|
filename = response.headers['content-disposition'][/filename=\"(.+?)\"/, 1]
|
76
|
-
open(filename, 'w') { |f| f << response }
|
74
|
+
open(File.join(path, filename), 'w') { |f| f << response }
|
77
75
|
|
78
76
|
# return subtitle filename
|
79
77
|
filename
|
@@ -86,7 +84,7 @@ module Addic7edDownloader
|
|
86
84
|
end
|
87
85
|
|
88
86
|
def url
|
89
|
-
@url ||=
|
87
|
+
@url ||= "#{BASE_URL}/serie/#{CGI.escape(@showname)}/#{@season}/#{@episode}/#{LANGUAGES[@lang][:id]}"
|
90
88
|
end
|
91
89
|
|
92
90
|
def build_subtitles_list
|
@@ -102,7 +100,6 @@ module Addic7edDownloader
|
|
102
100
|
end
|
103
101
|
|
104
102
|
# We return the completed subtitles, ordered by downloads desc
|
105
|
-
# Using bang methods for memory performance
|
106
103
|
subtitles.select(&:completed?).sort!.reverse!
|
107
104
|
end
|
108
105
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: addic7ed_downloader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Marchante
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -167,7 +167,8 @@ dependencies:
|
|
167
167
|
description:
|
168
168
|
email:
|
169
169
|
- davidmarchan@gmail.com
|
170
|
-
executables:
|
170
|
+
executables:
|
171
|
+
- addic7ed
|
171
172
|
extensions: []
|
172
173
|
extra_rdoc_files: []
|
173
174
|
files:
|
@@ -182,6 +183,7 @@ files:
|
|
182
183
|
- addic7ed_downloader.gemspec
|
183
184
|
- bin/console
|
184
185
|
- bin/setup
|
186
|
+
- exe/addic7ed
|
185
187
|
- lib/addic7ed_downloader.rb
|
186
188
|
- lib/addic7ed_downloader/common.rb
|
187
189
|
- lib/addic7ed_downloader/search.rb
|