omnifiles 0.2.1 → 0.3.0

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: f4ba409941d3f9b2cfcd8514723a1e0631afe42b
4
- data.tar.gz: ce8cf3dd318b202eac04940ad6f6f4c434a269ad
3
+ metadata.gz: 3cdc7404e8fb3bf594a9c686e40dec5a1bcff348
4
+ data.tar.gz: 7afd2f9c25f9a4c372e99dc82203974a795712ab
5
5
  SHA512:
6
- metadata.gz: d4bed8c5632f8f05a46f567b4f142aa4cfdfe7149481ab4235c0d8bfd7501d9682b3ed410b9d591f89ecc0256b0bbcbfb4e7e60e067a2531af33499ba0df4d5c
7
- data.tar.gz: 798149e7e66db1daa3a84fde24b4c6a0b107f91435d0a02db1a3fcd2da69031c80e3a06c3e623f4e2edcd88dd8a6b8b7f127d0a61c9003b1b857a0d962a08f38
6
+ metadata.gz: 0ca79679d327f92bfcdba960a2c3cda44222d3daad86aa933f31a7bfc2dd999b7783ff7469a960cc65609295633dc31ad8782dd8632b62119b2c44b5ee051776
7
+ data.tar.gz: 3f9b7eed3669d4f685962f6147ac4a8eb9c8060faa2dc70956565d4f8b5d4183c4a3d78d909e1c0f4a3307dd36bee2ead667d04099cbe69dc5c0ff31eb3127c0
@@ -6,3 +6,4 @@ development:
6
6
  name: omnifiles
7
7
  auth_opaque: alongopaquekey
8
8
  auth_password: secret
9
+ session_secret: SECRET
@@ -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
- @url = url('/f/'+name)
46
- if data['original_filename']
47
- @original_filename = URI.unescape data['original_filename']
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
- @original_filename = "<i>Not provided</i>"
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
- haml :stat
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
@@ -1,3 +1,4 @@
1
+ require 'psych'
1
2
  require 'settingslogic'
2
3
 
3
4
  module OmniFiles
@@ -9,4 +10,4 @@ module OmniFiles
9
10
  namespace ENV['RACK_ENV'] || 'development'
10
11
  load!
11
12
  end
12
- end
13
+ end
@@ -6,7 +6,7 @@ require 'digest/md5'
6
6
  module OmniFiles
7
7
 
8
8
  class UrlShortener
9
- def initialize salt, bytes_used=1
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module OmniFiles
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -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
- .left { width: 20%; float: left; }
7
- .right { overflow: auto; }
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(href=@url) #{@url}
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
@@ -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.2.1
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-02-22 00:00:00.000000000 Z
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: ''