simple_pvr 1.0.0 → 1.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +1 -4
- data/Gemfile.lock +72 -61
- data/README.md +51 -33
- data/bin/pvr_server +14 -6
- data/changelog.txt +11 -0
- data/development_server +14 -6
- data/features/channel_overview.feature +1 -1
- data/features/recordings.feature +30 -0
- data/features/step_definitions/pvr_steps.rb +34 -0
- data/features/support/env.rb +1 -2
- data/features/support/paths.rb +2 -0
- data/lib/simple_pvr.rb +2 -0
- data/lib/simple_pvr/model/database_initializer.rb +8 -0
- data/lib/simple_pvr/model/programme.rb +12 -2
- data/lib/simple_pvr/model/programme_actor.rb +14 -0
- data/lib/simple_pvr/model/programme_category.rb +14 -0
- data/lib/simple_pvr/model/programme_director.rb +13 -0
- data/lib/simple_pvr/model/programme_presenter.rb +13 -0
- data/lib/simple_pvr/model/recording.rb +12 -0
- data/lib/simple_pvr/programme_icon_fetcher.rb +15 -0
- data/lib/simple_pvr/pvr_initializer.rb +4 -4
- data/lib/simple_pvr/recorder.rb +4 -3
- data/lib/simple_pvr/recording_manager.rb +44 -24
- data/lib/simple_pvr/recording_planner.rb +3 -3
- data/lib/simple_pvr/scheduler.rb +12 -4
- data/lib/simple_pvr/server/base_controller.rb +12 -13
- data/lib/simple_pvr/server/channels_controller.rb +5 -5
- data/lib/simple_pvr/server/programmes_controller.rb +2 -2
- data/lib/simple_pvr/server/schedules_controller.rb +4 -4
- data/lib/simple_pvr/server/secured_controller.rb +71 -0
- data/lib/simple_pvr/server/shows_controller.rb +13 -8
- data/lib/simple_pvr/server/status_controller.rb +1 -1
- data/lib/simple_pvr/server/upcoming_recordings_controller.rb +1 -1
- data/lib/simple_pvr/version.rb +1 -1
- data/lib/simple_pvr/xmltv_reader.rb +37 -4
- data/public/css/typeahead.js-bootstrap.css +83 -0
- data/public/index.html +45 -37
- data/public/js/angular/http-auth-interceptor.js +122 -0
- data/public/js/app.js +4 -37
- data/public/js/controllers.js +22 -14
- data/public/js/directives.js +102 -0
- data/public/js/filters.js +0 -31
- data/public/js/services.js +64 -0
- data/public/js/typeahead/typeahead.min.js +7 -0
- data/public/partials/about.html +15 -13
- data/public/partials/channels.html +41 -36
- data/public/partials/programme.html +20 -4
- data/public/partials/programmeListing.html +14 -13
- data/public/partials/schedule.html +91 -86
- data/public/partials/schedules.html +28 -16
- data/public/partials/search.html +10 -11
- data/public/partials/show.html +26 -9
- data/public/partials/shows.html +5 -6
- data/public/partials/status.html +1 -1
- data/public/templates/loginDialog.html +30 -0
- data/public/templates/logoutLink.html +1 -0
- data/public/templates/titleSearch.html +5 -3
- data/simple_pvr.gemspec +6 -4
- data/spec/resources/dummyImage.png +1 -0
- data/spec/resources/programmes-with-categories.xmltv +27 -0
- data/spec/resources/programmes-with-credits.xmltv +24 -0
- data/spec/resources/programmes-with-icons.xmltv +25 -0
- data/spec/resources/programmes-with-presenters.xmltv +19 -0
- data/spec/resources/{programs-without-icon.xmltv → programmes-without-icon.xmltv} +0 -0
- data/spec/resources/{programs.xmltv → programmes.xmltv} +0 -4
- data/spec/simple_pvr/ffmpeg_spec.rb +24 -22
- data/spec/simple_pvr/hdhomerun_spec.rb +69 -67
- data/spec/simple_pvr/model/channel_spec.rb +101 -101
- data/spec/simple_pvr/model/programme_spec.rb +104 -104
- data/spec/simple_pvr/model/schedule_spec.rb +74 -74
- data/spec/simple_pvr/programme_icon_fetcher_spec.rb +25 -0
- data/spec/simple_pvr/pvr_initializer_spec.rb +40 -38
- data/spec/simple_pvr/recorder_spec.rb +37 -26
- data/spec/simple_pvr/recording_manager_spec.rb +160 -133
- data/spec/simple_pvr/recording_planner_spec.rb +213 -211
- data/spec/simple_pvr/scheduler_spec.rb +189 -172
- data/spec/simple_pvr/server/secured_controller_spec.rb +118 -0
- data/spec/simple_pvr/xmltv_reader_spec.rb +89 -41
- data/test/karma.conf.js +7 -4
- data/test/unit/filtersSpec.js +0 -36
- metadata +79 -63
- data/public/css/bootstrap-responsive.min.css +0 -9
- data/public/css/bootstrap.min.css +0 -9
- data/public/img/glyphicons-halflings-white.png +0 -0
- data/public/img/glyphicons-halflings.png +0 -0
- data/public/js/angular/angular-resource.min.js +0 -10
- data/public/js/angular/angular.min.js +0 -162
- data/public/js/bootstrap/bootstrap.min.js +0 -6
- data/public/js/jquery/jquery.min.js +0 -5
- data/test/lib/angular/angular-mocks.js +0 -1768
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'simple_pvr'
|
|
2
|
+
|
|
3
|
+
module SimplePvr
|
|
4
|
+
describe ProgrammeIconFetcher do
|
|
5
|
+
before do
|
|
6
|
+
@recording_dir = File.dirname(__FILE__) + '/../resources/recordings'
|
|
7
|
+
FileUtils.rm_rf(@recording_dir) if Dir.exists?(@recording_dir)
|
|
8
|
+
FileUtils.mkdir_p(@recording_dir)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'fetches image and stores it in specified location' do
|
|
12
|
+
destination_file = "#{@recording_dir}/dummyImage.png"
|
|
13
|
+
|
|
14
|
+
# We're using open-uri, which unfortunately does not understand file://, which would be perfect for
|
|
15
|
+
# this unit test. However, URLs starting with / are apparently interpreted as normal files.
|
|
16
|
+
source_url = "#{File.dirname(__FILE__)}/../resources/dummyImage.png"
|
|
17
|
+
|
|
18
|
+
Thread.should_receive(:new).and_yield
|
|
19
|
+
|
|
20
|
+
ProgrammeIconFetcher.fetch(source_url, destination_file)
|
|
21
|
+
|
|
22
|
+
File.read(destination_file).should == 'This is not really a PNG file...'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -1,50 +1,52 @@
|
|
|
1
1
|
require 'simple_pvr'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
SimplePvr::Model::DatabaseInitializer.stub(:setup)
|
|
6
|
-
|
|
7
|
-
@scheduler = double('Scheduler')
|
|
8
|
-
SimplePvr::Scheduler.stub(new: @scheduler)
|
|
9
|
-
|
|
10
|
-
@hdhomerun = double('HDHomeRun')
|
|
11
|
-
SimplePvr::HDHomeRun.stub(new: @hdhomerun)
|
|
12
|
-
|
|
13
|
-
@recording_manager = double('RecordingManager')
|
|
14
|
-
SimplePvr::RecordingManager.stub(new: @recording_manager)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it 'starts the scheduler' do
|
|
18
|
-
SimplePvr::Model::Channel.stub(all: [1, 2, 3, 4, 5])
|
|
19
|
-
@scheduler.should_receive(:start)
|
|
20
|
-
|
|
21
|
-
SimplePvr::PvrInitializer.setup
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
context 'when scheduler is started' do
|
|
3
|
+
module SimplePvr
|
|
4
|
+
describe PvrInitializer do
|
|
25
5
|
before do
|
|
26
|
-
|
|
6
|
+
Model::DatabaseInitializer.stub(:setup)
|
|
7
|
+
|
|
8
|
+
@scheduler = double('Scheduler')
|
|
9
|
+
Scheduler.stub(new: @scheduler)
|
|
10
|
+
|
|
11
|
+
@hdhomerun = double('HDHomeRun')
|
|
12
|
+
HDHomeRun.stub(new: @hdhomerun)
|
|
13
|
+
|
|
14
|
+
@recording_manager = double('RecordingManager')
|
|
15
|
+
RecordingManager.stub(new: @recording_manager)
|
|
27
16
|
end
|
|
28
|
-
|
|
29
|
-
it 'runs a channel scan if channels are missing' do
|
|
30
|
-
SimplePvr::Model::Channel.stub(all: [])
|
|
31
|
-
@hdhomerun.should_receive(:scan_for_channels)
|
|
32
17
|
|
|
33
|
-
|
|
34
|
-
|
|
18
|
+
it 'starts the scheduler' do
|
|
19
|
+
Model::Channel.stub(all: [1, 2, 3, 4, 5])
|
|
20
|
+
@scheduler.should_receive(:start)
|
|
35
21
|
|
|
36
|
-
|
|
37
|
-
SimplePvr::Model::Channel.stub(all: [1])
|
|
38
|
-
|
|
39
|
-
SimplePvr::PvrInitializer.setup
|
|
22
|
+
PvrInitializer.setup
|
|
40
23
|
end
|
|
24
|
+
|
|
25
|
+
context 'when scheduler is started' do
|
|
26
|
+
before do
|
|
27
|
+
@scheduler.stub(:start)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'runs a channel scan if channels are missing' do
|
|
31
|
+
Model::Channel.stub(all: [])
|
|
32
|
+
@hdhomerun.should_receive(:scan_for_channels)
|
|
33
|
+
|
|
34
|
+
PvrInitializer.setup
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'does nothing if channels.txt is present' do
|
|
38
|
+
Model::Channel.stub(all: [1])
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
PvrInitializer.setup
|
|
41
|
+
end
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
it 'initializes a HDHomeRun and RecordingManager instance' do
|
|
44
|
+
Model::Channel.stub(all: [1])
|
|
45
|
+
|
|
46
|
+
PvrInitializer.setup
|
|
47
|
+
PvrInitializer.hdhomerun.should == @hdhomerun
|
|
48
|
+
PvrInitializer.recording_manager.should == @recording_manager
|
|
49
|
+
end
|
|
48
50
|
end
|
|
49
51
|
end
|
|
50
52
|
end
|
|
@@ -1,32 +1,43 @@
|
|
|
1
1
|
require 'simple_pvr'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
SimplePvr::PvrInitializer.stub(hdhomerun: @hdhomerun)
|
|
10
|
-
|
|
11
|
-
@recording_manager = double('RecordingManager')
|
|
12
|
-
@recording_manager.stub(:create_directory_for_recording).with(@recording).and_return('recording directory')
|
|
13
|
-
SimplePvr::PvrInitializer.stub(recording_manager: @recording_manager)
|
|
14
|
-
|
|
15
|
-
@recorder = SimplePvr::Recorder.new(1, @recording)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it 'can start recording' do
|
|
19
|
-
@hdhomerun.should_receive(:start_recording).with(1, 282000000, 1098, 'recording directory')
|
|
20
|
-
|
|
21
|
-
@recorder.start!
|
|
22
|
-
end
|
|
3
|
+
module SimplePvr
|
|
4
|
+
describe Recorder do
|
|
5
|
+
before do
|
|
6
|
+
@programme = Model::Programme.new
|
|
7
|
+
@channel = Model::Channel.new(frequency: 282000000, channel_id: 1098)
|
|
8
|
+
@recording = Model::Recording.new(@channel, 'Star Trek', 'start time', 'duration', @programme)
|
|
23
9
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@hdhomerun.should_receive(:stop_recording).with(1)
|
|
27
|
-
SimplePvr::Ffmpeg.should_receive(:create_thumbnail_for).with('recording directory')
|
|
10
|
+
@hdhomerun = double('HDHomeRun')
|
|
11
|
+
PvrInitializer.stub(hdhomerun: @hdhomerun)
|
|
28
12
|
|
|
29
|
-
|
|
30
|
-
|
|
13
|
+
@recording_manager = double('RecordingManager')
|
|
14
|
+
@recording_manager.stub(:create_directory_for_recording).with(@recording).and_return('recording directory')
|
|
15
|
+
PvrInitializer.stub(recording_manager: @recording_manager)
|
|
16
|
+
|
|
17
|
+
@recorder = Recorder.new(1, @recording)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'can start recording' do
|
|
21
|
+
@hdhomerun.should_receive(:start_recording).with(1, 282000000, 1098, 'recording directory')
|
|
22
|
+
|
|
23
|
+
@recorder.start!
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'starts fetching programme icon when recording starts' do
|
|
27
|
+
@programme.icon_url = 'http://tv-images.com/myImage.png'
|
|
28
|
+
ProgrammeIconFetcher.should_receive(:fetch).with('http://tv-images.com/myImage.png', 'recording directory/icon')
|
|
29
|
+
@hdhomerun.should_receive(:start_recording)
|
|
30
|
+
|
|
31
|
+
@recorder.start!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'can stop recording as well, and creates a thumbnail' do
|
|
35
|
+
@hdhomerun.stub(:start_recording)
|
|
36
|
+
@hdhomerun.should_receive(:stop_recording).with(1)
|
|
37
|
+
Ffmpeg.should_receive(:create_thumbnail_for).with('recording directory')
|
|
38
|
+
|
|
39
|
+
@recorder.start!
|
|
40
|
+
@recorder.stop!
|
|
41
|
+
end
|
|
31
42
|
end
|
|
32
43
|
end
|
|
@@ -1,158 +1,185 @@
|
|
|
1
1
|
require 'simple_pvr'
|
|
2
2
|
require 'yaml'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
it 'knows which shows are recorded' do
|
|
16
|
-
@manager.shows.should == ['Another series', 'series 1']
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it 'can delete all episodes of a given show' do
|
|
20
|
-
@manager.delete_show('series 1')
|
|
21
|
-
File.exists?(@recording_dir + '/series 1').should be_false
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'knows which episodes of a given show exists' do
|
|
25
|
-
episodes = @manager.episodes_of('series 1')
|
|
4
|
+
module SimplePvr
|
|
5
|
+
describe RecordingManager do
|
|
6
|
+
before do
|
|
7
|
+
@recording_dir = File.dirname(__FILE__) + '/../resources/recordings'
|
|
8
|
+
FileUtils.rm_rf(@recording_dir) if Dir.exists?(@recording_dir)
|
|
9
|
+
FileUtils.mkdir_p(@recording_dir + "/series 1/1")
|
|
10
|
+
FileUtils.mkdir_p(@recording_dir + "/series 1/3")
|
|
11
|
+
FileUtils.mkdir_p(@recording_dir + "/Another series/10")
|
|
12
|
+
|
|
13
|
+
@manager = RecordingManager.new(@recording_dir)
|
|
14
|
+
end
|
|
26
15
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
it 'reads metadata for recordings if present' do
|
|
33
|
-
start_time = Time.now
|
|
34
|
-
metadata = {
|
|
35
|
-
channel: 'Channel 4',
|
|
36
|
-
subtitle: 'A subtitle',
|
|
37
|
-
description: 'A description',
|
|
38
|
-
start_time: start_time,
|
|
39
|
-
duration: 10.minutes
|
|
40
|
-
}
|
|
41
|
-
File.open(@recording_dir + '/series 1/3/metadata.yml', 'w') {|f| f.write(metadata.to_yaml) }
|
|
16
|
+
it 'knows which shows are recorded' do
|
|
17
|
+
@manager.shows.size.should == 2
|
|
18
|
+
@manager.shows.should include('Another series', 'series 1')
|
|
19
|
+
end
|
|
42
20
|
|
|
43
|
-
|
|
21
|
+
it 'can delete all recordings of a given show' do
|
|
22
|
+
@manager.delete_show('series 1')
|
|
23
|
+
File.exists?(@recording_dir + '/series 1').should be_false
|
|
24
|
+
end
|
|
44
25
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
26
|
+
it 'knows which recordings of a given show exists' do
|
|
27
|
+
recordings = @manager.recordings_of('series 1')
|
|
28
|
+
|
|
29
|
+
recordings.length.should == 2
|
|
30
|
+
recordings[0].id.should == '1'
|
|
31
|
+
recordings[1].id.should == '3'
|
|
32
|
+
end
|
|
49
33
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
it 'knows when thumbnail exists' do
|
|
66
|
-
FileUtils.touch(@recording_dir + "/series 1/1/thumbnail.png")
|
|
67
|
-
episodes = @manager.episodes_of('series 1')
|
|
68
|
-
|
|
69
|
-
episodes[0].has_thumbnail.should == true
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
it 'knows when no webm file exists' do
|
|
73
|
-
episodes = @manager.episodes_of('series 1')
|
|
74
|
-
|
|
75
|
-
episodes[0].has_webm.should == false
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
it 'knows when a webm file exists' do
|
|
79
|
-
FileUtils.touch(@recording_dir + "/series 1/1/stream.webm")
|
|
80
|
-
episodes = @manager.episodes_of('series 1')
|
|
81
|
-
|
|
82
|
-
episodes[0].has_webm.should == true
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it 'can delete an episode of a given show' do
|
|
86
|
-
@manager.delete_show_episode('series 1', '3')
|
|
87
|
-
File.exists?(@recording_dir + '/series 1/3').should be_false
|
|
88
|
-
end
|
|
34
|
+
it 'reads metadata for recordings if present' do
|
|
35
|
+
start_time = Time.now
|
|
36
|
+
metadata = {
|
|
37
|
+
channel: 'Channel 4',
|
|
38
|
+
subtitle: 'A subtitle',
|
|
39
|
+
description: 'A description',
|
|
40
|
+
start_time: start_time,
|
|
41
|
+
duration: 10.minutes
|
|
42
|
+
}
|
|
43
|
+
File.open(@recording_dir + '/series 1/3/metadata.yml', 'w') {|f| f.write(metadata.to_yaml) }
|
|
44
|
+
|
|
45
|
+
recordings = @manager.recordings_of('series 1')
|
|
46
|
+
|
|
47
|
+
recordings.length.should == 2
|
|
89
48
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
49
|
+
recordings[0].id.should == '1'
|
|
50
|
+
recordings[0].show_name.should == 'series 1'
|
|
51
|
+
|
|
52
|
+
recordings[1].id.should == '3'
|
|
53
|
+
recordings[1].show_name.should == 'series 1'
|
|
54
|
+
recordings[1].channel.should == 'Channel 4'
|
|
55
|
+
recordings[1].subtitle.should == 'A subtitle'
|
|
56
|
+
recordings[1].description.should == 'A description'
|
|
57
|
+
recordings[1].start_time.to_i.should == start_time.to_i
|
|
58
|
+
recordings[1].duration == 10.minutes
|
|
94
59
|
end
|
|
95
60
|
|
|
96
|
-
it '
|
|
97
|
-
@manager.
|
|
98
|
-
|
|
99
|
-
|
|
61
|
+
it 'knows when no icon exists' do
|
|
62
|
+
recordings = @manager.recordings_of('series 1')
|
|
63
|
+
|
|
64
|
+
recordings[0].has_icon.should be_false
|
|
100
65
|
end
|
|
101
66
|
|
|
102
|
-
it '
|
|
103
|
-
@
|
|
104
|
-
@manager.
|
|
67
|
+
it 'knows when icon exists' do
|
|
68
|
+
FileUtils.touch(@recording_dir + "/series 1/1/icon")
|
|
69
|
+
recordings = @manager.recordings_of('series 1')
|
|
70
|
+
|
|
71
|
+
recordings[0].has_icon.should be_true
|
|
72
|
+
end
|
|
105
73
|
|
|
106
|
-
|
|
74
|
+
it 'knows when no thumbnail exists' do
|
|
75
|
+
recordings = @manager.recordings_of('series 1')
|
|
76
|
+
|
|
77
|
+
recordings[0].has_thumbnail.should be_false
|
|
107
78
|
end
|
|
108
79
|
|
|
109
|
-
it '
|
|
110
|
-
@
|
|
111
|
-
@manager.
|
|
112
|
-
|
|
113
|
-
|
|
80
|
+
it 'knows when thumbnail exists' do
|
|
81
|
+
FileUtils.touch(@recording_dir + "/series 1/1/thumbnail.png")
|
|
82
|
+
recordings = @manager.recordings_of('series 1')
|
|
83
|
+
|
|
84
|
+
recordings[0].has_thumbnail.should be_true
|
|
114
85
|
end
|
|
115
86
|
|
|
116
|
-
it '
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
@manager.create_directory_for_recording(@recording)
|
|
121
|
-
|
|
122
|
-
File.exists?(@recording_dir + '/Star Trek/4').should be_true
|
|
87
|
+
it 'knows when no webm file exists' do
|
|
88
|
+
recordings = @manager.recordings_of('series 1')
|
|
89
|
+
|
|
90
|
+
recordings[0].has_webm.should be_false
|
|
123
91
|
end
|
|
124
92
|
|
|
125
|
-
it '
|
|
126
|
-
FileUtils.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
File.exists?(@recording_dir + '/Star Trek/5').should be_true
|
|
93
|
+
it 'knows when a webm file exists' do
|
|
94
|
+
FileUtils.touch(@recording_dir + "/series 1/1/stream.webm")
|
|
95
|
+
recordings = @manager.recordings_of('series 1')
|
|
96
|
+
|
|
97
|
+
recordings[0].has_webm.should be_true
|
|
131
98
|
end
|
|
132
|
-
|
|
133
|
-
it '
|
|
134
|
-
@manager.
|
|
135
|
-
|
|
136
|
-
metadata = YAML.load_file(@recording_dir + '/Star Trek/1/metadata.yml')
|
|
137
|
-
metadata[:title].should == 'Star Trek'
|
|
138
|
-
metadata[:channel].should == 'Channel 4'
|
|
139
|
-
metadata[:start_time].should == @start_time
|
|
140
|
-
metadata[:duration].should == 50.minutes
|
|
99
|
+
|
|
100
|
+
it 'can delete a recording of a given show' do
|
|
101
|
+
@manager.delete_show_recording('series 1', '3')
|
|
102
|
+
File.exists?(@recording_dir + '/series 1/3').should be_false
|
|
141
103
|
end
|
|
142
104
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
105
|
+
context 'when creating recording directories' do
|
|
106
|
+
before do
|
|
107
|
+
@start_time = Time.local(2012, 7, 23, 15, 30, 15)
|
|
108
|
+
@start_time_millis = @start_time.to_i
|
|
109
|
+
@recording = Model::Recording.new(double(name: 'Channel 4'), 'Star Trek', @start_time, 50.minutes)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'records to directory with record start time if it does not already exist' do
|
|
113
|
+
@manager.create_directory_for_recording(@recording)
|
|
114
|
+
|
|
115
|
+
File.exists?("#{@recording_dir}/Star Trek/#{@start_time_millis}").should be_true
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'appends sequence number to start time if time stamp is already used' do
|
|
119
|
+
FileUtils.mkdir_p("#{@recording_dir}/Star Trek/#{@start_time_millis}")
|
|
120
|
+
@manager.create_directory_for_recording(@recording)
|
|
121
|
+
|
|
122
|
+
File.exists?("#{@recording_dir}/Star Trek/#{@start_time_millis}-1").should be_true
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it 'finds next number in sequence for new directory if time stamp is already used' do
|
|
126
|
+
FileUtils.mkdir_p("#{@recording_dir}/Star Trek/#{@start_time_millis}")
|
|
127
|
+
FileUtils.mkdir_p("#{@recording_dir}/Star Trek/#{@start_time_millis}-1")
|
|
128
|
+
FileUtils.mkdir_p("#{@recording_dir}/Star Trek/#{@start_time_millis}-2")
|
|
129
|
+
@manager.create_directory_for_recording(@recording)
|
|
130
|
+
|
|
131
|
+
File.exists?("#{@recording_dir}/Star Trek/#{@start_time_millis}-3").should be_true
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'removes some potentially harmful characters from directory name' do
|
|
135
|
+
@recording.show_name = "Some... harmful/irritating\\ characters in: '*title\""
|
|
136
|
+
@manager.create_directory_for_recording(@recording)
|
|
137
|
+
|
|
138
|
+
File.exists?("#{@recording_dir}/Some harmfulirritating characters in title/#{@start_time_millis}").should be_true
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it 'finds a directory name for titles which would otherwise get an empty directory name' do
|
|
142
|
+
@recording.show_name = '/.'
|
|
143
|
+
@manager.create_directory_for_recording(@recording)
|
|
144
|
+
|
|
145
|
+
File.exists?("#{@recording_dir}/Unnamed/#{@start_time_millis}").should be_true
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'stores simple metadata if no programme information exists' do
|
|
149
|
+
@manager.create_directory_for_recording(@recording)
|
|
150
|
+
|
|
151
|
+
metadata = YAML.load_file("#{@recording_dir}/Star Trek/#{@start_time_millis}/metadata.yml")
|
|
152
|
+
metadata[:title].should == 'Star Trek'
|
|
153
|
+
metadata[:channel].should == 'Channel 4'
|
|
154
|
+
metadata[:start_time].should == @start_time
|
|
155
|
+
metadata[:duration].should == 50.minutes
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it 'stores extensive metadata if programme information exists' do
|
|
159
|
+
start_time = Time.local(2012, 7, 23, 15, 30, 15)
|
|
160
|
+
start_time_millis = start_time.to_i
|
|
161
|
+
recording = Model::Recording.new(double(name: 'Channel 4'), 'Extensive Metadata', start_time, 50.minutes)
|
|
162
|
+
recording.programme = Model::Programme.new(subtitle: 'A subtitle', description: "A description,\nspanning several lines")
|
|
163
|
+
recording.programme.categories.new(name: 'series')
|
|
164
|
+
recording.programme.categories.new(name: 'children')
|
|
165
|
+
recording.programme.directors.new(name: 'The director')
|
|
166
|
+
recording.programme.presenters.new(name: 'The presenter')
|
|
167
|
+
recording.programme.actors.new(role_name: 'First role', actor_name: 'First actor')
|
|
168
|
+
recording.programme.actors.new(role_name: 'Second role', actor_name: 'Second actor')
|
|
169
|
+
@manager.create_directory_for_recording(recording)
|
|
170
|
+
|
|
171
|
+
metadata = YAML.load_file("#{@recording_dir}/Extensive Metadata/#{start_time_millis}/metadata.yml")
|
|
172
|
+
metadata[:title].should == 'Extensive Metadata'
|
|
173
|
+
metadata[:channel].should == 'Channel 4'
|
|
174
|
+
metadata[:start_time].should == start_time
|
|
175
|
+
metadata[:duration].should == 50.minutes
|
|
176
|
+
metadata[:subtitle].should == 'A subtitle'
|
|
177
|
+
metadata[:description].should == "A description,\nspanning several lines"
|
|
178
|
+
metadata[:categories].should == ['series', 'children']
|
|
179
|
+
metadata[:directors].should == ['The director']
|
|
180
|
+
metadata[:presenters].should == ['The presenter']
|
|
181
|
+
metadata[:actors].should == [{role_name: 'First role', actor_name: 'First actor'}, {role_name: 'Second role', actor_name: 'Second actor'}]
|
|
182
|
+
end
|
|
156
183
|
end
|
|
157
184
|
end
|
|
158
185
|
end
|