get-addic7ed 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9d5ff8f9da39da43045c9cad1deb440fa6a54d8c
4
+ data.tar.gz: bad8feb10529aebe17e1507fd30b7db2f77d7c01
5
+ SHA512:
6
+ metadata.gz: f76e8571f9d431a8ce5fbaa6b958ae334e6fb2a88210ba5fe3a5964f0e07723fa32648aa557507e35ee9e8e44c0100a7b1c6b66d7b6f89ac6c6bf63792074b80
7
+ data.tar.gz: 5d5241b0f9a27a839eff5f1cbbf47112fd83932e136bfa9d629b9cfad1ea62dc89c1ef432158281b21927b31b9a7063a71509c85af7e86c7b596accb0aec105f
data/bin/get-addic7ed ADDED
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env ruby
2
+ require "bundler/setup"
3
+ require "optparse"
4
+ require "get-addic7ed"
5
+
6
+ ARGV << '-h' if ARGV.empty?
7
+
8
+ # Options
9
+ options = {}
10
+
11
+ optparse = OptionParser.new do |opts|
12
+ opts.banner = "Usage :\tget-addic7ed [options] <file1> [<file2>, <file3>, ...]\n"
13
+
14
+ # Help
15
+ opts.on_tail("-h", "--help", "Display this actual help page") do
16
+ puts opts
17
+ exit
18
+ end
19
+
20
+ # All Languages
21
+ opts.on_tail("-L", "--all-languages", "List all available languages") do
22
+ puts "All available languages :"
23
+ GetAddic7ed::LANGUAGES.each do |lang, infos|
24
+ puts "#{lang}:\t#{infos[:name]}"
25
+ end
26
+ exit
27
+ end
28
+
29
+ # Version
30
+ opts.on_tail("-V", "--version", "Get get-addic7ed version") do
31
+ puts "v#{GetAddic7ed::VERSION}"
32
+ exit
33
+ end
34
+
35
+ # Language
36
+ opts.on("-l LANGUAGE", "--language LANGUAGE", "Language code for your subtitle (French by default)") do |l|
37
+ options[:language] = l
38
+ end
39
+
40
+ # Choose manually
41
+ opts.on("-c", "--choose", "Choose your subitle manually") do |c|
42
+ options[:choose] = c
43
+ end
44
+
45
+ #Include Tag
46
+ opts.on("-t", "--tagged", "Include language tag in filename") do |t|
47
+ options[:tagged] = t
48
+ end
49
+
50
+ # Verbose
51
+ opts.on("-v", "--verbose", "Display more details") do |v|
52
+ options[:verbose] = v
53
+ end
54
+
55
+ # Quiet
56
+ opts.on("-q", "--quiet", "Run without output (cron-mode)") do |q|
57
+ options[:quiet] = q
58
+ end
59
+
60
+ # Do not download
61
+ opts.on("-n", "--do-not-download", "Do not download the subtitle") do |n|
62
+ options[:nodownload] = n
63
+ end
64
+
65
+ # Debbug mode
66
+ =begin
67
+ opts.on("-d", "--debug", "Debug mode [do not use]") do |d|
68
+ options[:debug] = d
69
+ end
70
+ =end
71
+
72
+ end
73
+
74
+ optparse.parse!
75
+
76
+ # By default
77
+ options[:filenames] = ARGV
78
+ options[:language] ||= 'fr'
79
+ options[:choose] ||= false
80
+ options[:tagged] ||= false
81
+ options[:verbose] ||= false
82
+ options[:quiet] ||= false
83
+ options[:nodownload] ||= false
84
+
85
+ # Set option in module GetAddic7ed
86
+ GetAddic7ed::OPT_CHOOSE = options[:choose]
87
+ GetAddic7ed::OPT_TAGGED = options[:tagged]
88
+ GetAddic7ed::OPT_VERBOSE = options[:verbose]
89
+ GetAddic7ed::OPT_QUIET = options[:quiet]
90
+ GetAddic7ed::OPT_NODOWNLOAD = options[:nodownload]
91
+
92
+ options[:filenames].each do |filename|
93
+ unless File.file? filename
94
+ puts "File Error : #{filename}\nSkipping..." unless options[:quiet]
95
+ next
96
+ end
97
+
98
+ #TODO if it's a directory explore videos files
99
+
100
+ begin
101
+
102
+ puts "===\tFile\t===" if options[:verbose]
103
+ file = GetAddic7ed::VideoFile.new(ARGV[0])
104
+ file.inspect if options[:verbose]
105
+
106
+ puts "\n===\tShow\t===" if options[:verbose]
107
+ episode = GetAddic7ed::Episode.new( file.filepath )
108
+ episode.inspect if options[:verbose]
109
+
110
+ puts "\n===\tSubtitle\t===" if options[:verbose]
111
+ subtitle = GetAddic7ed::Subtitle.new( episode, options[:language] )
112
+ subtitle.inspect if options[:verbose]
113
+
114
+ unless options[:nodownload]
115
+ puts "\nDownloading..." if options[:verbose]
116
+ subtitle.download_sub
117
+ else
118
+ puts "[Not Downloaded]"
119
+ end
120
+
121
+ rescue GetAddic7ed::InvalidFile
122
+ puts "Error : Argument Is Not A File"
123
+ rescue GetAddic7ed::ConnectionError
124
+ puts "Error : Failed To Reach Addic7ed.com"
125
+ rescue GetAddic7ed::ShowNotFound
126
+ puts "Error : Show Not Found"
127
+ rescue GetAddic7ed::NoSubtitleFound
128
+ puts "Error : No Subtitle Found"
129
+ rescue GetAddic7ed::DownloadError
130
+ puts "Error : Download Error"
131
+ rescue GetAddic7ed::ConnectionError
132
+ puts "Error : Connection Error"
133
+ rescue GetAddic7ed::DownloadLimitReached
134
+ puts "Error : You Have Reach The Download Limit On Addic7ed.com"
135
+ rescue GetAddic7ed::SubtitleCannotBeSaved
136
+ puts "Error : Subtitle Can't Be Save"
137
+ end
138
+
139
+ puts "Done." unless options[:quiet]
140
+ end
141
+
@@ -0,0 +1,53 @@
1
+ module GetAddic7ed
2
+ =begin
3
+ From addic7ed-ruby gem
4
+ =end
5
+
6
+ LANGUAGES = {
7
+ 'ar' => {name: 'Arabic', id: 38},
8
+ 'az' => {name: 'Azerbaijani', id: 48},
9
+ 'bn' => {name: 'Bengali', id: 47},
10
+ 'bs' => {name: 'Bosnian', id: 44},
11
+ 'bg' => {name: 'Bulgarian', id: 35},
12
+ 'ca' => {name: 'Català', id: 12},
13
+ 'cn' => {name: 'Chinese (Simplified)', id: 41},
14
+ 'zh' => {name: 'Chinese (Traditional)', id: 24},
15
+ 'hr' => {name: 'Croatian', id: 31},
16
+ 'cs' => {name: 'Czech', id: 14},
17
+ 'da' => {name: 'Danish', id: 30},
18
+ 'nl' => {name: 'Dutch', id: 17},
19
+ 'en' => {name: 'English', id: 1},
20
+ 'eu' => {name: 'Euskera', id: 13},
21
+ 'fi' => {name: 'Finnish', id: 28},
22
+ 'fr' => {name: 'French', id: 8},
23
+ 'gl' => {name: 'Galego', id: 15},
24
+ 'de' => {name: 'German', id: 11},
25
+ 'el' => {name: 'Greek', id: 27},
26
+ 'he' => {name: 'Hebrew', id: 23},
27
+ 'hu' => {name: 'Hungarian', id: 20},
28
+ 'id' => {name: 'Indonesian', id: 37},
29
+ 'it' => {name: 'Italian', id: 7},
30
+ 'ja' => {name: 'Japanese', id: 32},
31
+ 'ko' => {name: 'Korean', id: 42},
32
+ 'mk' => {name: 'Macedonian', id: 49},
33
+ 'ms' => {name: 'Malay', id: 40},
34
+ 'no' => {name: 'Norwegian', id: 29},
35
+ 'fa' => {name: 'Persian', id: 43},
36
+ 'pl' => {name: 'Polish', id: 21},
37
+ 'pt' => {name: 'Portuguese', id: 9},
38
+ 'pt-br' => {name: 'Portuguese (Brazilian)', id: 10},
39
+ 'ro' => {name: 'Romanian', id: 26},
40
+ 'ru' => {name: 'Russian', id: 19},
41
+ 'sr' => {name: 'Serbian (Cyrillic)', id: 39},
42
+ 'sr-la' => {name: 'Serbian (Latin)', id: 36},
43
+ 'sk' => {name: 'Slovak', id: 25},
44
+ 'sl' => {name: 'Slovenian', id: 22},
45
+ 'es' => {name: 'Spanish', id: 4},
46
+ 'es-la' => {name: 'Spanish (Latin America)', id: 6},
47
+ 'es-es' => {name: 'Spanish (Spain)', id: 5},
48
+ 'sv' => {name: 'Swedish', id: 18},
49
+ 'th' => {name: 'Thai', id: 46},
50
+ 'tr' => {name: 'Turkish', id: 16},
51
+ 'vi' => {name: 'Vietnamese', id: 45}
52
+ }
53
+ end
@@ -0,0 +1,94 @@
1
+ require "nokogiri"
2
+ require "fuzzystringmatch"
3
+ require "open-uri"
4
+
5
+ module GetAddic7ed
6
+ class Episode
7
+
8
+ REGEX_SEASON_EPISODE = /\WS?(?<season>\d{1,2})[XE](?<episode>\d{2})\W|\W(?<seasonepisode>[0-9]{3})\W/i
9
+ attr_reader :id, :title, :season, :episode, :filename, :filepath
10
+
11
+ def initialize filepath
12
+ @filename = File.basename filepath
13
+ @filepath = filepath
14
+
15
+ if results = REGEX_SEASON_EPISODE.match(filename)
16
+ pos = filename.rindex(REGEX_SEASON_EPISODE)
17
+ @title = filename[0, pos].gsub(/[.]|\s/i, ' ')
18
+
19
+ unless results[:seasonepisode]
20
+ @season = results[:season].to_i
21
+ @episode = results[:episode].to_i
22
+ else
23
+ @season = results[:seasonepisode][0].to_i
24
+ @episode = results[:seasonepisode][1,2].to_i
25
+ end
26
+ else
27
+ raise InvalidFilename
28
+ end
29
+
30
+ @id = self.class.get_show_id @title
31
+ raise ShowNotFound if @id == nil
32
+ end
33
+
34
+ #Get all show from addic7ed.com
35
+ def self.get_all_shows
36
+ uri = URI('http://www.addic7ed.com/')
37
+ all_shows = {}
38
+
39
+
40
+ puts "Try to reach Addic7ed.com, please wait..." unless GetAddic7ed::OPT_QUIET
41
+
42
+ begin
43
+ body = open(uri)
44
+ rescue
45
+ raise ConnectionError
46
+ end
47
+
48
+ html = Nokogiri::HTML(body)
49
+
50
+ html.css("#qsShow option").each do |d|
51
+ all_shows[d.text.downcase] = d.attr("value").to_i
52
+ end
53
+
54
+ return all_shows
55
+ end
56
+
57
+ # Get the show id from the list of all shows
58
+ def self.get_show_id show_title
59
+ all_shows = self.get_all_shows
60
+ # Looking in the show list correponding show_title
61
+ id = all_shows[show_title.to_s.downcase]
62
+ # In case we don't have the exact show name (ex: You're The Worst <> You.are.The.Worst)
63
+ if id == nil
64
+ best_result = 0
65
+ best_show_id = 0
66
+ best_show_title = nil
67
+
68
+ jarow = FuzzyStringMatch::JaroWinkler.create( :pure )
69
+ all_shows.each do |show, key|
70
+ matching = jarow.getDistance( show.downcase , show_title.to_s.downcase )
71
+ if matching > best_result
72
+ best_result = matching
73
+ best_show_id = key
74
+ best_show_title = show
75
+ end
76
+ end
77
+
78
+ id = best_show_id
79
+ end
80
+
81
+ return id
82
+ end
83
+
84
+ def inspect
85
+ puts "Filename".ljust(10) + ": #{@filename}"
86
+ puts "Filepath".ljust(10) + ": #{@filepath}"
87
+ puts "Id".ljust(10) + ": #{@id}"
88
+ puts "Title".ljust(10) + ": #{@title}"
89
+ puts "Season".ljust(10) + ": #{@season}"
90
+ puts "Episode".ljust(10) + ": #{@episode}"
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,14 @@
1
+ module GetAddic7ed
2
+ exceptions = [
3
+ :InvalidFile,
4
+ :InvalidFilename,
5
+ :ConnectionError,
6
+ :ShowNotFound,
7
+ :NoSubtitleFound,
8
+ :DownloadError,
9
+ :DownloadLimitReached,
10
+ :SubtitleCannotBeSaved
11
+ ]
12
+
13
+ exceptions.each { |e| const_set(e, Class.new(StandardError)) }
14
+ end
@@ -0,0 +1,158 @@
1
+ require "nokogiri"
2
+ require "fuzzystringmatch"
3
+ require "open-uri"
4
+ require 'net/http'
5
+
6
+ module GetAddic7ed
7
+ class Subtitle
8
+ attr_reader :episode, :lang, :link, :page_link
9
+
10
+ def initialize episode, lang = 'fr'
11
+ @episode = episode # Episode instance
12
+ @lang = lang
13
+ @page = get_page_link
14
+ @link = get_subtitle_link
15
+ end
16
+
17
+ def inspect
18
+ puts "Sub Lang".ljust(20) + ": #{GetAddic7ed::LANGUAGES[@lang][:name]}"
19
+ puts "Hearing Impaired".ljust(20) + ": #{@hi}"
20
+ puts "Page Link".ljust(20) + ": #{@page}"
21
+ puts "Download Link".ljust(20) + ": #{@link}"
22
+ end
23
+
24
+ def get_page_link
25
+ return "http://www.addic7ed.com/ajax_loadShow.php?show=#{@episode.id}&season=#{@episode.season}&langs=&hd=undeENDed&hi=#{@hi}"
26
+ end
27
+
28
+ def get_subtitle_link
29
+ puts "Searching for <#{GetAddic7ed::LANGUAGES[@lang][:name]}> subtitles..." unless GetAddic7ed::OPT_QUIET
30
+
31
+ # sub list
32
+ sub_list = get_sub_list
33
+
34
+ if sub_list.length == 1
35
+ return sub_list.first[:link]
36
+ elsif sub_list.length == 0
37
+ raise NoSubtitleFound
38
+ else
39
+ return sub_list[choose_sub(sub_list)][:link]
40
+ end
41
+ end
42
+
43
+ def get_sub_list
44
+ sub_list = []
45
+ all_sub_list = []
46
+
47
+ link = get_page_link
48
+ uri = URI(link)
49
+
50
+ begin
51
+ body = open(uri)
52
+ rescue
53
+ raise ConnectionError
54
+ end
55
+
56
+ html = Nokogiri::HTML(body)
57
+
58
+ html.css("#season table tbody tr.epeven").each do |sub|
59
+
60
+ current_sub = {
61
+ season: sub.children[0].text,
62
+ episode: sub.children[1].text,
63
+ lang: sub.children[3].text,
64
+ group: sub.children[4].text,
65
+ completed: sub.children[6].text,
66
+ link: "http://www.addic7ed.com#{sub.children[10].children.first['href']}"
67
+ }
68
+
69
+ sub_list.push (current_sub) if (
70
+ sub.children[0].text.to_i == @episode.season &&
71
+ sub.children[1].text.to_i == @episode.episode &&
72
+ sub.children[3].text.downcase == LANGUAGES[@lang][:name].downcase &&
73
+ sub.children[6].text == 'Completed'
74
+ )
75
+
76
+ all_sub_list.push ( current_sub ) if (
77
+ sub.children[0].text.to_i == @episode.season &&
78
+ sub.children[1].text.to_i == @episode.episode
79
+ )
80
+
81
+ next
82
+ end
83
+
84
+ if GetAddic7ed::OPT_CHOOSE
85
+ return all_sub_list
86
+ end
87
+
88
+ if sub_list.length > 0
89
+ # Looking for the corresponding subtitle sub group in filename
90
+ sub_list.each_index do |i|
91
+ if (@episode.filename.downcase =~ /#{Regexp.escape( sub_list[i][:group].downcase )}/ ) != nil
92
+ puts "> #{@episode.title} : S#{sub_list[i][:season].rjust(2, '0')}E#{sub_list[i][:episode].rjust(2, '0')}, #{sub_list[i][:lang]}, #{sub_list[i][:group]}" unless GetAddic7ed::OPT_QUIET
93
+
94
+ return Array.new.push( sub_list[i] )
95
+ end
96
+ end
97
+ end
98
+
99
+ return sub_list.length > 0 ? sub_list : all_sub_list
100
+ end
101
+
102
+ def choose_sub sub_list
103
+ if GetAddic7ed::OPT_CHOOSE
104
+ puts "Choose a subtitle :"
105
+ else
106
+ puts "No perfect match found.\nBut you can choose one of those instead :"
107
+ end
108
+
109
+ sub_list.each_index do |i|
110
+ print "\n#{i+1} -".ljust(6)
111
+ print "#{sub_list[i][:group]}".ljust(25)
112
+ print "#{sub_list[i][:lang]}".ljust(25)
113
+ print "#{sub_list[i][:completed]}".ljust(20)
114
+ end
115
+
116
+ puts "\n\nType 'exit' or '0' or 'q' to cancel.\n\n"
117
+
118
+ choice = -1
119
+
120
+ until (choice.to_i >= 1 && choice.to_i <= sub_list.length)
121
+ puts "* Which subtitle do you want ?"
122
+ print "> "
123
+ choice = STDIN.gets.chomp
124
+
125
+ if choice === "exit" || choice === "0" || choice === "q"
126
+ puts "Done."
127
+ exit
128
+ else
129
+ choice = choice.to_i
130
+ end
131
+ end
132
+
133
+ return choice-1
134
+ end
135
+
136
+ def download_sub
137
+ dir_path = File.dirname(@episode.filepath)
138
+ sub_name = File.basename(@episode.filepath, '.*')
139
+
140
+ begin
141
+ srt_filename = "#{dir_path}/#{sub_name}#{('.' + @lang) if GetAddic7ed::OPT_TAGGED}.srt"
142
+
143
+ #TODO check download limit /^\/downloadexceeded.php/.match
144
+
145
+ File.open(srt_filename, "wb") do |saved_file|
146
+ open("#{@link}", "rb", "Referer" => @page) do |read_file|
147
+ saved_file.write(read_file.read)
148
+ end
149
+ end
150
+ puts "Subtitle downloaded !" unless GetAddic7ed::OPT_QUIET
151
+ puts srt_filename unless GetAddic7ed::OPT_QUIET
152
+ rescue
153
+ raise DownloadError
154
+ end
155
+ end
156
+
157
+ end
158
+ end
@@ -0,0 +1,3 @@
1
+ module GetAddic7ed
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,40 @@
1
+ module GetAddic7ed
2
+ class VideoFile
3
+ attr_reader :filename, :filepath
4
+
5
+ def initialize(file)
6
+ @filepath = File.expand_path(file)
7
+
8
+ if self.class.file? (@filepath)
9
+ @filename = File.basename(@filepath)
10
+ else
11
+ raise InvalidVideoFile
12
+ end
13
+ end
14
+
15
+ def inspect
16
+ puts "Filename".ljust(10) + ": #{@filename}"
17
+ puts "Filepath".ljust(10) + ": #{@filepath}"
18
+ end
19
+
20
+ def self.file? filepath
21
+ if File.file? (filepath)
22
+ return true
23
+ else
24
+ raise InvalidFile
25
+ end
26
+ end
27
+
28
+ def self.video? filepath
29
+ if File.file? (filepath)
30
+ =begin
31
+ TODO : Find a way to make it work on windows, mac os x and linux
32
+ =end
33
+ return mimetype(filepath).start_with?("video") || File.extname(filepath) == ".mkv"
34
+ else
35
+ raise WrongArgument
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,6 @@
1
+ require "addic7ed/version"
2
+ require 'addic7ed/attr'
3
+ require 'addic7ed/errors'
4
+ require 'addic7ed/videofile'
5
+ require 'addic7ed/episode'
6
+ require 'addic7ed/subtitle'
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: get-addic7ed
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nicolas Vergoz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fuzzy-string-match
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Ruby tool to download subtitles from Addic7d based on video file name
70
+ email:
71
+ - nicolas.vergoz@gmail.com
72
+ executables:
73
+ - get-addic7ed
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - bin/get-addic7ed
78
+ - lib/addic7ed/attr.rb
79
+ - lib/addic7ed/episode.rb
80
+ - lib/addic7ed/errors.rb
81
+ - lib/addic7ed/subtitle.rb
82
+ - lib/addic7ed/version.rb
83
+ - lib/addic7ed/videofile.rb
84
+ - lib/get-addic7ed.rb
85
+ homepage: http://rubygems.org/gems/get-addic7ed
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.4.5.1
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: Get subtitles from Addic7ed
109
+ test_files: []