autotvnzb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ pkg
23
+ fixtures
24
+ tasks
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Pirate
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,18 @@
1
+ = test-gem
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but
13
+ bump version in a commit by itself I can ignore when I pull)
14
+ * Send me a pull request. Bonus points for topic branches.
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2009 Pirate. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "autotvnzb"
8
+ gem.summary = "Automatically download tv shows nzb"
9
+ gem.description = "Ruby tool to automatically download tv shows nzb from http://tvnzb.com/"
10
+ gem.email = "pirate.2061@gmail.com"
11
+ gem.authors = ["Pirate"]
12
+ gem.add_development_dependency "rspec", ">= 1.2.9"
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ gem.add_dependency "hpricot", ">= 0.8.1"
15
+ gem.add_dependency "httparty", ">= 0.4.5"
16
+ gem.add_dependency "optiflag", ">= 0.7"
17
+ gem.default_executable = "bin/autotvnzb"
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
22
+ end
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ end
29
+
30
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :spec => :check_dependencies
37
+
38
+ task :default => :spec
39
+
40
+ require 'rake/rdoctask'
41
+ Rake::RDocTask.new do |rdoc|
42
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
43
+
44
+ rdoc.rdoc_dir = 'rdoc'
45
+ rdoc.title = "test-gem #{version}"
46
+ rdoc.rdoc_files.include('README*')
47
+ rdoc.rdoc_files.include('lib/**/*.rb')
48
+ end
49
+
50
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/asset/failure.png ADDED
Binary file
data/asset/srt.png ADDED
Binary file
data/autotvnzb.gemspec ADDED
@@ -0,0 +1,69 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{autotvnzb}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Pirate"]
12
+ s.date = %q{2009-11-01}
13
+ s.default_executable = %q{bin/autotvnzb}
14
+ s.description = %q{Ruby tool to automatically download tv shows nzb from http://tvnzb.com/}
15
+ s.email = %q{pirate.2061@gmail.com}
16
+ s.executables = ["autotvnzb"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "asset/failure.png",
28
+ "asset/srt.png",
29
+ "autotvnzb.gemspec",
30
+ "bin/autotvnzb",
31
+ "lib/inspector.rb",
32
+ "lib/sabnzbd.rb",
33
+ "lib/tvnzb.rb",
34
+ "lib/tvshow.rb",
35
+ "spec/spec.opts",
36
+ "spec/spec_helper.rb"
37
+ ]
38
+ s.rdoc_options = ["--charset=UTF-8"]
39
+ s.require_paths = ["lib"]
40
+ s.rubygems_version = %q{1.3.5}
41
+ s.summary = %q{Automatically download tv shows nzb}
42
+ s.test_files = [
43
+ "spec/autotvnzb_spec.rb",
44
+ "spec/spec_helper.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
53
+ s.add_runtime_dependency(%q<hpricot>, [">= 0.8.1"])
54
+ s.add_runtime_dependency(%q<httparty>, [">= 0.4.5"])
55
+ s.add_runtime_dependency(%q<optiflag>, [">= 0.7"])
56
+ else
57
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
58
+ s.add_dependency(%q<hpricot>, [">= 0.8.1"])
59
+ s.add_dependency(%q<httparty>, [">= 0.4.5"])
60
+ s.add_dependency(%q<optiflag>, [">= 0.7"])
61
+ end
62
+ else
63
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
64
+ s.add_dependency(%q<hpricot>, [">= 0.8.1"])
65
+ s.add_dependency(%q<httparty>, [">= 0.4.5"])
66
+ s.add_dependency(%q<optiflag>, [">= 0.7"])
67
+ end
68
+ end
69
+
data/bin/autotvnzb ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optiflag'
4
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'inspector')
5
+
6
+ module AutoTvNZB extend OptiFlagSet
7
+ flag "p" do
8
+ description "Directory path with many TV Shows directories"
9
+ end
10
+ flag "apikey" do
11
+ description "Sabnzbd api key (from 0.4.9)"
12
+ end
13
+ character_flag :w # wait
14
+
15
+ and_process!
16
+ end
17
+
18
+ begin
19
+ inspector = Inspector.new(ARGV.flags.p, ARGV.flags.apikey, :wait => ARGV.flags.w?)
20
+ rescue => e
21
+ p e.to_s
22
+ Inspector.growl("AutoTvNZB Error!", 'look into the console log', 'failure.png')
23
+ end
data/lib/inspector.rb ADDED
@@ -0,0 +1,24 @@
1
+ require File.join(File.dirname(__FILE__), 'tvshow')
2
+ require "pathname"
3
+
4
+ class Inspector
5
+
6
+ attr_accessor :tv_shows
7
+
8
+ def initialize(path, apikey, options = {})
9
+ @path = Pathname.new(path).realpath.to_s
10
+
11
+ if options[:wait]
12
+ $stdout.print "Sleep 90\n"
13
+ sleep 90
14
+ end
15
+
16
+ $stdout.print "Begin searching for new TV Show episodes...\n"
17
+ @tv_shows = TvShow.search(@path, apikey)
18
+ end
19
+
20
+ def self.growl(title, msg, pri = 0)
21
+ system("/usr/local/bin/growlnotify -w -n autotvnzb --image #{File.dirname(__FILE__) + "/../asset/failure.png"} -p #{pri} -m #{msg.inspect} #{title} &")
22
+ end
23
+
24
+ end
data/lib/sabnzbd.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'httparty'
2
+
3
+ class Sabnzbd
4
+
5
+ include HTTParty
6
+ base_uri 'localhost:8080'
7
+
8
+ def self.add_url(url, apikey, category = nil, job_options = nil, script = nil)
9
+ options = { :apikey => apikey }
10
+ options[:name] = url
11
+ options[:cat] = category if !category.blank?
12
+ options[:pp] = job_options if !job_options.blank?
13
+ options[:script] = script if !script.blank?
14
+ verify api_call(:addurl, options)
15
+ rescue
16
+ $stdout.print "connection problem! sabnzbd launched?"
17
+ false
18
+ end
19
+
20
+ private
21
+
22
+ def self.verify(text)
23
+ text.strip == "ok"
24
+ end
25
+
26
+ def self.api_call(mode, opts = {})
27
+ opts.merge!(:mode => mode.to_s)
28
+ get("/sabnzbd/api", :query => opts)
29
+ end
30
+
31
+ end
data/lib/tvnzb.rb ADDED
@@ -0,0 +1,70 @@
1
+ require File.join(File.dirname(__FILE__), 'sabnzbd')
2
+ require 'hpricot'
3
+ require 'open-uri'
4
+
5
+ class TvNZB
6
+
7
+ def self.search_and_download(tv_show, apikey)
8
+ if tv_show_known?(tv_show)
9
+ # p url(tv_show)
10
+ doc = Hpricot(open(url(tv_show)))
11
+ doc.search("table.standard a[@href^='http://www.tvnzb.com/nzb/']").each do |el|
12
+ if tv_show.need?(el[:title]) && Sabnzbd.add_url(el[:href], apikey, "tv shows")
13
+ $stdout.print " #{el[:title]}\n"
14
+ tv_show.write_yml(el[:title])
15
+ end
16
+ end
17
+ else
18
+ $stdout.print "ID not found for '#{tv_show.name}' on tvnzb.com\n"
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def self.tv_show_known?(tv_show)
25
+ tv_show_id(tv_show.name) != nil
26
+ end
27
+
28
+ def self.url(tv_show)
29
+ "http://www.tvnzb.com/index.php?st=#{tv_show_id(tv_show.name)}"
30
+ end
31
+
32
+ def self.tv_show_id(name)
33
+ h = {"Book of Daniel"=>"270", "Dancing With The Stars US"=>"304", "Cane"=>"453", "Threshold"=>"175", "Medium"=>"34", "The Shot"=>"481", "Saturday Night Live"=>"240", "Everybody Loves Raymond"=>"65", "WWE Pay Per Views"=>"360", "CSI New York"=>"181", "On the Lot"=>"327", "The Universe"=>"342", "The Simpsons"=>"61", "Trailer Park Boys"=>"320", "Farscape"=>"290", "Scrubs"=>"39",
34
+ "Last Comic Standing"=>"377", "According to Jim"=>"73", "Family Guy"=>"106", "Samantha Who"=>"469", "The Princes Of Malibu"=>"138", "Stargate Atlantis"=>"93", "Army Wives"=>"332", "Standoff"=>"364", "Life is Wild"=>"473", "Pepper Dennis"=>"158", "Tru Calling"=>"60", "Days That Shook The World"=>"145", "The Surreal Life"=>"192", "Starved"=>"126", "The Girls Next Door"=>"572",
35
+ "Gastineau Girls"=>"284", "Extreme Makeover Home Edition"=>"241", "Two and a Half Men"=>"205", "Monkey Life"=>"413", "Doctor Who (2005)"=>"16", "The Mole"=>"515", "Yes Dear"=>"203", "The War At Home"=>"161", "The Border"=>"563", "Gary Unmarried"=>"550", "Numb3rs"=>"8", "Britannia High"=>"556", "Dollhouse"=>"575", "Roseanne"=>"354", "Revelations"=>"52", "Surviving Suburbia"=>"546",
36
+ "The Middleman"=>"514", "Grease Is The Word (ITV1 UK)"=>"311", "Pushing Daisies"=>"458", "Sophie"=>"494", "MacGyver"=>"359", "Survivor"=>"77", "Men in Trees"=>"478", "The Sopranos"=>"132", "Porn: A Family Business"=>"371", "Being Erica"=>"578", "Just Legal"=>"190", "Dilbert"=>"415", "Hells Kitchen (UK)"=>"599", "Man vs. Wild"=>"387", "Law & Order: SVU"=>"195", "Stacked"=>"53",
37
+ "College Hill Interns"=>"476", "Sex and the City"=>"245", "Journeyman"=>"420", "Invasion"=>"199", "The King of Queens"=>"84", "Canterburys Law"=>"506", "Neighbours"=>"370", "Reba"=>"85", "Supernatural"=>"166", "CSI"=>"179", "Miami Ink"=>"135", "The No. 1 Ladies Detective Agency"=>"594", "Tripping The Rift"=>"129", "Head Case"=>"592", "Underbelly"=>"510", "La Femme Nikita"=>"277",
38
+ "K-Ville"=>"439", "Jake In Progress"=>"6", "Clone"=>"561", "Peep Show (Channel 4 UK)"=>"308", "The Comeback"=>"92", "X-Files"=>"389", "Beautiful People"=>"102", "The Chopping Block (US)"=>"581", "Demons (UK)"=>"571", "Hope And Faith"=>"66", "Raising the Bar"=>"540", "Supernanny"=>"491", "Samurai Girl"=>"523", "Commander In Chief"=>"222", "Entourage"=>"91", "Fast Cars And Superstars"=>"362",
39
+ "The Unit"=>"155", "Life"=>"421", "Beavis and Butthead"=>"261", "Happy Tree Friends"=>"355", "John From Cincinnati"=>"369", "Skins"=>"500", "Dirty Jobs"=>"286", "The Showbiz Show"=>"173", "Ghost Whisperer"=>"217", "Bullrun"=>"317", "90210"=>"526", "Desperate Housewives"=>"29", "Out Of Practice"=>"189", "King Of The Hill"=>"64", "Stankervision"=>"125", "Wanted"=>"100", "The Starter Wife"=>"385",
40
+ "Big Shots"=>"461", "The Closer"=>"101", "Star Trek Deep Space 9"=>"278", "The Wonder Years"=>"249", "How I Met Your Mother"=>"206", "Wipeout"=>"522", "American Chopper"=>"356", "Side Order of Life"=>"396", "Wife Swap US"=>"208", "Friday Night with Jonathan Ross"=>"479", "The West Wing"=>"169", "The Game"=>"303", "Laguna Beach"=>"154", "Without A Trace"=>"74", "Fallen"=>"410", "Star Trek Enterprise"=>"234",
41
+ "Are You Smarter Than a 5th Grader?"=>"426", "Dont Forget the Lyrics"=>"399", "This American Life"=>"513", "The Penguins of Madagascar"=>"584", "Flight of the Conchord"=>"384", "Kid Nation"=>"462", "The Xtra Factor"=>"601", "Better Off Ted"=>"583", "The New Adventures of Old Christine"=>"536", "Intervention"=>"344", "Man V Food"=>"574", "Mad TV"=>"41", "Dirt"=>"507", "Moonlight"=>"454",
42
+ "Destination Truth"=>"504", "Wings"=>"105", "The Daily Show"=>"174", "Lipstick Jungle"=>"496", "Pirate Master"=>"343", "My Own Worst Enemy"=>"541", "Canadas Next Top Model"=>"363", "Eastbound And Down"=>"576", "English Premier League"=>"562", "Corner Gas"=>"130", "WildBoyz"=>"275", "The Lost Room"=>"326", "Crusoe"=>"544", "Alias"=>"3", "M.A.S.H."=>"358", "Charmed"=>"24", "Masters of Horror"=>"248",
43
+ "Meerkat Manor"=>"433", "Newport Harbor: The Real Orange County"=>"423", "Private Practice"=>"459", "The Business"=>"440", "Worst Week"=>"529", "Americas Got Talent"=>"351", "Little Britain USA"=>"532", "Courting Alex"=>"282", "Til Death"=>"352", "Top Chef"=>"447", "Chopped"=>"577", "The Company"=>"411", "Hells Kitchen"=>"345", "New Tricks"=>"348", "Rob Dyrdeks Fantasy Factory"=>"579",
44
+ "30 Days"=>"143", "The Riches"=>"322", "Caprica"=>"603", "Doctor Who Confidential"=>"367", "jPod"=>"498", "This Hour Has 22 Minutes"=>"565", "American Hot Rod"=>"427", "Late Show with David Letterman"=>"446", "The Cleaner"=>"527", "Buffy the Vampire Slayer"=>"346", "Seinfeld"=>"107", "Smash Lab"=>"503", "Jail"=>"431", "Avatar: The Last Airbender"=>"467", "Rock Star INXS"=>"116", "Stunt Junkies"=>"287", "Monk"=>"98",
45
+ "Highlander"=>"250", "Saxondale"=>"419", "The IT Crowd (UK)"=>"441", "Hex"=>"188", "Surface"=>"159", "Reunion"=>"157", "House"=>"164", "Generation Kill"=>"520", "Who Wants To Be A Superhero"=>"395", "Bleak House"=>"247", "7th Heaven"=>"224", "Trust Me"=>"568", "All of Us"=>"242", "The OC"=>"160", "Kings"=>"582", "Fight Girls"=>"374", "Star Trek: The Original Series"=>"383", "South Beach"=>"285", "The 4400"=>"99",
46
+ "Rita Rocks"=>"558", "The Apprentice"=>"5", "WWE RAW"=>"339", "Prototype This!"=>"559", "Strong Medicine"=>"139", "The Beast"=>"567", "Rocket Man"=>"209", "Cupid"=>"586", "Killer Instinct"=>"200", "Arrested Development"=>"22", "Cashmere Mafia"=>"487", "The Secret Life of the American Teenager"=>"569", "In Justice"=>"268", "Jekyll (UK)"=>"378", "Friday Night Lights"=>"472", "Traveler"=>"328",
47
+ "The X Factor (UK)"=>"600", "Brat Camp"=>"134", "Battlestar Galactica (2003)"=>"168", "American Dad"=>"63", "Flashpoint"=>"521", "Valentine"=>"554", "Party Down"=>"590", "Baywatch"=>"376", "Flash Gordon"=>"416", "Modern Marvels"=>"151", "Over There"=>"104", "South Park"=>"2", "Hole in the Wall"=>"533", "The Tonight Show with Jay Leno"=>"373", "Brainiac: Science Abuse"=>"316", "Odyssey 5"=>"115",
48
+ "Las Vegas Law"=>"289", "Everwood"=>"35", "My Fair Brady"=>"252", "Saving Grace"=>"404", "Crossing Jordan"=>"38", "Kolchak: The Night Stalker"=>"257", "Rules of Engagement"=>"450", "Will & Grace"=>"81", "Carnivale"=>"213", "The Ultimate Fighter"=>"335", "Psych"=>"331", "Britains Got Talent"=>"597", "Fear Itself"=>"517", "Still Standing"=>"70", "Big Love"=>"372", "The Singing Bee"=>"391",
49
+ "Living With Fran"=>"10", "Knight Rider"=>"519", "Mad Men"=>"407", "Run's House"=>"309", "The 70s House"=>"120", "Meet Mister Mom"=>"110", "Six Feet Under"=>"87", "Kitchen Confidential"=>"191", "Dark Angel"=>"267", "30 Rock"=>"299", "The Real Wedding Crashers"=>"340", "Day Break"=>"337", "Wonder Showzen"=>"71", "Boston Legal"=>"183", "Plus One (UK)"=>"573", "American Idol"=>"56",
50
+ "Masters of Science Fiction"=>"414", "Funland"=>"244", "Real Time with Bill Maher"=>"178", "Fifth Gear"=>"321", "The Sarah Jane Adventures"=>"557", "Punkd"=>"31", "Tommy Lee Goes To College"=>"111", "The Big Bang Theory"=>"449", "Last One Standing"=>"471", "The Man Show"=>"436", "Hidden Palms"=>"329", "The Amazing Race"=>"57", "United States of Tara"=>"570", "ER"=>"83", "My Name Is Earl"=>"194",
51
+ "Sit Down, Shut Up"=>"602", "Star Wars: The Clone Wars"=>"535", "Regenesis"=>"318", "Deadliest Catch"=>"306", "Law & Order: Trial By Jury"=>"15", "Huff"=>"276", "The Biggest Loser (US)"=>"604", "Terminator The Sarah Connor Chronicles"=>"489", "Topgear Australia"=>"551", "The Inside"=>"89", "Back To You"=>"443", "Dharma & Greg"=>"112", "Sanctuary"=>"310", "Treasure Hunters"=>"424", "Related"=>"221",
52
+ "Tyler Perrys House of Payne"=>"429", "Mythbusters"=>"281", "Carpoolers"=>"457", "Gossip Girl"=>"452", "The Dresden Files"=>"405", "Love Inc."=>"288", "Painkiller Jane"=>"307", "Greys Anatomy"=>"30", "Dexter"=>"336", "Cuts"=>"226", "Castle"=>"580", "Skating with Celebrities"=>"283", "The Black Donnellys"=>"319", "The IT Crowd"=>"438", "Trading Spouses"=>"253", "Friends"=>"223", "Britains Got More Talent"=>"598",
53
+ "Secret Diary of a Call Girl"=>"538", "Massive"=>"555", "After the Catch"=>"341", "Criminal Minds"=>"218", "Paranormal State"=>"486", "Lead Balloon"=>"482", "The Return of Jezebel James"=>"509", "The Simple Life"=>"55", "Dallas SWAT"=>"434", "Leverage"=>"560", "Star Trek The Next Generation"=>"236", "Legend Of The Seeker"=>"545", "Ashes to Ashes"=>"493", "October Road"=>"480", "Close To Home"=>"215",
54
+ "Swingtown"=>"518", "The Academy"=>"349", "Reaper"=>"451", "Terminal City"=>"243", "Airwolf"=>"350", "Still Game"=>"127", "Rome"=>"136", "Reno 911!"=>"108", "24"=>"298", "The Adventures of Tintin"=>"502", "Eleventh Hour (US)"=>"547", "Robot Chicken"=>"380", "Ice Road Truckers"=>"409", "Wire In The Blood"=>"403", "The Mentalist"=>"552", "Cold Case"=>"79", "Dawsons Creek"=>"418", "Joey"=>"76",
55
+ "CSI Miami"=>"180", "The Venture Brothers"=>"516", "The Apprentice Martha Stewart"=>"227", "Hustle"=>"272", "Barbershop"=>"95", "Stargate SG-1"=>"94", "Head Cases"=>"170", "Get a life"=>"483", "The Loop"=>"368", "The Six Million Dollar Man"=>"256", "George Lopez"=>"212", "Dragonball Z"=>"171", "The Listener"=>"589", "Lincoln Heights"=>"435", "Silent Witness"=>"442", "Dead Zone"=>"146",
56
+ "Heroes Unmasked"=>"430", "Kyle XY"=>"330", "Sherlock Holmes (1984)"=>"497", "Little Britain"=>"259", "New Amsterdam"=>"501", "Parks and Recreation"=>"595", "E-Ring"=>"201", "The Shield"=>"49", "The Dead Zone"=>"97", "Top Gear"=>"260", "Lie To Me"=>"564", "WWE SmackDown!"=>"338", "Justice League Unlimited"=>"279", "The Hills"=>"417", "South of Nowhere"=>"542", "Rock School"=>"149",
57
+ "Brotherhood"=>"393", "Viva Laughlin"=>"470", "The Bill Engvall Show"=>"402", "Damages"=>"394", "Late Night with Conan OBrien"=>"465", "Lobster Wars"=>"425", "Law & Order"=>"75", "The Wire"=>"231", "Listen Up"=>"33", "I Dream of Jeannie"=>"537", "Nashville"=>"432", "The Kill Point"=>"398", "Sons of Anarchy"=>"530", "The Colbert Report"=>"204", "Badger Or Bust"=>"334", "Lost"=>"51",
58
+ "The Bachelor"=>"323", "Californication"=>"406", "Cops"=>"313", "The Apprentice UK"=>"19", "Ax Men"=>"511", "Sleeper Cell"=>"265", "Shameless"=>"280", "Americas Next Top Model"=>"230", "Project Runway"=>"585", "Crash"=>"543", "Eureka"=>"382", "Twins"=>"176", "The A-Team"=>"488", "The Contender"=>"37", "Lexx"=>"246", "Testees"=>"553", "Eli Stone"=>"492", "Fringe"=>"524",
59
+ "Studio 60 on the Sunset Strip"=>"333", "Aliens in America"=>"468", "Damage Control"=>"124", "The Real World"=>"128", "Extras"=>"121", "Smallville"=>"11", "Breaking Bad"=>"499", "Penn & Teller: Bullshit!"=>"44", "Smoking Room, The"=>"148", "Dirty Sexy Money"=>"460", "In Plain Sight"=>"512", "Egypt"=>"210", "Southland"=>"588", "One Tree Hill"=>"7", "In Treatment"=>"495", "Third Watch"=>"18",
60
+ "Creature Comforts"=>"347", "Cavemen"=>"456", "American Inventor"=>"353", "The Life and Times of Tim"=>"531", "Celebrity Poker Showdown"=>"117", "Human Weapon"=>"408", "Jack & Bobby"=>"50", "Pretender"=>"271", "Rescue Me"=>"109", "Degrassi The Next Generation"=>"219", "Star Trek Voyager"=>"235", "Heroes"=>"294", "Heartland"=>"381", "Phenomenon"=>"477", "Rick Mercer Report"=>"566", "The Triangle"=>"266",
61
+ "JAG"=>"67", "Notes from the Underbelly"=>"325", "L.A. Ink"=>"445", "Harpers Island"=>"587", "Womens Murder Club"=>"466", "Freddie"=>"220", "Ghost Hunters"=>"122", "The Boondocks"=>"211", "World Series of Poker"=>"255", "Criss Angel Mindfreak"=>"251", "The Pick-Up Artist"=>"412", "Hooking Up"=>"131", "Shark"=>"448", "Girlfriends"=>"202", "N.C.I.S."=>"182", "Weeds"=>"103", "National Geographic Channel"=>"314",
62
+ "My Wife and Kids"=>"238", "The L Word"=>"46", "Four Kings"=>"269", "Gilmore Girls"=>"69", "Bionic Woman"=>"366", "Rodney"=>"254", "Mind Of Mencia"=>"147", "Drawn Together"=>"228", "Primeval"=>"593", "Lil Bush - Resident of the United States"=>"375", "The Ex List"=>"548", "ECW on Sci-Fi"=>"392", "Big Brother"=>"114", "Burn Notice"=>"386", "Code Monkeys"=>"401", "That 70s Show"=>"48", "Just for Laughs"=>"428",
63
+ "Nip Tuck"=>"196", "The Unusuals"=>"591", "Kitchen Nightmares"=>"444", "Beauty and The Geek"=>"88", "American Gladiators"=>"490", "Crumbs"=>"274", "Space: Above And Beyond"=>"291", "Everybody Hates Chris"=>"216", "Hot Properties"=>"214", "Its Always Sunny in Philadelphia"=>"123", "Greek"=>"388", "Prison Break"=>"144", "Eyes"=>"54", "The Bang"=>"263", "Oz"=>"162", "Viva La Bam"=>"13", "Aqua Teen Hunger Force"=>"508",
64
+ "Chuck"=>"455", "Spooks"=>"165", "Lewis Blacks: Root of All Evil"=>"505", "Krod Mandoon and the Flaming Sword of Fire"=>"596", "Law & Order: Criminal Intent"=>"62", "Las Vegas"=>"45", "Robin Hood"=>"463", "Malcolm in the Middle"=>"25", "Kojak (2005)"=>"36", "Fonejacker"=>"400", "Veronica Mars"=>"12", "Merlin (UK)"=>"534", "Jennas American Sex Star"=>"262", "True Blood"=>"525", "The Sarah Silverman Program"=>"464",
65
+ "The Cut"=>"152", "The Bernie Mac Show"=>"232", "UFC Unleashed"=>"258", "Privileged"=>"528", "My Kind Of Town"=>"96", "Joan of Arcadia"=>"237", "The Office"=>"43", "TNA iMPACT!"=>"315", "TNA Pay Per Views"=>"361", "Curb Your Enthusiasm"=>"207", "What I Like About You"=>"14", "State Of Mind"=>"397", "Band Of Brothers (HBO)"=>"119", "Jericho"=>"365", "Deadwood"=>"32", "Inferno 999"=>"437", "Meadowlands"=>"379",
66
+ "Blood Ties"=>"300", "Missing"=>"137", "American Body Shop"=>"390", "Ugly Betty"=>"324", "Pimp My Ride"=>"26", "Brothers And Sisters"=>"301", "Tell Me You Love Me"=>"422", "Life On Mars (USA)"=>"549", "Bones"=>"167", "So You Think You Can Dance"=>"153", "The Tudors"=>"302", "Blind Justice"=>"21", "Nurse Jackie"=>"620"}
67
+ h[name]
68
+ end
69
+
70
+ end
data/lib/tvshow.rb ADDED
@@ -0,0 +1,110 @@
1
+ require File.join(File.dirname(__FILE__), 'tvnzb')
2
+ require 'yaml'
3
+
4
+ class TvShow
5
+
6
+ attr_accessor :path, :name, :format, :episodes, :season, :number, :options
7
+
8
+ def initialize(name, path, apikey)
9
+ # p name
10
+ @name, @path, @episodes = name, path, []
11
+ load_yml_options
12
+ @format = @options['format'] || "hd"
13
+
14
+ if active?
15
+ $stdout.print "Searching new episode(s) for: #{name}\n"
16
+ search_episodes(path)
17
+ set_max_season_and_number
18
+ write_yml("#{season}x#{number}") if season && number
19
+ TvNZB.search_and_download(self, apikey)
20
+ end
21
+ end
22
+
23
+ def self.search(path, apikey)
24
+ # path is a dir with many tv_shows dir
25
+ base_dir = clean_dir(Dir.new(path))
26
+ base_dir.each do |tv_show_name|
27
+ new(tv_show_name, "#{path}/#{tv_show_name}", apikey)
28
+ end
29
+ end
30
+
31
+ def active?
32
+ @options['active'].nil? ? true : @options['active']
33
+ end
34
+
35
+ def hd?
36
+ format == "hd"
37
+ end
38
+
39
+ def need?(episode_name)
40
+ e = episode_data(episode_name)
41
+ e[:season] && (e[:season] > season || (e[:season] == season && e[:number] && e[:number] > number)) && e[:format] == format
42
+ end
43
+
44
+ def write_yml(episode_name)
45
+ yml_file = "#{path}/options.yml"
46
+ e = episode_data(episode_name)
47
+ old_options = YAML.load_file(yml_file) if File.exist?(yml_file)
48
+ if (old_options && (old_options['season'].nil? || e[:season] > old_options['season'] || old_options['number'].nil? || (e[:season] == old_options['season'] && e[:number] > old_options['number']))) || old_options.nil?
49
+ File.open(yml_file, "w") { |f| f.write @options.merge('season' => e[:season], 'number' => e[:number]).to_yaml }
50
+ end
51
+ end
52
+
53
+
54
+ private
55
+
56
+ def self.clean_dir(dir)
57
+ dir.select { |e| !["..", ".", ".DS_Store", ".com.apple.timemachine.supported", "Icon\r", "_autosub_.log"].include?(e) }
58
+ end
59
+
60
+ def load_yml_options
61
+ yml_file = "#{path}/options.yml"
62
+ @options = File.exist?(yml_file) ? YAML.load_file(yml_file) : {}
63
+ end
64
+
65
+ def set_max_season_and_number
66
+ if options['season']
67
+ @season = options['season'].to_i
68
+ @number = options['number'].to_i
69
+ elsif !episodes.empty?
70
+ @season = @episodes.max {|a,b| a[:season] <=> b[:season] }[:season]
71
+ @number = @episodes.select { |e| e[:season] == season }.max {|a,b| a[:number] <=> b[:number] }[:number]
72
+ end
73
+ end
74
+
75
+ def search_episodes(path)
76
+ elements = TvShow.clean_dir(Dir.new(path))
77
+ elements.each do |el|
78
+ el_path = "#{path}/#{el}"
79
+ if File.directory?(el_path)
80
+ search_episodes(el_path)
81
+ elsif episode_file?(el)
82
+ @episodes << episode_data(el_path)
83
+ end
84
+ end
85
+ end
86
+
87
+ def episode_file?(filename)
88
+ filename.match(/.*(([0-9]{1,2}X[0-9]{1,2})|(S[0-9][0-9]E[0-9][0-9])).*((\.avi)|(\.mkv))$/i)
89
+ end
90
+
91
+ def episode_data(path)
92
+ filename = File.basename(path)
93
+ case filename
94
+ when /S[0-9][0-9]E[0-9][0-9]/i # S02E03
95
+ season = filename.match(/.*S([0-9]{1,2})E.*$/i)[1].to_i
96
+ number = filename.match(/.*E([0-9]{1,2}).*$/i)[1].to_i
97
+ when /[0-9]{1,2}X[0-9]{1,2}/i # 2X03
98
+ season = filename.match(/.*([0-9]{1,2})X[0-9]{1,2}.*$/i)[1].to_i
99
+ number = filename.match(/.*[0-9]{1,2}X([0-9]{1,2}).*$/i)[1].to_i
100
+ end
101
+ format = case filename
102
+ when /720p/i
103
+ 'hd'
104
+ else
105
+ 'sd'
106
+ end
107
+ { :season => season, :number => number, :path => path, :name => filename, :format => format }
108
+ end
109
+
110
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "AutoTVNZB" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'spec'
4
+ require 'spec/autorun'
5
+
6
+ Spec::Runner.configure do |config|
7
+
8
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: autotvnzb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Pirate
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-01 00:00:00 +01:00
13
+ default_executable: bin/autotvnzb
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hpricot
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.8.1
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: httparty
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.4.5
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: optiflag
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0.7"
54
+ version:
55
+ description: Ruby tool to automatically download tv shows nzb from http://tvnzb.com/
56
+ email: pirate.2061@gmail.com
57
+ executables:
58
+ - autotvnzb
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - LICENSE
63
+ - README.rdoc
64
+ files:
65
+ - .gitignore
66
+ - LICENSE
67
+ - README.rdoc
68
+ - Rakefile
69
+ - VERSION
70
+ - asset/failure.png
71
+ - asset/srt.png
72
+ - autotvnzb.gemspec
73
+ - bin/autotvnzb
74
+ - lib/inspector.rb
75
+ - lib/sabnzbd.rb
76
+ - lib/tvnzb.rb
77
+ - lib/tvshow.rb
78
+ - spec/spec.opts
79
+ - spec/spec_helper.rb
80
+ has_rdoc: true
81
+ homepage:
82
+ licenses: []
83
+
84
+ post_install_message:
85
+ rdoc_options:
86
+ - --charset=UTF-8
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ version:
101
+ requirements: []
102
+
103
+ rubyforge_project:
104
+ rubygems_version: 1.3.5
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Automatically download tv shows nzb
108
+ test_files:
109
+ - spec/autotvnzb_spec.rb
110
+ - spec/spec_helper.rb