• R/O
  • SSH
  • HTTPS

rp-information: Commit


Commit MetaInfo

Revision55 (tree)
Time2012-10-21 16:28:34
Authormyoshida

Log Message

Ver. 1.0.2

Change Summary

Incremental Difference

--- tags/1.0.2/redmine_information/init.rb (nonexistent)
+++ tags/1.0.2/redmine_information/init.rb (revision 55)
@@ -0,0 +1,32 @@
1+require 'redmine'
2+
3+Redmine::Plugin.register :redmine_information do
4+ name 'Redmine Information Plugin'
5+ author 'M. Yoshida'
6+ description 'This is a plugin for information of Redmine'
7+ version '1.0.2'
8+ requires_redmine :version_or_higher => '2.0.0'
9+ url 'http://www.r-labs.org/projects/rp-admin-reports/wiki/Redmine_Information_Plugin'
10+ author_url 'http://yohshiy.blog.fc2.com/'
11+
12+ setmap = InfoCategory.hide_map();
13+ setmap[:use_dot] = false
14+ setmap[:dot_cmdpath] = 'dot'
15+ settings(:default => setmap,
16+ :partial => 'settings/info_settings')
17+ menu(:top_menu, :redmine_info,
18+ { :controller => 'info', :action => 'index'},
19+ :if => Proc.new { User.current.logged? })
20+
21+end
22+
23+
24+Redmine::MenuManager.map :redmine_info_menu do |menu|
25+ InfoCategory.push_menu(menu, :permissions, :html => {:class => 'roles'})
26+ InfoCategory.push_menu(menu, :workflows)
27+ InfoCategory.push_menu(menu, :settings)
28+ InfoCategory.push_menu(menu, :plugins)
29+ InfoCategory.push_menu(menu, :wiki_macros)
30+ InfoCategory.push_menu(menu, :rails_info)
31+ InfoCategory.push_menu(menu, :version, {:last => true, :html=>{:class => 'info'}})
32+end
--- tags/1.0.2/redmine_information/app/controllers/info_controller.rb (nonexistent)
+++ tags/1.0.2/redmine_information/app/controllers/info_controller.rb (revision 55)
@@ -0,0 +1,126 @@
1+require 'rails/info'
2+
3+class InfoController < ApplicationController
4+ unloadable
5+
6+ before_filter :require_login
7+
8+ helper :info
9+ include InfoHelper
10+ helper :graphviz
11+ include GraphvizHelper
12+
13+ def permissions
14+ @roles = Role.sorted.all
15+ @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
16+ end
17+
18+
19+ def workflows
20+ wfclass = nil
21+ if Redmine::VERSION::MAJOR == 2 and Redmine::VERSION::MINOR < 1
22+ wfclass = Workflow
23+ else
24+ wfclass = WorkflowTransition
25+ end
26+ @workflow_counts = wfclass.count_by_tracker_and_role
27+ @workflow_all_ng_roles = find_all_ng_roles(@workflow_counts)
28+
29+ @roles = Role.find(:all, :order => 'builtin, position')
30+ @role = Role.find_by_id(params[:role_id])
31+
32+ @trackers = Tracker.find(:all, :order => 'position')
33+ @tracker = Tracker.find_by_id(params[:tracker_id])
34+
35+ if @tracker && @tracker.issue_statuses.any?
36+ @statuses = @tracker.issue_statuses
37+ end
38+ @statuses ||= IssueStatus.find(:all, :order => 'position')
39+
40+ if (@tracker && @role && @statuses.any?)
41+ workflows = wfclass.all(:conditions => {:role_id => @role.id, :tracker_id => @tracker.id})
42+ @workflows = {}
43+ @workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
44+ @workflows['author'] = workflows.select {|w| w.author}
45+ @workflows['assignee'] = workflows.select {|w| w.assignee}
46+ end
47+
48+ end
49+
50+
51+ def settings
52+ # Mail Notification
53+ @notifiables = []
54+ Redmine::Notifiable.all.each {|notifiable|
55+ if notifiable.parent.present?
56+ next if (Setting.notified_events.include?(notifiable.parent))
57+ end
58+ @notifiables << notifiable
59+ }
60+ @deliveries = ActionMailer::Base.perform_deliveries
61+
62+ # Repository
63+ @commit_fix_status = IssueStatus.find_by_id(Setting[:commit_fix_status_id])
64+ unless (@commit_fix_status)
65+ @commit_fix_status = l(:label_no_change_option)
66+ end
67+ @commit_fix_done_ratio = Setting[:commit_fix_done_ratio]
68+ if (!@commit_fix_done_ratio or @commit_fix_done_ratio.empty?)
69+ @commit_fix_done_ratio = l(:label_no_change_option)
70+ end
71+
72+ @commit_logtime_enabled = Setting[:commit_logtime_enabled]
73+ if (@commit_logtime_enabled)
74+ @commit_logtime_enabled = (0 < @commit_logtime_enabled.to_i)
75+ end
76+ @commit_logtime_activity_name = l(:label_default)
77+ if (@commit_logtime_enabled)
78+ aid = Setting[:commit_logtime_activity_id]
79+ if (aid and 0 < aid.to_i)
80+ activity = TimeEntryActivity.find_by_id(aid)
81+ @commit_logtime_activity_name = activity.name if (activity)
82+ end
83+ end
84+
85+ end
86+
87+
88+ def plugins
89+ @plugins = Redmine::Plugin.all
90+ end
91+
92+
93+ def show
94+ @icat = params[:id]
95+ case @icat
96+ when 'permissions'; permissions;
97+ when 'workflows'; workflows;
98+ when 'settings'; settings;
99+ when 'plugins'; plugins;
100+ when 'version'
101+ @db_adapter_name = ActiveRecord::Base.connection.adapter_name
102+ end
103+ end
104+
105+
106+ def index
107+ end
108+
109+
110+ private
111+ def find_all_ng_roles(workflow_counts)
112+ roles_map = {}
113+ workflow_counts.each do |tracker, roles|
114+ roles.each do |role, count|
115+ roles_map[role] = 0 unless roles_map[role]
116+ roles_map[role] += count
117+ end
118+ end
119+ all_ng_roles = []
120+ roles_map.each {|role, count|
121+ all_ng_roles << role if (count == 0)
122+ }
123+ return all_ng_roles
124+ end
125+
126+end
--- tags/1.0.2/redmine_information/app/helpers/info_helper.rb (nonexistent)
+++ tags/1.0.2/redmine_information/app/helpers/info_helper.rb (revision 55)
@@ -0,0 +1,47 @@
1+module InfoHelper
2+
3+ def is_shown?(catsym)
4+ return (User.current.admin? or InfoCategory::is_shown?(catsym));
5+ end
6+
7+ def is_admin_only?(catsym)
8+ return (User.current.admin? and !InfoCategory::is_shown?(catsym));
9+ end
10+
11+ def show_bool(boolval, falsestr = nil)
12+ if (boolval)
13+ raw "<span class='icon icon-checked'></span>"
14+ else
15+ raw(falsestr ? h(falsestr) : '&nbsp;')
16+ end
17+ end
18+
19+
20+ def workflows_empty?(statuses, workflows)
21+ for old_status in @statuses
22+ for new_status in @statuses
23+ hit = workflows.detect {|w|
24+ w.old_status_id == old_status.id && w.new_status_id == new_status.id
25+ }
26+ return false if hit
27+ end
28+ end
29+ return true
30+ end
31+
32+ def workflow_flowable?(old_status, new_status, *wfs)
33+ wfs.each {|wf|
34+ next unless wf
35+ sts = wf.detect {|w| w.old_status_id == old_status.id && w.new_status_id == new_status.id}
36+ return true if sts
37+ }
38+ return false
39+ end
40+
41+
42+ def workflow_has_author_assignee
43+ (1 < Redmine::VERSION::MAJOR ||
44+ (1 == Redmine::VERSION::MAJOR && 2 <= Redmine::VERSION::MINOR))
45+ end
46+
47+end
--- tags/1.0.2/redmine_information/app/helpers/graphviz_helper.rb (nonexistent)
+++ tags/1.0.2/redmine_information/app/helpers/graphviz_helper.rb (revision 55)
@@ -0,0 +1,143 @@
1+require 'kconv'
2+
3+module GraphvizHelper
4+
5+ include InfoHelper
6+
7+ def dot_line(name, options = {})
8+ line = name.to_s + " "
9+ unless options.empty?
10+ optstrs = options.map {|key, val|
11+ "#{key} = #{val}"
12+ }
13+ line += " [#{optstrs.join(', ')}]"
14+ end
15+ line += ';'
16+ end
17+
18+ def dot_line_connect(a, b, isboth=false)
19+ opts = {}
20+ opts['dir'] = 'both' if isboth
21+ dot_line("#{a} -> #{b}", opts)
22+ end
23+
24+ def dot_digraph(name, &blk)
25+ str = "digraph #{name} {"
26+ str += yield
27+ str += "}"
28+ end
29+
30+ def quote(str)
31+ "\"#{str}\""
32+ end
33+
34+
35+ def create_dot_statuses(statuses, uses)
36+ opt = {}
37+ str = ""
38+ statuses.each {|sts|
39+ next unless uses.include?(sts.position)
40+ opt.clear
41+ if (sts.is_default?)
42+ opt['style'] = 'filled'
43+ opt['fillcolor'] = quote 'yellow'
44+ elsif (sts.is_closed?)
45+ opt['style'] = 'filled'
46+ opt['fillcolor'] = quote '#D3D3D3'
47+ end
48+ opt['label'] = quote sts.name
49+ str += dot_line(sts.position, opt)
50+ }
51+ str
52+ end
53+
54+
55+ def create_dot_workflow(statuses, wf, subwf)
56+ str = ""
57+ uses = []
58+ for stspos in 0..(statuses.size-1)
59+ for nstspos in (stspos+1)..(statuses.size-1)
60+ fore = workflow_flowable?(statuses[stspos], statuses[nstspos], wf, subwf)
61+ back = workflow_flowable?(statuses[nstspos], statuses[stspos], wf, subwf)
62+ if (fore)
63+ str += dot_line_connect(statuses[stspos].position, statuses[nstspos].position, back)
64+ elsif (back)
65+ str += dot_line_connect(statuses[nstspos].position, statuses[stspos].position)
66+ end
67+ if (fore or back)
68+ uses << statuses[stspos].position
69+ uses << statuses[nstspos].position
70+ end
71+ end
72+ end
73+ [str, uses.uniq]
74+ end
75+
76+
77+ def create_dot_digraph_workflow(graphname, statuses, wf, subwf)
78+ dot_digraph(quote graphname) {
79+ str = "ranksep = 0.3;"
80+ opt = {'shape' => 'box', 'margin' => '0.05'}
81+ str += dot_line('node', opt)
82+ struses = create_dot_workflow(statuses, wf, subwf)
83+ str += create_dot_statuses(statuses, struses.last)
84+ str += struses.first
85+ }
86+ end
87+
88+
89+ def exec_dot(src)
90+ dest = ""
91+ errstr = ""
92+ reststr = ""
93+ bgnptn = /^<svg/
94+ endptn = /^<\/svg>/
95+ errptn = /^Error/i
96+ warningptn = /^\(dot(\.exe)?:\d+\)/i
97+ dotcmd = Setting.plugin_redmine_information[:dot_cmdpath]
98+ dotcmd = 'dot' if (!dotcmd.kind_of?(String) or dotcmd.empty?)
99+ begin
100+ IO.popen("\"#{dotcmd}\" -Tsvg 2>&1", 'r+') {|io|
101+ io.puts src
102+ io.close_write
103+ while (str = io.gets)
104+ if (errptn =~ str)
105+ errstr << str
106+ elsif (warningptn =~ str)
107+ errstr << str
108+ elsif (bgnptn)
109+ if (bgnptn =~ str)
110+ dest += str
111+ bgnptn = nil
112+ else
113+ reststr << str
114+ end
115+ elsif (!bgnptn and endptn)
116+ dest += str
117+ endptn = nil if (endptn =~ str)
118+ else
119+ reststr << str
120+ end
121+ end
122+ }
123+ rescue => evar
124+ errstr << l(:text_err_dot) + "\n"
125+ errstr << Kconv.toutf8(evar.to_s)
126+ end
127+ if (dest.empty? or !$?.exited? or $?.exitstatus != 0)
128+ errstr = l(:text_err_dot) + "\n" + Kconv.toutf8(errstr)
129+ errstr << Kconv.toutf8(reststr)
130+ end
131+ {:svg=>dest, :err=>errstr}
132+ end
133+
134+ def create_workflow_chart(graphname, statuses, wf, subwf)
135+ results = exec_dot(create_dot_digraph_workflow(graphname, statuses, wf, subwf))
136+ output = results[:svg]
137+ unless (results[:err].blank?)
138+ output += "<div class='nodata'> #{simple_format(results[:err])}</div>"
139+ end
140+ output
141+ end
142+
143+end
--- tags/1.0.2/redmine_information/config/routes.rb (nonexistent)
+++ tags/1.0.2/redmine_information/config/routes.rb (revision 55)
@@ -0,0 +1,3 @@
1+
2+match '/information/:id', :to=> 'info#show', :via=>'get'
3+match '/information', :to=> 'info#index', :via=>'get'
--- tags/1.0.2/redmine_information/config/locales/de.yml (nonexistent)
+++ tags/1.0.2/redmine_information/config/locales/de.yml (revision 55)
@@ -0,0 +1,21 @@
1+de:
2+ label_redmine_info: Information
3+
4+ label_info_categories: Informationskategorien
5+ label_hide_info_categories: Auswahl Kategorien für Systeminformatiomnen
6+ label_workflow_chart: Workflow Übersicht
7+ label_use_dot: Graphviz(dot) wird verwendet
8+ label_dot_cmdpath: Der Installationpfad für Graphviz "dot"
9+ descript_dot_cmdpath: Falls hier nicht zu sehen ist, wird Graphviz "dot" verwendet.
10+
11+ label_wiki_macros: Wiki Makros
12+ label_rails_info: Rails Information
13+
14+ label_all_ng: Alle NG
15+
16+ text_no_public: "Informationen dieser Kategorie sind nicht öffentlich."
17+ text_err_dot: Fehler beim Aufruf der dot Executable.
18+ text_no_rails_info: "Anzeige von Rails Infomationen für diese Distribution nicht möglich."
19+
20+ label_notification: Benachrichtigung
21+ label_action: Aktion
--- tags/1.0.2/redmine_information/config/locales/ko.yml (nonexistent)
+++ tags/1.0.2/redmine_information/config/locales/ko.yml (revision 55)
@@ -0,0 +1,22 @@
1+# Translation by Ki Won Kim (http://xyz37.blog.me, xyz37@naver.com)
2+ko:
3+ label_redmine_info: "정보"
4+
5+ label_info_categories: "정보 범주"
6+ label_hide_info_categories: "숨길 정보 범주 선택"
7+ label_workflow_chart: "업무흐름 차트"
8+ label_use_dot: "Graphviz(dot) 사용(http://www.graphviz.org 설치 해야함)"
9+ label_dot_cmdpath: "\"dot\"의 파일 경로"
10+ descript_dot_cmdpath: "빈칸이면 \"dot\" 이 사용됨."
11+
12+ label_wiki_macros: "위키 매크로"
13+ label_rails_info: "Rails 정보"
14+
15+ label_all_ng: "모두 NG"
16+
17+ text_no_public: "이 범주의 정보는 공용화 할 수 없습니다."
18+ text_err_dot: "dot 명령이 실패 했습니다."
19+ text_no_rails_info: "이 Rails 버전에서는 Rails 정보를 보여줄 수 없습니다."
20+
21+ label_notification: "알림"
22+ label_action: "동작"
--- tags/1.0.2/redmine_information/config/locales/zh.yml (nonexistent)
+++ tags/1.0.2/redmine_information/config/locales/zh.yml (revision 55)
@@ -0,0 +1,21 @@
1+zh:
2+ label_redmine_info: 系统信息
3+
4+ label_info_categories: 系统信息分类
5+ label_hide_info_categories: 设置用户不可见信息
6+ label_workflow_chart: 工作流程图
7+ label_use_dot: 使用Graphviz(DOT)展示
8+ label_dot_cmdpath: DOT 文件路径
9+ descript_dot_cmdpath: 若为空,则DOT已被使用
10+
11+ label_wiki_macros: Wiki 宏信息
12+ label_rails_info: Rails 版本信息
13+
14+ label_all_ng: 未分级用户(ALL NG)
15+
16+ text_no_public: "此类信息不能设置为公开浏览。"
17+ text_err_dot: 无法执行DOT命令。
18+ text_no_rails_info: "无法显示当前所用Rails的版本。"
19+
20+ label_notification: 已配置
21+ label_action: 通知处理内容
\ No newline at end of file
--- tags/1.0.2/redmine_information/config/locales/en.yml (nonexistent)
+++ tags/1.0.2/redmine_information/config/locales/en.yml (revision 55)
@@ -0,0 +1,21 @@
1+en:
2+ label_redmine_info: Information
3+
4+ label_info_categories: Information categories
5+ label_hide_info_categories: Selections of hidden information categories
6+ label_workflow_chart: Work flow chart
7+ label_use_dot: Use Graphviz(dot)
8+ label_dot_cmdpath: The file path of "dot"
9+ descript_dot_cmdpath: If this is blank, "dot" is used.
10+
11+ label_wiki_macros: Wiki macros
12+ label_rails_info: Rails information
13+
14+ label_all_ng: ALL NG
15+
16+ text_no_public: "Information on this category isn't made public."
17+ text_err_dot: Failed to execute dot command.
18+ text_no_rails_info: "Can't show Rails infomation in this Rails version."
19+
20+ label_notification: Notification
21+ label_action: Action
--- tags/1.0.2/redmine_information/config/locales/ja.yml (nonexistent)
+++ tags/1.0.2/redmine_information/config/locales/ja.yml (revision 55)
@@ -0,0 +1,22 @@
1+ja:
2+ label_redmine_info: 情報
3+
4+ label_info_categories: カテゴリ
5+ label_hide_info_categories: 非表示にするカテゴリの選択
6+ label_workflow_chart: ワークフロー チャート
7+ label_use_dot: Graphviz(dot) を使用する
8+ label_dot_cmdpath: dot コマンドのパス
9+ descript_dot_cmdpath: 省略時は "dot"
10+
11+ label_wiki_macros: Wiki マクロ
12+ label_rails_info: Rails 情報
13+
14+ label_all_ng: すべて不可
15+
16+ text_no_public: このカテゴリの情報は公開されていません。
17+ text_err_dot: dot コマンドの実行に失敗しました。
18+ text_no_rails_info: 現在のバージョンの Rails では Rails 情報を表示できません。
19+
20+ label_notification: 通知
21+ label_action: アクション
22+
--- tags/1.0.2/redmine_information/lib/info_category.rb (nonexistent)
+++ tags/1.0.2/redmine_information/lib/info_category.rb (revision 55)
@@ -0,0 +1,55 @@
1+#
2+# info_category.rb
3+#
4+
5+class InfoCategory
6+
7+ @@captions = {}
8+
9+ def self.categories
10+ [:permissions, :workflows, :settings, :plugins, :wiki_macros, :rails_info, :version]
11+ end
12+
13+ def self.caption(sym)
14+ case sym.to_sym
15+ when :permissions
16+ :label_permissions_report
17+ when :workflows
18+ :label_workflow
19+ when :version
20+ :label_information_plural
21+ else
22+ ('label_' + sym.to_s).to_sym
23+ end
24+ end
25+
26+
27+ def self.hide_map
28+ map = {}
29+ InfoCategory.categories.each {|catsym|
30+ map['hide_' + catsym.to_s] = (catsym.to_s == "rails_info") ? true : false
31+ }
32+ map
33+ end
34+
35+
36+ def self.push_menu(menu, catsym, opts = {})
37+ url = {:controller => :info, :action => :show}
38+ copts = opts.clone
39+
40+ url[:id] = catsym
41+ copts[:if] = Proc.new { (InfoCategory::is_shown?(catsym) or User.current.admin?) }
42+
43+ copts[:caption] = self.caption(catsym)
44+
45+ menu.push(catsym, url, copts)
46+ end
47+
48+
49+ def self.is_shown?(catsym)
50+ hidekey = 'hide_' + catsym.to_s
51+ return !Setting.plugin_redmine_information[hidekey]
52+ end
53+
54+
55+end
--- tags/1.0.2/redmine_information/assets/stylesheets/redmine_info.css (nonexistent)
+++ tags/1.0.2/redmine_information/assets/stylesheets/redmine_info.css (revision 55)
@@ -0,0 +1,5 @@
1+#admin-menu a.wiki-macros { background-image: url('../images/wiki_macros.png'); }
2+#admin-menu a.rails-info { background-image: url('../images/rails_mini.png'); }
3+.icon-weak { background-image: url('../images/true_weak.png'); }
4+th.selected, td.selected{ text-decoration: underline;}
5+td.target{ border: inset 2px black; }
\ No newline at end of file
Show on old repository browser