omnifiles 0.2.1 → 0.3.0
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.
- checksums.yaml +4 -4
- data/config/settings.yaml.example +1 -0
- data/lib/omnifiles/protectedapp.rb +57 -10
- data/lib/omnifiles/settings.rb +2 -1
- data/lib/omnifiles/shortener.rb +2 -2
- data/lib/omnifiles/storage.rb +11 -2
- data/lib/omnifiles/version.rb +1 -1
- data/lib/omnifiles/views/index.haml +123 -0
- data/lib/omnifiles/views/stat.haml +19 -9
- data/omnifiles.gemspec +2 -0
- metadata +31 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cdc7404e8fb3bf594a9c686e40dec5a1bcff348
|
4
|
+
data.tar.gz: 7afd2f9c25f9a4c372e99dc82203974a795712ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ca79679d327f92bfcdba960a2c3cda44222d3daad86aa933f31a7bfc2dd999b7783ff7469a960cc65609295633dc31ad8782dd8632b62119b2c44b5ee051776
|
7
|
+
data.tar.gz: 3f9b7eed3669d4f685962f6147ac4a8eb9c8060faa2dc70956565d4f8b5d4183c4a3d78d909e1c0f4a3307dd36bee2ead667d04099cbe69dc5c0ff31eb3127c0
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'sinatra'
|
4
|
+
require 'sinatra/flash'
|
4
5
|
require 'filemagic'
|
5
6
|
require 'uri'
|
6
7
|
require 'tempfile'
|
@@ -17,6 +18,11 @@ module OmniFiles
|
|
17
18
|
Settings.auth_password
|
18
19
|
end
|
19
20
|
|
21
|
+
enable :sessions
|
22
|
+
set :session_secret, Settings.session_secret
|
23
|
+
|
24
|
+
register Sinatra::Flash
|
25
|
+
|
20
26
|
# POST a file
|
21
27
|
post '/store/' do
|
22
28
|
store_file
|
@@ -26,6 +32,10 @@ module OmniFiles
|
|
26
32
|
store_file
|
27
33
|
end
|
28
34
|
|
35
|
+
def make_visible_filename filename
|
36
|
+
filename ? URI.unescape(filename) : "<i>Not provided</i>"
|
37
|
+
end
|
38
|
+
|
29
39
|
def format_time_str time
|
30
40
|
if time
|
31
41
|
time.localtime.to_s
|
@@ -34,6 +44,19 @@ module OmniFiles
|
|
34
44
|
end
|
35
45
|
end
|
36
46
|
|
47
|
+
def make_haml_data_from_doc doc
|
48
|
+
{
|
49
|
+
shortened: doc['shortened'],
|
50
|
+
url: url('/f/' + doc['shortened']),
|
51
|
+
original_filename: make_visible_filename(doc['original_filename']),
|
52
|
+
mime: doc['mime'],
|
53
|
+
access_time: format_time_str(doc['accessed']['time']),
|
54
|
+
created_time: format_time_str(doc['created']['time']),
|
55
|
+
access_count: doc['accessed']['count']
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
# GET stat of file
|
37
60
|
get '/stat/:name' do |name|
|
38
61
|
logger.info "Route GET stat #{name}"
|
39
62
|
|
@@ -42,19 +65,43 @@ module OmniFiles
|
|
42
65
|
data = @storage.get_file name
|
43
66
|
halt 404, "File not found" unless data
|
44
67
|
|
45
|
-
@
|
46
|
-
|
47
|
-
|
68
|
+
@hdata = make_haml_data_from_doc data
|
69
|
+
logger.info @hdata.inspect
|
70
|
+
|
71
|
+
haml :stat
|
72
|
+
end
|
73
|
+
|
74
|
+
# POST to delete file
|
75
|
+
# cannot remap methods
|
76
|
+
post '/delete/:name' do |name|
|
77
|
+
logger.info "Route POST to delete file #{name}"
|
78
|
+
|
79
|
+
target_path = File.join(Settings.storage_dir, name)
|
80
|
+
|
81
|
+
if @storage.delete_file(name)
|
82
|
+
if File.file?(target_path)
|
83
|
+
FileUtils.rm target_path
|
84
|
+
flash[:notice] = "Successfully deleted file #{name}"
|
85
|
+
else
|
86
|
+
flash[:error] = "Cannot delete file #{name} from disk"
|
87
|
+
end
|
48
88
|
else
|
49
|
-
|
89
|
+
flash[:error] = "Cannot delete file #{name} from mongo"
|
50
90
|
end
|
51
|
-
@access_count = data['accessed']['count']
|
52
|
-
@access_time = format_time_str data['accessed']['time']
|
53
|
-
@created_time = format_time_str data['created']['time']
|
54
|
-
@mime = data['mime']
|
55
|
-
@shortened = name
|
56
91
|
|
57
|
-
|
92
|
+
redirect to('/')
|
93
|
+
end
|
94
|
+
|
95
|
+
# GET index
|
96
|
+
get '/' do
|
97
|
+
logger.info "Route GET index"
|
98
|
+
|
99
|
+
@hdata = []
|
100
|
+
@storage.enumerate_docs do |doc|
|
101
|
+
@hdata << make_haml_data_from_doc(doc)
|
102
|
+
end
|
103
|
+
|
104
|
+
haml :index
|
58
105
|
end
|
59
106
|
|
60
107
|
# POST handler with form/body handling
|
data/lib/omnifiles/settings.rb
CHANGED
data/lib/omnifiles/shortener.rb
CHANGED
@@ -6,7 +6,7 @@ require 'digest/md5'
|
|
6
6
|
module OmniFiles
|
7
7
|
|
8
8
|
class UrlShortener
|
9
|
-
def initialize salt, bytes_used
|
9
|
+
def initialize salt, bytes_used
|
10
10
|
@salt = salt
|
11
11
|
@bytes_used = bytes_used
|
12
12
|
# base62
|
@@ -33,4 +33,4 @@ module OmniFiles
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
end
|
36
|
+
end
|
data/lib/omnifiles/storage.rb
CHANGED
@@ -18,7 +18,7 @@ class Storage
|
|
18
18
|
@coll = db.collection('files')
|
19
19
|
raise 'Cannot use collection' unless @coll
|
20
20
|
|
21
|
-
@shortener = UrlShortener.new(SecureRandom.hex(8))
|
21
|
+
@shortener = UrlShortener.new(SecureRandom.hex(8), 1)
|
22
22
|
end
|
23
23
|
|
24
24
|
# returns shortened url
|
@@ -30,8 +30,8 @@ class Storage
|
|
30
30
|
@logger.info "Hashing value " + hashing
|
31
31
|
shortened = @shortener.shorten hashing
|
32
32
|
counter += 1
|
33
|
+
next if shortened.size < 5
|
33
34
|
same_shortened = @coll.find_one({shortened: shortened}, :fields => [ "_id" ])
|
34
|
-
@logger.info same_shortened
|
35
35
|
raise 'Something goes wrong' if counter > 100
|
36
36
|
end while same_shortened
|
37
37
|
shortened
|
@@ -59,6 +59,15 @@ class Storage
|
|
59
59
|
@coll.find_one({ _id: data["_id"]})
|
60
60
|
end
|
61
61
|
|
62
|
+
def delete_file shortened
|
63
|
+
resp = @coll.remove({shortened: shortened})
|
64
|
+
resp['ok'] && resp['n'] > 0
|
65
|
+
end
|
66
|
+
|
67
|
+
def enumerate_docs
|
68
|
+
@coll.find.each { |doc| yield doc }
|
69
|
+
end
|
70
|
+
|
62
71
|
end
|
63
72
|
|
64
73
|
end
|
data/lib/omnifiles/version.rb
CHANGED
@@ -0,0 +1,123 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title OmniFiles files
|
5
|
+
:css
|
6
|
+
body {
|
7
|
+
padding: 5px;
|
8
|
+
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
9
|
+
}
|
10
|
+
|
11
|
+
/* From http://purecss.io */
|
12
|
+
.pure-table {
|
13
|
+
/* Remove spacing between table cells (from Normalize.css) */
|
14
|
+
border-collapse: collapse;
|
15
|
+
border-spacing: 0;
|
16
|
+
empty-cells: show;
|
17
|
+
border: 1px solid #cbcbcb;
|
18
|
+
}
|
19
|
+
|
20
|
+
.pure-table caption {
|
21
|
+
color: #000;
|
22
|
+
font: italic 85%/1 arial, sans-serif;
|
23
|
+
padding: 1em 0;
|
24
|
+
text-align: center;
|
25
|
+
}
|
26
|
+
|
27
|
+
.pure-table td, .pure-table th {
|
28
|
+
border-left: 1px solid #cbcbcb;/* inner column border */
|
29
|
+
border-width: 0 0 0 1px;
|
30
|
+
font-size: inherit;
|
31
|
+
margin: 0;
|
32
|
+
overflow: visible; /*to make ths where the title is really long work*/
|
33
|
+
padding: 0.5em 0.5em; /* cell padding */
|
34
|
+
}
|
35
|
+
|
36
|
+
/* Consider removing this next declaration block, as it causes problems when
|
37
|
+
there's a rowspan on the first cell. Case added to the tests. issue#432 */
|
38
|
+
.pure-table td:first-child, .pure-table th:first-child {
|
39
|
+
border-left-width: 0;
|
40
|
+
}
|
41
|
+
|
42
|
+
.pure-table thead {
|
43
|
+
background-color: #e0e0e0;
|
44
|
+
color: #000;
|
45
|
+
text-align: left;
|
46
|
+
vertical-align: bottom;
|
47
|
+
}
|
48
|
+
|
49
|
+
.pure-table td {
|
50
|
+
background-color: transparent;
|
51
|
+
}
|
52
|
+
|
53
|
+
/* BORDERED TABLES */
|
54
|
+
.pure-table-bordered td {
|
55
|
+
border-bottom: 1px solid #cbcbcb;
|
56
|
+
}
|
57
|
+
.pure-table-bordered tbody > tr:last-child > td {
|
58
|
+
border-bottom-width: 0;
|
59
|
+
}
|
60
|
+
|
61
|
+
.wide
|
62
|
+
{
|
63
|
+
width: 100%;
|
64
|
+
}
|
65
|
+
|
66
|
+
.delete
|
67
|
+
{
|
68
|
+
color: #ff0000;
|
69
|
+
text-align: center;
|
70
|
+
font-weight: bold;
|
71
|
+
text-decoration: none;
|
72
|
+
border: none;
|
73
|
+
background: none;
|
74
|
+
cursor: pointer;
|
75
|
+
}
|
76
|
+
|
77
|
+
.flash {
|
78
|
+
position: relative;
|
79
|
+
margin-bottom: 5px;
|
80
|
+
border-radius: 3px;
|
81
|
+
padding: 8px 20px 8px 20px;
|
82
|
+
}
|
83
|
+
|
84
|
+
.flash.notice {
|
85
|
+
color: rgb(70, 136, 71);
|
86
|
+
background-color: rgba(223, 240, 216, 0.9);
|
87
|
+
}
|
88
|
+
|
89
|
+
.flash.error {
|
90
|
+
color: rgb(185, 74, 72);
|
91
|
+
background-color: rgba(242, 222, 222, 0.9);
|
92
|
+
}
|
93
|
+
|
94
|
+
%body
|
95
|
+
%h1 Files
|
96
|
+
%table.pure-table.pure-table-bordered.wide
|
97
|
+
%thead
|
98
|
+
%tr
|
99
|
+
%th #
|
100
|
+
%th URL
|
101
|
+
%th Filename
|
102
|
+
%th Accessed
|
103
|
+
%th Accessed at
|
104
|
+
%th Created at
|
105
|
+
%th MIME
|
106
|
+
%th
|
107
|
+
%tbody
|
108
|
+
-@hdata.each_with_index do |doc, i|
|
109
|
+
%tr
|
110
|
+
%td=i
|
111
|
+
%td
|
112
|
+
%a{href: doc[:url]} #{doc[:url]}
|
113
|
+
%td=doc[:original_filename]
|
114
|
+
%td=doc[:access_count]
|
115
|
+
%td=doc[:access_time]
|
116
|
+
%td=doc[:created_time]
|
117
|
+
%td=doc[:mime]
|
118
|
+
%td
|
119
|
+
%form{ :action => "/delete/#{doc[:shortened]}", :method => 'post' }
|
120
|
+
%button.delete{ :type => 'submit'}Delete
|
121
|
+
|
122
|
+
%p
|
123
|
+
=styled_flash
|
@@ -3,10 +3,17 @@
|
|
3
3
|
%head
|
4
4
|
%title OmniFiles statistics
|
5
5
|
:css
|
6
|
-
|
7
|
-
|
6
|
+
body {
|
7
|
+
padding: 5px;
|
8
|
+
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
9
|
+
}
|
10
|
+
|
11
|
+
.left { width: 20%; float: left; }
|
12
|
+
|
13
|
+
.right { overflow: auto; }
|
14
|
+
|
8
15
|
%body
|
9
|
-
%h1 Statistics for #{@shortened}
|
16
|
+
%h1 Statistics for #{@hdata[:shortened]}
|
10
17
|
#container
|
11
18
|
.left
|
12
19
|
%p URL:
|
@@ -17,9 +24,12 @@
|
|
17
24
|
%p MIME:
|
18
25
|
.right
|
19
26
|
%p
|
20
|
-
%a
|
21
|
-
%p=@original_filename
|
22
|
-
%p=@access_count
|
23
|
-
%p=@access_time
|
24
|
-
%p=@created_time
|
25
|
-
%p=@mime
|
27
|
+
%a{href: @hdata[:url]} #{@hdata[:url]}
|
28
|
+
%p=@hdata[:original_filename]
|
29
|
+
%p=@hdata[:access_count]
|
30
|
+
%p=@hdata[:access_time]
|
31
|
+
%p=@hdata[:created_time]
|
32
|
+
%p=@hdata[:mime]
|
33
|
+
|
34
|
+
%p
|
35
|
+
=styled_flash
|
data/omnifiles.gemspec
CHANGED
@@ -26,5 +26,7 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_runtime_dependency "bson_ext", "~> 1.12.0"
|
27
27
|
spec.add_runtime_dependency "haml", "~> 4.0.0"
|
28
28
|
spec.add_runtime_dependency "settingslogic", "~> 2.0.0"
|
29
|
+
spec.add_runtime_dependency "psych", "~> 2.0.0"
|
29
30
|
spec.add_runtime_dependency "thin", "~> 1.6.0"
|
31
|
+
spec.add_runtime_dependency "sinatra-flash", "~> 0.3.0"
|
30
32
|
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- theirix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 2.0.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: psych
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 2.0.0
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 2.0.0
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: thin
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,6 +150,20 @@ dependencies:
|
|
136
150
|
- - "~>"
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: 1.6.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: sinatra-flash
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.3.0
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.3.0
|
139
167
|
description: File storage and URL shortener.
|
140
168
|
email:
|
141
169
|
- theirix@gmail.com
|
@@ -160,6 +188,7 @@ files:
|
|
160
188
|
- lib/omnifiles/shortener.rb
|
161
189
|
- lib/omnifiles/storage.rb
|
162
190
|
- lib/omnifiles/version.rb
|
191
|
+
- lib/omnifiles/views/index.haml
|
163
192
|
- lib/omnifiles/views/stat.haml
|
164
193
|
- omnifiles.gemspec
|
165
194
|
homepage: ''
|