Add documents (merges foodcoops/foodsoft#353)
This commit is contained in:
parent
33c9b23e2f
commit
8bb58c5519
18 changed files with 310 additions and 0 deletions
1
Gemfile
1
Gemfile
|
@ -56,6 +56,7 @@ gem 'foodsoft_messages', path: 'plugins/messages'
|
|||
# plugins not enabled by default
|
||||
#gem 'foodsoft_current_orders', path: 'plugins/current_orders'
|
||||
#gem 'foodsoft_uservoice', path: 'plugins/uservoice'
|
||||
#gem 'foodsoft_documents', path: 'plugins/documents'
|
||||
|
||||
|
||||
group :production do
|
||||
|
|
32
plugins/documents/README.md
Normal file
32
plugins/documents/README.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
FoodsoftDocuments
|
||||
=================
|
||||
|
||||
This plugin adds documents to foodsoft. A new 'Documents' menu entry is added below the 'Foodcoops' menu in the navigation bar.
|
||||
|
||||
This plugin is not enabled by default. To install it, add uncomment the
|
||||
corresponding line in the `Gemfile`, or add:
|
||||
|
||||
```Gemfile
|
||||
gem 'foodsoft_documents', path: 'lib/foodsoft_documents'
|
||||
```
|
||||
|
||||
This plugin introduces the foodcoop config option `use_documents`, which can be
|
||||
set to `true` to enable documents. May be useful in multicoop deployments.
|
||||
|
||||
|
||||
## Notes
|
||||
|
||||
This plugin may have some issues on certain installations:
|
||||
|
||||
* Files are stored in the database (up to 16MB per file). If your database has
|
||||
size limitations, you may want to consider how to use them.
|
||||
|
||||
* Members can upload any filetypes and filenames, which means there is no
|
||||
protection against files with viruses, or executable files.
|
||||
|
||||
Before this plugin would be enabled by default, at least the latter would need
|
||||
to be solved.
|
||||
|
||||
|
||||
This plugin is part of the foodsoft package and uses the GPL-3 license (see
|
||||
foodsoft's LICENSE for the full license text).
|
40
plugins/documents/Rakefile
Normal file
40
plugins/documents/Rakefile
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env rake
|
||||
begin
|
||||
require 'bundler/setup'
|
||||
rescue LoadError
|
||||
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
||||
end
|
||||
begin
|
||||
require 'rdoc/task'
|
||||
rescue LoadError
|
||||
require 'rdoc/rdoc'
|
||||
require 'rake/rdoctask'
|
||||
RDoc::Task = Rake::RDocTask
|
||||
end
|
||||
|
||||
RDoc::Task.new(:rdoc) do |rdoc|
|
||||
rdoc.rdoc_dir = 'rdoc'
|
||||
rdoc.title = 'FoodsoftDocuments'
|
||||
rdoc.options << '--line-numbers'
|
||||
rdoc.rdoc_files.include('README.rdoc')
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
end
|
||||
|
||||
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
||||
load 'rails/tasks/engine.rake'
|
||||
|
||||
|
||||
|
||||
Bundler::GemHelper.install_tasks
|
||||
|
||||
require 'rake/testtask'
|
||||
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.libs << 'lib'
|
||||
t.libs << 'test'
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = false
|
||||
end
|
||||
|
||||
|
||||
task :default => :test
|
63
plugins/documents/app/controllers/documents_controller.rb
Normal file
63
plugins/documents/app/controllers/documents_controller.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
require 'filemagic'
|
||||
|
||||
class DocumentsController < ApplicationController
|
||||
before_filter -> { require_plugin_enabled FoodsoftDocuments }
|
||||
|
||||
def index
|
||||
if params["sort"]
|
||||
sort = case params["sort"]
|
||||
when "name" then "name"
|
||||
when "created_at" then "created_at"
|
||||
when "name_reverse" then "name DESC"
|
||||
when "created_at_reverse" then "created_at DESC"
|
||||
end
|
||||
else
|
||||
sort = "name"
|
||||
end
|
||||
|
||||
@documents = Document.page(params[:page]).per(@per_page).order(sort)
|
||||
end
|
||||
|
||||
def new
|
||||
@document = Document.new
|
||||
end
|
||||
|
||||
def create
|
||||
@document = Document.new
|
||||
@document.data = params[:document][:data].read
|
||||
@document.mime = FileMagic.new(FileMagic::MAGIC_MIME).buffer(@document.data)
|
||||
if params[:document][:name] == ''
|
||||
name = params[:document][:data].original_filename
|
||||
name = File.basename(name)
|
||||
@document.name = name.gsub(/[^\w\.\-]/, '_')
|
||||
else
|
||||
@document.name = params[:document][:name]
|
||||
end
|
||||
@document.created_by = current_user
|
||||
@document.save!
|
||||
redirect_to documents_path, notice: I18n.t('documents.create.notice')
|
||||
rescue => error
|
||||
redirect_to documents_path, alert: t('documents.create.error', error: error.message)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@document = Document.find(params[:id])
|
||||
if @document.created_by == current_user or current_user.role_admin?
|
||||
@document.destroy
|
||||
redirect_to documents_path, notice: t('documents.destroy.notice')
|
||||
else
|
||||
redirect_to documents_path, alert: t('documents.destroy.no_right')
|
||||
end
|
||||
rescue => error
|
||||
redirect_to documents_path, alert: t('documents.destroy.error', error: error.message)
|
||||
end
|
||||
|
||||
def show
|
||||
@document = Document.find(params[:id])
|
||||
filename = @document.name
|
||||
unless filename.include? '.'
|
||||
filename += '.' + MIME::Types[@document.mime].first.preferred_extension
|
||||
end
|
||||
send_data(@document.data, :filename => filename, :type => @document.mime)
|
||||
end
|
||||
end
|
5
plugins/documents/app/models/document.rb
Normal file
5
plugins/documents/app/models/document.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class Document < ActiveRecord::Base
|
||||
belongs_to :created_by, :class_name => 'User', :foreign_key => 'created_by_user_id'
|
||||
|
||||
validates_presence_of :data
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
/ insert_before ':root:first-child'
|
||||
= config_input form, :use_documents, as: :boolean
|
20
plugins/documents/app/views/documents/_documents.html.haml
Normal file
20
plugins/documents/app/views/documents/_documents.html.haml
Normal file
|
@ -0,0 +1,20 @@
|
|||
- if Document.count > 20
|
||||
= items_per_page
|
||||
= pagination_links_remote @documents
|
||||
%table.table.table-striped
|
||||
%thead
|
||||
%tr
|
||||
%th= sort_link_helper heading_helper(Document, :name), "name", :per_page => @per_page
|
||||
%th= sort_link_helper heading_helper(Document, :created_at), "created_at", :per_page => @per_page
|
||||
%th= heading_helper(Document, :created_by)
|
||||
%th
|
||||
%tbody
|
||||
- for document in @documents
|
||||
%tr
|
||||
%td= link_to document.name, document
|
||||
%td= format_time(document.created_at)
|
||||
%td= h show_user(document.created_by)
|
||||
%td
|
||||
- if document.created_by == current_user or current_user.role_admin?
|
||||
= link_to t('ui.delete'), document, :method => :delete, :data => {:confirm => t('admin.confirm', name: document.name)},
|
||||
class: 'btn btn-mini btn-danger'
|
7
plugins/documents/app/views/documents/index.html.haml
Normal file
7
plugins/documents/app/views/documents/index.html.haml
Normal file
|
@ -0,0 +1,7 @@
|
|||
- title t('.title')
|
||||
|
||||
- content_for :actionbar do
|
||||
= link_to t('.new'), new_document_path, class: 'btn btn-primary'
|
||||
|
||||
#documentsTable
|
||||
= render :partial => "documents"
|
1
plugins/documents/app/views/documents/index.js.haml
Normal file
1
plugins/documents/app/views/documents/index.js.haml
Normal file
|
@ -0,0 +1 @@
|
|||
$('#documentsTable').html('#{escape_javascript(render("documents"))}');
|
8
plugins/documents/app/views/documents/new.html.haml
Normal file
8
plugins/documents/app/views/documents/new.html.haml
Normal file
|
@ -0,0 +1,8 @@
|
|||
- title t('.title')
|
||||
|
||||
= simple_form_for(@document) do |f|
|
||||
= f.input :name, as: :string
|
||||
= f.input :data, as: :file
|
||||
.form-actions
|
||||
= f.submit class: 'btn'
|
||||
= link_to t('ui.or_cancel'), :back
|
29
plugins/documents/config/locales/de.yml
Normal file
29
plugins/documents/config/locales/de.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
de:
|
||||
activerecord:
|
||||
attributes:
|
||||
document:
|
||||
created_at: Erstellt am
|
||||
created_by_user_id: Erstellt von
|
||||
data: Daten
|
||||
mime: MIME-Typ
|
||||
name: Name
|
||||
config:
|
||||
hints:
|
||||
use_documents: Einfache Dokumentenverwaltung aktivieren
|
||||
keys:
|
||||
use_documents: Dokumente verwenden
|
||||
navigation:
|
||||
documents: Dokumente
|
||||
documents:
|
||||
create:
|
||||
error: 'Dokument konnte nicht erstellt werden: %{error}'
|
||||
notice: Dokument wurde erstellt
|
||||
destroy:
|
||||
error: 'Dokument konnt nicht gelöscht werden: %{error}'
|
||||
no_right: Du hast nicht genügend Rechte um die Datei zu löschen
|
||||
notice: Dokument wurde gelöscht
|
||||
index:
|
||||
new: Neues Dokument anlegen
|
||||
title: Dokumente
|
||||
new:
|
||||
title: Neues Dokument
|
29
plugins/documents/config/locales/en.yml
Normal file
29
plugins/documents/config/locales/en.yml
Normal file
|
@ -0,0 +1,29 @@
|
|||
en:
|
||||
activerecord:
|
||||
attributes:
|
||||
document:
|
||||
created_at: Created at
|
||||
created_by_user_id: Created by
|
||||
data: Data
|
||||
mime: MIME type
|
||||
name: Name
|
||||
config:
|
||||
hints:
|
||||
use_documents: Add a basic document sharing page to the foodcoop menu.
|
||||
keys:
|
||||
use_documents: Enable documents
|
||||
navigation:
|
||||
documents: Documents
|
||||
documents:
|
||||
create:
|
||||
error: 'Document could not be created: %{error}'
|
||||
notice: Document was created
|
||||
destroy:
|
||||
error: 'Document could not be deleted: %{error}'
|
||||
no_right: You do not have enough rights to delete the document
|
||||
notice: Document was deleted
|
||||
index:
|
||||
new: Upload new document
|
||||
title: Documents
|
||||
new:
|
||||
title: New Document
|
9
plugins/documents/config/routes.rb
Normal file
9
plugins/documents/config/routes.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
Rails.application.routes.draw do
|
||||
|
||||
scope '/:foodcoop' do
|
||||
|
||||
resources :documents
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
class CreateDocuments < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :documents do |t|
|
||||
t.string :name
|
||||
t.string :mime
|
||||
t.binary :data, limit: 16.megabyte
|
||||
t.integer :created_by_user_id
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :documents
|
||||
end
|
||||
end
|
22
plugins/documents/foodsoft_documents.gemspec
Normal file
22
plugins/documents/foodsoft_documents.gemspec
Normal file
|
@ -0,0 +1,22 @@
|
|||
$:.push File.expand_path("../lib", __FILE__)
|
||||
|
||||
# Maintain your gem's version:
|
||||
require "foodsoft_documents/version"
|
||||
|
||||
# Describe your gem and declare its dependencies:
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "foodsoft_documents"
|
||||
s.version = FoodsoftDocuments::VERSION
|
||||
s.authors = ["paroga"]
|
||||
s.email = ["paroga@paroga.com"]
|
||||
s.homepage = "https://github.com/foodcoops/foodsoft"
|
||||
s.summary = "Documents plugin for foodsoft."
|
||||
s.description = "Adds simple document management to foodsoft."
|
||||
|
||||
s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "README.md"]
|
||||
s.test_files = Dir["test/**/*"]
|
||||
|
||||
s.add_dependency "rails"
|
||||
s.add_dependency "deface", "~> 1.0.0"
|
||||
s.add_dependency "ruby-filemagic"
|
||||
end
|
9
plugins/documents/lib/foodsoft_documents.rb
Normal file
9
plugins/documents/lib/foodsoft_documents.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
require 'foodsoft_documents/engine'
|
||||
|
||||
module FoodsoftDocuments
|
||||
# Return whether the documents are used or not.
|
||||
# Enabled by default in {FoodsoftConfig} since it used to be part of the foodsoft core.
|
||||
def self.enabled?
|
||||
FoodsoftConfig[:use_documents]
|
||||
end
|
||||
end
|
15
plugins/documents/lib/foodsoft_documents/engine.rb
Normal file
15
plugins/documents/lib/foodsoft_documents/engine.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
module FoodsoftDocuments
|
||||
class Engine < ::Rails::Engine
|
||||
def navigation(primary, context)
|
||||
return unless FoodsoftDocuments.enabled?
|
||||
return if primary[:foodcoop].nil?
|
||||
sub_nav = primary[:foodcoop].sub_navigation
|
||||
sub_nav.items <<
|
||||
SimpleNavigation::Item.new(primary, :documents, I18n.t('navigation.documents'), context.documents_path)
|
||||
# move to right before tasks item
|
||||
if i = sub_nav.items.index(sub_nav[:tasks])
|
||||
sub_nav.items.insert(i, sub_nav.items.delete_at(-1))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
3
plugins/documents/lib/foodsoft_documents/version.rb
Normal file
3
plugins/documents/lib/foodsoft_documents/version.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
module FoodsoftDocuments
|
||||
VERSION = "0.0.1"
|
||||
end
|
Loading…
Reference in a new issue