ongaku_ryoho_server 0.1.1 → 0.2
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/bin/ongaku_ryoho_server +13 -6
- data/lib/ongaku_ryoho_server/application.rb +13 -137
- data/lib/ongaku_ryoho_server/list.rb +65 -0
- data/lib/ongaku_ryoho_server/process.rb +111 -0
- data/lib/ongaku_ryoho_server/version.rb +1 -1
- data/lib/ongaku_ryoho_server.rb +9 -3
- data/ongaku_ryoho_server.gemspec +3 -3
- metadata +50 -17
data/bin/ongaku_ryoho_server
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require_relative
|
2
|
+
require_relative "../lib/ongaku_ryoho_server.rb"
|
3
3
|
|
4
4
|
#
|
5
5
|
# Look for some of the Sinatra options and pass them along
|
@@ -7,16 +7,23 @@ require_relative '../lib/ongaku_ryoho_server.rb'
|
|
7
7
|
options = {}
|
8
8
|
|
9
9
|
if ARGV.any?
|
10
|
-
require
|
10
|
+
require "optparse"
|
11
11
|
OptionParser.new { |op|
|
12
|
-
op.on(
|
13
|
-
op.on(
|
14
|
-
op.on(
|
12
|
+
op.on("-p port", "set the port (default is 4567)") { |val| options[:port] = Integer(val) }
|
13
|
+
op.on("-o addr", "set the host (default is 0.0.0.0)") { |val| options[:bind] = val }
|
14
|
+
op.on("-x", "turn on the mutex lock (default is off)") { options[:lock] = true }
|
15
15
|
}.parse!(ARGV.dup)
|
16
16
|
end
|
17
17
|
|
18
18
|
|
19
|
+
#
|
20
|
+
# Build list
|
21
|
+
|
22
|
+
OngakuRyohoServer::List.save
|
23
|
+
puts "Collection saved at #{OngakuRyohoServer::List.config_file_path}\n\n"
|
24
|
+
|
25
|
+
|
19
26
|
#
|
20
27
|
# Run the server
|
21
28
|
|
22
|
-
OngakuRyohoServer.run(options)
|
29
|
+
OngakuRyohoServer.run(options)
|
@@ -1,176 +1,52 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'mp3info'
|
3
|
-
require 'sinatra'
|
4
|
-
require 'puma'
|
5
|
-
require 'uri'
|
6
|
-
|
7
1
|
module OngakuRyohoServer
|
8
2
|
#
|
9
3
|
# { Application }
|
10
4
|
#
|
11
5
|
# === Info
|
12
6
|
#
|
13
|
-
# Sinatra application
|
14
|
-
#
|
7
|
+
# Sinatra application to handle the incoming
|
8
|
+
# http requests or whatever
|
15
9
|
|
16
10
|
class Application < Sinatra::Base
|
17
11
|
set :environment, :production
|
18
12
|
set :server, :puma
|
19
13
|
|
14
|
+
FILE_FORMATS = %w{ mp3 mp4 ogg flac wav wma }
|
20
15
|
|
21
16
|
# root
|
22
|
-
get
|
17
|
+
get "/" do
|
23
18
|
content_type :json
|
24
|
-
|
19
|
+
|
20
|
+
OngakuRyohoServer::List.get
|
25
21
|
end
|
26
22
|
|
27
23
|
|
28
24
|
# availability
|
29
|
-
get
|
25
|
+
get "/available?" do
|
30
26
|
"As it happens, I am."
|
31
27
|
end
|
32
28
|
|
33
29
|
|
34
30
|
# compare filelists
|
35
|
-
post
|
31
|
+
post "/check" do
|
36
32
|
content_type :json
|
37
|
-
|
33
|
+
|
34
|
+
collection = params[:file_list]
|
35
|
+
OngakuRyohoServer::Process.check_files(collection).to_json
|
38
36
|
end
|
39
37
|
|
40
38
|
|
41
39
|
# music file
|
42
|
-
get %r{.(
|
40
|
+
get %r{.(#{FILE_FORMATS.join("|")})$}i do
|
43
41
|
requested_item = URI.unescape(request.path_info[1..-1])
|
44
42
|
File.exists?(requested_item) ? send_file(requested_item) : 404
|
45
43
|
end
|
46
44
|
|
47
45
|
|
48
|
-
# crossdomain.xml
|
49
|
-
get '/crossdomain.xml' do
|
50
|
-
content_type :xml
|
51
|
-
%{<?xml version="1.0"?>
|
52
|
-
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
|
53
|
-
<cross-domain-policy>
|
54
|
-
<allow-access-from domain="*" />
|
55
|
-
</cross-domain-policy>
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
|
60
46
|
# everything else
|
61
47
|
get %r{.+} do
|
62
48
|
403
|
63
49
|
end
|
64
50
|
|
65
|
-
|
66
|
-
#
|
67
|
-
# Read directory
|
68
|
-
#
|
69
|
-
# => find music in the current directory
|
70
|
-
#
|
71
|
-
# [output]
|
72
|
-
# file list
|
73
|
-
#
|
74
|
-
def read_directory
|
75
|
-
Dir.glob('**/*.{mp3}')
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
#
|
80
|
-
# Check files
|
81
|
-
#
|
82
|
-
# => compares a given file list to the file list from the current directory
|
83
|
-
# show which files are missing and scan the ones that are new
|
84
|
-
#
|
85
|
-
# [params]
|
86
|
-
# file_list_from_client
|
87
|
-
#
|
88
|
-
# [output]
|
89
|
-
# object containing missing_files and new_tracks array
|
90
|
-
#
|
91
|
-
def check_files(file_list_from_client)
|
92
|
-
file_list_from_client = JSON.parse(file_list_from_client)
|
93
|
-
file_list_from_server = read_directory
|
94
|
-
|
95
|
-
missing_files = file_list_from_client - file_list_from_server
|
96
|
-
new_files = file_list_from_server - file_list_from_client
|
97
|
-
|
98
|
-
new_tracks = process_music(new_files, { last_modified: Time.now })
|
99
|
-
|
100
|
-
return {
|
101
|
-
missing_files: missing_files,
|
102
|
-
new_tracks: new_tracks
|
103
|
-
}
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
#
|
108
|
-
# Process this directory
|
109
|
-
#
|
110
|
-
# => read directory and process its contents
|
111
|
-
#
|
112
|
-
# [output]
|
113
|
-
# processed contents (see method below)
|
114
|
-
#
|
115
|
-
def process_this_directory
|
116
|
-
music_collection = read_directory
|
117
|
-
return process_music(music_collection)
|
118
|
-
end
|
119
|
-
|
120
|
-
|
121
|
-
#
|
122
|
-
# Process music
|
123
|
-
#
|
124
|
-
# => open each music track, get its tags and return all of them
|
125
|
-
#
|
126
|
-
# [params]
|
127
|
-
# music_collection : array of files to process (i.e. filepaths)
|
128
|
-
# extra_properties : properties to include in each track object/hash
|
129
|
-
#
|
130
|
-
# [output]
|
131
|
-
# tracks : collection of all the tracks their tags
|
132
|
-
#
|
133
|
-
def process_music(music_collection, extra_properties = {})
|
134
|
-
tracks = []
|
135
|
-
|
136
|
-
# loop over every track
|
137
|
-
music_collection.each do |location|
|
138
|
-
rpartition = location.rpartition('/')
|
139
|
-
filename = rpartition[2]
|
140
|
-
|
141
|
-
track = {}
|
142
|
-
|
143
|
-
case File.extname(filename)
|
144
|
-
when '.mp3'
|
145
|
-
Mp3Info.open(location) do |mp3|
|
146
|
-
tags = {
|
147
|
-
title: mp3.tag.title,
|
148
|
-
artist: mp3.tag.artist,
|
149
|
-
album: mp3.tag.album,
|
150
|
-
year: mp3.tag.year,
|
151
|
-
tracknr: mp3.tag.tracknum,
|
152
|
-
genres: mp3.tag.genre_s
|
153
|
-
}
|
154
|
-
|
155
|
-
tags.each do |key, value|
|
156
|
-
tags[key] = 'Unknown' if value.nil? or (value.respond_to?(:empty) and value.empty?)
|
157
|
-
end
|
158
|
-
|
159
|
-
tags.merge!({ filename: filename, location: location })
|
160
|
-
|
161
|
-
track = tags.clone
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
unless track.empty?
|
166
|
-
track.merge!(extra_properties)
|
167
|
-
tracks << track
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# return all tracks
|
172
|
-
return tracks
|
173
|
-
end
|
174
|
-
|
175
51
|
end
|
176
|
-
end
|
52
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module OngakuRyohoServer
|
2
|
+
#
|
3
|
+
# { List }
|
4
|
+
#
|
5
|
+
# === Info
|
6
|
+
#
|
7
|
+
# Module for handling the lists,
|
8
|
+
# tracks data saved in json files
|
9
|
+
|
10
|
+
module List
|
11
|
+
|
12
|
+
CONFIG_PATH = File.expand_path("~/.ongaku_ryoho/server")
|
13
|
+
|
14
|
+
#
|
15
|
+
# Get digest
|
16
|
+
#
|
17
|
+
# => Creates a digest from the path of the current directory
|
18
|
+
#
|
19
|
+
def self.get_digest
|
20
|
+
digested_path = Digest::SHA1.hexdigest(Dir.pwd)
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
#
|
25
|
+
# Configuration file path
|
26
|
+
#
|
27
|
+
# => Build path to config file
|
28
|
+
#
|
29
|
+
def self.config_file_path
|
30
|
+
"#{CONFIG_PATH}/#{self.get_digest}.json"
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
#
|
35
|
+
# Get
|
36
|
+
#
|
37
|
+
# => Get the list for the current directory
|
38
|
+
#
|
39
|
+
def self.get
|
40
|
+
path = self.config_file_path
|
41
|
+
File.open(path, "r") if File.file?(path)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
#
|
46
|
+
# Save
|
47
|
+
#
|
48
|
+
# => Save the list for the current directory
|
49
|
+
#
|
50
|
+
def self.save
|
51
|
+
path = self.config_file_path
|
52
|
+
file_list = OngakuRyohoServer::Process.directory
|
53
|
+
collection = OngakuRyohoServer::Process.files(file_list).to_json
|
54
|
+
|
55
|
+
# make path
|
56
|
+
FileUtils.mkpath(CONFIG_PATH)
|
57
|
+
|
58
|
+
# make file
|
59
|
+
File.open(path, "w") do |f|
|
60
|
+
f.write collection
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module OngakuRyohoServer
|
2
|
+
#
|
3
|
+
# { Process }
|
4
|
+
#
|
5
|
+
# === Info
|
6
|
+
#
|
7
|
+
# Module for processing the current directory
|
8
|
+
# and music files
|
9
|
+
|
10
|
+
module Process
|
11
|
+
|
12
|
+
#
|
13
|
+
# Read directory
|
14
|
+
#
|
15
|
+
# => find music in the current directory
|
16
|
+
#
|
17
|
+
# [output]
|
18
|
+
# file list
|
19
|
+
#
|
20
|
+
def self.directory
|
21
|
+
file_formats = OngakuRyohoServer::Application::FILE_FORMATS.join(",")
|
22
|
+
Dir.glob("**/*.{#{file_formats}}")
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
#
|
27
|
+
# Check files
|
28
|
+
#
|
29
|
+
# => compares a given file list to the file list from the current directory
|
30
|
+
# show which files are missing and scan the ones that are new
|
31
|
+
#
|
32
|
+
# [params]
|
33
|
+
# file_list
|
34
|
+
#
|
35
|
+
# [output]
|
36
|
+
# object containing missing_files and new_tracks array
|
37
|
+
#
|
38
|
+
def self.check_files(file_list)
|
39
|
+
file_list = JSON.parse(file_list)
|
40
|
+
file_list_from_current_directory = OngakuRyohoServer::Process.directory
|
41
|
+
|
42
|
+
missing_files = file_list - file_list_from_current_directory
|
43
|
+
new_files = file_list_from_current_directory - file_list
|
44
|
+
|
45
|
+
new_tracks = OngakuRyohoServer::Process.files(
|
46
|
+
new_files, { last_modified: Time.now }
|
47
|
+
)
|
48
|
+
|
49
|
+
return {
|
50
|
+
missing_files: missing_files,
|
51
|
+
new_tracks: new_tracks
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
#
|
57
|
+
# Process files
|
58
|
+
#
|
59
|
+
# => open each music track, get its tags and return all of them
|
60
|
+
#
|
61
|
+
# [params]
|
62
|
+
# file_list : array of files (paths) to process
|
63
|
+
# extra_properties : properties to include in each track object/hash
|
64
|
+
#
|
65
|
+
# [output]
|
66
|
+
# tracks list : collection of all the tracks their tags
|
67
|
+
# and the extra information
|
68
|
+
#
|
69
|
+
def self.files(file_list, extra_properties = {})
|
70
|
+
tracks = []
|
71
|
+
|
72
|
+
# loop over every track
|
73
|
+
file_list.each do |location|
|
74
|
+
rpartition = location.rpartition("/")
|
75
|
+
filename = rpartition[2]
|
76
|
+
|
77
|
+
track = {}
|
78
|
+
|
79
|
+
TagLib::FileRef.open(location) do |fileref|
|
80
|
+
tag = fileref.tag
|
81
|
+
|
82
|
+
tags = {
|
83
|
+
title: tag.title,
|
84
|
+
artist: tag.artist,
|
85
|
+
album: tag.album,
|
86
|
+
year: tag.year,
|
87
|
+
track: tag.track,
|
88
|
+
genre: tag.genre
|
89
|
+
}
|
90
|
+
|
91
|
+
tags.each do |key, value|
|
92
|
+
tags[key] = "Unknown" if value.nil? or (value.respond_to?(:empty) and value.empty?)
|
93
|
+
end
|
94
|
+
|
95
|
+
tags.merge!({ filename: filename, location: location })
|
96
|
+
|
97
|
+
track = tags.clone
|
98
|
+
end
|
99
|
+
|
100
|
+
unless track.empty?
|
101
|
+
track.merge!(extra_properties)
|
102
|
+
tracks << track
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# return all tracks
|
107
|
+
return tracks
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
data/lib/ongaku_ryoho_server.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
|
+
require "json"
|
2
|
+
require "uri"
|
3
|
+
require "digest/sha1"
|
4
|
+
require "puma"
|
5
|
+
require "sinatra"
|
6
|
+
require "taglib"
|
7
|
+
|
1
8
|
require_relative "ongaku_ryoho_server/version"
|
9
|
+
require_relative "ongaku_ryoho_server/process"
|
10
|
+
require_relative "ongaku_ryoho_server/list"
|
2
11
|
require_relative "ongaku_ryoho_server/application"
|
3
12
|
|
4
13
|
module OngakuRyohoServer
|
5
|
-
#
|
6
|
-
# { Class methods }
|
7
|
-
|
8
14
|
def self.run(options)
|
9
15
|
OngakuRyohoServer::Application.run!(options)
|
10
16
|
end
|
data/ongaku_ryoho_server.gemspec
CHANGED
@@ -15,9 +15,9 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = OngakuRyohoServer::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency 'json', '~> 1.
|
19
|
-
gem.add_dependency 'ruby
|
20
|
-
gem.add_dependency 'sinatra', '~> 1.3.
|
18
|
+
gem.add_dependency 'json', '~> 1.7.5'
|
19
|
+
gem.add_dependency 'taglib-ruby', '~> 0.5.2'
|
20
|
+
gem.add_dependency 'sinatra', '~> 1.3.3'
|
21
21
|
gem.add_dependency 'puma'
|
22
22
|
|
23
23
|
gem.add_development_dependency 'rake'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ongaku_ryoho_server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.2'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,44 +9,59 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-10-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.
|
21
|
+
version: 1.7.5
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.7.5
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
|
-
name: ruby
|
27
|
-
requirement:
|
31
|
+
name: taglib-ruby
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ~>
|
31
36
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
37
|
+
version: 0.5.2
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.5.2
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: sinatra
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ~>
|
42
52
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.3.
|
53
|
+
version: 1.3.3
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.3.3
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: puma
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: rake
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,7 +85,12 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
description: Serves music to Ongaku Ryoho clients
|
70
95
|
email:
|
71
96
|
- icid.asset@gmail.com
|
@@ -82,6 +107,8 @@ files:
|
|
82
107
|
- bin/ongaku_ryoho_server
|
83
108
|
- lib/ongaku_ryoho_server.rb
|
84
109
|
- lib/ongaku_ryoho_server/application.rb
|
110
|
+
- lib/ongaku_ryoho_server/list.rb
|
111
|
+
- lib/ongaku_ryoho_server/process.rb
|
85
112
|
- lib/ongaku_ryoho_server/version.rb
|
86
113
|
- ongaku_ryoho_server.gemspec
|
87
114
|
homepage: https://github.com/icidasset/ongaku_ryoho_server
|
@@ -96,15 +123,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
123
|
- - ! '>='
|
97
124
|
- !ruby/object:Gem::Version
|
98
125
|
version: '0'
|
126
|
+
segments:
|
127
|
+
- 0
|
128
|
+
hash: 819011088545897320
|
99
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
130
|
none: false
|
101
131
|
requirements:
|
102
132
|
- - ! '>='
|
103
133
|
- !ruby/object:Gem::Version
|
104
134
|
version: '0'
|
135
|
+
segments:
|
136
|
+
- 0
|
137
|
+
hash: 819011088545897320
|
105
138
|
requirements: []
|
106
139
|
rubyforge_project:
|
107
|
-
rubygems_version: 1.8.
|
140
|
+
rubygems_version: 1.8.24
|
108
141
|
signing_key:
|
109
142
|
specification_version: 3
|
110
143
|
summary: Serves music to Ongaku Ryoho clients
|