anstaendig 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,7 @@
1
+ = anstaendig
2
+
3
+ == Installation
4
+
5
+ gem build anstaendig.gemspec
6
+ sudo gem install anstaendig-*.gem
7
+
data/bin/anstaendig ADDED
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Script to download videos from various streaming sites.
4
+ #
5
+ # Author:: henning mueller (mailto:henning@orgizm.net)
6
+ # Copyright:: Copyright (c) 2010 henning mueller
7
+ # License:: Beerware
8
+
9
+ require( 'uri' )
10
+ require( 'getoptlong' )
11
+
12
+ # Add source lib directory to include paths for require to work if anstaendig
13
+ # not installed as a gem.
14
+ $:.unshift( File.dirname( __FILE__ ) + '/../lib' )
15
+ require( 'anstaendig' )
16
+ include( Anstaendig )
17
+
18
+ # Shows a summary of the command line options.
19
+ def usageMessage
20
+ $stderr << "#{File.basename( $0 )} [options] <url>
21
+ Download videos from video streaming sites.
22
+
23
+ -h This help.
24
+ -l List available agents.
25
+ -m Keep mess (do not clean up on Interrupt).
26
+ -o name File to save the video to.
27
+ -q quality Quality of the video.
28
+ -r Recode to Theora/Vorbis.
29
+ -s Only show stream URL.
30
+
31
+ "
32
+ exit( 1 )
33
+ end
34
+
35
+ # Prints available download agents.
36
+ def listAgents
37
+ puts( AGENTS.keys.sort )
38
+ exit( 0 )
39
+ end
40
+
41
+ # Returns a new filename, if the desired one is taken.
42
+ def nextFilename( filename )
43
+ if( File.exists?( filename ) )
44
+ new = filename.insert( filename.index( /\./, -5 ), '.new' )
45
+ nextFilename( new )
46
+ else
47
+ return( filename )
48
+ end
49
+ end
50
+
51
+ options = GetoptLong.new(
52
+ [ '-h', GetoptLong::NO_ARGUMENT ],
53
+ [ '-l', GetoptLong::NO_ARGUMENT ],
54
+ [ '-m', GetoptLong::NO_ARGUMENT ],
55
+ [ '-o', GetoptLong::REQUIRED_ARGUMENT ],
56
+ [ '-q', GetoptLong::REQUIRED_ARGUMENT ],
57
+ [ '-r', GetoptLong::NO_ARGUMENT ],
58
+ [ '-s', GetoptLong::NO_ARGUMENT ]
59
+ )
60
+
61
+ saveAs = ""
62
+ quality = :default
63
+ cleanUp = true
64
+ recodeOGG, showStreamURL = false
65
+
66
+ options.each do |option, argument|
67
+ case( option )
68
+ when '-h'
69
+ usageMessage
70
+ when '-l'
71
+ listAgents
72
+ when '-m'
73
+ cleanUp = false
74
+ when '-o'
75
+ saveAs = argument
76
+ when '-q'
77
+ quality = argument.to_sym
78
+ when '-r'
79
+ recodeOGG = true
80
+ when '-s'
81
+ showStreamURL = true
82
+ end
83
+ end
84
+
85
+ begin
86
+ uri = URI.parse( ARGV[0] )
87
+ rescue URI::InvalidURIError
88
+ usageMessage
89
+ end
90
+
91
+ agent = AGENTS[ uri.host ].new( uri, quality )
92
+
93
+ if( showStreamURL )
94
+ puts( agent.url )
95
+ exit( 0 )
96
+ end
97
+
98
+ if( saveAs.empty? )
99
+ agent.filename = nextFilename( agent.filename )
100
+ else
101
+ agent.filename = saveAs
102
+ end
103
+
104
+ begin
105
+ agent.run
106
+ rescue Interrupt
107
+ if( cleanUp and File.exists?( agent.filename ) )
108
+ File.unlink( agent.filename )
109
+ end
110
+ end
111
+
112
+ if( recodeOGG )
113
+ agent.recode
114
+ end
@@ -0,0 +1,48 @@
1
+ module Anstaendig
2
+ AGENTS = Hash.new
3
+
4
+ # This interface describes download agents.
5
+ class AbstractAgent
6
+ attr_accessor :filename, :url
7
+
8
+ # Exception should be thrown, if an non-existent quality is demanded
9
+ # by the user.
10
+ class NoSuchQualityException
11
+ end
12
+
13
+ # If an agent does not set @filename, it would be the current time
14
+ # and date.
15
+ def initialize( url, quality = :high )
16
+ @filename = Time.now.to_i
17
+ end
18
+
19
+ # Calls the ripping process after substitution of certain characters
20
+ # in the filename generated by the agent.
21
+ def run
22
+ [ '/', '"', "'" ].each do |char|
23
+ @filename.gsub!( char, '' )
24
+ end
25
+
26
+ rip
27
+ end
28
+
29
+ # Contains the subshell command to rip the video stream. mplayer by
30
+ # default. Meant to be overloaded by the agent if necessary.
31
+ def rip
32
+ `mplayer -user-agent "#{userAgent}" -dumpstream -dumpfile "#{@filename}" "#{@url}"`
33
+ end
34
+
35
+ # Contains the subshell command to recode the video to a Vorbis/Theora
36
+ # encoded video in an OGG container. Meant to be overloaded by the
37
+ # agent if necessary.
38
+ def recode
39
+ `ffmpeg -i "#{@filename}" -acodec libvorbis -vcodec libtheora "#{@filename}.ogg"`
40
+ end
41
+
42
+ # Return the user agent which is sent on stream retrieval. Meant to be
43
+ # overloaded by the agent if necessary.
44
+ def userAgent
45
+ "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.2) Gecko/20100323 Namoroka/3.6.2"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module Anstaendig
2
+ # Agent for anstaendig to download videos from the 3sat media center.
3
+ #
4
+ # Author:: henning mueller (mailto:henning@orgizm.net)
5
+ # Copyright:: Copyright (c) 2010 henning mueller
6
+ # License:: Beerware
7
+
8
+ # 3sat agent class inherits from agent interface.
9
+ class DreiSatAgent < AbstractAgent
10
+ AGENTS[ 'www.3sat.de' ] = self
11
+
12
+ def initialize( uri, quality )
13
+ require( 'nokogiri' )
14
+ require( 'open-uri' )
15
+ require( 'iconv' )
16
+
17
+ uri.query += '&mode=play'
18
+
19
+ doc = Nokogiri::HTML( open( uri.to_s ) )
20
+
21
+ title = doc.xpath( '//title' ).inner_html
22
+ title = title.gsub!( '3sat.Mediathek - Video: ', '' ) + '.wmv'
23
+
24
+ asx = doc.xpath( '//embed[@id="Player2"]' ).attr( 'data' )
25
+ asx = Nokogiri::HTML( open( asx ) )
26
+
27
+ @filename = Iconv.conv( 'utf8', 'latin1', title )
28
+ @url = asx.xpath( '//ref' ).attr( 'href' )
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,49 @@
1
+ module Anstaendig
2
+ # Agent for anstaendig to download videos from the ARD media center.
3
+ #
4
+ # Author:: henning mueller (mailto:henning@orgizm.net)
5
+ # Copyright:: Copyright (c) 2010 henning mueller
6
+ # License:: Beerware
7
+
8
+ # ARD agent class inherits from agent interface.
9
+ class ArdAgent < AbstractAgent
10
+ AGENTS[ 'www.ardmediathek.de' ] = self
11
+
12
+ def initialize( uri, quality )
13
+ require( 'nokogiri' )
14
+ require( 'open-uri' )
15
+
16
+ doc = Nokogiri::HTML( open( uri.to_s ) )
17
+ raw = doc.content.split( "\r\n" ).grep( /rtmp/ )
18
+
19
+ @url = case( quality )
20
+ when :high, :default
21
+ conjure( raw.last )
22
+ when :medium
23
+ begin
24
+ conjure( raw[1] )
25
+ rescue( NoMethodError )
26
+ raise( NoSuchQualityException )
27
+ end
28
+ when :low
29
+ conjure( raw.first )
30
+ else
31
+ raise( NoSuchQualityException )
32
+ end
33
+
34
+ title = doc.xpath( '//title' ).inner_text
35
+ title = title.gsub( 'ARD Mediathek: ', '' )
36
+ n = title.index( /\ -\ [A-Za-z]*,/ ) - 1
37
+
38
+ @filename = title[0..n] + '.flv'
39
+ end
40
+
41
+ def conjure( string )
42
+ a = string.index( '"' ) + 1
43
+ b = string.index( '", "' ) - 1
44
+ c = string.index( '")' ) - 1
45
+
46
+ string.slice( a..b ) + string.slice( b+5..c )
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,49 @@
1
+ module Anstaendig
2
+ # Agent for anstaendig to download videos from the arte media center.
3
+ #
4
+ # Author:: henning mueller (mailto:henning@orgizm.net)
5
+ # Copyright:: Copyright (c) 2010 henning mueller
6
+ # License:: Beerware
7
+
8
+ #
9
+ # TODO
10
+ # This extracts the correct filename and url, but the stream ripping dies
11
+ # somehow after a few minutes.
12
+ #
13
+
14
+ # arte agent class inherits from agent interface.
15
+ class ArteAgent < AbstractAgent
16
+ AGENTS[ 'videos.arte.tv' ] = self
17
+
18
+ def initialize( uri, quality )
19
+ require( 'nokogiri' )
20
+ require( 'open-uri' )
21
+
22
+ lang = ENV['LANG'].slice(0..1)
23
+
24
+ doc = open( uri.to_s ).readlines
25
+
26
+ doc = Nokogiri::XML( open(
27
+ doc.grep( /vars_player\.videorefFileUrl/ )
28
+ .first.match( /(http.*xml)/ )[1]
29
+ ))
30
+
31
+ doc.xpath( '//videos/video' ).each do |item|
32
+ if( item.attr( 'lang' ) == lang )
33
+ doc = Nokogiri::XML( open( item.attr( 'ref' ) ) )
34
+ end
35
+ end
36
+
37
+ @filename = doc.xpath( '//name' ).first.text + '.wmv'
38
+
39
+ case( quality )
40
+ when :hd, :high, :default
41
+ @url = doc.xpath( '//urls/url[@quality="hd"]' ).text
42
+ when :sd, :medium, :low
43
+ @url = doc.xpath( '//urls/url[@quality="sd"]' ).text
44
+ else
45
+ raise( NoSuchQualityException )
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,47 @@
1
+ module Anstaendig
2
+ # Agent for anstaendig to download videos from the ZDF media center.
3
+ #
4
+ # Author:: henning mueller (mailto:henning@orgizm.net)
5
+ # Copyright:: Copyright (c) 2010 henning mueller
6
+ # License:: Beerware
7
+
8
+ # ZDF agent class inherits from agent interface.
9
+ class ZdfAgent < AbstractAgent
10
+ AGENTS[ 'www.zdf.de' ] = self
11
+
12
+ def initialize( uri, quality )
13
+ require( 'nokogiri' )
14
+ require( 'open-uri' )
15
+
16
+ uri = uri.to_s
17
+
18
+ if( uri =~ /hauptnavigation\/startseite\/#/ )
19
+ uri.gsub!( 'hauptnavigation/startseite/#/', '' )
20
+ end
21
+
22
+ doc = Nokogiri::HTML( open( uri ) )
23
+
24
+ quality = case( quality )
25
+ when :high, :default
26
+ '/veryhigh/'
27
+ when :medium, :low
28
+ '/300/'
29
+ else
30
+ raise( NoSuchQualityException )
31
+ end
32
+
33
+ doc.xpath( '//a[@class="play"]' ).each do |temp|
34
+ temp = temp.attribute( 'href' ).to_s
35
+ if( temp.include?( quality ) and temp.include?( '.asx' ) )
36
+ uri = temp
37
+ end
38
+ end
39
+
40
+ @filename = doc.xpath( '//h1[@class="beitragHeadline"]' ).inner_text + '.wmv'
41
+
42
+ doc = Nokogiri::HTML( open( uri ) )
43
+ # @url = doc.xpath( '//ref' ).attr( 'href' )
44
+ @url = doc.to_s.match( /(mms.*wmv)/ )[0]
45
+ end
46
+ end
47
+ end
data/lib/anstaendig.rb ADDED
@@ -0,0 +1,11 @@
1
+ $:.unshift( File.dirname( __FILE__ ) )
2
+
3
+ # The Anstaendig module includes an abstract agent class and all agents
4
+ # implementing this.
5
+ module Anstaendig
6
+ VERSION = '0.1.0'
7
+ end
8
+
9
+ Dir.glob( $:.first + '/**/*.rb' ).sort.each do |file|
10
+ require( file )
11
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: anstaendig
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - henning mueller
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-05-31 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: anstaendig is a extendable script to rip movie clips from TV station media center sites.
23
+ email: henning@orgizm.net
24
+ executables:
25
+ - anstaendig
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - bin/anstaendig
32
+ - lib/anstaendig.rb
33
+ - lib/anstaendig/agents/zdf.rb
34
+ - lib/anstaendig/agents/ard.rb
35
+ - lib/anstaendig/agents/3sat.rb
36
+ - lib/anstaendig/agents/arte.rb
37
+ - lib/anstaendig/abstractagent.rb
38
+ - README.rdoc
39
+ has_rdoc: true
40
+ homepage:
41
+ licenses: []
42
+
43
+ post_install_message:
44
+ rdoc_options: []
45
+
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ hash: 3
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ hash: 3
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.7
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Rip clips from TV station media center sites.
73
+ test_files: []
74
+