omnifiles 0.1.2 → 0.2.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: e77c0d22099ad90e4c8b8b911bf02f75772b8863
4
- data.tar.gz: a8b8677804088a48c6074f85e648b221db58396a
3
+ metadata.gz: 61daf02bef5c9ccee10e457e697b86c126032990
4
+ data.tar.gz: 05366a0ad9cce4edb2fe36cc98255327282d9767
5
5
  SHA512:
6
- metadata.gz: 725524c2140e85489a1f67b12a92576e560e106af6cebc447a4a35984dbd2bdb5565f37f11dfbb6fd4c85c5c8e3dcb0bcf5f23fb93d902d29d4a0acea7a3499b
7
- data.tar.gz: 8bfe2cd8971e47799f2bc6d4d556c34916039fd5518cf0328bb0d9542d8672ca8d8da9957040403618416458e6bc445efc61f712517aabca2dc568b407e7975c
6
+ metadata.gz: e0d20083542daa12cd7be3d7a34b38707619e28d09922bc35e1de6f86aa4e82f1864eb8460ba6926989e13b69afe44fbc923e9d162653ef09039c3da96a2e555
7
+ data.tar.gz: a3a05d6339b2b6e49d465f91c6daba16a267f809b6d79a405cea74c68451b4caf3ca3d2cea624670da25a3188f3af753c171884b74421e41e5f5e652db35121b
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  File storage and shortener server.
8
8
 
9
- OmniFiles is built with Sinatra and Rack and uses an sqlite database to store shortened
9
+ OmniFiles is built with Sinatra and Rack and uses an Mongo database to store shortened
10
10
  urls and statistics.
11
11
 
12
12
  ## Installation
@@ -1,5 +1,8 @@
1
1
  development:
2
2
  storage_dir: storage
3
- db: omnifiles.sqlite3
3
+ db:
4
+ host: localhost
5
+ port: 27017
6
+ name: omnifiles
4
7
  auth_opaque: alongopaquekey
5
- auth_password: secret
8
+ auth_password: secret
@@ -34,6 +34,14 @@ module OmniFiles
34
34
  store_file
35
35
  end
36
36
 
37
+ def format_time_str time
38
+ if time
39
+ time.localtime.to_s
40
+ else
41
+ '<i>Not yet</i>'
42
+ end
43
+ end
44
+
37
45
  get '/stat/:name' do |name|
38
46
  logger.info "Route GET stat #{name}"
39
47
 
@@ -48,7 +56,9 @@ module OmniFiles
48
56
  else
49
57
  @original_filename = "<i>Not provided</i>"
50
58
  end
51
- @access_count = data['accessed']
59
+ @access_count = data['accessed']['count']
60
+ @access_time = format_time_str data['accessed']['time']
61
+ @created_time = format_time_str data['created']['time']
52
62
  @mime = data['mime']
53
63
  @shortened = name
54
64
 
@@ -117,4 +127,4 @@ module OmniFiles
117
127
 
118
128
  end
119
129
 
120
- end
130
+ end
@@ -17,7 +17,7 @@ module OmniFiles
17
17
 
18
18
  halt 500, "Wrong URL" if name != BaseApp.sanitize(name)
19
19
 
20
- data = @storage.get_file name
20
+ data = @storage.get_file_and_bump name
21
21
  logger.info "Data #{data}"
22
22
  halt 404, "File not found" unless data
23
23
 
@@ -28,7 +28,7 @@ module OmniFiles
28
28
  mime = data['mime']
29
29
  mime = 'application/octet-stream' unless mime && mime != ''
30
30
 
31
- logger.info "Data #{data}, file #{path}, was at #{filename}"
31
+ logger.info "File '#{path}' was named '#{filename}'"
32
32
 
33
33
  if filename && !filename.empty?
34
34
  headers 'X-Original-Filename' => filename
@@ -38,4 +38,4 @@ module OmniFiles
38
38
 
39
39
  end
40
40
 
41
- end
41
+ end
@@ -16,8 +16,7 @@ module OmniFiles
16
16
  before do
17
17
  logger.info "Fired " + self.class.to_s
18
18
  FileUtils.mkdir_p(Settings.storage_dir)
19
- FileUtils.mkdir_p(File.dirname(Settings.db))
20
- @storage = Storage.new Settings.db, logger
19
+ @storage = Storage.new Settings.db.host, Settings.db.port, Settings.db.name, logger
21
20
  end
22
21
 
23
22
  def self.sanitize s
@@ -25,4 +24,4 @@ module OmniFiles
25
24
  end
26
25
  end
27
26
 
28
- end
27
+ end
@@ -2,19 +2,23 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'digest/md5'
5
- require 'sqlite3'
5
+ require 'bson'
6
+ require 'mongo'
6
7
 
7
8
  module OmniFiles
8
9
 
9
- class Storage
10
+ class Storage
11
+ def initialize mongo_host, mongo_port, mongo_name, logger
12
+ @logger = logger
13
+ client = Mongo::MongoClient.new(mongo_host, mongo_port)
14
+ raise 'No mongo found' unless client
15
+ db = client.db(mongo_name)
16
+ raise 'No mongo db found' unless db
17
+ @logger.info "Mongo collections " + db.collection_names.join(',')
18
+ @coll = db.collection('files')
19
+ raise 'Cannot use collection' unless @coll
10
20
 
11
- def initialize db_filename, logger
12
- @logger = logger
13
- @db = SQLite3::Database.new(db_filename, :results_as_hash => true)
14
- if (@db.table_info('files') or []) == []
15
- Storage.create_schema @db
16
- end
17
- @shortener = UrlShortener.new(SecureRandom.hex(8))
21
+ @shortener = UrlShortener.new(SecureRandom.hex(8))
18
22
  end
19
23
 
20
24
  # returns shortened url
@@ -26,37 +30,35 @@ module OmniFiles
26
30
  @logger.info "Hashing value " + hashing
27
31
  shortened = @shortener.shorten hashing
28
32
  counter += 1
29
- unique_id = @db.get_first_row("SELECT COUNT(shortened) FROM files WHERE shortened = ?", [shortened])[0] == 0
30
- end until unique_id
33
+ same_shortened = @coll.find_one({shortened: shortened}, :fields => [ "_id" ])
34
+ @logger.info same_shortened
35
+ raise 'Something goes wrong' if counter > 100
36
+ end while same_shortened
31
37
  shortened
32
38
  end
33
39
 
34
40
  def put_file shortened, filename, mime
35
- @db.execute("INSERT INTO files (original_filename, shortened, mime, accessed)"+
36
- "VALUES ( ?, ?, ?, 0 )",
37
- [filename, shortened, mime])
41
+ doc = { original_filename: filename, shortened: shortened, mime: mime,
42
+ accessed: { count: 0 }, created: { time: Time.now.utc } }
43
+ res = @coll.insert(doc)
44
+ @logger.info "mongo put result: #{res}"
38
45
  end
39
46
 
40
47
  # returns full url
41
48
  def get_file shortened
42
- data = @db.get_first_row("SELECT * FROM files WHERE shortened = ?", [shortened])
43
- if data
44
- @db.execute("UPDATE files SET accessed = accessed + 1 WHERE shortened = ?", [shortened])
45
- end
46
- data
49
+ @coll.find_one({shortened: shortened})
47
50
  end
48
51
 
49
- private
50
- def self.create_schema db
51
- db.execute <<-SQL
52
- CREATE TABLE files (
53
- shortened TEXT NOT NULL,
54
- original_filename TEXT,
55
- mime TEXT,
56
- accessed INTEGER);
57
- CREATE INDEX shortened_INDEX ON files (shortened);
58
- SQL
52
+ # returns full url and update statistics
53
+ def get_file_and_bump shortened
54
+ data = @coll.find_one({shortened: shortened})
55
+ return nil unless data
56
+ @coll.update({ _id: data["_id"]}, {
57
+ "$inc" => { "accessed.count" => 1 },
58
+ "$set" => { "accessed.time" => Time.now.utc } })
59
+ @coll.find_one({ _id: data["_id"]})
59
60
  end
60
- end
61
61
 
62
- end
62
+ end
63
+
64
+ end
@@ -1,3 +1,3 @@
1
1
  module OmniFiles
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -10,10 +10,14 @@
10
10
  %p URL:
11
11
  %p Original name:
12
12
  %p Access count:
13
+ %p Accessed at:
14
+ %p Created at:
13
15
  %p MIME:
14
16
  .right
15
17
  %p
16
18
  %a(href=@url) #{@url}
17
19
  %p=@original_filename
18
20
  %p=@access_count
19
- %p=@mime
21
+ %p=@access_time
22
+ %p=@created_time
23
+ %p=@mime
data/omnifiles.gemspec CHANGED
@@ -23,7 +23,8 @@ Gem::Specification.new do |spec|
23
23
  spec.add_runtime_dependency "sinatra", "~> 1.4.5"
24
24
  spec.add_runtime_dependency "sinatra-assetpack", "~> 0.3.3"
25
25
  spec.add_runtime_dependency "ruby-filemagic", "~> 0.6.0"
26
- spec.add_runtime_dependency "sqlite3", "~> 1.3.10"
26
+ spec.add_runtime_dependency "mongo", "~> 1.12.0"
27
+ spec.add_runtime_dependency "bson_ext", "~> 1.12.0"
27
28
  spec.add_runtime_dependency "haml", "~> 4.0.0"
28
29
  spec.add_runtime_dependency "settingslogic", "~> 2.0.0"
29
30
  spec.add_runtime_dependency "thin", "~> 1.6.0"
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.2
4
+ version: 0.2.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-01-08 00:00:00.000000000 Z
11
+ date: 2015-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,19 +81,33 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.6.0
83
83
  - !ruby/object:Gem::Dependency
84
- name: sqlite3
84
+ name: mongo
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 1.3.10
89
+ version: 1.12.0
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 1.3.10
96
+ version: 1.12.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: bson_ext
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.12.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.12.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: haml
99
113
  requirement: !ruby/object:Gem::Requirement