frypan 0.0.1 → 1.0.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.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
-