pig-media-server 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/pig-media-server +4 -0
- data/lib/pig-media-server.rb +10 -0
- data/lib/pig-media-server/book2.erb +59 -0
- data/lib/pig-media-server/cli.rb +21 -0
- data/lib/pig-media-server/crawl.rb +23 -0
- data/lib/pig-media-server/model/comic.rb +64 -0
- data/lib/pig-media-server/model/migrate.rb +26 -0
- data/lib/pig-media-server/model/pig.rb +98 -0
- data/lib/pig-media-server/script.rb +4 -0
- data/lib/pig-media-server/version.rb +3 -0
- data/lib/pig-media-server/views/_ft_other.haml +0 -0
- data/lib/pig-media-server/views/_ft_read.haml +9 -0
- data/lib/pig-media-server/views/_ft_txt.haml +1 -0
- data/lib/pig-media-server/views/_ft_video.haml +6 -0
- data/lib/pig-media-server/views/_link.haml +14 -0
- data/lib/pig-media-server/views/_new_flag.haml +4 -0
- data/lib/pig-media-server/views/app.scss +85 -0
- data/lib/pig-media-server/views/book.coffee +236 -0
- data/lib/pig-media-server/views/book2.erb +59 -0
- data/lib/pig-media-server/views/config.coffee +8 -0
- data/lib/pig-media-server/views/config.haml +29 -0
- data/lib/pig-media-server/views/index.haml +45 -0
- data/lib/pig-media-server/views/movie.coffee +159 -0
- data/lib/pig-media-server/views/read.haml +34 -0
- data/lib/pig-media-server/views/remote.coffee +25 -0
- data/lib/pig-media-server/views/remote.haml +14 -0
- data/lib/pig-media-server/views/session.coffee +6 -0
- data/lib/pig-media-server/views/sessions.haml +11 -0
- data/lib/pig-media-server/views/storage.coffee +32 -0
- data/lib/pig-media-server/views/swipe.erb +433 -0
- data/lib/pig-media-server/views/unread.coffee +14 -0
- data/lib/pig-media-server/web.rb +201 -0
- data/pig-media-server.gemspec +32 -0
- metadata +250 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0ff123f0aaed9b937221166e54c4ac8b6f6fa679
|
4
|
+
data.tar.gz: 4f8a904d67e83f4e01990f213ebfb1787d71abaf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c058d2d0b84f5daf5738b87adfe3c3d203f21978fd5b2fba1f6c85d5103f6faa6aed9e6c158eaa7869336cfdd4cb412daee71f613c59270f948d2a24e8104a4a
|
7
|
+
data.tar.gz: e534588976add8bdd3a97463647970b1265945b3791abf10bce29b84b9a70cf837d3593dfa4aebbc515234a4d73e6145c25ad929c3580c31fb12680fe8fcc17a
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 ssig33
|
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,29 @@
|
|
1
|
+
# PigMediaServer
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'pig-media-server'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install pig-media-server
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,59 @@
|
|
1
|
+
var mode = "landscape"
|
2
|
+
var cached = {}
|
3
|
+
var size = window_size()
|
4
|
+
|
5
|
+
function is_NaN($value){
|
6
|
+
return (typeof $value == 'number' && $value.toString() == 'NaN');
|
7
|
+
}
|
8
|
+
|
9
|
+
function _id(){
|
10
|
+
return $("#id").text()
|
11
|
+
}
|
12
|
+
|
13
|
+
function now(){
|
14
|
+
var count = parseInt($("#now").text())
|
15
|
+
if(is_NaN(count)){
|
16
|
+
return 0
|
17
|
+
}else{
|
18
|
+
return count
|
19
|
+
}
|
20
|
+
}
|
21
|
+
function _now(str){
|
22
|
+
return $("#now").text(str)
|
23
|
+
}
|
24
|
+
function is_left(){
|
25
|
+
return $("#is_left").text() === "true"
|
26
|
+
}
|
27
|
+
|
28
|
+
function width() {
|
29
|
+
if ( window.innerWidth ) {
|
30
|
+
return window.innerWidth;
|
31
|
+
}
|
32
|
+
else if ( document.documentElement && document.documentElement.clientWidth != 0 ) {
|
33
|
+
return document.documentElement.clientWidth;
|
34
|
+
}
|
35
|
+
else if ( document.body ) {
|
36
|
+
return document.body.clientWidth;
|
37
|
+
}
|
38
|
+
return 0;
|
39
|
+
}
|
40
|
+
|
41
|
+
function height() {
|
42
|
+
if ( window.innerHeight ) {
|
43
|
+
return window.innerHeight;
|
44
|
+
}
|
45
|
+
else if ( document.documentElement && document.documentElement.clientHeight != 0 ) {
|
46
|
+
return document.documentElement.clientHeight;
|
47
|
+
}
|
48
|
+
else if ( document.body ) {
|
49
|
+
return document.body.clientHeight;
|
50
|
+
}
|
51
|
+
return 0;
|
52
|
+
}
|
53
|
+
|
54
|
+
function is_portlait(){
|
55
|
+
return (height()/width())<1
|
56
|
+
}
|
57
|
+
function window_size(){
|
58
|
+
return {height: height(), width: width()}
|
59
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
case ARGV[0]
|
2
|
+
when 'setup'
|
3
|
+
require 'fileutils'
|
4
|
+
config = Pit.get("Pig Media Server", require:{
|
5
|
+
'path' => 'Path of your storage',
|
6
|
+
'groonga' => "Path of groonga's files",
|
7
|
+
'exclude_path' => 'Exclude Path(Array)',
|
8
|
+
'user_data_path' => 'Path of User Data'
|
9
|
+
})
|
10
|
+
|
11
|
+
puts "Path: #{config['path']}"
|
12
|
+
puts "Groonga: #{config['groonga']}"
|
13
|
+
FileUtils.mkdir_p config['user_data_path']
|
14
|
+
when 'crawl'
|
15
|
+
require 'pig-media-server/crawl'
|
16
|
+
PigMediaServer::Crawl.new.all
|
17
|
+
when 'server'
|
18
|
+
port = ARGV[1] ? ARGV[1].to_i : 8080
|
19
|
+
require 'pig-media-server/web'
|
20
|
+
PigMediaServer::Web.run! host: '0.0.0.0', port: port
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'pig-media-server'
|
2
|
+
require 'pig-media-server/model/pig'
|
3
|
+
|
4
|
+
module PigMediaServer
|
5
|
+
class Crawl
|
6
|
+
def all
|
7
|
+
config = Pit.get("Pig Media Server")
|
8
|
+
array = Dir.glob("#{config['path']}/**/*").sort
|
9
|
+
array.each_with_index{|x,i|
|
10
|
+
next if File::ftype(x) == 'directory'
|
11
|
+
flag = false
|
12
|
+
config['exclude_path'].each{|e| flag = true if x =~ /#{e.sub(/\//, '\/')}/ } if config['exclude_path'].class.to_s == 'Array'
|
13
|
+
next if flag
|
14
|
+
Pig.find_or_create_by_path x
|
15
|
+
puts "Crawl #{i+1} / #{array.count}"
|
16
|
+
}
|
17
|
+
all = Pig.all
|
18
|
+
all.each_with_index{|x,i|
|
19
|
+
puts "Check #{i+1} / #{all.count}"
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'zipruby'
|
2
|
+
require 'RMagick'
|
3
|
+
|
4
|
+
class Comic
|
5
|
+
attr_accessor :record, :config
|
6
|
+
def initialize record
|
7
|
+
self.record = record
|
8
|
+
self.config = Pit.get "Pig Media Server"
|
9
|
+
end
|
10
|
+
def id; self.record._key;end
|
11
|
+
def max_page; self.files.count; end
|
12
|
+
def title; self.record.path.split("/").last;end
|
13
|
+
def left
|
14
|
+
data = "#{self.config['user_data_path']}/comic_#{self.record._key}.comic"
|
15
|
+
open(data, 'w'){|f| f.puts({left: false}.to_json)} unless File.exist? data
|
16
|
+
JSON.parse(open(data).read)['left']
|
17
|
+
end
|
18
|
+
|
19
|
+
def info count
|
20
|
+
m = self.image(count)
|
21
|
+
x = m.columns
|
22
|
+
y = m.rows
|
23
|
+
{portlait: (x.to_f/y.to_f > 1.0)}
|
24
|
+
end
|
25
|
+
|
26
|
+
def page count
|
27
|
+
m = self.image count
|
28
|
+
case m.format
|
29
|
+
when "JPEG"
|
30
|
+
type = 'image/jpeg'
|
31
|
+
when "PNG"
|
32
|
+
type = 'image/png'
|
33
|
+
end
|
34
|
+
[m.to_blob, type]
|
35
|
+
end
|
36
|
+
|
37
|
+
def image count
|
38
|
+
count = count.to_i-1
|
39
|
+
count = 0 if count < 0
|
40
|
+
file = nil
|
41
|
+
name = self.files[count]
|
42
|
+
Zip::Archive.open(self.record.path) do |as|
|
43
|
+
as.each do |a|
|
44
|
+
if a.name == name
|
45
|
+
file = a.read
|
46
|
+
break
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
Magick::Image.from_blob(file).first
|
51
|
+
end
|
52
|
+
|
53
|
+
def files
|
54
|
+
ar = []
|
55
|
+
Zip::Archive.open(self.record.path) do |as|
|
56
|
+
as.each do |a|
|
57
|
+
if a.name =~ /.png$/ or a.name =~ /.jpg$/ or a.name =~ /.PNG$/ or a.name =~ /.JPG$/ or a.name =~ /.jpeg$/ or a.name =~ /.JPEG$/
|
58
|
+
ar << a.name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
ar.sort
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
config = Pit.get("Pig Media Server")
|
2
|
+
|
3
|
+
if File.exist? "#{config['groonga']}/search"
|
4
|
+
Groonga::Database.open "#{config['groonga']}/search"
|
5
|
+
else
|
6
|
+
FileUtils.mkdir_p config['groonga'] rescue nil
|
7
|
+
Groonga::Database.create path: "#{config['groonga']}/search"
|
8
|
+
end
|
9
|
+
|
10
|
+
unless Groonga['Files']
|
11
|
+
puts "create table 'Files'"
|
12
|
+
Groonga::Schema.define do |schema|
|
13
|
+
schema.create_table("Files", type: :patricia_trie, key_type: 'ShortText'){|table|
|
14
|
+
table.short_text "path"
|
15
|
+
table.long_text "metadata"
|
16
|
+
table.long_text "srt"
|
17
|
+
table.short_text 'size'
|
18
|
+
table.int64 "mtime"
|
19
|
+
}
|
20
|
+
schema.create_table("Index", type: :patricia_trie, key_type: "ShortText", default_tokenizer: "TokenBigram", key_normalize: true) { |table|
|
21
|
+
table.index "Files.path"
|
22
|
+
table.index "Files.metadata"
|
23
|
+
table.index "Files.srt"
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#coding:utf-8
|
2
|
+
require 'pig-media-server/model/migrate'
|
3
|
+
|
4
|
+
class Pig
|
5
|
+
attr_accessor :record, :config
|
6
|
+
def initialize record
|
7
|
+
unless record.size
|
8
|
+
record.size = File::Stat.new(record.path).size.to_s rescue nil
|
9
|
+
end
|
10
|
+
self.record = record
|
11
|
+
self.config = Pit.get "Pig Media Server"
|
12
|
+
end
|
13
|
+
def key; self.record._key;end
|
14
|
+
def name; self.record.path.split('/').last; end
|
15
|
+
def mtime; Time.at(self.record.mtime);end
|
16
|
+
def size; self.record.size;end
|
17
|
+
def metadata; self.record.metadata;end
|
18
|
+
def srt; self.record.srt;end
|
19
|
+
def url; '/volume' + URI.encode(self.record.path.sub(/#{config['path'].sub(/\//, '\/')}/, ''));end
|
20
|
+
def type
|
21
|
+
case self.name.split('.').last
|
22
|
+
when 'mp4', 'MP4', 'webm'
|
23
|
+
'video'
|
24
|
+
when 'zip', 'ZIP'
|
25
|
+
'read'
|
26
|
+
when 'txt', 'TXT'
|
27
|
+
'txt'
|
28
|
+
else
|
29
|
+
'other'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
def comic
|
33
|
+
Comic.new self.record
|
34
|
+
end
|
35
|
+
def webvtt
|
36
|
+
str = <<EOS
|
37
|
+
WEBVTT
|
38
|
+
|
39
|
+
#{self.srt.split("\n").delete_if{|x| x.to_i.to_s == x.chomp}.map{|x| if x =~ /\d\d:\d\d/; x.gsub!(/,/, '.');else; x = x.gsub(/</, '<').gsub(/>/, '>');end; x}.join("\n")}
|
40
|
+
EOS
|
41
|
+
str.chomp.chomp
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
def self.find key
|
47
|
+
case key.class.to_s
|
48
|
+
when 'Array'
|
49
|
+
return key.map{|x| self.new Groonga['Files'][x]}
|
50
|
+
when 'String'
|
51
|
+
return self.new Groonga['Files'][key]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.search opts
|
56
|
+
query = Sewell.generate opts[:query].to_s, %w{metadata path srt}
|
57
|
+
limit = opts[:limit] ? opts[:limit].to_i : 50
|
58
|
+
page = opts[:page].to_i < 1 ? 1 : opts[:page].to_i
|
59
|
+
order = (opts[:order] == 'ascending' or opts[:order] == 'descending') ? opts[:order] : 'descending'
|
60
|
+
result = Groonga['Files'].select(query)
|
61
|
+
if result.count == 0
|
62
|
+
begin
|
63
|
+
result = Groonga['Files'].select{|x| x.path.match str}
|
64
|
+
rescue
|
65
|
+
end
|
66
|
+
end
|
67
|
+
if opts[:sort] == 'name'
|
68
|
+
list = result.paginate([key: 'path', order: order], size: 2000, page: page).map{|x| Pig.new x}.sort{|x,y|
|
69
|
+
x.path.split('/').last.sub(/^\d\d*_/, '') <=> y.path.split('/').last.sub(/^\d\d*_/, '')
|
70
|
+
}.reverse rescue list = []
|
71
|
+
list.reverse! if order == 'descending'
|
72
|
+
else
|
73
|
+
list = result.paginate([key: 'mtime', order: order], size: limit, page: page).map{|x| Pig.new x} rescue list = []
|
74
|
+
end
|
75
|
+
list
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.find_or_create_by_path path
|
79
|
+
key = Digest::MD5.hexdigest(path).to_s
|
80
|
+
unless Groonga['Files'][key]
|
81
|
+
stat = File::Stat.new path
|
82
|
+
Groonga["Files"].add(key)
|
83
|
+
Groonga["Files"][key].path = path
|
84
|
+
Groonga["Files"][key].mtime = stat.mtime.to_i
|
85
|
+
Groonga['Files'][key].size = stat.size.to_s
|
86
|
+
end
|
87
|
+
return Pig.new Groonga['Files'][key]
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.all
|
91
|
+
Groonga['Files'].select.map{|x| Pig.new x}
|
92
|
+
end
|
93
|
+
|
94
|
+
def check
|
95
|
+
return false unless self.record
|
96
|
+
Groonga['Files'].delete self.record._key unless File.exist? self.record.path
|
97
|
+
end
|
98
|
+
end
|
File without changes
|
@@ -0,0 +1,9 @@
|
|
1
|
+
%a{href: 'javascript:void(0)', key: record.key, class: record.type} Read
|
2
|
+
-#
|
3
|
+
- if session[:user_id] and record.size.to_i < 1024*1024*200
|
4
|
+
%a.kindle{href: "/to_kindle/#{record.key}?path=#{CGI.escape request.url}"} Send To Kindle
|
5
|
+
-else
|
6
|
+
- unless record.kindle
|
7
|
+
%a.kindle{href: "/convert_to_kindle/#{record.key}?path=#{CGI.escape request.url}"} Convert to Kindle
|
8
|
+
-else
|
9
|
+
%a.kindle{href: record.kindle_url, target: '_blank'} Download Kindle
|
@@ -0,0 +1 @@
|
|
1
|
+
!=partial :_ft_read, locals: {record: record}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
-if record.srt
|
2
|
+
%a.watch{href: 'javascript:void(0)', srt: 'true', url: record.url, key: record.key, title: record.name}watch
|
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
|