jeeves-pvr 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/ruby18
2
+ #
3
+ # This file was generated by RubyGems.
4
+ #
5
+ # The application 'jeeves-pvr' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'rubygems'
10
+
11
+ version = ">= 0"
12
+
13
+ if ARGV.first
14
+ str = ARGV.first
15
+ str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
16
+ if str =~ /\A_(.*)_\z/
17
+ version = $1
18
+ ARGV.shift
19
+ end
20
+ end
21
+
22
+ #gem 'jeeves-pvr', version
23
+ #require 'jeeves'
24
+ executable = Gem.bin_path('jeeves-pvr', 'jeeves', version)
25
+ puts executable
26
+ load executable
@@ -0,0 +1,46 @@
1
+ #
2
+ # Configuration Options for: Jeeves::Config
3
+ #
4
+
5
+ # Add a file partition for Jeeves. Must have the following parameters:
6
+ # :path - valid file path to the partition to be added (not a device path),
7
+ # :key - the key given to the partition when it was initialised,
8
+ # :mountable - true if the partition should be mounted directly,
9
+ # :mounted_on - path of mount point if the partition is not one itself
10
+ #
11
+ # Use :mountable=>true to enable the partition to be mounted - needs to be an entry in /etc/fstab
12
+ # If the partition is not directly mountable but is on a mountable device partition that you also want
13
+ # mounted then use :mounted_on=>/path/to/partition instead
14
+ #add_partition
15
+ add_partition :path=>'/home/jeeves', :key=>'d1520a02b294db739bddb2324482310116f39d07'
16
+ add_partition :path=>'/home/jeeves_2', :key=>'9227567edca1bb8018d2c7bda592dbb69a89af35'
17
+
18
+ # Specify what to do if a specified partition cannot be added, e.g. because it has not been mounted
19
+ # Can be one of the following:
20
+ # :ignore - log an info message and carry on
21
+ # :warn - let the user know but carry on
22
+ # :fatal - do not continue without the partition
23
+ #
24
+ # The default is to warn but carry on. Jeeves should still be able to allocate a file even if there are
25
+ # missing partitions in the store
26
+ store_errors :warn
27
+
28
+ # Specify the environment within which Jeeves services (Jetuner etc) are expected
29
+ # to be operating. Should be one of :dev, :test or :prod
30
+ #environment :dev
31
+
32
+ # URL to the Jeeves listing/TV application that has info on programme listings
33
+ jeeves_tv_url 'http://tv.jeeves.osburn-sharp.ath.cx'
34
+
35
+ # Set the base rate for estimating data storage in kbytes per second. Note
36
+ # for some tuners this may need to be scaled, which can be done at the time
37
+ # of allocation.
38
+ #base_data_rate 416
39
+
40
+ # Specify a directory where jeeves can put working files etc. If you are working
41
+ # across a network then this directory needs to be shared across the network too.
42
+ working_dir '/home/jeeves/.jeeves'
43
+
44
+ # URL to the Jeeves video application to which recorded videos are referred etc
45
+ jeeves_url 'http://jeeves.osburn-sharp.ath.cx'
46
+
@@ -0,0 +1,68 @@
1
+ #
2
+ # Author:: R.J.Sharp
3
+ # Email:: robert(a)osburn-sharp.ath.cx
4
+ # Copyright:: Copyright (c) 2011
5
+ # License:: Open Software Licence v3.0
6
+ #
7
+ # This software is licensed for use under the Open Software Licence v. 3.0
8
+ # The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
9
+ # and in the file LICENCE. Under the terms of this licence, all derivative works
10
+ # must themselves be licensed under the Open Software Licence v. 3.0
11
+ #
12
+ #
13
+ require 'jerbil/jerbil_service/base'
14
+ require 'jerbil/jerbil_service/support'
15
+ require 'jerbil/support'
16
+ require 'jerbil/config'
17
+
18
+ # pull in things to do with jeeves
19
+
20
+ require 'jeeves/listings'
21
+ require 'jeeves/store'
22
+ require 'jeeves/tags'
23
+ require 'jeeves/config'
24
+ require 'jeeves/errors'
25
+
26
+ #
27
+ # == Jeeves Service
28
+ #
29
+ # Synopsis of the whole service
30
+ #
31
+ module Jeeves
32
+
33
+ # add generic class methods
34
+ extend JerbilService::Support
35
+
36
+ # === Jeeves Service class
37
+ #
38
+ # Description of how the service class works
39
+ #
40
+ # class Service < JerbilService::Base
41
+ #
42
+ # # Document the constructor as required.
43
+ # #
44
+ # # pkey:: string - private key that must be used for
45
+ # # supervision calls (e.g. stop_callback)
46
+ # # options:: hash of options, preferably as created by Jeckyl. See documentation
47
+ # # on JerbilService::Base for assumed options re logging etc
48
+ # #
49
+ # def initialize(pkey, options)
50
+ #
51
+ # # do things that cannot be done when $SAFE > 0
52
+ #
53
+ # # the symbol should be the app name and must correspond to a service in /etc/services
54
+ # super(:jeeves, pkey, options)
55
+ #
56
+ # # DRb is now working, this process may have daemonized and $SAFE = 1
57
+ #
58
+ # end
59
+ #
60
+ # #
61
+ # # define additional class methods to make things happen
62
+ # #
63
+ #
64
+ # # do not redefine the superclass methods unless you are absolutely sure you know
65
+ # # what you are doing.
66
+ #
67
+ # end
68
+ end
@@ -0,0 +1,141 @@
1
+ #
2
+ #
3
+ # = Configuration settings for Jeeves Applications etc
4
+ #
5
+ # == Jeckyl config
6
+ #
7
+ # Author:: Robert Sharp
8
+ # Copyright:: Copyright (c) 2013 Robert Sharp
9
+ # License:: Open Software Licence v3.0
10
+ #
11
+ # This software is licensed for use under the Open Software Licence v. 3.0
12
+ # The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
13
+ # and in the file copyright.txt. Under the terms of this licence, all derivative works
14
+ # must themselves be licensed under the Open Software Licence v. 3.0
15
+ #
16
+ #
17
+ #
18
+ require 'jeckyl'
19
+
20
+ module Jeeves
21
+
22
+ # define all of the configuration settings for Jeeves. Derived from
23
+ # Jellog to provide logging options for store operations
24
+ #
25
+ class Config < Jeckyl::Config
26
+
27
+ def configure_add_partition(params={})
28
+ comment "Add a file partition for Jeeves. Must have the following parameters:",
29
+ " :path - valid file path to the partition to be added (not a device path),",
30
+ " :key - the key given to the partition when it was initialised,",
31
+ " :mountable - true if the partition should be mounted directly,",
32
+ " :mounted_on - path of mount point if the partition is not one itself",
33
+ " ",
34
+ "Use :mountable=>true to enable the partition to be mounted - needs to be an entry in /etc/fstab",
35
+ "If the partition is not directly mountable but is on a mountable device partition that you also want",
36
+ "mounted then use :mounted_on=>/path/to/partition instead"
37
+
38
+ # ignore calls to get a default, which will not have the right params
39
+ return unless params.kind_of?(Hash)
40
+
41
+ @stores ||= Hash.new
42
+
43
+ if @stores.has_key?(params[:path]) then
44
+ # should not have defined the store already...
45
+ raise Jeckyl::ConfigError, "Duplicate store: #{params[:path]}"
46
+ end
47
+
48
+ # make sure this is a writable directory
49
+ # but if its not mounted it may not be!
50
+ #a_writable_dir(params[:path])
51
+
52
+ # if Jeeves.store_key(params[:path]) != params[:key] then
53
+ # # store has not been initialised with this key
54
+ # raise Jeckyl::ConfigError, "Incorrect/missing key for store: #{params[:path]}"
55
+ # end
56
+
57
+ @stores[params[:path]] = {:key=>params[:key]}
58
+
59
+ # check that both mount options have not been provided
60
+ if params[:mountable] then
61
+ if params.has_key?(:mounted_on) then
62
+ raise Jeckyl::ConfigError, "Please provide :mountable or :mounted_on but not both"
63
+ end
64
+ @stores[params[:path]][:mount_point] = params[:path]
65
+ end
66
+
67
+ if params.has_key?(:mounted_on) then
68
+ a_readable_file(params[:mounted_on]) # the directory may not be writable!
69
+ @stores[params[:path]][:mount_point] = params[:mounted_on]
70
+ end
71
+
72
+ return @stores
73
+
74
+ end
75
+
76
+ def configure_base_data_rate(kbpm)
77
+ default 25000 / 60 # reasonable rate for dvb
78
+ comment "Set the base rate for estimating data storage in kbytes per second. Note",
79
+ "for some tuners this may need to be scaled, which can be done at the time",
80
+ "of allocation."
81
+
82
+ a_type_of(kbpm, Integer) && in_range(kbpm, 100, 10000)
83
+
84
+ end
85
+
86
+ def configure_jeeves_url(url)
87
+ comment "URL to the Jeeves video application to which recorded videos are referred etc"
88
+
89
+ a_matching_string(url, /https?:\/\/[\S]+/)
90
+ end
91
+
92
+ def configure_jeeves_tv_url(url)
93
+ comment "URL to the Jeeves listing/TV application that has info on programme listings"
94
+
95
+ a_matching_string(url, /https?:\/\/[\S]+/)
96
+ end
97
+
98
+ def configure_jeeves_uri_timeout(timeout)
99
+ default 2 * 60 # 2 minutes
100
+ comment "Set the timeout on updating Jeeves TV with the listings data. This can",
101
+ "take a long time so usually it exceeds the default. Needs to be in seconds.",
102
+ "To set an infinite timeout, use 0"
103
+
104
+ a_type_of(timeout, Integer) && in_range(timeout, 0, 10000) # some very high upper limit
105
+
106
+ end
107
+
108
+ def configure_store_errors(symb)
109
+ default :warn
110
+ comment "Specify what to do if a specified partition cannot be added, e.g. because it has not been mounted",
111
+ "Can be one of the following:",
112
+ " :ignore - log an info message and carry on",
113
+ " :warn - let the user know but carry on",
114
+ " :fatal - do not continue without the partition",
115
+ "",
116
+ "The default is to warn but carry on. Jeeves should still be able to allocate a file even if there are",
117
+ "missing partitions in the store"
118
+
119
+ a_member_of(symb, [:ignore, :warn, :fatal])
120
+
121
+ end
122
+
123
+ def configure_working_dir(dir)
124
+ default '/tmp'
125
+ comment "Specify a directory where jeeves can put working files etc. If you are working",
126
+ "across a network then this directory needs to be shared across the network too."
127
+
128
+ a_writable_dir(dir)
129
+
130
+ end
131
+
132
+ def configure_environment(env)
133
+ default :dev
134
+ comment "Specify the environment within which Jeeves services (Jetuner etc) are expected",
135
+ "to be operating. Should be one of :dev, :test or :prod"
136
+ a_member_of(env, [:dev, :test, :prod])
137
+ end
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,70 @@
1
+ #
2
+ # Author:: R.J.Sharp
3
+ # Email:: robert(a)osburn-sharp.ath.cx
4
+ # Copyright:: Copyright (c) 2011
5
+ # License:: Open Software Licence v3.0
6
+ #
7
+ # This software is licensed for use under the Open Software Licence v. 3.0
8
+ # The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
9
+ # and in the file LICENCE. Under the terms of this licence, all derivative works
10
+ # must themselves be licensed under the Open Software Licence v. 3.0
11
+ #
12
+ #
13
+ # This file groups together all the errors for jeeves.
14
+ # Preceed each class with a description of the error
15
+
16
+ module Jeeves
17
+
18
+ # A general class for all errors created by this project. All specific exceptions
19
+ # should be children of this class
20
+ class JeevesError < RuntimeError; end
21
+
22
+ class VersionError < JeevesError; end
23
+
24
+ # errors raised by the scheduler
25
+ class JscheduleError < JeevesError; end
26
+
27
+ #the tuner type for a scheduler is not valid
28
+ class InvalidTuner < JscheduleError; end
29
+
30
+ # the tuner does not have the given mode
31
+ class InvalidMode < JscheduleError; end
32
+
33
+ # a schedule request is missing a required parameter
34
+ class MissingParam < JscheduleError; end
35
+
36
+ # the tuner is busy
37
+ class TunerBusy < JscheduleError; end
38
+
39
+ # store related errors
40
+ class StoreError < JeevesError; end
41
+
42
+ class InvalidPartition < StoreError; end
43
+
44
+ class InvalidPartitionKey < StoreError; end
45
+
46
+ class DiskError < JeevesError; end
47
+
48
+ # listings related errors
49
+ class ListingError < JeevesError; end
50
+ class VideoError < JeevesError; end
51
+
52
+
53
+ class TaggerError < JeevesError; end
54
+
55
+ # A Jeckyl option that is needed has not been provided
56
+ class MissingOption < TaggerError; end
57
+
58
+ # the file provided cannot be read
59
+ class FileError < TaggerError; end
60
+
61
+ # the url does not work
62
+ class UrlError < TaggerError; end
63
+
64
+ # there was an error with the XML tags
65
+ class XMLError < TaggerError; end
66
+
67
+ # error creating matroska file
68
+ class MkvError < TaggerError; end
69
+
70
+ end
@@ -0,0 +1,116 @@
1
+ #
2
+ #
3
+ # = Xmltv
4
+ #
5
+ # == methods for interfacing xmltv with jeeves
6
+ #
7
+ # Author:: Robert Sharp
8
+ # Copyright:: Copyright (c) 2013 Robert Sharp
9
+ # License:: Open Software Licence v3.0
10
+ #
11
+ # This software is licensed for use under the Open Software Licence v. 3.0
12
+ # The terms of this licence can be found at http://www.opensource.org/licenses/osl-3.0.php
13
+ # and in the file copyright.txt. Under the terms of this licence, all derivative works
14
+ # must themselves be licensed under the Open Software Licence v. 3.0
15
+ #
16
+ #
17
+ #
18
+ require 'jeckyl/errors'
19
+ require 'jeeves/errors'
20
+
21
+ module Jeeves
22
+
23
+ # load the latest listings data into Jeeves
24
+ #
25
+ # jeeves will use existing listings data if it was downloaded
26
+ # less than 6 hours ago. This can be overriden with the :force option
27
+ #
28
+ # If the :reset option is set to true then the listings data will replace
29
+ # all existing data and not just append to it.
30
+ #
31
+ # @param [Hash] params to control the loading
32
+ # @option [String] :working_dir, see config
33
+ # @option [String] :jeeves_tv_url, see config
34
+ # @option [Boolean] :force - set to true to force new listings data
35
+ # @option [Boolean] :reset - set to true to reset all listings data
36
+ def Jeeves.update_listings(params={})
37
+
38
+ working_dir = params[:working_dir]
39
+ unless File.directory?(working_dir) && File.writable?(working_dir)
40
+ # if config file is used this should not be possible
41
+ raise Jeckyl::ConfigError, "Cannot write to #{working_dir}"
42
+ end
43
+
44
+ chan_txt_file = File.join(working_dir, 'channels.txt')
45
+ listings_file = File.join(working_dir, 'listings.xml')
46
+
47
+ age = 0
48
+ # see how old it is
49
+ age = Time.now - File.mtime(listings_file) if FileTest.exists?(listings_file)
50
+
51
+ age = 0 if params[:update_listings] == true
52
+
53
+ jeeves_tv_url = params[:jeeves_tv_url]
54
+
55
+ # check how old the listings file is
56
+ unless age > 0 && age < (60*60*6) then
57
+ # its more than 6 hours old, so renew it
58
+ # or you forced renewal!
59
+
60
+ # make sure it does not already exist
61
+ FileUtils.rm_f(chan_txt_file)
62
+ FileUtils.rm_f(listings_file)
63
+
64
+
65
+ # get the channels info from jeeves_tv
66
+ cmd = "/usr/bin/wget #{jeeves_tv_url}/bchannels.txt -O #{chan_txt_file}"
67
+
68
+
69
+ unless system(cmd)
70
+ raise ListingError, "#{cmd}\n failed with error #{$?}"
71
+ end
72
+
73
+ unless File.exists?(chan_txt_file)
74
+ raise ListingError, "Failed to create file: #{chan_txt_file}"
75
+ end
76
+
77
+ # now copy this file to where xmltv expects to find it.
78
+ # cheat with shell cos of ~
79
+ cmd = "cp #{chan_txt_file} ~/.xmltv/tv_grab_uk_rt.conf"
80
+ unless system(cmd)
81
+ raise ListingError, "Failed to copy file: #{cmd}"
82
+ end
83
+
84
+ cmd = "/usr/bin/tv_grab_uk_rt >#{listings_file}"
85
+ unless system(cmd)
86
+ raise ListingError, "Failed to grab listings: #{$?}\n #{cmd}"
87
+ end
88
+ end
89
+
90
+ listings_url = URI.encode(listings_file) # ensure it is OK as url
91
+
92
+ # and now poke jeeves-tv to let it know there is something to process
93
+ #cmd = "/usr/bin/wget #{jeeves_tv_url}/load?file=#{listings_url}"
94
+ url = "#{jeeves_tv_url}/load?file=#{listings_url}"
95
+ url << "&reset=true" if params[:reset_listings]
96
+
97
+ # unless system(cmd)
98
+ # raise ListingError, "Failed to load programme info: #{$?}\n#{cmd}"
99
+ # end
100
+
101
+ rto = params[:jeeves_uri_timeout]
102
+ rto = nil if rto == 0 # makes it infinite
103
+
104
+ response = Array.new
105
+ open(url, read_timeout:rto) do |resp|
106
+ resp.each_line do |line|
107
+ response << line
108
+ end
109
+ end
110
+
111
+ # test that the response was OK
112
+
113
+ return true
114
+ end
115
+
116
+ end