anstaendig 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+