omnifiles 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6168535895fcefcd6125d84d87fd2deba8161d36
4
- data.tar.gz: 435bc5685890875c42eeaaeb89a76b1f259da2c9
3
+ metadata.gz: 10d0e6b7d9a8c8ba27681ce9726d63baf309c22e
4
+ data.tar.gz: 33e13a6d786009124e6312d6a26cd9872fcb50e8
5
5
  SHA512:
6
- metadata.gz: 2d68c691076c59bc970367d9c8b325c15f38ce4f1b1f74bf757b0409bea74d6bce83089b6305e903a17b08e38b7f321b99c71b4f02d8c59591613b368fe3501c
7
- data.tar.gz: 20146b39ff0cff35866da53a4c35492a1b9abf5df4b642cc50c4d2e146eda110ed7b5d01f0efde14b437cd63807854035f77cf3de90b2c0541f58616385038d2
6
+ metadata.gz: cebc8b5441cbd3d053a7d0465e7867a20d96f5894b1d8090f7ad031123a6bc494388e44552e295cc0abc0f0e1323f90268c935e4f98085b64377308158d27d51
7
+ data.tar.gz: 41f1711c4d30660f493fcec462beca32fabacf7f6827defb1bedaeef147548572bc4ede0e15d8ff9fdc291b36dfb6e67ba36368a36b831e4c9069b9165214dbc
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # OmniFiles
2
2
 
