├── LICENSE.txt
├── README.md
├── Rakefile
├── app
├── controllers
│ └── mediabrowser_controller.rb
└── views
│ └── mediabrowser
│ └── list.html.erb
├── config
├── application.rb
└── routes.rb
├── init.rb
├── install.rb
├── lib
├── mediabrowser.rb
└── routing.rb
├── public
├── css
│ └── list.css
└── images
│ ├── delete.png
│ ├── dir.png
│ └── file.png
├── test
├── mediabrowser_test.rb
└── test_helper.rb
└── uninstall.rb
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Copyright (c) 2013 Vincent Agnano
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # A file manager for rails 3
2 |
3 | Rails 3 plugin for browsing and managing files from a web page (admin
4 | in most cases).
5 |
6 | It does NOT use any database as it works directly on file structure.
7 |
8 | 
9 |
10 |
11 | ## Run it
12 |
13 | open your browser at http://0.0.0.0:3000/mediabrowser, and manage files and
14 | directories from there.
15 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rake'
2 | require 'rake/testtask'
3 | require 'rake/rdoctask'
4 |
5 | desc 'Default: run unit tests.'
6 | task :default => :test
7 |
8 | desc 'Test the mediabrowser plugin.'
9 | Rake::TestTask.new(:test) do |t|
10 | t.libs << 'lib'
11 | t.libs << 'test'
12 | t.pattern = 'test/**/*_test.rb'
13 | t.verbose = true
14 | end
15 |
16 | desc 'Generate documentation for the mediabrowser plugin.'
17 | Rake::RDocTask.new(:rdoc) do |rdoc|
18 | rdoc.rdoc_dir = 'rdoc'
19 | rdoc.title = 'Mediabrowser'
20 | rdoc.options << '--line-numbers' << '--inline-source'
21 | rdoc.rdoc_files.include('README')
22 | rdoc.rdoc_files.include('lib/**/*.rb')
23 | end
--------------------------------------------------------------------------------
/app/controllers/mediabrowser_controller.rb:
--------------------------------------------------------------------------------
1 | class MediabrowserController < ApplicationController
2 |
3 | before_filter :define_path
4 |
5 |
6 | def define_path
7 | @public_path = File.join(Rails.root.to_s, 'public')
8 | @uploads_url = '/uploads'
9 | @upload_path = File.join(@public_path, @uploads_url)
10 | @current_url = params[:dir] || @uploads_url
11 | @current_path = File.join(@public_path, @current_url)+ '/*'
12 | end
13 |
14 |
15 | def list
16 |
17 | @dirs = []
18 | @files = []
19 | Dir.glob(@current_path).sort.each do |file|
20 | file_obj = {
21 | :url => file.gsub(@public_path, ''),
22 | :name => File.basename(file),
23 | }
24 | if File.directory?(file)
25 | @dirs << file_obj
26 | else
27 | file_obj.merge!({
28 | :type => ['gif','jpg','jpeg','png'].index(File.extname(file)[1..-1]) ? :image : :file,
29 | :icon => '/mediabrowser/images/file.png',
30 | })
31 | puts file_obj[:type]
32 | if file_obj[:type] == :image
33 | file_obj[:icon] = file_obj[:url]
34 | end
35 | @files << file_obj
36 | end
37 | end
38 |
39 | @breadcrumb = []
40 | curr_crumb = ''
41 | @current_url.each(File::SEPARATOR) do |crumb|
42 | crumb.gsub!('/', '')
43 | if crumb != ''
44 | curr_crumb += File::SEPARATOR + crumb
45 | puts curr_crumb
46 | @breadcrumb << {
47 | :name => crumb,
48 | :url => curr_crumb,
49 | }
50 | end
51 | end
52 | end
53 |
54 |
55 | def create_dir
56 | slugged_name = slugify(params[:new_dir][:name])
57 | path = File.join(@public_path, params[:new_dir][:path])
58 | create_path = File.join(path, slugged_name)
59 |
60 | if secured_path?(path) && !File.exist?(create_path) && FileUtils.mkdir(create_path)
61 | notice = 'Directory "%s" was successfully created' % slugged_name
62 | else
63 | notice = 'Directory "%s" could not be created' % slugged_name
64 | end
65 | redirect_to request.referer, :notice => notice
66 | end
67 |
68 |
69 | def create_file
70 | data = params[:new_file][:file]
71 | filename = data.original_filename
72 | target_name = slugify(filename)
73 |
74 | if filename_ext = File.extname(filename)
75 | target_name = slugify(filename[0..-(filename_ext.length+1)]) + filename_ext
76 | end
77 | target = File.join(@public_path, params[:new_file][:path], target_name)
78 | File.open(target, 'w+') do |file|
79 | file.write(data.read)
80 | end
81 | notice = File.exist?(target) \
82 | ? 'File "%s" was successfully added' % File.basename(target_name)\
83 | : 'File "%s" could not be uploaded' % File.basename(target_name)
84 | redirect_to request.referer, :notice => notice
85 | end
86 |
87 |
88 | def delete
89 | file_path = File.join(@public_path, params[:file])
90 | if secured_path?(file_path) && FileUtils.rm_r(file_path)
91 | notice = '"%s" was successfully deleted' % File.basename(params[:file])
92 | else
93 | notice = '"%s" could not be deleted' % File.basename(params[:file])
94 | end
95 | redirect_to request.referer, :notice => notice
96 | end
97 |
98 |
99 | protected
100 |
101 | def secured_path?(file_path)
102 | return File.exist?(file_path) && ! File.dirname(file_path).index(@public_path).nil?
103 | end
104 |
105 |
106 |
107 | def slugify(value)
108 | return value.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n, '').to_s\
109 | .downcase\
110 | .gsub(/[']+/, '')\
111 | .gsub(/\W+/, ' ')\
112 | .strip\
113 | .gsub(' ', '-')
114 | end
115 |
116 | end
117 |
--------------------------------------------------------------------------------
/app/views/mediabrowser/list.html.erb:
--------------------------------------------------------------------------------
1 | <% puts 'template talks' %>
2 |
3 |
4 | <% if flash[:notice] %>
5 |
<%= flash[:notice] %>
6 | <% end %>
7 | <% if flash[:error] %>
8 | <%= flash[:error] %>
9 | <% end %>
10 |
11 |
12 |
20 |
21 |
29 |
30 |
35 |
36 |
37 | <% @dirs.each do |dir| %>
38 | -
39 |
44 |
45 |
46 | - delete
47 |
48 |
49 | <% end %>
50 |
51 |
52 |
53 | <% @files.each do |file| %>
54 | -
55 |
56 |
![<%= file[:name] %>](<%= file[:icon] %>)
57 |
58 |
59 |
60 | - delete
61 |
62 |
63 | <% end %>
64 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | class Application < Rails::Application
2 | config.upload_url = '/uploads'
3 | end
4 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails::Application.routes.draw do
2 | match '/mediabrowser' => 'mediabrowser#list', :as => :mediabrowser
3 | match '/mediabrowser/delete' => 'mediabrowser#delete', :as => :delete_file_mediabrowser
4 | match '/mediabrowser/dir/create' => 'mediabrowser#create_dir', :as => :create_dir_mediabrowser
5 | match '/mediabrowser/file/create' => 'mediabrowser#create_file', :as => :create_file_mediabrowser
6 | end
7 |
--------------------------------------------------------------------------------
/init.rb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinyll/rails-mediabrowser/febbc0b78ffeb2cb268851afc9d33cd87fa18e54/init.rb
--------------------------------------------------------------------------------
/install.rb:
--------------------------------------------------------------------------------
1 | require 'fileutils'
2 |
3 | RAILS_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '/../../../')) unless defined? RAILS_ROOT
4 |
5 | public_dir = File.expand_path(File.join(RAILS_ROOT, 'public'))
6 |
7 | puts 'Publishing web assets to public folder'
8 | FileUtils.cp_r(
9 | File.join(File.dirname(__FILE__), 'public'),\
10 | File.join(public_dir, 'mediabrowser')
11 | )
12 |
13 | upload_dir = File.join(public_dir, 'uploads')
14 | unless File.exists?(upload_dir)
15 | puts 'Creating uploads directory at "%s"' % upload_dir
16 | FileUtils.mkdir(upload_dir)
17 | end
18 |
19 | puts 'chmod 777 on uploads directory "%s"' % upload_dir
20 | FileUtils.chmod_R(0777, upload_dir)
21 |
--------------------------------------------------------------------------------
/lib/mediabrowser.rb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinyll/rails-mediabrowser/febbc0b78ffeb2cb268851afc9d33cd87fa18e54/lib/mediabrowser.rb
--------------------------------------------------------------------------------
/lib/routing.rb:
--------------------------------------------------------------------------------
1 | module Mediabrowser
2 | module Routing
3 | module MapperExtensions
4 | def mediabrowser
5 | @set.add_route('/mediabrowser', {:controller => 'mediabrowser_controller', :action => 'list', :as => :mediabrowser})
6 | @set.add_route('/mediabrowser/delete', {:controller => 'mediabrowser_controller', :action => 'delete', :as => :delete_file_mediabrowser})
7 | @set.add_route('/mediabrowser/dir/create', { :controller => 'mediabrowser', :action => 'create_dir', :as => :create_dir_mediabrowser})
8 | @set.add_route('/mediabrowser/file/create', { :controller => 'mediabrowser/file/create', :action => 'create_file', :as => :create_file_mediabrowser})
9 | end
10 | end
11 | end
12 | end
13 |
14 |
15 | ActionController::Routing::RouteSet::Mapper.send(:include, Mediabrowser::Routing::MapperExtensions)
--------------------------------------------------------------------------------
/public/css/list.css:
--------------------------------------------------------------------------------
1 | form#new_file, form#new_dir {
2 | float: left;
3 | background-color: #EEE;
4 | border: 1px solid #999;
5 | color: #333;
6 | margin-right: 50px;
7 | padding: 10px;
8 | width: 300px;
9 | }
10 |
11 | form#new_file h2, form#new_dir h2 {
12 | font-size: 1.2em;
13 | color: #333;
14 | margin: 0;
15 | }
16 |
17 | form#new_file input[type="submit"], form#new_dir input[type="submit"] {
18 | display: block;
19 | width: 150px;
20 | border-radius: 3px;
21 | background-color: #CCC;
22 | border: 1px solid #999;
23 | font-weight: bold;
24 | }
25 | form#new_file input[type="submit"]:hover, form#new_dir input[type="submit"]:hover {
26 | background-color: #BBB;
27 | cursor: pointer;
28 | }
29 | form#new_dir input[type="text"] {
30 | border: 1px solid #CCC;
31 | }
32 |
33 | #breadcrumb {
34 | clear: both;
35 | border-bottom: 1px solid #999;
36 | font-weight: bold;
37 | padding: 20px 0 10px 0;
38 | }
39 | #breadcrumb li {
40 | display: inline;
41 | }
42 | #breadcrumb li a {
43 | color: #333;
44 | }
45 |
46 | ul.directories, ul.files {
47 | clear: both;
48 | display: inline;
49 | list-style: none;
50 | }
51 | ul.directories > li, ul.files > li {
52 | float: left;
53 | width: 120px;
54 | height: 100px;
55 | margin: 10px;
56 | border: 1px solid #999;
57 | background-color: #EEE;
58 | text-align: center;
59 | }
60 | .directories .icon a {
61 | background: transparent url('/mediabrowser/images/dir.png') no-repeat 50% 10px;
62 | text-decoration: none;
63 | }
64 | .directories .icon a label {
65 | display: none;
66 | }
67 |
68 | ul.files > li:not(.image) .icon img {
69 | margin-top: 8px;
70 | }
71 | ul.files > li.image .icon img {
72 | margin: 0 auto;
73 | width: 100%;
74 | }
75 |
76 | .icon > a {
77 | display: block;
78 | height: 80px;
79 | overflow: hidden;
80 | }
81 |
82 | .infos {
83 | background-color: #CCC;
84 | border-top: 1px solid #999;
85 | width: auto;
86 | height: 19px;
87 | overflow: hidden;
88 | list-style: none;
89 | padding: 0;
90 | margin: 0;
91 | font-size: 12px;
92 | color: #333;
93 | position: relative;
94 | text-align: left;
95 | }
96 | ul.infos li {
97 | margin: 0;
98 | }
99 | .infos .label {
100 | width: 100px;
101 | }
102 | .infos .delete a {
103 | display: block;
104 | width: 20px;
105 | height: 20px;
106 | position: absolute;
107 | top: 2px;
108 | right: 0;
109 | text-indent: -5000px;
110 | background: transparent url('/mediabrowser/images/delete.png') no-repeat;
111 | }
--------------------------------------------------------------------------------
/public/images/delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinyll/rails-mediabrowser/febbc0b78ffeb2cb268851afc9d33cd87fa18e54/public/images/delete.png
--------------------------------------------------------------------------------
/public/images/dir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinyll/rails-mediabrowser/febbc0b78ffeb2cb268851afc9d33cd87fa18e54/public/images/dir.png
--------------------------------------------------------------------------------
/public/images/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vinyll/rails-mediabrowser/febbc0b78ffeb2cb268851afc9d33cd87fa18e54/public/images/file.png
--------------------------------------------------------------------------------
/test/mediabrowser_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class MediabrowserTest < ActiveSupport::TestCase
4 | # Replace this with your real tests.
5 | test "the truth" do
6 | assert true
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'test/unit'
3 | require 'active_support'
4 |
--------------------------------------------------------------------------------
/uninstall.rb:
--------------------------------------------------------------------------------
1 | require 'fileutils'
2 |
3 | RAILS_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '/../../../')) unless defined? RAILS_ROOT
4 |
5 |
6 | puts 'Removing mediabrowser web assets from public folder'
7 |
8 |
9 | FileUtils.rm_r(File.expand_path(File.join(RAILS_ROOT, 'public', 'mediabrowser')))
10 |
11 | puts 'the uploads folder was not removed. Delete it manually if you do not need it nomore.'
12 |
--------------------------------------------------------------------------------