kaede 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +14 -0
- data/ChangeLog.md +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +109 -0
- data/Rakefile +6 -0
- data/bin/kaede +4 -0
- data/kaede.gemspec +36 -0
- data/kaede.rb.sample +25 -0
- data/kaede.service.sample +16 -0
- data/lib/kaede.rb +12 -0
- data/lib/kaede/channel.rb +4 -0
- data/lib/kaede/cli.rb +81 -0
- data/lib/kaede/config.rb +33 -0
- data/lib/kaede/database.rb +146 -0
- data/lib/kaede/dbus.rb +5 -0
- data/lib/kaede/dbus/generator.rb +32 -0
- data/lib/kaede/dbus/program.rb +125 -0
- data/lib/kaede/dbus/scheduler.rb +28 -0
- data/lib/kaede/notifier.rb +72 -0
- data/lib/kaede/program.rb +39 -0
- data/lib/kaede/recorder.rb +150 -0
- data/lib/kaede/scheduler.rb +174 -0
- data/lib/kaede/syoboi_calendar.rb +39 -0
- data/lib/kaede/updater.rb +61 -0
- data/lib/kaede/version.rb +3 -0
- data/spec/fixtures/vcr/cal_chk/all.yml +6906 -0
- data/spec/fixtures/vcr/cal_chk/days7.yml +3581 -0
- data/spec/kaede/notifier_spec.rb +60 -0
- data/spec/kaede/recorder_spec.rb +176 -0
- data/spec/kaede/scheduler_spec.rb +55 -0
- data/spec/kaede/syoboi_calendar_spec.rb +20 -0
- data/spec/kaede/updater_spec.rb +67 -0
- data/spec/spec_helper.rb +50 -0
- data/spec/tools/assdumper +2 -0
- data/spec/tools/b25 +6 -0
- data/spec/tools/clean-ts +2 -0
- data/spec/tools/recpt1 +8 -0
- data/spec/tools/statvfs +2 -0
- metadata +309 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 763474045525030a9ac8d0ef492f763f325dee9b
|
4
|
+
data.tar.gz: 03949c0dfd3f2c3e6c7764b36c08c2c9943d79e7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a513df57390c5a072726e9c9aeeaffe62400f3fe69dd0a2d91f191d2bf8d058edda6b0c7487d8168ce48eadd20345c1dc69a5a2d0937021966d80217c774e8cc
|
7
|
+
data.tar.gz: b5dc2c6b26e45d3b81e7bf34b72b1ac161d2b63567a8684e55b49b38b274af1aab7d04d7298861441cf30514627691b1b78ae802ede2378405b5623de21967b0
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 2.0.0
|
5
|
+
- 2.1.1
|
6
|
+
- ruby-head
|
7
|
+
before_install:
|
8
|
+
- export NOKOGIRI_USE_SYSTEM_LIBRARIES=1
|
9
|
+
before_script:
|
10
|
+
- bundle exec bin/kaede dbus-policy $USER > kaede.conf
|
11
|
+
- sudo mv kaede.conf /etc/dbus-1/system.d/kaede.conf
|
12
|
+
matrix:
|
13
|
+
allow_failures:
|
14
|
+
- rvm: ruby-head
|
data/ChangeLog.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Kohei Suzuki
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# Kaede
|
2
|
+
[![Build Status](https://api.travis-ci.org/eagletmt/kaede.svg)](https://travis-ci.org/eagletmt/kaede)
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/eagletmt/kaede/badge.png)](https://coveralls.io/r/eagletmt/kaede)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/eagletmt/kaede.png)](https://codeclimate.com/github/eagletmt/kaede)
|
5
|
+
|
6
|
+
Scheduler for recpt1 recorder using [Syoboi Calendar](http://cal.syoboi.jp/).
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'kaede'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install kaede
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
### Requirements
|
24
|
+
- sqlite3
|
25
|
+
- redis
|
26
|
+
- dbus
|
27
|
+
- recpt1
|
28
|
+
- b25
|
29
|
+
- [statvfs](https://github.com/eagletmt/eagletmt-recutils/tree/master/statvfs)
|
30
|
+
- [clean-ts](https://github.com/eagletmt/eagletmt-recutils/tree/master/clean-ts)
|
31
|
+
- [assdumper](https://github.com/eagletmt/eagletmt-recutils/tree/master/assdumper)
|
32
|
+
|
33
|
+
Some of them should be optional, though.
|
34
|
+
|
35
|
+
### Setup
|
36
|
+
```sh
|
37
|
+
kaede dbus-policy $KAEDE_USER > kaede.conf
|
38
|
+
sudo mv kaede.conf /etc/dbus-1/system.d/kaede.conf
|
39
|
+
|
40
|
+
cp kaede.rb.sample kaede.rb
|
41
|
+
vim kaede.rb
|
42
|
+
|
43
|
+
cp kaede.service.sample kaede.service
|
44
|
+
vim kaede.service
|
45
|
+
|
46
|
+
sudo cp kaede.service /etc/systemd/system/kaede.service
|
47
|
+
sudo systemctl enable kaede.service
|
48
|
+
sudo systemctl start kaede.service
|
49
|
+
```
|
50
|
+
|
51
|
+
Add your available channels.
|
52
|
+
|
53
|
+
```sh
|
54
|
+
kaede add-channel MX -c kaede.rb --recorder 16 --syoboi 19
|
55
|
+
kaede add-channel BS11 -c kaede.rb --recorder 211 --syoboi 128
|
56
|
+
...
|
57
|
+
```
|
58
|
+
|
59
|
+
Add your favorite anime tids.
|
60
|
+
|
61
|
+
```sh
|
62
|
+
kaede add-tid -c kaede.rb 3331
|
63
|
+
...
|
64
|
+
```
|
65
|
+
|
66
|
+
### Operations
|
67
|
+
Update programs and schedules. It supposed to be run periodically (by cron or systemd.timer).
|
68
|
+
|
69
|
+
```sh
|
70
|
+
kaede update -c kaede.rb
|
71
|
+
```
|
72
|
+
|
73
|
+
List schedules.
|
74
|
+
|
75
|
+
```sh
|
76
|
+
gdbus introspect --system --dest cc.wanko.kaede1 --object-path /cc/wanko/kaede1/program -r
|
77
|
+
```
|
78
|
+
|
79
|
+
Reload schedules (usually not needed).
|
80
|
+
|
81
|
+
```sh
|
82
|
+
dbus-send --system --dest=cc.wanko.kaede1 /cc/wanko/kaede1/scheduler cc.wanko.kaede1.Scheduler.Reload
|
83
|
+
```
|
84
|
+
|
85
|
+
Stop scheduler. The current scheduler process exits after all the running recorders finish.
|
86
|
+
|
87
|
+
```sh
|
88
|
+
dbus-send --system --dest=cc.wanko.kaede1 /cc/wanko/kaede1/scheduler cc.wanko.kaede1.Scheduler.Stop
|
89
|
+
```
|
90
|
+
|
91
|
+
## What recorder does
|
92
|
+
1. Post the earlier tweet (optional).
|
93
|
+
2. Record the program into `record_dir` by recpt1.
|
94
|
+
- At the same time, decode into `cache_dir` by b25.
|
95
|
+
- At the same time, dump ass into `cache_dir` by assdumper.
|
96
|
+
3. Post the later tweet (optional).
|
97
|
+
4. Clean the recorded TS (in `cache_dir`) into `cabinet_dir`.
|
98
|
+
5. Move dumped ass (in `cache_dir`) into `cabinet_dir`.
|
99
|
+
6. Enqueue the filename into `redis_queue`.
|
100
|
+
- Use it as an encoder queue.
|
101
|
+
- My usage: https://github.com/eagletmt/eagletmt-recutils/tree/master/encoder
|
102
|
+
|
103
|
+
## Contributing
|
104
|
+
|
105
|
+
1. Fork it ( https://github.com/eagletmt/kaede/fork )
|
106
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
107
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
108
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
109
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/kaede
ADDED
data/kaede.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'kaede/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "kaede"
|
8
|
+
spec.version = Kaede::VERSION
|
9
|
+
spec.authors = ["Kohei Suzuki"]
|
10
|
+
spec.email = ["eagletmt@gmail.com"]
|
11
|
+
spec.summary = %q{Scheduler for recpt1 recorder using Syoboi Calendar}
|
12
|
+
spec.description = %q{Scheduler for recpt1 recorder using Syoboi Calendar}
|
13
|
+
spec.homepage = "https://github.com/eagletmt/kaede"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler"
|
22
|
+
spec.add_development_dependency "coveralls"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.0.0.beta2"
|
25
|
+
spec.add_development_dependency "simplecov"
|
26
|
+
spec.add_development_dependency "timecop"
|
27
|
+
spec.add_development_dependency "vcr"
|
28
|
+
spec.add_development_dependency "webmock"
|
29
|
+
spec.add_dependency "ruby-dbus"
|
30
|
+
spec.add_dependency "nokogiri"
|
31
|
+
spec.add_dependency "redis"
|
32
|
+
spec.add_dependency "sleepy_penguin"
|
33
|
+
spec.add_dependency "sqlite3"
|
34
|
+
spec.add_dependency "thor"
|
35
|
+
spec.add_dependency "twitter"
|
36
|
+
end
|
data/kaede.rb.sample
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require 'twitter'
|
3
|
+
|
4
|
+
Kaede.configure do |config|
|
5
|
+
config.b25 = '/usr/bin/b25'
|
6
|
+
config.recpt1 = '/usr/bin/recpt1'
|
7
|
+
config.assdumper = '/home/eagletmt/bin/assdumper'
|
8
|
+
config.clean_ts = '/home/eagletmt/bin/clean-ts'
|
9
|
+
config.statvfs = '/home/eagletmt/bin/statvfs'
|
10
|
+
config.database_path = '/home/eagletmt/work/kaede/kaede.db'
|
11
|
+
config.record_dir = '/home/pt'
|
12
|
+
config.cache_dir = '/home/pt/cache'
|
13
|
+
config.cabinet_dir = '/home/pt'
|
14
|
+
config.redis = Redis.new(db: 1)
|
15
|
+
config.redis_queue = 'jobs'
|
16
|
+
config.twitter = Twitter::REST::Client.new do |config|
|
17
|
+
config.consumer_key = 'CONSUMER_KEY'
|
18
|
+
config.consumer_secret = 'CONSUMER_SECRET'
|
19
|
+
config.access_token = 'ACCESS_TOKEN'
|
20
|
+
config.access_token_secret = 'ACCESS_TOKEN_SECRET'
|
21
|
+
end
|
22
|
+
config.twitter_target = 'eagletmt'
|
23
|
+
end
|
24
|
+
|
25
|
+
# vim: set ft=ruby:
|
@@ -0,0 +1,16 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description=Kaede Recorder
|
3
|
+
|
4
|
+
[Service]
|
5
|
+
WorkingDirectory=/home/eagletmt/work/kaede
|
6
|
+
User=eagletmt
|
7
|
+
ExecStart=/usr/bin/bundle exec bin/kaede scheduler -c kaede.rb
|
8
|
+
ExecReload=/usr/bin/kill -HUP $MAINPID
|
9
|
+
ExecStop=/usr/bin/dbus-send --print-reply --system --dest=cc.wanko.kaede1 /cc/wanko/kaede1/scheduler cc.wanko.kaede1.Scheduler.Stop
|
10
|
+
Restart=always
|
11
|
+
KillMode=none
|
12
|
+
StandardOutput=journal
|
13
|
+
StandardError=journal
|
14
|
+
|
15
|
+
[Install]
|
16
|
+
WantedBy=multi-user.target
|
data/lib/kaede.rb
ADDED
data/lib/kaede/cli.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Kaede
|
4
|
+
class CLI < Thor
|
5
|
+
package_name 'kaede'
|
6
|
+
|
7
|
+
class_option :config,
|
8
|
+
desc: 'Path to config file',
|
9
|
+
banner: 'PATH',
|
10
|
+
type: :string,
|
11
|
+
aliases: :c
|
12
|
+
|
13
|
+
desc 'scheduler', 'Start scheduler'
|
14
|
+
def scheduler
|
15
|
+
require 'kaede/database'
|
16
|
+
require 'kaede/scheduler'
|
17
|
+
load_config
|
18
|
+
|
19
|
+
db = Kaede::Database.new(Kaede.config.database_path)
|
20
|
+
Kaede::Scheduler.setup(db)
|
21
|
+
Kaede::Scheduler.start
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'add-channel NAME', 'Add available channel'
|
25
|
+
option :recorder,
|
26
|
+
desc: 'Channel number for the recorder',
|
27
|
+
banner: 'CH',
|
28
|
+
type: :numeric,
|
29
|
+
required: true
|
30
|
+
option :syoboi,
|
31
|
+
desc: 'Channel number for Syoboi Calendar',
|
32
|
+
banner: 'CH',
|
33
|
+
type: :numeric,
|
34
|
+
required: true
|
35
|
+
def add_channel(name)
|
36
|
+
require 'kaede/database'
|
37
|
+
require 'kaede/channel'
|
38
|
+
load_config
|
39
|
+
|
40
|
+
db = Kaede::Database.new(Kaede.config.database_path)
|
41
|
+
db.add_channel(Channel.new(nil, name, options[:recorder], options[:syoboi]))
|
42
|
+
end
|
43
|
+
|
44
|
+
desc 'add-tid TID', 'Add tracking title'
|
45
|
+
def add_tid(tid)
|
46
|
+
require 'kaede/database'
|
47
|
+
load_config
|
48
|
+
|
49
|
+
db = Kaede::Database.new(Kaede.config.database_path)
|
50
|
+
db.add_tracking_title(tid.to_i)
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'update', 'Update jobs and programs by Syoboi Calendar'
|
54
|
+
def update
|
55
|
+
require 'kaede/database'
|
56
|
+
require 'kaede/syoboi_calendar'
|
57
|
+
require 'kaede/updater'
|
58
|
+
load_config
|
59
|
+
|
60
|
+
db = Kaede::Database.new(Kaede.config.database_path)
|
61
|
+
syobocal = Kaede::SyoboiCalendar.new
|
62
|
+
Kaede::Updater.new(db, syobocal).update
|
63
|
+
end
|
64
|
+
|
65
|
+
desc 'dbus-policy USER', 'Generate dbus policy file'
|
66
|
+
def dbus_policy(user)
|
67
|
+
require 'kaede/dbus/generator'
|
68
|
+
|
69
|
+
puts DBus::Generator.new.generate_policy(user)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def load_config
|
75
|
+
require 'kaede'
|
76
|
+
if path = options[:config]
|
77
|
+
load File.realpath(path)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/kaede/config.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'redis'
|
3
|
+
|
4
|
+
module Kaede
|
5
|
+
class Config
|
6
|
+
attr_accessor :redis, :redis_queue, :twitter, :twitter_target
|
7
|
+
|
8
|
+
path_attrs = [:b25, :recpt1, :assdumper, :clean_ts, :statvfs, :database_path, :record_dir, :cache_dir, :cabinet_dir]
|
9
|
+
attr_reader *path_attrs
|
10
|
+
path_attrs.each do |attr|
|
11
|
+
define_method("#{attr}=") do |arg|
|
12
|
+
instance_variable_set("@#{attr}", Pathname.new(arg))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
self.b25 = '/usr/bin/b25'
|
18
|
+
self.recpt1 = '/usr/bin/recpt1'
|
19
|
+
self.assdumper = '/usr/bin/assdumper'
|
20
|
+
self.clean_ts = '/usr/bin/clean-ts'
|
21
|
+
self.statvfs = '/usr/bin/statvfs'
|
22
|
+
basedir = Pathname.new(ENV['HOME']).join('kaede')
|
23
|
+
self.database_path = basedir.join('kaede.db')
|
24
|
+
self.record_dir = basedir.join('records')
|
25
|
+
self.cache_dir = basedir.join('cache')
|
26
|
+
self.cabinet_dir = basedir.join('cabinet')
|
27
|
+
self.twitter = nil
|
28
|
+
self.twitter_target = nil
|
29
|
+
self.redis = Redis.new
|
30
|
+
self.redis_queue = 'jobs'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'sqlite3'
|
3
|
+
require 'kaede/channel'
|
4
|
+
require 'kaede/program'
|
5
|
+
|
6
|
+
module Kaede
|
7
|
+
class Database
|
8
|
+
extend Forwardable
|
9
|
+
def_delegators :@db, :transaction
|
10
|
+
|
11
|
+
def initialize(path)
|
12
|
+
@db = SQLite3::Database.new(path.to_s)
|
13
|
+
@db.send(:set_boolean_pragma, 'foreign_keys', true)
|
14
|
+
prepare_tables
|
15
|
+
end
|
16
|
+
|
17
|
+
def prepare_tables
|
18
|
+
@db.execute_batch <<-SQL
|
19
|
+
CREATE TABLE IF NOT EXISTS channels (
|
20
|
+
id integer PRIMARY KEY AUTOINCREMENT,
|
21
|
+
name varchar(255) NOT NULL UNIQUE,
|
22
|
+
for_recorder integer NOT NULL UNIQUE,
|
23
|
+
for_syoboi integer NOT NULL UNIQUE
|
24
|
+
);
|
25
|
+
CREATE TABLE IF NOT EXISTS programs (
|
26
|
+
pid integer PRIMARY KEY ON CONFLICT REPLACE,
|
27
|
+
tid integer NOT NULL,
|
28
|
+
start_time datetime NOT NULL,
|
29
|
+
end_time datetime NOT NULL,
|
30
|
+
channel_id integer NOT NULL,
|
31
|
+
count varchar(16),
|
32
|
+
start_offset integer NOT NULL,
|
33
|
+
subtitle varchar(255),
|
34
|
+
title varchar(255),
|
35
|
+
comment varchar(255),
|
36
|
+
FOREIGN KEY(channel_id) REFERENCES channels(id)
|
37
|
+
);
|
38
|
+
CREATE TABLE IF NOT EXISTS jobs (
|
39
|
+
pid integer PRIMARY KEY,
|
40
|
+
enqueued_at datetime NOT NULL,
|
41
|
+
finished_at datetime,
|
42
|
+
created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
43
|
+
FOREIGN KEY(pid) REFERENCES programs(pid)
|
44
|
+
);
|
45
|
+
CREATE TABLE IF NOT EXISTS tracking_titles (
|
46
|
+
tid integer NOT NULL UNIQUE,
|
47
|
+
created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
|
48
|
+
);
|
49
|
+
SQL
|
50
|
+
end
|
51
|
+
private :prepare_tables
|
52
|
+
|
53
|
+
DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
|
54
|
+
|
55
|
+
def to_db_datetime(time)
|
56
|
+
time.utc.strftime(DATETIME_FORMAT)
|
57
|
+
end
|
58
|
+
|
59
|
+
def from_db_datetime(str)
|
60
|
+
Time.parse("#{str} UTC").localtime
|
61
|
+
end
|
62
|
+
|
63
|
+
def current_timestamp
|
64
|
+
to_db_datetime(Time.now)
|
65
|
+
end
|
66
|
+
private :current_timestamp
|
67
|
+
|
68
|
+
def get_jobs
|
69
|
+
@db.execute('SELECT pid, enqueued_at FROM jobs WHERE finished_at IS NULL AND enqueued_at >= ? ORDER BY enqueued_at', [current_timestamp]).map do |pid, enqueued_at|
|
70
|
+
{ pid: pid, enqueued_at: from_db_datetime(enqueued_at) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def update_job(pid, enqueued_at)
|
75
|
+
@db.execute('INSERT OR REPLACE INTO jobs (pid, enqueued_at, created_at) VALUES (?, ?, ?)', [pid, to_db_datetime(enqueued_at), current_timestamp])
|
76
|
+
end
|
77
|
+
|
78
|
+
def delete_job(pid)
|
79
|
+
@db.execute('DELETE FROM jobs WHERE pid = ?', pid)
|
80
|
+
end
|
81
|
+
|
82
|
+
def get_program(pid)
|
83
|
+
get_programs([pid])[pid]
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_programs(pids)
|
87
|
+
rows = @db.execute(<<-SQL)
|
88
|
+
SELECT pid, tid, start_time, end_time, channels.name, for_syoboi, for_recorder, count, start_offset, subtitle, title, comment
|
89
|
+
FROM programs
|
90
|
+
INNER JOIN channels ON programs.channel_id = channels.id
|
91
|
+
WHERE programs.pid IN (#{pids.join(', ')})
|
92
|
+
SQL
|
93
|
+
programs = {}
|
94
|
+
rows.each do |row|
|
95
|
+
program = Program.new(*row)
|
96
|
+
program.start_time = from_db_datetime(program.start_time)
|
97
|
+
program.end_time = from_db_datetime(program.end_time)
|
98
|
+
programs[program.pid] = program
|
99
|
+
end
|
100
|
+
programs
|
101
|
+
end
|
102
|
+
|
103
|
+
def mark_finished(pid)
|
104
|
+
@db.execute('UPDATE jobs SET finished_at = ? WHERE pid = ?', [current_timestamp, pid])
|
105
|
+
end
|
106
|
+
|
107
|
+
def get_channels
|
108
|
+
@db.execute('SELECT * FROM channels').map do |row|
|
109
|
+
Channel.new(*row)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def add_channel(channel)
|
114
|
+
@db.execute('INSERT INTO channels (name, for_recorder, for_syoboi) VALUES (?, ?, ?)', [channel.name, channel.for_recorder, channel.for_syoboi])
|
115
|
+
end
|
116
|
+
|
117
|
+
def update_program(program, channel)
|
118
|
+
row = [
|
119
|
+
program.pid,
|
120
|
+
program.tid,
|
121
|
+
to_db_datetime(program.start_time),
|
122
|
+
to_db_datetime(program.end_time),
|
123
|
+
channel.id,
|
124
|
+
program.count,
|
125
|
+
program.start_offset,
|
126
|
+
program.subtitle,
|
127
|
+
program.title,
|
128
|
+
program.comment,
|
129
|
+
]
|
130
|
+
@db.execute(<<-SQL, row)
|
131
|
+
INSERT INTO programs (pid, tid, start_time, end_time, channel_id, count, start_offset, subtitle, title, comment)
|
132
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
133
|
+
SQL
|
134
|
+
end
|
135
|
+
|
136
|
+
def add_tracking_title(tid)
|
137
|
+
@db.execute('INSERT INTO tracking_titles (tid, created_at) VALUES (?, ?)', [tid, current_timestamp])
|
138
|
+
end
|
139
|
+
|
140
|
+
def get_tracking_titles
|
141
|
+
@db.execute('SELECT tid FROM tracking_titles').map do |row|
|
142
|
+
row[0]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|