├── .gitignore
├── README.md
├── app
├── controllers
│ └── assets_controller.rb
└── views
│ └── assets
│ ├── _links.erb
│ ├── by_type.html.erb
│ └── index.html.erb
├── config
├── locales
│ ├── cs.yml
│ ├── de.yml
│ ├── en.yml
│ ├── es.yml
│ ├── fr.yml
│ ├── it.yml
│ ├── ja.yml
│ ├── ko.yml
│ ├── ru.yml
│ ├── sl.yml
│ └── zh.yml
├── mappings.yml
└── routes.rb
└── init.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | /nbproject
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Assets plugin for redmine
2 | =========================
3 |
4 | Provides a central location to view all your project's assets.
5 |
6 | Overview
7 | --------
8 |
9 | This will enable the `Assets` tab in your project. The assets tab groups assets by your different asset types.
10 | The asset types currently supported are `Issues`, `Messages`, `Documents`, `Versions` (from the Files module), and `WikiPages`.
11 | Only the types that have uploaded files in the current project will be displayed. Drilling down into an asset type
12 | will show an alphabetical list of assets, grouped by category if applicable.
13 |
14 | Requirements
15 | ------------
16 |
17 | * Rails 3
18 |
19 | Installation
20 | ------------
21 |
22 | 0. Follow the Redmine plugin installation steps at: [http://www.redmine.org/wiki/redmine/Plugins](http://www.redmine.org/wiki/redmine/Plugins)
23 | 1. Cd to your redmine `plugins/` dir
24 | 2. Git-clone the plugin from this repo into a folder in there: `git clone git://github.com/bshaffer/redmine-assets-plugin.git redmine_assets_plugin` (*You must name your directory with underscores as shown here, or the plugin will throw a fatal error*)
25 | 3. Run the plugin migrations `rake redmine:plugins:migrate`
26 | 4. Restart your Redmine web servers (e.g. mongrel, thin, mod_rails)
27 | 5. Login to your Redmine install as an Administrator
28 | 6. Setup the permissions for the assets module for your roles
29 | 7. Enable the module on a per-project basis as needed.
30 |
31 | NOTE: the plugin directory *has* to be "redmine_assets_plugin"
32 |
33 | Activation
34 | ----------
35 |
36 | To activate in your project:
37 |
38 | * Navigate to your project's "Settings" page
39 | * Under the "Modules" tab, check the box next to "Assets list" and save
40 |
41 | Config
42 | ------
43 |
44 | You can configure additional asset types via the `config/mappings.yml` file. Mappings to the
45 | content type's project_ids and categories are found here. Contact me or submit a pull request for additional asset types.
46 |
47 | * Leaving out the "category" key in `mappings.yml` will disable categorization.
48 | * Leaving out the "project_id" key will default to *project_id*.
49 |
50 | As a bare minimum, the mappings.yml file requires the name of the asset type, followed by an empty hash:
51 |
52 | NewAssetType: {}
53 |
54 | This will display the assets for class NewAssetType with a project_id field and no categories.
55 |
56 | Screenshots
57 | -----------
58 |
59 | When you click the **Assets** Tab in your project, you will see all the content types in your project that have assets uploaded to them:
60 | 
61 |
62 | If anyone has attached any files to the **Document** content type, they will be listed here, organized by Document Category
63 | 
64 |
65 | All files attached to **Issues** will be listed here, organized by Issue Category
66 | 
67 |
--------------------------------------------------------------------------------
/app/controllers/assets_controller.rb:
--------------------------------------------------------------------------------
1 | class AssetsController < ApplicationController
2 |
3 | before_filter :authorize, :asset_types
4 | before_filter :find_project, :only => [:index, :by_type]
5 |
6 | def index
7 | @types = types_for_project #Attachment.find(:all, :group => "container_type", :select => "container_type" ).collect(&:container_type)
8 | end
9 |
10 | def by_type
11 | @type = params[:type];
12 |
13 | # Forward 404 if type does not exist in the mapping
14 | @mappings[@type].nil? rescue return render :file => "#{Rails.root}/public/404.html", :status => 404
15 |
16 | @mapping = @mappings[@type];
17 | table_name = (eval @type).table_name
18 | @options = {:deletable => true, :author => true}
19 |
20 | # Every type will have this join
21 | joins = ["INNER JOIN #{table_name} ON #{table_name}.id = container_id and container_type = '#{@type}'"]
22 |
23 | # Add extra joins if applicable (for categories or project ID)
24 | if !@mapping['joins'].nil?
25 | joins << "LEFT JOIN #{@mapping['joins']}"
26 | end
27 |
28 | # Every type will have these conditions
29 | conditions = "container_type = '#{@type}' AND #{@mapping['project_id']} = #{@project.id}";
30 |
31 | # If a category mapping exists
32 | if(!@mapping['category'].nil?)
33 | @assets = Attachment.find(:all, {
34 | :conditions => conditions,
35 | :joins => joins.join(' '),
36 | :order => "#{@mapping['category']['name']} ASC, attachments.filename ASC"})
37 |
38 | # If a category mapping doesnt exist
39 | else
40 | @assets = Attachment.find(:all, {
41 | :conditions => conditions,
42 | :joins => joins.join(' '),
43 | :order => "attachments.filename ASC"})
44 |
45 | end
46 | end
47 |
48 | private
49 | def types_for_project
50 | joins = []
51 | wheres = []
52 | @mappings.each_pair do |type, mapping|
53 | table = (eval type).table_name
54 |
55 | joins << "LEFT JOIN #{table} ON #{table}.id = container_id AND container_type = '#{type}'"
56 |
57 | if !mapping['joins'].nil?
58 | joins << "LEFT JOIN #{mapping['joins']}"
59 | end
60 |
61 | wheres << "(#{mapping['project_id']} = #{@project.id})"
62 | end
63 |
64 | return Attachment.find(:all, {:select => "container_type", :group => "container_type", :conditions => wheres.join(' OR '), :joins => joins.join(' ')}).collect(&:container_type).compact
65 | end
66 |
67 | def find_project
68 | @project = Project.find(params[:project_id])
69 | raise ActiveRecord::RecordNotFound, l(:asset_project_not_found_error) + " id:" + params[:project_id] unless @project
70 | end
71 |
72 | def asset_types
73 | require 'yaml'
74 | @mappings = YAML::load(File.open("#{Rails.root}/plugins/redmine_assets_plugin/config/mappings.yml"))
75 | # set defaults
76 | @mappings.each_pair do |type, mapping|
77 | table = (eval type).table_name
78 | if mapping.nil?
79 | @mappings[type] = mapping = {}
80 | end
81 |
82 | if mapping['project_id'].nil?
83 | @mappings[type]['project_id'] = "#{table}.project_id"
84 | end
85 |
86 | if !mapping['category'].nil? && mapping['category']['relation'].nil?
87 | @mappings[type]['category']['relation'] = 'category'
88 | end
89 |
90 | if !mapping['category'].nil? && mapping['category']['id'].nil?
91 | @mappings[type]['category']['id'] = 'category_id'
92 | end
93 |
94 | if !mapping['category'].nil? && mapping['category']['name'].nil?
95 | @mappings[type]['category']['name'] = 'name'
96 | end
97 | end
98 | end
99 |
100 | def authorize
101 | find_project
102 | super
103 | end
104 | end
105 |
--------------------------------------------------------------------------------
/app/views/assets/_links.erb:
--------------------------------------------------------------------------------
1 | <% if category_relation %>
2 | <%= current_category = nil %>
3 | <% end %>
4 |
5 |
6 | <% for attachment in attachments %>
7 | <% if category_relation %>
8 | <% category = eval "attachment.container.#{category_relation}" %>
9 | <% if(current_category != category) %>
10 |
<%= category %>
11 | <% current_category = category %>
12 | <% end %>
13 | <% end %>
14 |
15 |
<%= link_to_attachment attachment, :class => 'icon icon-attachment' -%>
16 | <%= h(" - #{attachment.description}") unless attachment.description.blank? %>
17 | (<%= number_to_human_size attachment.filesize %>)
18 | <% if options[:deletable] %>
19 | <%= link_to image_tag('delete.png'), {:controller => 'attachments', :action => 'destroy', :id => attachment},
20 | :confirm => l(:text_are_you_sure),
21 | :method => :delete,
22 | :class => 'delete',
23 | :title => l(:button_delete) %>
24 | <% end %>
25 | <% if options[:author] %>
26 | <%= attachment.author %>, <%= format_time(attachment.created_on) %>
27 | <% end %>
28 |
29 | <% end %>
30 |
31 |
--------------------------------------------------------------------------------
/app/views/assets/by_type.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
<%= l(@mapping['i18n'].nil? ? 'label_'+@type.underscore : @mapping['i18n']) %> <%= l(:assets_project_heading) %> <%= @project.name %>
3 |
4 |
5 | <%= render :partial => 'assets/links', :locals => {:attachments => @assets, :options => @options, :category_relation => @mapping['category'].nil? ? nil : @mapping['category']['relation']} %>
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/views/assets/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
<%= l(:assets_project_heading) %> <%= @project.name %>
3 | <% if !@types.blank? %>
4 |
5 | <% for type in @types %>
6 | - <%= link_to l(@mappings[type]['i18n'].nil? ? 'label_'+type.underscore : @mappings[type]['i18n']) + ' ' + l(:label_asset_plural), assets_by_type_path(:type => type, :project_id => params[:project_id]) %>
7 | <% end %>
8 |
9 | <% else %>
10 |
<%= l(:no_assets_added) %>
11 | <% end %>
12 |
--------------------------------------------------------------------------------
/config/locales/cs.yml:
--------------------------------------------------------------------------------
1 | #Assets English locale File for Rails >= 2.2.2
2 | cs:
3 | asset_project_not_found_error: "Projekt nebyl nalezen!"
4 | assets_project_heading: Přílohy pro
5 | label_asset_plural: Přílohy
6 | no_assets_added: Žádné přílohy nebyly nalezeny
--------------------------------------------------------------------------------
/config/locales/de.yml:
--------------------------------------------------------------------------------
1 | #language file for de - post rails 2.2.2
2 | de:
3 | asset_project_not_found_error: "Projekte nicht gefunden!"
4 | assets_project_heading: Assets für
5 | label_asset_plural: Assets
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | #Assets English locale File for Rails >= 2.2.2
2 | en:
3 | asset_project_not_found_error: "Project not found!"
4 | assets_project_heading: Assets for
5 | label_asset_plural: Assets
6 | no_assets_added: No assets have been added
--------------------------------------------------------------------------------
/config/locales/es.yml:
--------------------------------------------------------------------------------
1 | #Assets en locacles file
2 | es:
3 | asset_project_not_found_error: "Project not found!"
4 | assets_project_heading: Assets for
5 | label_asset_plural: Assets
--------------------------------------------------------------------------------
/config/locales/fr.yml:
--------------------------------------------------------------------------------
1 | #language file for fr - post rails 2.2.2
2 | fr:
3 | asset_project_not_found_error: "Project not found!"
4 | assets_project_heading: Assets for
5 | label_asset_plural: Assets
--------------------------------------------------------------------------------
/config/locales/it.yml:
--------------------------------------------------------------------------------
1 | #language file for it - pre rails 2.2.2
2 | it:
3 | asset_project_not_found_error: "Project not found!"
4 | assets_project_heading: Assets for
5 | label_asset_plural: Assets
--------------------------------------------------------------------------------
/config/locales/ja.yml:
--------------------------------------------------------------------------------
1 | #Assets Japanese locale File for Rails >= 2.2.2
2 | ja:
3 | asset_project_not_found_error: "Project not found!"
4 | assets_project_heading: Assets for
5 | label_asset_plural: Assets
--------------------------------------------------------------------------------
/config/locales/ko.yml:
--------------------------------------------------------------------------------
1 | #Assets Korean locale File for Rails >= 2.2.2
2 | ko:
3 | asset_project_not_found_error: "Project not found!"
4 | assets_project_heading: Assets for
5 | label_asset_plural: Assets
--------------------------------------------------------------------------------
/config/locales/ru.yml:
--------------------------------------------------------------------------------
1 | #Assets Russian locale File for Rails >= 2.2.2
2 | ru:
3 | asset_project_not_found_error: "Project not found!"
4 | assets_project_heading: Assets for
5 | label_asset_plural: Assets
--------------------------------------------------------------------------------
/config/locales/sl.yml:
--------------------------------------------------------------------------------
1 | #Assets English locale File for Rails >= 2.2.2
2 | sl:
3 | asset_project_not_found_error: "Projekt ne obstaja!"
4 | assets_project_heading: Priponke za
5 | label_asset_plural: Priponke
6 | no_assets_added: Priponke niso dodane
--------------------------------------------------------------------------------
/config/locales/zh.yml:
--------------------------------------------------------------------------------
1 | #Assets zh locacles file
2 | zh:
3 | asset_project_not_found_error: "Project not found!"
4 | assets_project_heading: Assets for
5 | label_asset_plural: Assets
--------------------------------------------------------------------------------
/config/mappings.yml:
--------------------------------------------------------------------------------
1 | # Tells plugin where to find project_id and asset category on each item
2 |
3 | Document:
4 | category:
5 | id: category_id
6 | relation: category
7 | name: name
8 | table: enumerations
9 |
10 | joins: enumerations on documents.category_id = enumerations.id AND type='DocumentCategory'
11 |
12 | Issue:
13 | category:
14 | id: category_id
15 | relation: category
16 | name: name
17 | table: issue_categories
18 |
19 | joins: issue_categories on issues.category_id = issue_categories.id
20 |
21 | Message:
22 | category:
23 | id: board_id
24 | relation: board
25 | table: boards
26 | name: name
27 |
28 | joins: boards on board_id = boards.id
29 | project_id: boards.project_id
30 | i18n: label_board
31 |
32 | Version:
33 | project_id: versions.project_id
34 |
35 | Project:
36 | project_id: projects.id
37 |
38 | WikiPage:
39 | category:
40 | id: id
41 | relation: title
42 | table: wiki_pages
43 | name: wiki_pages.title
44 |
45 | joins: wikis on wiki_id = wikis.id
46 | project_id: wikis.project_id
47 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | #custom routes for this plugin
2 | RedmineApp::Application.routes.draw do
3 | match '/projects/:project_id/assets' => 'assets#index', :via => [:get], :as => 'assets'
4 | match '/projects/:project_id/assets/:type/type' => 'assets#by_type', :as => 'assets_by_type', :via => [:get]
5 | end
6 |
--------------------------------------------------------------------------------
/init.rb:
--------------------------------------------------------------------------------
1 | require 'redmine'
2 |
3 | Dir[File.join(File.dirname(__FILE__),'vendor','plugins','*')].each do |dir|
4 | path = File.join(dir, 'lib')
5 | $LOAD_PATH << path
6 | Dependencies.load_paths << path
7 | Dependencies.load_once_paths.delete(path)
8 | end
9 |
10 | Redmine::Plugin.register :redmine_assets_plugin do
11 | name 'Redmine Assets plugin'
12 | author 'Brent Shaffer'
13 | url 'https://github.com/bshaffer/redmine-assets-plugin'
14 | author_url 'http://brentertainment.com'
15 | description 'Provides a central location to view all your project\'s assets.'
16 | version '0.0.1'
17 |
18 | project_module :assets_list do
19 | permission :view_asset, {:assets => [:index, :by_type] }
20 |
21 | permission :edit_asset,
22 | {:asset => [:create, :destroy, :new, :toggle_complete, :sort, :edit, :update],
23 | :issues => [:edit, :update]}
24 | end
25 |
26 | menu :project_menu, :project_assets, {:controller => 'assets', :action => 'index'}, :caption => :label_asset_plural, :after => :new_issue, :param => :project_id
27 | end
28 |
29 |
30 |
--------------------------------------------------------------------------------