suby 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/bin/suby +101 -0
  2. metadata +46 -0
data/bin/suby ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if ARGV.include? '-h'
4
+ puts "#{File.basename $0} video"
5
+ puts " Find and download subtitles for the given video file"
6
+ exit
7
+ end
8
+
9
+ require 'net/http'
10
+ require 'nokogiri'
11
+
12
+ SUB_EXTENSIONS = %w[srt sub]
13
+ archive = '__archive__'
14
+ site = 'www.tvsubtitles.net'
15
+ search_url = '/search.php'
16
+ lang = 'en'
17
+
18
+ def extract_subs_from_archive(archive)
19
+ case `file #{archive}`
20
+ when /Zip archive data/
21
+ subs = `unzip -qql #{archive}`.scan(/\d{2}:\d{2} (.+?(?:#{SUB_EXTENSIONS.join '|'}))$/).map(&:first)
22
+ raise "no subtitles in #{archive}" if subs.empty?
23
+ subs_for_unzip = subs.map { |sub| sub.gsub(/(\[|\])/) { "\\#{$1}" } }
24
+ system 'unzip', archive, *subs_for_unzip, 1 => :close
25
+ puts "found subtitles: #{subs.join(', ')}"
26
+ else
27
+ raise "unknown archive type (#{archive})"
28
+ end
29
+
30
+ # Cleaning
31
+ File.unlink archive
32
+ subs
33
+ end
34
+
35
+ # cache
36
+ show_urls = {}
37
+ show_pages = {}
38
+
39
+ ARGV.each { |file|
40
+ next if SUB_EXTENSIONS.include? File.extname(file)
41
+ next(puts "Skipping: #{file}") if SUB_EXTENSIONS.any? { |ext|
42
+ File.exist? File.basename(file, File.extname(file)) + ".#{ext}" }
43
+
44
+ unless /^(?<tvshow>.+) (?<season>\d{1,2})x(?<episode>\d{1,2}) - .+\.[a-z]+?$/ =~ file
45
+ next puts "wrong file format (#{file}). Must be:\n<tvshow> <season>x<episode> - <title>.<ext>"
46
+ end
47
+ season, episode = [season, episode].map(&:to_i)
48
+ puts "Searching subtitles for #{file}:"
49
+ puts "Show: #{tvshow}, Season: #{season}, Episode: #{episode}"
50
+
51
+ Net::HTTP.start(site) { |tvsubtitles|
52
+ # search tvshow
53
+ tvshow_url = (show_urls[tvshow] ||= begin
54
+ post = Net::HTTP::Post.new(search_url)
55
+ post.form_data = { 'q' => tvshow }
56
+ results = Nokogiri tvsubtitles.request(post).body
57
+ url = results.css('ul li div a').first[:href]
58
+
59
+ raise 'could not find the show' unless /^\/tvshow-(\d+)\.html$/ =~ url
60
+ "/tvshow-#{$1}-#{season}.html"
61
+ end)
62
+ puts "tvshow url: #{tvshow_url}"
63
+
64
+ # search episode
65
+ tvshow = (show_pages[tvshow] ||= Nokogiri tvsubtitles.get(tvshow_url).body)
66
+ tr = tvshow.css('div.left_articles table tr').find { |tr|
67
+ tr.children.find { |td| td.name == 'td' && td.text =~ /\A#{season}x0?#{episode}\z/ }
68
+ }
69
+ episode_url = nil
70
+ tr.children.find { |td|
71
+ td.children.find { |a|
72
+ a.name == 'a' && a[:href].start_with?('episode') && episode_url = a[:href]
73
+ }
74
+ }
75
+
76
+ raise "invalid episode url: #{episode_url}" unless episode_url =~ /^episode-(\d+)\.html$/
77
+ episode_url = "/episode-#{$1}-#{lang}.html"
78
+ puts "episode url: #{episode_url}"
79
+
80
+ # subtitles
81
+ subtitles = Nokogiri tvsubtitles.get(episode_url).body
82
+
83
+ # TODO: choose 720p or most downloaded instead of first found
84
+ subtitle_url = subtitles.css('div.left_articles a').find { |a| a.name == 'a' && a[:href].start_with?('/subtitle') }[:href]
85
+ raise 'invalid subtitle url' unless subtitle_url =~ /^\/subtitle-(\d+)\.html/
86
+ puts "subtitle url: #{subtitle_url}"
87
+
88
+ # download
89
+ download_url = tvsubtitles.get("/download-#{$1}.html")['Location']
90
+ download_url = URI.escape('/'+download_url)
91
+ puts "download url: #{download_url}"
92
+
93
+ # extract
94
+ zip = tvsubtitles.get(download_url).body
95
+ open(archive, 'wb') { |f| f.write zip }
96
+ subs = extract_subs_from_archive(archive)
97
+ new_name = File.basename(file, File.extname(file))+File.extname(subs.first)
98
+ File.rename(subs.first, new_name)
99
+ puts "Renaming to #{new_name}"
100
+ }
101
+ }
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: suby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - eregon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-06-15 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Find and download subtitles
15
+ email:
16
+ executables:
17
+ - suby
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/suby
22
+ homepage:
23
+ licenses: []
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 1.8.5
43
+ signing_key:
44
+ specification_version: 3
45
+ summary: Subtitles' downloader
46
+ test_files: []