pig-media-server 0.3.2 → 2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/bin/pig-media-server +4 -1
- data/gulpfile.js +33 -0
- data/javascripts/application.js +117 -0
- data/javascripts/chromecast.js +57 -0
- data/javascripts/components/head.js +106 -0
- data/javascripts/components/list.js +104 -0
- data/javascripts/components/new_flag.js +23 -0
- data/javascripts/components/player.js +171 -0
- data/javascripts/components/query_list.js +68 -0
- data/javascripts/components/sort.js +64 -0
- data/javascripts/components/watch.js +48 -0
- data/javascripts/controller.js +62 -0
- data/javascripts/custom_list.js +14 -0
- data/javascripts/event_dispatcher.js +21 -0
- data/javascripts/recent.js +34 -0
- data/javascripts/utils.js +22 -0
- data/javascripts/video.js +10 -0
- data/lib/pig-media-server/api.rb +96 -0
- data/lib/pig-media-server/aspect.rb +10 -5
- data/lib/pig-media-server/backup.rb +69 -0
- data/lib/pig-media-server/cli.rb +60 -25
- data/lib/pig-media-server/crawl.rb +41 -5
- data/lib/pig-media-server/kindle_send.rb +31 -24
- data/lib/pig-media-server/model/data.rb +106 -0
- data/lib/pig-media-server/model/migrate.rb +34 -0
- data/lib/pig-media-server/model/pig.rb +11 -2
- data/lib/pig-media-server/version.rb +1 -1
- data/lib/pig-media-server/views/_custom_links.haml +4 -0
- data/lib/pig-media-server/views/_ft_flv.haml +1 -0
- data/lib/pig-media-server/views/_ft_pdf.haml +0 -0
- data/lib/pig-media-server/views/_ft_video.haml +9 -4
- data/lib/pig-media-server/views/_link.haml +4 -1
- data/lib/pig-media-server/views/_new_flag.haml +1 -1
- data/lib/pig-media-server/views/app.scss +10 -1
- data/lib/pig-media-server/views/bundle.js +13 -0
- data/lib/pig-media-server/views/chromecast.coffee +54 -0
- data/lib/pig-media-server/views/config.coffee +13 -1
- data/lib/pig-media-server/views/config.haml +27 -4
- data/lib/pig-media-server/views/feed.builder +3 -2
- data/lib/pig-media-server/views/flv.coffee +33 -0
- data/lib/pig-media-server/views/index.haml +11 -5
- data/lib/pig-media-server/views/meta.haml +4 -4
- data/lib/pig-media-server/views/movie.coffee +65 -39
- data/lib/pig-media-server/views/react.haml +22 -0
- data/lib/pig-media-server/views/remote.haml +2 -2
- data/lib/pig-media-server/views/session.coffee +5 -0
- data/lib/pig-media-server/views/storage.coffee +5 -16
- data/lib/pig-media-server/views/sub.haml +5 -6
- data/lib/pig-media-server/views/subview.coffee +109 -19
- data/lib/pig-media-server/views/tv.coffee +97 -0
- data/lib/pig-media-server/views/tv.haml +33 -0
- data/lib/pig-media-server/views/unread.coffee +10 -0
- data/lib/pig-media-server/web.rb +102 -37
- data/package.json +23 -0
- data/pig-media-server.gemspec +5 -0
- metadata +123 -38
@@ -1,9 +1,45 @@
|
|
1
1
|
require 'pig-media-server'
|
2
2
|
require 'pig-media-server/model/pig'
|
3
|
+
require 'mechanize'
|
3
4
|
|
4
5
|
|
5
6
|
module PigMediaServer
|
6
7
|
class Crawl
|
8
|
+
|
9
|
+
def recommend
|
10
|
+
users = Groonga['Datas'].select.to_a.map{|x| x.original_key}.select{|x| x =~ /user_data/}.map{|x| x.split("/")[1]}.uniq
|
11
|
+
|
12
|
+
users.each do |user|
|
13
|
+
keys = []
|
14
|
+
animetick = Groonga['Datas'].select{|x| x.original_key == "user_data/#{user}/animetick" }.first
|
15
|
+
if animetick
|
16
|
+
animetick = animetick.body.gsub('"', '')
|
17
|
+
alice = Mechanize.new
|
18
|
+
page = alice.get("http://animetick.net/users/#{animetick}")
|
19
|
+
titles = page.root.xpath('//*[@id="body"]/div[3]/ul/li/div[2]').map{|x| x.inner_text}.map{|x|
|
20
|
+
x.gsub(/\n\ +/, '')
|
21
|
+
}
|
22
|
+
titles.each{|title|
|
23
|
+
title = title.split('').map{|x|
|
24
|
+
if x =~ /\p{Han}|\p{Hiragana}|\p{Katakana}|[0-9a-zA-Z]/
|
25
|
+
x
|
26
|
+
else
|
27
|
+
' '
|
28
|
+
end
|
29
|
+
|
30
|
+
}.join('').sub(/\ +$/, '')
|
31
|
+
Groonga['Files'].select(Sewell.generate(title, ['path'])).select{|x| x.path =~ '.mp4'}.to_a.each{|record|
|
32
|
+
next if record.mtime < Time.now.to_i-86400*30*5
|
33
|
+
keys << record
|
34
|
+
}
|
35
|
+
}
|
36
|
+
keys = keys.sort_by{|x| -x.mtime}.map{|x| x._key}
|
37
|
+
FileUtils.mkdir_p "#{$config['user_data_path']}/recommend"
|
38
|
+
open("#{$config['user_data_path']}/recommend/#{user}", 'w'){|f| f.puts keys.join("\n")}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
7
43
|
def all
|
8
44
|
$config = Pit.get("Pig Media Server")
|
9
45
|
if ARGV[1]
|
@@ -11,15 +47,15 @@ module PigMediaServer
|
|
11
47
|
else
|
12
48
|
array = Dir.glob("#{$config['path']}/**/*").sort
|
13
49
|
end
|
14
|
-
|
50
|
+
|
51
|
+
array.each.with_index(1){|x,i|
|
15
52
|
next unless File.exist?(x)
|
16
53
|
next if File::ftype(x) == 'directory'
|
17
|
-
|
18
|
-
$config['exclude_path'].each{|e| flag = true if x =~ /#{e.sub(/\//, '\/')}/ } if $config['exclude_path'].class.to_s == 'Array'
|
19
|
-
next if flag
|
54
|
+
next if $config['exclude_path'].class == Array && $config['exclude_path'].find{|e| x =~ /#{e.sub(/\//, '\/')}/ }
|
20
55
|
Pig.find_or_create_by_path x
|
21
|
-
puts "Crawl #{i
|
56
|
+
puts "Crawl #{i} / #{array.count}" if i % 100 == 0 or i ==array.count
|
22
57
|
}
|
58
|
+
self.recommend
|
23
59
|
end
|
24
60
|
end
|
25
61
|
end
|
@@ -2,50 +2,57 @@ require 'mail'
|
|
2
2
|
require 'pony'
|
3
3
|
require 'pig-media-server'
|
4
4
|
require 'pig-media-server/model/pig'
|
5
|
+
require 'pig-media-server/model/data'
|
5
6
|
|
6
7
|
module PigMediaServer
|
7
8
|
class KindleSend
|
8
9
|
def run
|
9
10
|
pit_config = Pit.get 'Pig Media Server'
|
10
|
-
|
11
|
-
begin
|
11
|
+
100.times do
|
12
|
+
#begin
|
12
13
|
GC.start
|
13
|
-
|
14
|
+
a = AppData.all.select{|x| x[:value].class == String and x[:key] =~ /kindle/ and x[:value] =~ /@/}.sort{|a2,b| a2[:key] <=> b[:key]}
|
15
|
+
froms = a.select{|x| x[:key] =~ /from/}
|
16
|
+
tos = a.select{|x| x[:key] =~ /to/}
|
17
|
+
from_data = {}
|
18
|
+
tos.count.times{|i|
|
19
|
+
from_data[tos[i][:value]] = froms[i][:value]
|
20
|
+
}
|
14
21
|
Dir.glob("#{pit_config['user_data_path']}/kindle/queue/*").each{|x|
|
15
22
|
begin
|
16
23
|
queue = x.split('/').last
|
17
24
|
key = queue.split('_').first
|
18
|
-
user_id = queue.split('_').last
|
19
|
-
config = JSON.parse open("#{pit_config['user_data_path']}/#{user_id}.json").read
|
20
|
-
p [key, user_id, config['kindle_to'], config['kindle_from']]
|
21
25
|
|
22
26
|
pig = Pig.find key
|
23
|
-
puts 'start send'
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
puts 'start send: ' + pig.path
|
28
|
+
from_data.each{|to, from|
|
29
|
+
begin
|
30
|
+
p [to, from]
|
31
|
+
Pony.mail({
|
32
|
+
:to => to,
|
33
|
+
from: from,
|
34
|
+
subject: '',
|
35
|
+
body: '',
|
36
|
+
attachments: {"#{key}.mobi" => File.read(pig.record.path)},
|
37
|
+
:via => :smtp,
|
38
|
+
:via_options => pit_config['smtp'].dup
|
39
|
+
})
|
40
|
+
rescue
|
41
|
+
end
|
35
42
|
}
|
36
43
|
rescue =>e
|
37
44
|
p e
|
38
45
|
p e.backtrace
|
39
46
|
end
|
40
|
-
FileUtils.cd '/home/ssig33/
|
47
|
+
FileUtils.cd '/home/ssig33/server'
|
41
48
|
FileUtils.rm x
|
42
49
|
puts 'end '+x
|
43
50
|
}
|
44
|
-
rescue => e
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
sleep
|
51
|
+
#rescue => e
|
52
|
+
# p e
|
53
|
+
# p e.backtrace
|
54
|
+
#end
|
55
|
+
sleep 10
|
49
56
|
end
|
50
57
|
end
|
51
58
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#coding:utf-8
|
2
|
+
require 'fileutils'
|
3
|
+
require 'digest/md5'
|
4
|
+
require 'pig-media-server/model/migrate'
|
5
|
+
|
6
|
+
$config = $config || Pit.get("Pig Media Server")
|
7
|
+
|
8
|
+
|
9
|
+
class AppData
|
10
|
+
def self.find key
|
11
|
+
key = Digest::MD5.hexdigest(key)
|
12
|
+
parse(Groonga['Datas'][key].body)
|
13
|
+
rescue
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.set key, value
|
18
|
+
g_key = Digest::MD5.hexdigest(key)
|
19
|
+
Groonga['Datas'].add g_key
|
20
|
+
Groonga['Datas'][g_key].body = value.to_json
|
21
|
+
Groonga['Datas'][g_key].original_key = key
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.all
|
25
|
+
Groonga['Datas'].select.to_a.map{|x|
|
26
|
+
{key: x.original_key, value: parse(x.body)}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.parse val
|
31
|
+
case val
|
32
|
+
when 'true'
|
33
|
+
true
|
34
|
+
when 'false'
|
35
|
+
false
|
36
|
+
else
|
37
|
+
JSON.parse val
|
38
|
+
end
|
39
|
+
rescue
|
40
|
+
if val.class == String
|
41
|
+
val.gsub(/^"|"$/, '')
|
42
|
+
else
|
43
|
+
val
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Stars
|
49
|
+
def self.list user
|
50
|
+
Pig.find Groonga['Stars'].select{|x|
|
51
|
+
x._key =~ user
|
52
|
+
}.to_a.map{|x| x._key.split('/').last}
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.star? user, key
|
56
|
+
key =user+'/'+key
|
57
|
+
!!Groonga['Stars'][key]
|
58
|
+
rescue
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.star user, key
|
63
|
+
key =user+'/'+key
|
64
|
+
if Groonga['Stars'].add key
|
65
|
+
Groonga['Stars'].delete key
|
66
|
+
else
|
67
|
+
Groonga['Stars'].add key
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.unstar user, key
|
72
|
+
key =user+'/'+key
|
73
|
+
Groonga['Stars'].delete key
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Recents
|
78
|
+
def self.list user
|
79
|
+
hash = {}
|
80
|
+
Groonga['Recents'].select{|x|
|
81
|
+
x._key =~ user
|
82
|
+
}.to_a.map{|x| x._key.split("/").last}.each{|x|
|
83
|
+
hash["movie/#{x}"] = {}
|
84
|
+
}
|
85
|
+
hash
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.recent? user, key
|
89
|
+
key =user+'/'+key
|
90
|
+
!!Groonga['Recents'][key]
|
91
|
+
rescue
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.recent user, key
|
96
|
+
key =user+'/'+key
|
97
|
+
Groonga['Recents'].add key
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
Dir.glob($config['user_data_path']+"/**/*.json").sort.each{|x|
|
102
|
+
user = x.split("/").last.split(".json").first
|
103
|
+
JSON.parse(open(x).read).map{|t| t}.select{|a| a.last.class != Array and a.last.class != Hash}.each{|ary|
|
104
|
+
AppData.set("user_data/#{user}/#{ary.first}", ary.last)
|
105
|
+
}
|
106
|
+
}
|
@@ -24,3 +24,37 @@ unless Groonga['Files']
|
|
24
24
|
}
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
unless Groonga['Datas']
|
29
|
+
puts "create table 'Datas'"
|
30
|
+
Groonga::Schema.define do |schema|
|
31
|
+
schema.create_table("Datas", type: :patricia_trie, key_type: 'ShortText'){|table|
|
32
|
+
table.long_text "body"
|
33
|
+
table.long_text 'original_key'
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
unless Groonga['Stars']
|
39
|
+
puts "create table 'Stars'"
|
40
|
+
Groonga::Schema.define do |schema|
|
41
|
+
schema.create_table("Stars", type: :patricia_trie, key_type: 'ShortText'){|table|
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
unless Groonga['Recents']
|
47
|
+
puts "create table 'Recents'"
|
48
|
+
Groonga::Schema.define do |schema|
|
49
|
+
schema.create_table("Recents", type: :patricia_trie, key_type: 'ShortText'){|table|
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
unless Groonga['QueryList']
|
55
|
+
puts "create table 'QueryList'"
|
56
|
+
Groonga::Schema.define do |schema|
|
57
|
+
schema.create_table("QueryList", type: :patricia_trie, key_type: 'ShortText'){|table| table.short_text "query" }
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#coding:utf-8
|
2
2
|
require 'fileutils'
|
3
3
|
require 'pig-media-server/model/migrate'
|
4
|
+
require 'pig-media-server/model/data'
|
4
5
|
|
5
6
|
CONFIG = Pit.get('Pig Media Server')
|
6
7
|
|
@@ -16,20 +17,25 @@ class Pig
|
|
16
17
|
def key; self.record._key;end
|
17
18
|
def name; self.record.path.split('/').last; end
|
18
19
|
def mtime; Time.at(self.record.mtime);end
|
20
|
+
def mtime_to_i; self.record.mtime; end
|
19
21
|
def size; self.record.size;end
|
20
22
|
def metadata; self.record.metadata;end
|
21
23
|
def srt; self.record.srt;end
|
22
24
|
def url; 'http://'+self.config['hostname']+ '/volume' + URI.encode(self.record.path.sub(/#{config['path'].sub(/\//, '\/')}/, ''));end
|
23
25
|
def type
|
24
26
|
case self.name.split('.').last
|
25
|
-
when 'mp4', 'MP4', 'webm'
|
27
|
+
when 'mp4', 'MP4', 'webm', 'm4v'
|
26
28
|
'video'
|
27
29
|
when 'zip', 'ZIP'
|
28
30
|
'read'
|
31
|
+
when 'pdf'
|
32
|
+
'pdf'
|
29
33
|
when 'txt', 'TXT'
|
30
34
|
'txt'
|
31
35
|
when 'mobi'
|
32
36
|
'mobi'
|
37
|
+
when 'flv'
|
38
|
+
'flv'
|
33
39
|
else
|
34
40
|
'other'
|
35
41
|
end
|
@@ -57,7 +63,10 @@ str.chomp.chomp
|
|
57
63
|
open("#{self.config['user_data_path']}/rate/queue.txt", "a"){|x| x.puts "#{self.key} #{rate}"}
|
58
64
|
end
|
59
65
|
|
60
|
-
|
66
|
+
def to_hash(opts = {})
|
67
|
+
hash = {key: self.key, name: self.name, mtime: self.mtime, size: self.size, url: self.url, type: self.type, mtime_to_i: self.mtime_to_i}
|
68
|
+
hash
|
69
|
+
end
|
61
70
|
|
62
71
|
def self.find key
|
63
72
|
case key.class.to_s
|
@@ -0,0 +1 @@
|
|
1
|
+
%a.flv{href: 'javascript:void(0)', url: record.url, key: record.key, title: record.name}watch
|
File without changes
|
@@ -1,6 +1,11 @@
|
|
1
1
|
-if record.srt
|
2
|
-
%a.watch{href: 'javascript:void(0)', srt: 'true', url: record.url, key: record.key, title: record.name}
|
2
|
+
%a.watch{href: 'javascript:void(0)', srt: 'true', url: record.url, key: record.key, title: record.name} Watch
|
3
3
|
-else
|
4
|
-
%a.watch{href: 'javascript:void(0)', url: record.url, key: record.key, title: record.name}
|
5
|
-
-if
|
6
|
-
%a.remote{href: 'javascript:void(0)', key: record.key}
|
4
|
+
%a.watch{href: 'javascript:void(0)', url: record.url, key: record.key, title: record.name} Watch
|
5
|
+
-if remote?
|
6
|
+
%a.remote{href: 'javascript:void(0)', key: record.key} Remote
|
7
|
+
-if request.env['HTTP_X_REAL_IP'].to_s =~ /192.168/
|
8
|
+
- url = record.url.sub(/pig.ssig33.com/, '192.168.1.53')
|
9
|
+
%a.remote.chromecast{href: 'javascript:void(0)', onclick: "chrome_cast('#{url}', '#{record.key}')", style: 'display:none'} Chromecast
|
10
|
+
-else
|
11
|
+
%a.remote.chromecast{href: 'javascript:void(0)', onclick: "chrome_cast('#{record.url}', '#{record.key}')", style: 'display:none'} Chromecast
|
@@ -2,13 +2,16 @@
|
|
2
2
|
!=partial :"_new_flag", locals: {record: l}
|
3
3
|
%a.main_link{key: l.key, href: l.url}=h(l.name)
|
4
4
|
!=partial :"_ft_#{l.type}", locals: {record: l}
|
5
|
+
-if session[:user_id]
|
6
|
+
%a.star{href: "/star?href=#{CGI.escape request.url}&key=#{l.key}", key: l.key} #{star?(l.key) ? 'Unstar' : 'Star'}
|
5
7
|
%span.mtime=l.mtime.to_s.sub(/\ \+0900$/, '')
|
6
|
-
%span.size=number_to_human_size(l.size).encode('UTF-8', 'UTF-8')
|
8
|
+
%span.size=number_to_human_size(l.size).to_s.encode('UTF-8', 'UTF-8')
|
7
9
|
%a.meta{href: "/meta/#{l.key}"} Meta
|
8
10
|
-if l.srt
|
9
11
|
%a.sub.meta{href: "/sub/#{l.key}"} Sub
|
10
12
|
-if l.type == 'txt' or l.type == 'read'
|
11
13
|
%a.ao.meta{href: "/ao/#{l.key}"} Aozora
|
14
|
+
!=partial :"_custom_links", locals: {record: l}
|
12
15
|
%a.delete{href: 'javascript:void(0)', onclick: "var ok=confirm('Really?'); if (ok) location.href='/delete/#{l.key}?href=#{CGI.escape request.url}'; return false;"} Delete
|
13
16
|
%br
|
14
17
|
|
@@ -1,3 +1,7 @@
|
|
1
|
+
button, a, input{
|
2
|
+
margin-right: 3px;
|
3
|
+
}
|
4
|
+
|
1
5
|
body {
|
2
6
|
text-align:center;
|
3
7
|
background:black;
|
@@ -10,6 +14,10 @@ body {
|
|
10
14
|
text-align:left;
|
11
15
|
}
|
12
16
|
|
17
|
+
:fullscreen{
|
18
|
+
overflow:scroll;
|
19
|
+
}
|
20
|
+
|
13
21
|
#notice{ color:green; }
|
14
22
|
#error{ color:red; }
|
15
23
|
.small{ font-size:small;}
|
@@ -30,7 +38,7 @@ nick{color:lightpink}
|
|
30
38
|
.x-small{font-size:x-small}
|
31
39
|
span.link{font-size:x-large}
|
32
40
|
|
33
|
-
a.watch, a.read, a.txt, a.recent, a.kindle{
|
41
|
+
a.remote, a.flv, a.watch, a.read, a.txt, a.recent, a.kindle{
|
34
42
|
color:mistyrose;
|
35
43
|
}
|
36
44
|
|
@@ -78,6 +86,7 @@ a.delete{
|
|
78
86
|
width:3em !important;
|
79
87
|
text-align:center !important;
|
80
88
|
font-size:100% !important;
|
89
|
+
cursor: pointer;
|
81
90
|
}
|
82
91
|
.main_link {
|
83
92
|
margin-left:3em;
|