3
+ [![Gem Version](https://img.shields.io/gem/v/omnifiles.svg)](https://rubygems.org/gems/omnifiles)
4
+ [![Code Climate](https://codeclimate.com/github/theirix/omnifiles/badges/gpa.svg)](https://codeclimate.com/github/theirix/omnifiles)
5
+ [![Dependency Status](https://gemnasium.com/theirix/omnifiles.svg)](https://gemnasium.com/theirix/omnifiles)
6
+
3
7
  File storage and shortener server.
4
8
 
5
9
  OmniFiles is built with Sinatra and Rack and uses an sqlite database to store shortened
@@ -15,15 +19,14 @@ OmniFiles is a Rack application and can be used as a gem or as a server in local
15
19
 
16
20
  gem install omnifiles
17
21
 
18
- 2. Create a settings file `/path/to/settings.yaml` by copying `config/settings.yaml.example`.
19
- Location of file must be specified in env variable `OMNIFILES_SETTINGS`.
22
+ 2. Point an env variable `OMNIFILES_SETTINGS` to location of a settings file `/path/to/settings.yaml` (see Configurarion).
20
23
 
21
24
  3. Start an app as a Thin server
22
25
 
23
26
  OMNIFILES_SETTINGS=/path/to/settings.yaml omnifiles
24
27
  Of course, you can provide any additional Thin options:
25
28
 
26
- OMNIFILES_SETTINGS=/path/to/settings.yaml omnifiles -l /var/log/omnifiles.log -P /var/run/omnifiles.pid -d
29
+ OMNIFILES_SETTINGS=/path/to/settings.yaml omnifiles -p 3000
27
30
 
28
31
  ## As a rack app
29
32
 
@@ -35,20 +38,36 @@ OmniFiles can be started using `config.ru` with you favourite Rack server.
35
38
 
36
39
  bundle install
37
40
 
38
- 3. Create a settings file `/path/to/settings.yaml` by copying `config/settings.yaml.example`.
39
- Location of file must be specified in env variable `OMNIFILES_SETTINGS`.
41
+ 3. Point an env variable `OMNIFILES_SETTINGS` to location of a settings file `/path/to/settings.yaml` (see Configurarion).
40
42
 
41
43
  4. Start Rack app
42
44
 
43
45
  rackup
44
46
 
47
+ ## Configuration
48
+
49
+ Settings file template can be found at `config/settings.yaml.example`.
50
+
51
+ If you prefer production Rack environment, please use `production` instead of `development` section in the config.
52
+ Also specify `-E production` at `omnifiles` (actially Thin) command line.
53
+
54
+ If you prefer to run omnifiles as a daemon, don't forget to set log and pid location. Author prefer to follow XDG and place all the files at the `~/.local/share/omnifiles`, including the database. So one can use following command line:
55
+
56
+ OMNIFILES_SETTINGS=$HOME/.local/share/omnifiles/settings.yaml omnifiles -d -a 127.0.0.1 -p 3000 \
57
+ -l $HOME/.local/share/omnifiles/omnifiles.log \
58
+ -P $HOME/.local/share/omnifiles/omnifiles.pid
59
+
45
60
  ## Usage
46
61
 
47
62
  1. Storing files.
48
- OmniFiles can store files by issuing an authenticated POST request
63
+ OmniFiles can store files by issuing an authenticated POST form request:
49
64
 
50
65
  % curl --digest -u user:secret -F "file=@/path/to/file.jpg" 'http://localhost:3000/store'
51
66
  http://localhost:3000/f/e63A12
67
+ Or you can post a file just as a binary POST data:
68
+
69
+ % curl --digest -u user:secret -H "Content-Type: application/octet-stream" --data-binary "@/path/to/file.jpg" 'http://localhost:3000/store'
70
+ http://localhost:3000/f/e63A12
52
71
  OmniFiles returns a short url in response so you can just issue following command to save URL in clipboard
53
72
 
54
73
  % curl --digest -u user:secret -F "file=@/path/to/file.jpg" 'http://localhost:3000/store' | pbcopy
@@ -69,4 +88,4 @@ using web browser or curl
69
88
 
70
89
  ## License information
71
90
 
72
- Please consult with the LICENSE.txt for license information.
91
+ Please consult with the LICENSE.txt for license information. It is MIT by the way.
@@ -1,5 +1,5 @@
1
1
  development:
2
- storage_dir: /var/lib/omnifiles/storage
3
- db: /var/lib/omnifiles/omnifiles.sqlite3
2
+ storage_dir: storage
3
+ db: omnifiles.sqlite3
4
4
  auth_opaque: alongopaquekey
5
5
  auth_password: secret
@@ -3,6 +3,7 @@
3
3
  require 'sinatra'
4
4
  require 'filemagic'
5
5
  require 'uri'
6
+ require 'tempfile'
6
7
  require 'settingslogic'
7
8
  require 'haml'
8
9
  require 'rack'
@@ -42,7 +43,11 @@ module OmniFiles
42
43
  halt 404, "File not found" unless data
43
44
 
44
45
  @url = url('/f/'+name)
45
- @original_filename = URI.unescape data['original_filename']
46
+ if data['original_filename']
47
+ @original_filename = URI.unescape data['original_filename']
48
+ else
49
+ @original_filename = "<i>Not provided</i>"
50
+ end
46
51
  @access_count = data['accessed']
47
52
  @mime = data['mime']
48
53
  @shortened = name
@@ -50,33 +55,33 @@ module OmniFiles
50
55
  haml :stat
51
56
  end
52
57
 
58
+ # POST handler with form/body handling
53
59
  def store_file
54
60
  logger.info "Route POST store"
55
61
  begin
56
62
  req = Rack::Request.new(env)
57
- post_file = req.POST['file']
58
- original_filename = URI.escape(File.basename(post_file[:filename]))
59
-
60
- temp_file = post_file[:tempfile]
63
+ if !req.POST || req.POST == {}
64
+ logger.info "Saving POST body to temp file"
61
65
 
62
- # Determine file mime and desired url
63
- mime = FileMagic.mime.file temp_file.path
66
+ original_filename = nil
64
67
 
65
- # Short URL is composed from escaped filename from form, mime type and leading file bytes
66
- shortened = @storage.shorten_file temp_file.path, original_filename, mime
68
+ # Make a temp file with body content
69
+ temp_file = Tempfile.new("omnifiles-post-")
70
+ File.open(temp_file.path, 'wb') do |ftemp|
71
+ IO.copy_stream(req.body, ftemp)
72
+ end
73
+ else
74
+ logger.info "Using POST form"
67
75
 
68
- # Save file to storage
69
- target_path = File.join(Settings.storage_dir, shortened)
70
- raise "Not so unique id #{shortened}" if File.exists? target_path
71
- FileUtils.cp temp_file.path, target_path
76
+ # Use a Rack provided file with content
77
+ post_file = req.POST['file']
78
+ original_filename = URI.escape(File.basename(post_file[:filename]))
72
79
 
73
- # Put record to storage
74
- @storage.put_file shortened, original_filename, mime
75
- short_url = url('/f/'+shortened)
80
+ temp_file = post_file[:tempfile]
81
+ end
76
82
 
77
- logger.info "Stored file #{target_path} to shortened #{shortened}, magic '#{mime}'"
83
+ store_with_file temp_file.path, original_filename
78
84
 
79
- short_url
80
85
  ensure
81
86
  if temp_file
82
87
  temp_file.close
@@ -85,6 +90,31 @@ module OmniFiles
85
90
  end
86
91
  end
87
92
 
93
+ # Save temporary file to storage
94
+ def store_with_file path, original_filename
95
+ # Take a sample of file
96
+ sample = Digest::MD5.hexdigest(IO.binread(path, 0x100))
97
+
98
+ # Determine file mime and desired url
99
+ mime = FileMagic.mime.file path
100
+
101
+ # Short URL is composed from escaped filename from form, mime type and leading file bytes
102
+ shortened = @storage.shorten_file sample, original_filename, mime
103
+
104
+ # Save file to storage
105
+ target_path = File.join(Settings.storage_dir, shortened)
106
+ raise "Not so unique id #{shortened}" if File.exists? target_path
107
+ FileUtils.cp path, target_path
108
+
109
+ # Put record to storage
110
+ @storage.put_file shortened, original_filename, mime
111
+ short_url = url('/f/'+shortened)
112
+
113
+ logger.info "Stored file #{target_path} to shortened #{shortened}, magic '#{mime}'"
114
+
115
+ short_url
116
+ end
117
+
88
118
  end
89
119
 
90
120
  end
@@ -30,7 +30,9 @@ module OmniFiles
30
30
 
31
31
  logger.info "Data #{data}, file #{path}, was at #{filename}"
32
32
 
33
- headers 'X-Original-Filename' => filename
33
+ if filename && !filename.empty?
34
+ headers 'X-Original-Filename' => filename
35
+ end
34
36
  send_file path, :type => mime
35
37
  end
36
38
 
@@ -18,10 +18,11 @@ module OmniFiles
18
18
  end
19
19
 
20
20
  # returns shortened url
21
- def shorten_file path, filename, mime
21
+ def shorten_file sample, filename, mime
22
22
  counter = 0
23
23
  begin
24
- hashing = [filename, mime, Digest::MD5.hexdigest(IO.binread(path, 0x100)), counter.to_s].join '|'
24
+ # filename can be null
25
+ hashing = [filename.to_s, mime, sample, counter.to_s].join '|'
25
26
  @logger.info "Hashing value " + hashing
26
27
  shortened = @shortener.shorten hashing
27
28
  counter += 1
@@ -1,3 +1,3 @@
1
1
  module OmniFiles
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omnifiles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - theirix
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-05 00:00:00.000000000 Z
11
+ date: 2015-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler