saphira 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +29 -0
  3. data/Rakefile +39 -0
  4. data/app/assets/images/saphira/icons/32x32/direction_up.png +0 -0
  5. data/app/assets/images/saphira/icons/32x32/file.png +0 -0
  6. data/app/assets/images/saphira/icons/32x32/folder.png +0 -0
  7. data/app/assets/javascripts/saphira/application.js +9 -0
  8. data/app/assets/javascripts/saphira/file_items.js +2 -0
  9. data/app/assets/stylesheets/saphira/application.css +7 -0
  10. data/app/assets/stylesheets/saphira/file_items.css +17 -0
  11. data/app/assets/stylesheets/scaffold.css +56 -0
  12. data/app/controllers/saphira/application_controller.rb +4 -0
  13. data/app/controllers/saphira/file_items_controller.rb +104 -0
  14. data/app/helpers/saphira/application_helper.rb +4 -0
  15. data/app/helpers/saphira/file_items_helper.rb +4 -0
  16. data/app/models/saphira/file_item.rb +83 -0
  17. data/app/views/layouts/saphira/application.html.erb +14 -0
  18. data/app/views/saphira/file_items/_form.html.erb +33 -0
  19. data/app/views/saphira/file_items/edit_file.html.erb +6 -0
  20. data/app/views/saphira/file_items/edit_folder.html.erb +6 -0
  21. data/app/views/saphira/file_items/index.html.erb +30 -0
  22. data/app/views/saphira/file_items/new_file.html.erb +5 -0
  23. data/app/views/saphira/file_items/new_folder.html.erb +5 -0
  24. data/app/views/saphira/file_items/show.html.erb +39 -0
  25. data/config/initializers/acts_as_taggable_on.rb +1 -0
  26. data/config/initializers/awesome_nested_set.rb +1 -0
  27. data/config/initializers/dragonfly.rb +7 -0
  28. data/config/initializers/exifr.rb +2 -0
  29. data/config/initializers/friendly_id.rb +1 -0
  30. data/config/routes.rb +5 -0
  31. data/db/migrate/20110904170134_create_saphira_file_items.rb +23 -0
  32. data/db/migrate/20110904170241_acts_as_taggable_on_migration.rb +28 -0
  33. data/lib/saphira/engine.rb +5 -0
  34. data/lib/saphira/version.rb +3 -0
  35. data/lib/saphira.rb +4 -0
  36. data/lib/tasks/saphira_tasks.rake +4 -0
  37. data/test/dummy/Guardfile +8 -0
  38. data/test/dummy/Rakefile +7 -0
  39. data/test/dummy/app/assets/javascripts/application.js +9 -0
  40. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  41. data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
  42. data/test/dummy/app/controllers/application_controller.rb +3 -0
  43. data/test/dummy/app/helpers/application_helper.rb +2 -0
  44. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  45. data/test/dummy/config/application.rb +45 -0
  46. data/test/dummy/config/boot.rb +10 -0
  47. data/test/dummy/config/cucumber.yml +8 -0
  48. data/test/dummy/config/database.yml +28 -0
  49. data/test/dummy/config/environment.rb +5 -0
  50. data/test/dummy/config/environments/development.rb +30 -0
  51. data/test/dummy/config/environments/production.rb +60 -0
  52. data/test/dummy/config/environments/test.rb +42 -0
  53. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  54. data/test/dummy/config/initializers/inflections.rb +10 -0
  55. data/test/dummy/config/initializers/mime_types.rb +5 -0
  56. data/test/dummy/config/initializers/secret_token.rb +7 -0
  57. data/test/dummy/config/initializers/session_store.rb +8 -0
  58. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  59. data/test/dummy/config/locales/en.yml +5 -0
  60. data/test/dummy/config/routes.rb +4 -0
  61. data/test/dummy/config.ru +4 -0
  62. data/test/dummy/db/development.sqlite3 +0 -0
  63. data/test/dummy/db/migrate/20110904172951_create_saphira_file_items.rb +23 -0
  64. data/test/dummy/db/migrate/20110904172952_acts_as_taggable_on_migration.rb +28 -0
  65. data/test/dummy/db/schema.rb +54 -0
  66. data/test/dummy/db/test.sqlite3 +0 -0
  67. data/test/dummy/features/manage_file_items.feature +35 -0
  68. data/test/dummy/features/step_definitions/file_item_steps.rb +18 -0
  69. data/test/dummy/features/step_definitions/web_steps.rb +211 -0
  70. data/test/dummy/features/support/env.rb +50 -0
  71. data/test/dummy/features/support/files/eos-550d-wrong-orientation.jpg +0 -0
  72. data/test/dummy/features/support/paths.rb +38 -0
  73. data/test/dummy/features/support/selectors.rb +39 -0
  74. data/test/dummy/lib/tasks/cucumber.rake +65 -0
  75. data/test/dummy/log/development.log +524 -0
  76. data/test/dummy/log/test.log +362 -0
  77. data/test/dummy/public/404.html +26 -0
  78. data/test/dummy/public/422.html +26 -0
  79. data/test/dummy/public/500.html +26 -0
  80. data/test/dummy/public/favicon.ico +0 -0
  81. data/test/dummy/script/cucumber +10 -0
  82. data/test/dummy/script/rails +6 -0
  83. data/test/dummy/system/files/development/2011/09/04/20_16_51_527_IMG_0074.JPG +0 -0
  84. data/test/dummy/system/files/development/2011/09/04/20_16_51_527_IMG_0074.JPG.meta +1 -0
  85. data/test/dummy/system/files/test/2011/09/04/20_14_52_22_eos_550d_wrong_orientation.jpg +0 -0
  86. data/test/dummy/system/files/test/2011/09/04/20_14_52_22_eos_550d_wrong_orientation.jpg.meta +1 -0
  87. data/test/dummy/tmp/cache/assets/C54/230/sprockets%2F63597bd80af49501176a9c782c200818 +0 -0
  88. data/test/dummy/tmp/cache/assets/C8A/C90/sprockets%2Fb0034d98e259fe21084231df778476e5 +0 -0
  89. data/test/dummy/tmp/cache/assets/CBB/220/sprockets%2Fe50398a56291b292932098dbaf6f60e7 +0 -0
  90. data/test/dummy/tmp/cache/assets/CED/3A0/sprockets%2F5598ef34994d21041804d8edaae45e75 +0 -0
  91. data/test/dummy/tmp/cache/assets/D0F/940/sprockets%2Fe5a0c84816880ab73280e1d7c6c6b53f +0 -0
  92. data/test/dummy/tmp/cache/assets/D25/A40/sprockets%2F3597585a09358e74b9addba0fc954d87 +0 -0
  93. data/test/dummy/tmp/cache/assets/D28/040/sprockets%2F54bad3bcb77f949259960f3f80837af9 +0 -0
  94. data/test/dummy/tmp/cache/assets/D8B/C20/sprockets%2F5b4cb2011e99baa41b98122dabfe94d0 +0 -0
  95. data/test/dummy/tmp/cache/assets/DA9/040/sprockets%2F840de459a6d1c9d87c8dcaf24f128b6c +0 -0
  96. data/test/dummy/tmp/cache/assets/DD1/040/sprockets%2Fd417bfb346f42b08fa70df9d17c9a4ee +0 -0
  97. data/test/dummy/tmp/cache/assets/DF8/F80/sprockets%2Fdda7c25be0e8e262ebc270da9775abd4 +0 -0
  98. data/test/dummy/tmp/cache/assets/E32/DF0/sprockets%2Fbd8fed5e48cbc136c85e9c4ab6d1e3b4 +0 -0
  99. data/test/dummy/tmp/dragonfly/cache/body/11/4316e3371abd942602830d5ce3e55d4ba94ec5 +0 -0
  100. data/test/dummy/tmp/dragonfly/cache/body/3e/f63b348d8ad48be7f3d8869f255af8d5d8b19f +8982 -0
  101. data/test/dummy/tmp/dragonfly/cache/body/61/e9711fd55eccdf62882cb8d127b22664f7023f +3 -0
  102. data/test/dummy/tmp/dragonfly/cache/body/a1/d3d5a6ed952ccf4816b4a96d4767ce9bae8164 +5 -0
  103. data/test/dummy/tmp/dragonfly/cache/body/c2/d1fe276d6e527c155855e99dc19d239b6d71f3 +7 -0
  104. data/test/dummy/tmp/dragonfly/cache/body/cb/052a86fcf83c49b8a1c5ca5f29b11ba31d4038 +17 -0
  105. data/test/dummy/tmp/dragonfly/cache/body/d4/ff9b03ee9e54acce72e6b793693031079eb150 +332 -0
  106. data/test/dummy/tmp/dragonfly/cache/meta/24/d0aebc1b6d4ac3b10caa6cfabf89b0ad8551c5 +0 -0
  107. data/test/dummy/tmp/dragonfly/cache/meta/37/fb962d39887389e020d58ef1f745ef1a6107cc +0 -0
  108. data/test/dummy/tmp/dragonfly/cache/meta/78/da9e9f151eb605b427b43e2098640de3fd4a6d +0 -0
  109. data/test/dummy/tmp/dragonfly/cache/meta/8a/00f63a175cfe09352e9103621040457aafc9e8 +0 -0
  110. data/test/dummy/tmp/dragonfly/cache/meta/a0/d65624dcf4c7e6827639f25060a3bf4bd6020d +0 -0
  111. data/test/dummy/tmp/dragonfly/cache/meta/ee/fe74949a8c2a0bbc077385a12944d9f98a12e0 +0 -0
  112. data/test/dummy/tmp/dragonfly/cache/meta/f9/67ac04386c59253bd80f4034d18af166cc5691 +0 -0
  113. data/test/fixtures/saphira/file_items.yml +25 -0
  114. data/test/functional/saphira/file_items_controller_test.rb +51 -0
  115. data/test/integration/navigation_test.rb +10 -0
  116. data/test/saphira_test.rb +7 -0
  117. data/test/test_helper.rb +10 -0
  118. data/test/unit/helpers/saphira/file_items_helper_test.rb +6 -0
  119. data/test/unit/saphira/file_item_test.rb +9 -0
  120. metadata +276 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 Paul Spieker
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ Saphira
2
+ =======
3
+
4
+ Saphira is a file manager written for RoR using dragonfly. It's created for the great Railsyard CMS, but it's using the mountable engines introduced in rails 3.1, so it would be useable without RY as well.
5
+
6
+ Currently this project is under development and not finished at all but in order to have it under version control, it's already available on github.
7
+
8
+ Features
9
+ --------
10
+ * Create folders
11
+ * Upload files
12
+ * Tag files
13
+ * Automatically read EXIF data from images
14
+
15
+ To-Do
16
+ -----
17
+ * Link for file download
18
+ * Manage authorizations
19
+ * WebDav access
20
+ * Search files
21
+
22
+ Requirements
23
+ ------------
24
+ * Rails 3.1.x
25
+ * Some gems - check Gemfile
26
+
27
+ Installation
28
+ ------------
29
+ Add the gem to your gemfile: `gem 'saphira', :git => 'git://github.com/spieker/saphira.git'` and add `mount Saphira::Engine => "/saphira", :as => 'saphira'` to your `routes.rb` file to mount the engine. The file manager should be available at `http://localhost:3000/saphira` then.
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Saphira'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+ Bundler::GemHelper.install_tasks
28
+
29
+ require 'rake/testtask'
30
+
31
+ Rake::TestTask.new(:test) do |t|
32
+ t.libs << 'lib'
33
+ t.libs << 'test'
34
+ t.pattern = 'test/**/*_test.rb'
35
+ t.verbose = false
36
+ end
37
+
38
+
39
+ task :default => :test
@@ -0,0 +1,9 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ //= require jquery
8
+ //= require jquery_ujs
9
+ //= require_tree .
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,7 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require_self
6
+ *= require_tree .
7
+ */
@@ -0,0 +1,17 @@
1
+ div.information {
2
+ float: right;
3
+ }
4
+
5
+ table.key-value {
6
+ tr {
7
+ td.key {
8
+ background-color: #DDDDDD;
9
+ }
10
+ td.value {
11
+ background-color: #EEEEEE;
12
+ }
13
+ th {
14
+ background-color: #DDDDDD;
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,56 @@
1
+ body { background-color: #fff; color: #333; }
2
+
3
+ body, p, ol, ul, td {
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ pre {
10
+ background-color: #eee;
11
+ padding: 10px;
12
+ font-size: 11px;
13
+ }
14
+
15
+ a { color: #000; }
16
+ a:visited { color: #666; }
17
+ a:hover { color: #fff; background-color:#000; }
18
+
19
+ div.field, div.actions {
20
+ margin-bottom: 10px;
21
+ }
22
+
23
+ #notice {
24
+ color: green;
25
+ }
26
+
27
+ .field_with_errors {
28
+ padding: 2px;
29
+ background-color: red;
30
+ display: table;
31
+ }
32
+
33
+ #error_explanation {
34
+ width: 450px;
35
+ border: 2px solid red;
36
+ padding: 7px;
37
+ padding-bottom: 0;
38
+ margin-bottom: 20px;
39
+ background-color: #f0f0f0;
40
+ }
41
+
42
+ #error_explanation h2 {
43
+ text-align: left;
44
+ font-weight: bold;
45
+ padding: 5px 5px 5px 15px;
46
+ font-size: 12px;
47
+ margin: -7px;
48
+ margin-bottom: 0px;
49
+ background-color: #c00;
50
+ color: #fff;
51
+ }
52
+
53
+ #error_explanation ul li {
54
+ font-size: 12px;
55
+ list-style: square;
56
+ }
@@ -0,0 +1,4 @@
1
+ module Saphira
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,104 @@
1
+ module Saphira
2
+ class FileItemsController < ApplicationController
3
+ # GET /file_items
4
+ # GET /file_items.json
5
+ def index
6
+ @file_item = FileItem.new(:name => 'ROOT')
7
+ @file_items = FileItem.where(:parent_id => nil).all
8
+
9
+ p "*"*80
10
+ p @file_item
11
+
12
+ respond_to do |format|
13
+ format.html # index.html.erb
14
+ format.json { render json: @file_items }
15
+ end
16
+ end
17
+
18
+ # GET /file_items/1
19
+ # GET /file_items/1.json
20
+ def show
21
+ @file_item = FileItem.find_by_path(params[:id])
22
+
23
+ respond_to do |format|
24
+ format.html do
25
+ case @file_item.item_type
26
+ when Saphira::FileItem::TYPE_FOLDER
27
+ @file_items = @file_item.children
28
+ render :action => 'index'
29
+ else
30
+ render
31
+ end
32
+ end
33
+ format.json { render json: @file_item }
34
+ end
35
+ end
36
+
37
+ # GET /file_items/new
38
+ # GET /file_items/new.json
39
+ def new
40
+ @file_item = FileItem.new
41
+ @file_item.item_type = params[:type]
42
+ @file_item.parent_id = params[:parent_id]
43
+
44
+ respond_to do |format|
45
+ format.html { render :action => "new_#{@file_item.item_type}" }
46
+ format.json { render json: @file_item }
47
+ end
48
+ end
49
+
50
+ # GET /file_items/1/edit
51
+ def edit
52
+ @file_item = FileItem.find_by_path(params[:id])
53
+
54
+ respond_to do |format|
55
+ format.html { render :action => "edit_#{@file_item.item_type}" }
56
+ format.json { render json: @file_item }
57
+ end
58
+ end
59
+
60
+ # POST /file_items
61
+ # POST /file_items.json
62
+ def create
63
+ @file_item = FileItem.new(params[:file_item])
64
+
65
+ respond_to do |format|
66
+ if @file_item.save
67
+ format.html { redirect_to @file_item, notice: 'File item was successfully created.' }
68
+ format.json { render json: @file_item, status: :created, location: @file_item }
69
+ else
70
+ format.html { render action: "new_#{@file_item.item_type}" }
71
+ format.json { render json: @file_item.errors, status: :unprocessable_entity }
72
+ end
73
+ end
74
+ end
75
+
76
+ # PUT /file_items/1
77
+ # PUT /file_items/1.json
78
+ def update
79
+ @file_item = FileItem.find_by_path(params[:id])
80
+
81
+ respond_to do |format|
82
+ if @file_item.update_attributes(params[:file_item])
83
+ format.html { redirect_to @file_item, notice: 'File item was successfully updated.' }
84
+ format.json { head :ok }
85
+ else
86
+ format.html { render action: "edit_#{@file_item.item_type}" }
87
+ format.json { render json: @file_item.errors, status: :unprocessable_entity }
88
+ end
89
+ end
90
+ end
91
+
92
+ # DELETE /file_items/1
93
+ # DELETE /file_items/1.json
94
+ def destroy
95
+ @file_item = FileItem.find_by_path(params[:id])
96
+ @file_item.destroy
97
+
98
+ respond_to do |format|
99
+ format.html { redirect_to file_items_url }
100
+ format.json { head :ok }
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,4 @@
1
+ module Saphira
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Saphira
2
+ module FileItemsHelper
3
+ end
4
+ end
@@ -0,0 +1,83 @@
1
+ module Saphira
2
+ class FileItem < ActiveRecord::Base
3
+ extend FriendlyId
4
+
5
+ TYPE_FILE = 'file'
6
+ TYPE_FOLDER = 'folder'
7
+
8
+ serialize :dynamic_attributes
9
+
10
+ validates_presence_of :name
11
+ validates_uniqueness_of :name, :scope => :parent_id
12
+
13
+ acts_as_nested_set
14
+ friendly_id :name, :use => :scoped, :scope => :parent_id
15
+ acts_as_taggable
16
+ file_accessor :file do
17
+ after_assign do |img|
18
+ if (img.image?)
19
+ case img.mime_type
20
+ when 'image/jpeg'
21
+ exifr = EXIFR::JPEG.new(img.path.to_s)
22
+ when 'image/tiff'
23
+ exifr = EXIFR::TIFF.new(img.path.to_s)
24
+ end
25
+ # http://www.dcresource.com/reviews/exif_key.html
26
+ if exifr
27
+ self.attr_set :field_image_capture_date, exifr.date_time_original
28
+ self.attr_set :field_image_exposure_time, exifr.exposure_time
29
+ self.attr_set :field_image_f_number, exifr.f_number
30
+ self.attr_set :field_image_capture_date, exifr.date_time_original
31
+ self.attr_set :field_image_make, exifr.make
32
+ self.attr_set :field_image_model, exifr.model
33
+ self.attr_set :field_image_orientation, exifr.orientation.to_i
34
+
35
+ # Some cameras are having a orientation sensor. The output is saved in the
36
+ # EXIF orientation attribute. If the orientation is set, try to rotate the
37
+ # image like specified (see: http://www.impulseadventure.com/photo/exif-orientation.html)
38
+ if exifr.orientation
39
+ case exifr.orientation.to_i
40
+ when 8
41
+ img.process!(:rotate, 270)
42
+ self.attr_set :field_image_orientation_transformed, true
43
+ when 3
44
+ img.process!(:rotate, 180)
45
+ self.attr_set :field_image_orientation_transformed, true
46
+ when 6
47
+ img.process!(:rotate, 90)
48
+ self.attr_set :field_image_orientation_transformed, true
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ belongs_to :user
57
+
58
+ # generate the path of this item, to find it easier
59
+ before_save do
60
+ parent = self.parent
61
+ if parent
62
+ self.path = parent.path+'/'+self.slug
63
+ else
64
+ self.path = self.slug
65
+ end
66
+ end
67
+
68
+ def attr_set(name, value)
69
+ self.dynamic_attributes ||= {}
70
+ self.dynamic_attributes[name.to_sym] = value
71
+ self.dynamic_attributes = self.dynamic_attributes.delete_if { |k, v| v.blank? }
72
+ end
73
+
74
+ def attr_get(name)
75
+ self.dynamic_attributes ||= {}
76
+ self.dynamic_attributes[name.to_sym]
77
+ end
78
+
79
+ def to_param
80
+ self.path.empty? ? super : self.path
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Saphira</title>
5
+ <%= stylesheet_link_tag "saphira/application" %>
6
+ <%= javascript_include_tag "saphira/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,33 @@
1
+ <%= form_for(@file_item) do |f| %>
2
+ <% if @file_item.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@file_item.errors.count, "error") %> prohibited this file_item from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @file_item.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :name %><br />
16
+ <%= f.text_field :name %>
17
+ </div>
18
+ <% unless @file_item.item_type == Saphira::FileItem::TYPE_FOLDER %>
19
+ <div class="field">
20
+ <%= f.label :file %><br />
21
+ <%= f.file_field :file %>
22
+ </div>
23
+ <% end %>
24
+ <div class="field">
25
+ <%= f.label :tag_list %><br />
26
+ <%= f.text_field :tag_list %>
27
+ </div>
28
+ <div class="actions">
29
+ <%= f.hidden_field :item_type %>
30
+ <%= f.hidden_field :parent_id %>
31
+ <%= f.submit 'Create' %>
32
+ </div>
33
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing file</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @file_item %> |
6
+ <%= link_to 'Back', file_items_path %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing folder</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', @file_item %> |
6
+ <%= link_to 'Back', file_items_path %>
@@ -0,0 +1,30 @@
1
+ <h1>Listing <%= @file_item.name %></h1>
2
+
3
+ <table>
4
+ <% unless @file_item.id.nil? %>
5
+ <tr>
6
+ <td><%= link_to image_tag('saphira/icons/32x32/direction_up.png'), (@file_item.parent || file_items_path) %></td>
7
+ <td><%= link_to '..', (@file_item.parent || file_items_path) %></td>
8
+ <td></td>
9
+ <td></td>
10
+ </tr>
11
+ <% end %>
12
+ <% @file_items.each do |file_item| %>
13
+ <tr class="<%= file_item.item_type %> <%= file_item.slug %>">
14
+ <td><%= link_to image_tag('saphira/icons/32x32/'+file_item.item_type+'.png'), file_item %></td>
15
+ <td><%= link_to file_item.name, file_item %></td>
16
+ <td><%= file_item.file.mime_type if file_item.file %></td>
17
+ <td class="actions"><%= link_to 'Destroy', file_item, confirm: 'Are you sure?', method: :delete, id: "saphira-action-destroy-#{file_item.slug}" %></td>
18
+ </tr>
19
+ <% end %>
20
+ </table>
21
+
22
+ <br />
23
+
24
+ <%= link_to 'New File', new_file_item_path(:type => Saphira::FileItem::TYPE_FILE, :parent_id => @file_item.id) %>
25
+ <%= link_to 'New Folder', new_file_item_path(:type => Saphira::FileItem::TYPE_FOLDER, :parent_id => @file_item.id) %>
26
+
27
+ <% unless @file_item.id.nil? %>
28
+ <%= link_to 'Edit', edit_file_item_path(@file_item) %> |
29
+ <%= link_to 'Back', (@file_item.parent || file_items_path) %>
30
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <h1>New File</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', file_items_path %>
@@ -0,0 +1,5 @@
1
+ <h1>New Folder</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', file_items_path %>
@@ -0,0 +1,39 @@
1
+ <p id="notice"><%= notice %></p>
2
+
3
+ <div>
4
+ <div class="information">
5
+ <table class="key-value">
6
+ <tr>
7
+ <th colspan="2">General</th>
8
+ </tr>
9
+ <tr>
10
+ <td class="key">Name</td>
11
+ <td class="value"><%= @file_item.name %></td>
12
+ </tr>
13
+ <tr>
14
+ <td class="key">Tags</td>
15
+ <td class="value"><%= @file_item.tag_list %></td>
16
+ </tr>
17
+ <tr>
18
+ <th colspan="2">Additional</th>
19
+ </tr>
20
+ <% @file_item.dynamic_attributes.each do |key, value| %>
21
+ <tr>
22
+ <td class="key"><%= t key, :scope => 'saphira.dynamic_attributes' %></td>
23
+ <td class="value"><%= value %></td>
24
+ </tr>
25
+ <% end %>
26
+ </table>
27
+ </div>
28
+
29
+ <% if @file_item.file_uid %>
30
+ <div class="image">
31
+ <%= image_tag @file_item.file.thumb('300x300').url %>
32
+ </div>
33
+ <% end %>
34
+
35
+ <div style="clear: both;"></div>
36
+ </div>
37
+
38
+ <%= link_to 'Edit', edit_file_item_path(@file_item) %> |
39
+ <%= link_to 'Back', @file_item.parent || file_items_path %>
@@ -0,0 +1 @@
1
+ require 'acts-as-taggable-on'
@@ -0,0 +1 @@
1
+ require 'awesome_nested_set'
@@ -0,0 +1,7 @@
1
+ require 'dragonfly/rails/images'
2
+
3
+ app = Dragonfly[:images]
4
+ app.datastore.root_path = ::Rails.root.join('system/files', ::Rails.env).to_s
5
+ app.job :thumb_square do |size|
6
+ process :thumb, "#{size}x#{size}#"
7
+ end
@@ -0,0 +1,2 @@
1
+ require 'exifr'
2
+
@@ -0,0 +1 @@
1
+ require 'friendly_id'
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ Saphira::Engine.routes.draw do
2
+ resources :file_items, :path => '/files', :id => /[^\\.]+/
3
+
4
+ root :to => 'file_items#index'
5
+ end
@@ -0,0 +1,23 @@
1
+ class CreateSaphiraFileItems < ActiveRecord::Migration
2
+ def change
3
+ create_table :saphira_file_items do |t|
4
+ t.string :name
5
+ t.string :item_type
6
+ t.string :file_uid
7
+ t.string :file_name
8
+ t.string :slug
9
+ t.string :path
10
+ t.integer :parent_id
11
+ t.integer :lft
12
+ t.integer :rgt
13
+ t.text :dynamic_attributes
14
+
15
+ t.timestamps
16
+ end
17
+ add_index :saphira_file_items, :slug
18
+ add_index :saphira_file_items, :path, :unique => true
19
+ add_index :saphira_file_items, :parent_id
20
+ add_index :saphira_file_items, :lft
21
+ add_index :saphira_file_items, :rgt
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ class ActsAsTaggableOnMigration < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :tags do |t|
4
+ t.string :name
5
+ end
6
+
7
+ create_table :taggings do |t|
8
+ t.references :tag
9
+
10
+ # You should make sure that the column created is
11
+ # long enough to store the required class names.
12
+ t.references :taggable, :polymorphic => true
13
+ t.references :tagger, :polymorphic => true
14
+
15
+ t.string :context
16
+
17
+ t.datetime :created_at
18
+ end
19
+
20
+ add_index :taggings, :tag_id
21
+ add_index :taggings, [:taggable_id, :taggable_type, :context]
22
+ end
23
+
24
+ def self.down
25
+ drop_table :taggings
26
+ drop_table :tags
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ module Saphira
2
+ class Engine < Rails::Engine
3
+ isolate_namespace Saphira
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Saphira
2
+ VERSION = "0.0.1"
3
+ end
data/lib/saphira.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "saphira/engine"
2
+
3
+ module Saphira
4
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :saphira do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'cucumber' do
5
+ watch(%r{^features/.+\.feature$})
6
+ watch(%r{^features/support/.+$}) { 'features' }
7
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
8
+ end