pig-media-server 0.3.2 → 2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/bin/pig-media-server +4 -1
  4. data/gulpfile.js +33 -0
  5. data/javascripts/application.js +117 -0
  6. data/javascripts/chromecast.js +57 -0
  7. data/javascripts/components/head.js +106 -0
  8. data/javascripts/components/list.js +104 -0
  9. data/javascripts/components/new_flag.js +23 -0
  10. data/javascripts/components/player.js +171 -0
  11. data/javascripts/components/query_list.js +68 -0
  12. data/javascripts/components/sort.js +64 -0
  13. data/javascripts/components/watch.js +48 -0
  14. data/javascripts/controller.js +62 -0
  15. data/javascripts/custom_list.js +14 -0
  16. data/javascripts/event_dispatcher.js +21 -0
  17. data/javascripts/recent.js +34 -0
  18. data/javascripts/utils.js +22 -0
  19. data/javascripts/video.js +10 -0
  20. data/lib/pig-media-server/api.rb +96 -0
  21. data/lib/pig-media-server/aspect.rb +10 -5
  22. data/lib/pig-media-server/backup.rb +69 -0
  23. data/lib/pig-media-server/cli.rb +60 -25
  24. data/lib/pig-media-server/crawl.rb +41 -5
  25. data/lib/pig-media-server/kindle_send.rb +31 -24
  26. data/lib/pig-media-server/model/data.rb +106 -0
  27. data/lib/pig-media-server/model/migrate.rb +34 -0
  28. data/lib/pig-media-server/model/pig.rb +11 -2
  29. data/lib/pig-media-server/version.rb +1 -1
  30. data/lib/pig-media-server/views/_custom_links.haml +4 -0
  31. data/lib/pig-media-server/views/_ft_flv.haml +1 -0
  32. data/lib/pig-media-server/views/_ft_pdf.haml +0 -0
  33. data/lib/pig-media-server/views/_ft_video.haml +9 -4
  34. data/lib/pig-media-server/views/_link.haml +4 -1
  35. data/lib/pig-media-server/views/_new_flag.haml +1 -1
  36. data/lib/pig-media-server/views/app.scss +10 -1
  37. data/lib/pig-media-server/views/bundle.js +13 -0
  38. data/lib/pig-media-server/views/chromecast.coffee +54 -0
  39. data/lib/pig-media-server/views/config.coffee +13 -1
  40. data/lib/pig-media-server/views/config.haml +27 -4
  41. data/lib/pig-media-server/views/feed.builder +3 -2
  42. data/lib/pig-media-server/views/flv.coffee +33 -0
  43. data/lib/pig-media-server/views/index.haml +11 -5
  44. data/lib/pig-media-server/views/meta.haml +4 -4
  45. data/lib/pig-media-server/views/movie.coffee +65 -39
  46. data/lib/pig-media-server/views/react.haml +22 -0
  47. data/lib/pig-media-server/views/remote.haml +2 -2
  48. data/lib/pig-media-server/views/session.coffee +5 -0
  49. data/lib/pig-media-server/views/storage.coffee +5 -16
  50. data/lib/pig-media-server/views/sub.haml +5 -6
  51. data/lib/pig-media-server/views/subview.coffee +109 -19
  52. data/lib/pig-media-server/views/tv.coffee +97 -0
  53. data/lib/pig-media-server/views/tv.haml +33 -0
  54. data/lib/pig-media-server/views/unread.coffee +10 -0
  55. data/lib/pig-media-server/web.rb +102 -37
  56. data/package.json +23 -0
  57. data/pig-media-server.gemspec +5 -0
  58. 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
- array.each_with_index{|x,i|
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
- flag = false
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+1} / #{array.count}"
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
- while true
11
- begin
11
+ 100.times do
12
+ #begin
12
13
  GC.start
13
- from_hash = Hash[*Dir.glob("#{pit_config['user_data_path']}/*.json").map{|t| JSON.parse open(t).read}.select{|t| t['kindle_to'] and t['kindle_from']}.map{|t| [t['kindle_to'], t['kindle_from']]}.select{|t| t.first != '' and t.last != ''}.flatten]
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
- from_hash.each{|to, from|
25
- p [to, from]
26
- Pony.mail({
27
- :to => to,
28
- from: from,
29
- subject: '',
30
- body: '',
31
- attachments: {"#{key}.mobi" => File.read(pig.record.path)},
32
- :via => :smtp,
33
- :via_options => pit_config['smtp'].dup
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/dev/pig'
47
+ FileUtils.cd '/home/ssig33/server'
41
48
  FileUtils.rm x
42
49
  puts 'end '+x
43
50
  }
44
- rescue => e
45
- p e
46
- p e.backtrace
47
- end
48
- sleep 1
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
@@ -1,3 +1,3 @@
1
1
  module PigMediaServer
2
- VERSION = "0.3.2"
2
+ VERSION = "2"
3
3
  end
@@ -0,0 +1,4 @@
1
+ - if CONFIG['custom_links']
2
+ - CONFIG['custom_links'].each do |c|
3
+ -if c['type'].index(record.type)
4
+ %a{href: eval('"'+c['path']+'"')}=c['title']
@@ -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}watch
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}watch
5
- -if hash()['remote']
6
- %a.remote{href: 'javascript:void(0)', key: record.key} remote
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,4 +1,4 @@
1
- -if record.type == 'video'
1
+ -if record.type == 'video' or record.type == 'flv'
2
2
  %span.new_flag{key: "movie/#{record.record._key}", style: 'color:lime; font-size:large'}
3
3
  -elsif record.type == 'read'
4
4
  =''
@@ -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;