Browse Source

[server] basic directory support

encrypt 4 years ago
parent
commit
5f0db983b4
1 changed files with 56 additions and 11 deletions
  1. 56 11
      server/server.rb

+ 56 - 11
server/server.rb

@@ -1,9 +1,27 @@
+# coding: utf-8
 require 'sinatra'
 require 'securerandom'
 require 'json'
 
 set :storage_directory, './storage/'
 
+def is_base32?(str)
+  table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567='
+  if str.force_encoding("UTF-8").ascii_only?
+    str.each_char { |c| return false unless table.include?(c) }
+    return true
+  else
+    return false
+  end
+end
+
+def path_is_base32?(str)
+  str.split('/').each do |p|
+    return false unless is_base32?(p)
+  end
+  return true
+end
+    
 get '/' do
   redirect 'index.html'
 end
@@ -17,12 +35,32 @@ post '/room' do
   {id: id}.to_json
 end
 
+# mkdir
+
+post '/room/mkdir/:id' do |id|
+  if Dir.exists?(settings.storage_directory+id)
+    if params[:path] && path_is_base32?(params[:path])
+      Dir.mkdir(settings.storage_directory+id+"/"+params[:path])
+      return 200
+    end   
+  end
+  403
+end
+
 # get room content
 
-get '/room/:id' do |id|
-  if Dir.exist?(settings.storage_directory+id)
+get '/room/:id/*?' do |id,path|
+  dir = settings.storage_directory+id
+  dir += path_is_base32?(path) ? '/'+path : ''
+  puts dir
+  if Dir.exist?(dir)
     content_type 'text/json'
-    Dir.glob(settings.storage_directory+id+'/*').map { |f| File.basename(f)}.to_json
+    Dir.glob(dir+'/*').map { |f|
+      {
+        is_directory: File.directory?(f),
+        name: File.basename(f),
+        last_updated: File.mtime(f)
+      }}.to_json
   else
     404
   end
@@ -31,14 +69,21 @@ end
 # upload a file 
 
 post '/room/:id' do |id|
-  unless params[:file] &&
-         (tmpfile = params[:file][:tempfile]) &&
-         (name = params[:file][:filename])
-    403
-    return
+  if Dir.exists?(settings.storage_directory+id)
+    unless params[:file] &&
+           (tmpfile = params[:file][:tempfile]) &&
+           (name = params[:file][:filename]) &&
+           params[:path] &&
+           path_is_base32?(params[:path]) &&
+           Dir.exists?(settings.storage_directory+id+'/'+params[:path])
+      403
+      return
+    end
+    FileUtils.cp(tmpfile, settings.storage_directory+id+'/'+params[:path]+'/'+name)
+    200
+  else
+    404
   end
-  FileUtils.cp(tmpfile, settings.storage_directory+id+"/"+name)
-  200
 end
 
 # remove a room
@@ -48,7 +93,7 @@ end
 
 # get a file
 
-get '/room/:id/:filename' do |id, filename|
+get '/room/file/:id/:filename' do |id, filename|
   send_file File.join(settings.storage_directory+id, filename)
 end