frypan 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/_README.md DELETED
@@ -1,31 +0,0 @@
1
- # Frypan
2
-
3
- TODO: Write a gem description
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- ```ruby
10
- gem 'frypan'
11
- ```
12
-
13
- And then execute:
14
-
15
- $ bundle
16
-
17
- Or install it yourself as:
18
-
19
- $ gem install frypan
20
-
21
- ## Usage
22
-
23
- TODO: Write usage instructions here
24
-
25
- ## Contributing
26
-
27
- 1. Fork it ( https://github.com/[my-github-username]/frypan/fork )
28
- 2. Create your feature branch (`git checkout -b my-new-feature`)
29
- 3. Commit your changes (`git commit -am 'Add some feature'`)
30
- 4. Push to the branch (`git push origin my-new-feature`)
31
- 5. Create a new Pull Request
data/bin/frypan DELETED
@@ -1,55 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # -*- coding: utf-8 -*-
3
- # -*- mode: ruby -*-
4
-
5
- require 'mongo'
6
-
7
- def install(home_path)
8
- # 1. mongodbのバイナリを落として [homepath]/mongodb.tarに保存
9
- # 2. 解凍する。[homepath]/mongodb/bin/mongodってな具合になる
10
- # 3. [homepath]/db/作る
11
- end
12
-
13
- def fork_db(home_path, port=27017)
14
- mongod = "#{home_path}/mongodb/bin/mongod"
15
- db = "#{home_path}/db/"
16
- log = "#{home_path}/db/server.log"
17
- status = `#{mongod} --dbpath #{db} --logpath #{log} --port #{port} --fork`
18
- pid = status.lines.map{|ln| ln.match(/forked process: (\d+)/)}.select{|a| a}.first[1].to_i
19
- success = status.lines.any?{|ln| ln.match(/successfully/)}
20
- if success then pid else nil end
21
- end
22
-
23
- def connect_db(port=27017, host="localhost")
24
- Mongo::Connection.new(host, port).db("frypan_core")
25
- end
26
-
27
- begin
28
- pid = fork_db("~/Workspace/")
29
- TinyFRP::Runtime.new(main_signal(connect_db)).run(:loop)
30
- ensure
31
- Process.kill("TERM", pid) if pid
32
- end
33
-
34
-
35
-
36
- db = hoge
37
- api_server = APIServer.new(db) # fork webrick. only op-command throw.
38
- epg = hoge
39
- tuner = [fuga]
40
-
41
- command = TinyFRP.lift{ api_server.get_next_command } # one-unit-command OR nil
42
- current_time = TinyFRP.lift{ Time.now.strftime("%Y%m%d%H%M%S") }
43
- epg_flag = hoge
44
- tuners_flag = [fuga]
45
-
46
- main = TinyFRP::Bundle.new(command, current_time, epg_flag, tuners_flag) >> Node.top(setting)
47
-
48
- TinyFRP.loop(main) do |out|
49
- out[:reserve1].action(db)
50
- out[:reserve2].action(db)
51
- out[:reserve3].action(db)
52
- out[:reserve4].action(db)
53
- out[:epg].action(epg)
54
- out[:tuner1].action(tuner1)
55
- end
@@ -1,30 +0,0 @@
1
- module Frypan
2
- class DBSyncList
3
- def initialize(name, db)
4
- @coll = db.collection(name)
5
- end
6
-
7
- def +(list)
8
- list.each{|a| @coll.insert(a)}
9
- self
10
- end
11
-
12
- def update(alt_list)
13
- @coll.remove
14
- alt_list.each{|a| @coll.insert(a)}
15
- self
16
- end
17
-
18
- def update_elements(elements, ident_key)
19
- elements.each do |a|
20
- @coll.update({ident_key => a[ident_key]}, {"$set" => a}, true)
21
- end
22
- self
23
- end
24
-
25
- def to_a
26
- @coll.find.to_a
27
- end
28
- end
29
- end
30
-
@@ -1,23 +0,0 @@
1
- module Frypan
2
- class EpgParser
3
- require 'm2ts_parser'
4
- class ParserProcess
5
- def initialize(file_path)
6
-
7
- end
8
-
9
- def finished?
10
-
11
- end
12
-
13
- def get_parsed
14
-
15
- end
16
- end
17
-
18
- def parse(file_path)
19
- ParserProcess.new(file_path)
20
- end
21
- end
22
- end
23
-
@@ -1,150 +0,0 @@
1
- module Frypan
2
- require 'tiny_frp'
3
- module Node
4
- def self.overlaped?(list_of_range)
5
- !list_of_range.sort{|a, b| a.begin <=> b.begin}.each_cons(2).all?{|a, b| a.end <= b.begin}
6
- end
7
-
8
- def self.apply_operations(list, ops)
9
- case
10
- when ops == []
11
- [list, ""]
12
- when ops.first[:kind] == :add
13
- added_list = list + [ops.first[:target]]
14
- if overlaped?(added_list.map{|a| a[:start_time]..a[:end_time]})
15
- [nil, "cannot add reservation: #{ops.first[:target]}"]
16
- else
17
- apply_operations(added_list, ops.drop(1))
18
- end
19
- when ops.first[:kind] == :remove
20
- if list.find{|a| a[:start_time] == ops.first[:target][:start_time]}
21
- apply_operations(list.reject{|a| a[:start_time] == ops.first[:target][:start_time]}, ops.drop(1))
22
- else
23
- [nil, "unexist remove reservation id: #{ops.first[:target][:id]}"]
24
- end
25
- else
26
- [nil, "unknown operation '#{ops.first[:kind]}'"]
27
- end
28
- end
29
-
30
- def self.ReserveListFoldp(tuner_id, initial_list=[])
31
- TinyFRP.foldp(launch: nil, list: initial_list, ack: nil) do |acc, command, current_time|
32
- case
33
- when command && command[:target_tuner] == tuner_id
34
- new_list, status = *apply_operations(acc[:list], command[:operations])
35
- ack = command.merge({
36
- timestamp: current_time,
37
- succeeded: !!new_list,
38
- status: status
39
- })
40
- if new_list
41
- {launch: nil, list: new_list.sort{|a, b| a[:start_time] <=> b[:start_time]}, ack: ack}
42
- else
43
- {launch: nil, ack: ack}
44
- end
45
- when acc[:list] != [] && acc[:list].first[:start_time] <= current_time
46
- {launch: acc[:list].first, list: acc[:list].drop(1), ack: nil}
47
- else
48
- {launch: nil, ack: nil}
49
- end
50
- end
51
- end
52
-
53
- def self.PersistantReserveListFoldp(tuner_id, dbsync_reserve)
54
- TinyFRP.foldp(last_list: nil, list: dbsync_reserve) do |acc, rlist|
55
- if !acc[:last_list] || acc[:last_list] != rlist[:list]
56
- {last_list: rlist[:list], list: acc[:list].update(rlist[:list])}
57
- else
58
- {}
59
- end
60
- end
61
- end
62
-
63
- def self.RecordingAsyncFoldp(tuner)
64
- TinyFRP.foldp(busy: false, rec_process: nil, waiting: [], log: []) do |acc, rlist|
65
- case
66
- when rlist[:launch]
67
- {waiting: acc[:waiting] + [rlist[:launch]], log: []}
68
- when acc[:busy]
69
- {busy: !acc[:rec_process].finished?, log: acc[:rec_process].get_log}
70
- when acc[:waiting] != []
71
- {
72
- busy: true,
73
- rec_process: tuner.rec(acc[:waiting].first),
74
- waiting: acc[:waiting].drop(1),
75
- log: []
76
- }
77
- else
78
- {log: []}
79
- end
80
- end
81
- end
82
-
83
- def self.RecordingLogFoldp(initial_log=[])
84
- TinyFRP.foldp(log: initial_log, epg_order: [], recorded: []) do |acc, *log_inputs|
85
- if log_inputs.any?{|a| a != []}
86
- new_logs = log_inputs.select{|a| a != []}.flatten
87
- {
88
- log: acc[:log] + new_logs,
89
- epg_order: Fnc.find_epg_order(new_logs),
90
- recorded: Fnc.find_recorded(new_logs)
91
- }
92
- else
93
- {epg_order: [], recorded: []}
94
- end
95
- end
96
- end
97
-
98
- def self.EpgExtractAsyncFoldp(epg_parser)
99
- TinyFRP.foldp(busy: false, parser_process: nil, waiting: [], extracted: []) do |acc, log|
100
- case
101
- when log[:epg_order]
102
- {waiting: acc[:waiting] + [log[:epg_order]], extracted: []}
103
- when acc[:busy]
104
- {busy: !acc[:parser_process].finished?, extracted: acc[:parser_process].get_parsed}
105
- when acc[:waiting] != []
106
- {
107
- busy: true,
108
- parser_process: epg_parser.parse(acc[:waiting].first[:file_path]),
109
- waiting: acc[:waiting].drop(1),
110
- extracted: []
111
- }
112
- else
113
- {extracted: []}
114
- end
115
- end
116
- end
117
-
118
- def self.ProgramListFoldp(initial_list=[])
119
- TinyFRP.foldp(list: initial_list) do |acc, epg|
120
- if epg[:extracted] != []
121
- # epg[:extracted] := list of {program_id: [service_id, event_id], ...}
122
- {list: acc[:list].update_elements(epg[:extracted], :program_id)}
123
- else
124
- {}
125
- end
126
- end
127
- end
128
-
129
- def self.RecordedListFoldp(initial_list=[])
130
- TinyFRP.foldp(list: initial_list) do |acc, log|
131
- if log[:recorded] != []
132
- {list: acc[:list] + log[:recorded]}
133
- else
134
- {}
135
- end
136
- end
137
- end
138
-
139
- def self.UIresponseFoldp(initial_list=[])
140
- TinyFRP.foldp(list: initial_list) do |acc, current_time, *acks|
141
- if acks.any?{|a| a}
142
- {list: acc[:list] + acks.select{|a| a}}
143
- else
144
- {}
145
- end
146
- end
147
- end
148
- end
149
- end
150
-
@@ -1,47 +0,0 @@
1
- module Frypan
2
- class Tuner
3
- class RecordingProcess
4
- def initialize(command)
5
- @reader, writer = IO.pipe
6
- @pid = Process.spawn(command, :err => writer, :out => writer)
7
- @mutex = Mutex.new
8
- @logs = []
9
- Thread.new{
10
- while IO::select([@reader])
11
- @mutex.synchronize{
12
- @logs << @reader.gets.chomp
13
- }
14
- end
15
- }
16
- end
17
-
18
- def finished?
19
- @finished ||= Process.waitpid2(@pid, Process::WNOHANG)
20
- end
21
-
22
- def get_log
23
- res = []
24
- @mutex.synchronize{
25
- res = @logs.dup
26
- @logs = []
27
- }
28
- res
29
- end
30
- end
31
-
32
- def initialize(format_str)
33
- @format_str = format_str
34
- end
35
-
36
- def rec(setting)
37
- RecordingProcess.new(Tuner.make_command(@format_str, setting))
38
- end
39
-
40
- def self.make_command(format_str, setting)
41
- setting.keys.inject(format_str) do |str, key|
42
- str.gsub("<#{key}>", setting[key].to_s)
43
- end
44
- end
45
- end
46
- end
47
-
@@ -1,171 +0,0 @@
1
- $LIBRARY_ROOT_PATH = File.dirname(File.expand_path(File.dirname(__FILE__)))
2
-
3
- module Frypan
4
- module UnitTest
5
- require 'test/unit'
6
- require $LIBRARY_ROOT_PATH + '/lib/frypan/node.rb'
7
-
8
- class DummyList
9
- attr_reader :array
10
- def initialize(init=[])
11
- @array = []
12
- end
13
-
14
- def +(list)
15
- DummyList.new(@array + list)
16
- end
17
-
18
- def update(alt_list)
19
- DummyList.new(alt_list)
20
- end
21
-
22
- def update_elements(elements, ident_key)
23
- if elements == []
24
- self
25
- else
26
- update_element(elements.first, ident_key).update_elements(elements.drop(1), ident_key)
27
- end
28
- end
29
-
30
- def update_element(element, ident_key)
31
- if @array.find{|a| a[ident_key] == element[ident_key]}
32
- DummyList.new(@array.map{|a| a[ident_key] == element[ident_key] ? element : a})
33
- else
34
- DummyList.new(@array + [element])
35
- end
36
- end
37
- end
38
-
39
- class DummyTuner
40
- class DummyRecordingProcess
41
- def initialize(logs)
42
- @logs = logs.dup
43
- end
44
-
45
- def finished?
46
- @logs.empty?
47
- end
48
-
49
- def get_log
50
- @logs.shift || []
51
- end
52
- end
53
-
54
- def initialize(logs)
55
- @logs = logs
56
- end
57
-
58
- def rec(setting)
59
- DummyRecordingProcess.new(@logs)
60
- end
61
- end
62
-
63
- class DummyEpgParser
64
- class DummyParserProcess
65
- def initialize(parseds)
66
- @parseds = parseds.dup
67
- end
68
-
69
- def finished?
70
- @parseds.empty?
71
- end
72
-
73
- def get_parsed
74
- @parseds.shift || []
75
- end
76
- end
77
-
78
- def initialize(parseds)
79
- @parseds = parseds
80
- end
81
-
82
- def parse(file_path)
83
- DummyParserProcess.new(@parseds)
84
- end
85
- end
86
-
87
- module Util
88
- def mkcom(command_id, target_tuner, *ops)
89
- {command_id: command_id, target_tuner: target_tuner, operations: ops}
90
- end
91
-
92
- def mkop(kind, target)
93
- {kind: kind, target: target}
94
- end
95
-
96
- def mkres(id, start_time, end_time)
97
- {id: id, start_time: start_time, end_time: end_time}
98
- end
99
- end
100
-
101
- class NodeTest < Test::Unit::TestCase
102
- include Util
103
-
104
- def test_ReserveListFoldp
105
- n = Node.ReserveListFoldp(:test_tuner, [])
106
- vals = [
107
- nil,
108
- com1 = mkcom(0, :test_tuner, mkop(:add, res1 = mkres(0, 2, 5))),
109
- com2 = mkcom(1, :test_tuner, mkop(:add, res2 = mkres(1, 5, 7))),
110
- nil,
111
- com3 = mkcom(2, :test_tuner, mkop(:add, res3 = mkres(2, 6, 10)))
112
- ].each_with_index.map{|a, i| n.call(a, i)}
113
-
114
- assert_equal({launch: nil, list: [], ack: nil}, vals[0])
115
-
116
- expect_ack1 = com1.merge(timestamp: 1, succeeded: true, status: "")
117
- assert_equal({launch: nil, list: [res1], ack: expect_ack1}, vals[1])
118
-
119
- expect_ack2 = com2.merge(timestamp: 2, succeeded: true, status: "")
120
- assert_equal({launch: nil, list: [res1, res2], ack: expect_ack2}, vals[2])
121
-
122
- assert_equal({launch: res1, list: [res2], ack: nil}, vals[3])
123
-
124
- expect_ack3 = com3.merge(timestamp: 4, succeeded: false, status: vals[4][:ack][:status])
125
- assert_equal({launch: nil, list: [res2], ack: expect_ack3}, vals[4])
126
- end
127
-
128
- def test_PersistantReserveListFoldp
129
- n = Node.PersistantReserveListFoldp(:tuner_tuner, DummyList.new([]))
130
- vals = [
131
- {list: [:a]},
132
- {list: [:a]},
133
- {list: [:a, :b]},
134
- ].map{|a| n.call(a)}
135
-
136
- assert_equal(vals[0], vals[1])
137
- assert_not_equal(vals[1], vals[2])
138
- end
139
-
140
- def test_RecordingAsyncFoldp
141
- n = Node.RecordingAsyncFoldp(DummyTuner.new([[0, 1], [2]]))
142
- v = [
143
- {launch: nil},
144
- {launch: :a},
145
- {launch: nil},
146
- {launch: :b},
147
- {launch: nil},
148
- {launch: nil},
149
- {launch: nil},
150
- {launch: nil},
151
- {launch: nil},
152
- {launch: nil},
153
- {launch: nil},
154
- ].map{|a| n.call(a)}
155
-
156
- assert_equal({busy: false, rec_process: v[0][:rec_process], waiting: [], log: []}, v[0])
157
- assert_equal({busy: false, rec_process: v[1][:rec_process], waiting: [:a], log: []}, v[1])
158
- assert_equal({busy: true, rec_process: v[2][:rec_process], waiting: [], log: []}, v[2])
159
- assert_equal({busy: true, rec_process: v[3][:rec_process], waiting: [:b], log: []}, v[3])
160
- assert_equal({busy: true, rec_process: v[4][:rec_process], waiting: [:b], log: [0, 1]}, v[4])
161
- assert_equal({busy: true, rec_process: v[5][:rec_process], waiting: [:b], log: [2]}, v[5])
162
- assert_equal({busy: false, rec_process: v[6][:rec_process], waiting: [:b], log: []}, v[6])
163
- assert_equal({busy: true, rec_process: v[7][:rec_process], waiting: [], log: []}, v[7])
164
- assert_equal({busy: true, rec_process: v[8][:rec_process], waiting: [], log: [0, 1]}, v[8])
165
- assert_equal({busy: true, rec_process: v[9][:rec_process], waiting: [], log: [2]}, v[9])
166
- assert_equal({busy: false, rec_process: v[10][:rec_process], waiting: [], log: []}, v[10])
167
- end
168
- end
169
- end
170
- end
171
-