synrp 0.16.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in synrp.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ synrp (0.16.4)
5
+ cri (~> 2.2)
6
+ json
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ cri (2.2.1)
12
+ json (1.6.6)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ synrp!
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/synrp ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Try loading bundler if it's possible
4
+ begin
5
+ require 'rubygems'
6
+ require 'bundler/setup'
7
+ rescue LoadError
8
+ # no problem
9
+ end
10
+
11
+ # Add lib to load path
12
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
13
+
14
+ require 'synrp'
15
+ require 'synrp/cli'
16
+
17
+ Synrp::CLI.run(ARGV)
18
+
data/lib/synrp/cli.rb ADDED
@@ -0,0 +1,190 @@
1
+ require 'cri'
2
+
3
+ module Synrp::CLI
4
+
5
+ synRP = Synrp::SynRP.new
6
+
7
+ @cmd = Cri::Command.define do
8
+ name 'rpt'
9
+ usage 'rpt [options] [command] [options]'
10
+ summary 'to access ressourceplanning via commandline'
11
+ description <<-DESC
12
+ For --site, --username and --passwort parameters you can
13
+ also use a yaml config file.
14
+
15
+ To do so, just
16
+
17
+ cp config.yaml.sample ~/.synRP_config.yaml
18
+
19
+ DESC
20
+
21
+ flag :h, :help, 'show help for this command' do |value, cmd|
22
+ puts @cmd.help
23
+ exit 0
24
+ end
25
+
26
+ required :s, :site, 'domain name of respt system (without http://)'
27
+ required :u, :username, 'username at given site'
28
+ required :p, :password, 'password at given site'
29
+ end
30
+
31
+ @cmd.add_command Cri::Command.new_basic_help
32
+
33
+ @cmd.define_command do
34
+ name 'req'
35
+ aliases :request, :allocation_request
36
+ usage 'req [options]'
37
+ summary 'requests ressources'
38
+
39
+ required :k, :kw, 'yyyy-Wn (e. g. 2012-W6)'
40
+ required :P, :project, 'project id or name'
41
+ required :e, :person, 'person id or display name (find id via "persons")'
42
+ required :m, :minutes, 'request time in minutes'
43
+ required :c, :comment, 'comment to the request'
44
+
45
+ run do |opts, args|
46
+
47
+ synRP.verify_opts_present(opts, [ :site, :username, :password, :kw, :project, :person, :minutes ])
48
+
49
+ synRP.connect(opts[:site], opts[:username], opts[:password])
50
+
51
+ project_id = synRP.find_project_id_by_project_name(opts[:project]) || opts[:project]
52
+ person_id = synRP.find_person_id_by_displayname(opts[:person]) || opts[:person]
53
+
54
+ synRP.request_res(opts[:kw], project_id, person_id, opts[:minutes], opts[:comment])
55
+ end
56
+ end
57
+
58
+ @cmd.define_command do
59
+ name 'availabilities'
60
+ usage 'availabilities [options]'
61
+ summary 'check who is available in given week'
62
+
63
+ required :k, :kw, 'yyyy-Wn (e. g. 2012-W6)'
64
+
65
+ run do |opts, args|
66
+
67
+ synRP.verify_opts_present(opts, [ :site, :username, :password, :kw ])
68
+
69
+ synRP.connect(opts[:site], opts[:username], opts[:password])
70
+
71
+ puts JSON.pretty_generate synRP.get_availabilities_persons(opts[:kw])
72
+ end
73
+ end
74
+
75
+ @cmd.define_command do
76
+ name 'allocation_requests'
77
+ usage 'allocation_requests [options]'
78
+ summary 'get all allocation requests of a given week'
79
+
80
+ required :k, :kw, 'yyyy-Wn (e. g. 2012-W6)'
81
+
82
+ run do |opts, args|
83
+
84
+ synRP.verify_opts_present(opts, [ :site, :username, :password, :kw ])
85
+
86
+ synRP.connect(opts[:site], opts[:username], opts[:password])
87
+
88
+ puts JSON.pretty_generate synRP.get_allocation_requests(opts[:kw])
89
+ end
90
+ end
91
+
92
+ @cmd.define_command do
93
+ name 'remaining_availabilities'
94
+ usage 'remaining_availabilities [options]'
95
+ summary 'remaining_availabilities of a given week'
96
+
97
+ required :k, :kw, 'yyyy-Wn (e. g. 2012-W6)'
98
+
99
+ run do |opts, args|
100
+
101
+ synRP.verify_opts_present(opts, [ :site, :username, :password, :kw ])
102
+
103
+ synRP.connect(opts[:site], opts[:username], opts[:password])
104
+
105
+ puts JSON.pretty_generate synRP.calculate_remaining_availabilities(opts[:kw])
106
+ end
107
+ end
108
+
109
+ @cmd.define_command do
110
+ name 'reqs_of_person'
111
+ usage 'reqs_of_person [options]'
112
+ summary 'get all allocation requests of a given week of a person'
113
+
114
+ required :k, :kw, 'yyyy-Wn (e. g. 2012-W6)'
115
+ required :e, :person, 'person id or display name (find id via "persons")'
116
+
117
+ run do |opts, args|
118
+
119
+ synRP.verify_opts_present(opts, [ :site, :username, :password, :kw, :person ])
120
+
121
+ synRP.connect(opts[:site], opts[:username], opts[:password])
122
+
123
+ person_id = synRP.find_person_id_by_displayname(opts[:person]) || opts[:person]
124
+
125
+ puts JSON.pretty_generate synRP.get_allocation_requests_of_person(opts[:kw], person_id)
126
+ end
127
+ end
128
+
129
+ @cmd.define_command do
130
+ name 'req_all_meta'
131
+ usage 'req_all_meta [options]'
132
+ summary 'request meta ressources for all available employees'
133
+
134
+ required :k, :kw, 'yyyy-Wn (e. g. 2012-W6)'
135
+
136
+ run do |opts, args|
137
+
138
+ synRP.verify_opts_present(opts, [ :site, :username, :password, :kw ])
139
+
140
+ synRP.connect(opts[:site], opts[:username], opts[:password])
141
+
142
+ project_id = synRP.find_project_id_by_project_name("Meta")
143
+
144
+ all_persons = synRP.get_persons
145
+
146
+ synRP.get_availabilities(opts[:kw]).each do |person_id, minutes|
147
+ person = all_persons.find {|p| p["id"] == person_id.to_i }
148
+ if minutes > 0 && person["visible"]
149
+ synRP.request_res(opts[:kw], project_id, person_id, 120, 'Default Meta')
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ @cmd.define_command do
156
+ name 'persons'
157
+ usage 'persons [options]'
158
+ summary 'get all persons as json'
159
+
160
+ run do |opts, args|
161
+
162
+ synRP.verify_opts_present(opts, [ :site, :username, :password ])
163
+
164
+ synRP.connect(opts[:site], opts[:username], opts[:password])
165
+
166
+ puts JSON.pretty_generate synRP.get_persons
167
+ end
168
+ end
169
+
170
+ @cmd.define_command do
171
+ name 'projects'
172
+ usage 'projects [options]'
173
+ summary 'get all projects as json'
174
+
175
+ run do |opts, args|
176
+
177
+ synRP.verify_opts_present(opts, [ :site, :username, :password ])
178
+
179
+ synRP.connect(opts[:site], opts[:username], opts[:password])
180
+
181
+ puts JSON.pretty_generate synRP.get_projects
182
+ end
183
+ end
184
+
185
+ def self.run(args)
186
+ @cmd.run(ARGV)
187
+ end
188
+
189
+ end
190
+
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Library to use SynRP REST API
4
+ #
5
+ # Author
6
+ #
7
+ # Fabian Buch
8
+ #
9
+
10
+ require 'net/http'
11
+ require 'json'
12
+ require 'yaml'
13
+
14
+ module Synrp
15
+ class SynRP
16
+
17
+ def setup(opts)
18
+ opts = verify_opts_present(opts, [ :site, :username, :password ])
19
+ end
20
+
21
+ def verify_opts_present(opts, req_opts)
22
+ config_opts = read_config
23
+ req_opts.each do |r_opt|
24
+ unless opts[r_opt]
25
+ if config_opts[r_opt.to_s]
26
+ opts[r_opt] = config_opts[r_opt.to_s]
27
+ else
28
+ $stderr.puts "--#{r_opt} option is required"
29
+ exit 1
30
+ end
31
+ end
32
+ end
33
+ opts
34
+ end
35
+
36
+ def read_config
37
+ begin
38
+ return YAML.load_file(File.expand_path("~/.synRP_config.yaml"))
39
+ rescue
40
+ begin
41
+ current_dir = File.dirname(File.expand_path(__FILE__))
42
+ return YAML.load_file(current_dir + "/config.yaml")
43
+ rescue
44
+ end
45
+ end
46
+ return {}
47
+ end
48
+
49
+ def connect(site, username, password)
50
+ $conn = Net::HTTP.new(site, 80)
51
+ resp, data = $conn.post("/web/j_spring_security_check", "j_username=#{username}&j_password=#{password}", {})
52
+ cookie = resp.response['set-cookie']
53
+ $headers = { "Cookie" => cookie }
54
+ end
55
+
56
+ def get_persons
57
+ resp, data = $conn.get("/web/persons.json", $headers)
58
+ JSON.parse data
59
+ end
60
+
61
+ def find_project_id_by_project_name(pname)
62
+ project = get_projects.find {|p| p["name"] == pname }
63
+ project_id = project ? project["id"] : nil
64
+ end
65
+
66
+ def find_person_id_by_displayname(person_name)
67
+ person = get_persons.find { |p|
68
+ # replace weird whitespace with new one before comparing
69
+ p["displayName"].gsub(/\302\240/, ' ').match(person_name)
70
+ }
71
+ person_id = person ? person["id"] : nil
72
+ end
73
+
74
+ def find_person_by_id(id)
75
+ get_persons.find {|p| p["id"].to_s == id.to_s }
76
+ end
77
+
78
+ def get_projects
79
+ resp, data = $conn.get("/web/projects.json", $headers)
80
+ JSON.parse data
81
+ end
82
+
83
+ def get_availabilities(yearWeek)
84
+ resp, data = $conn.get("/web/availabilities.json?yearWeek=#{yearWeek}", $headers)
85
+ av = JSON.parse data
86
+ without_invisible = av.reject { |k,v| !find_person_by_id(k)["visible"] }
87
+ end
88
+
89
+ # get availabilities with resolved person, not their IDs
90
+ def get_availabilities_persons(yearWeek)
91
+ avails = get_availabilities(yearWeek)
92
+ avails.map { |k,v| { find_person_by_id(k)["displayName"], "#{v / 60.0} h" } }.inject(&:merge)
93
+ end
94
+
95
+ def get_allocation_requests(yearWeek)
96
+ resp, data = $conn.get("/web/allocation-requests.json?yearWeek=#{yearWeek}", $headers)
97
+ JSON.parse data
98
+ end
99
+
100
+ def get_allocation_requests_of_person(yearWeek, person_id)
101
+ reqs = get_allocation_requests(yearWeek)
102
+ reqs.find_all { |req| req["person"]["id"].to_s == person_id.to_s }
103
+ end
104
+
105
+ def calculate_remaining_availabilities(yearWeek)
106
+ avails = get_availabilities(yearWeek)
107
+ avails_minus_requests = avails.map do |person_id, minutes|
108
+ person = find_person_by_id(person_id)
109
+ reqs_of_person = get_allocation_requests_of_person(yearWeek, person_id)
110
+ remaining_minutes = minutes - sum_minutes_of_requests(reqs_of_person)
111
+ { person, remaining_minutes }
112
+ end.inject(&:merge)
113
+ avails_minus_requests.to_a.sort_by { |av| -av[1] }
114
+ end
115
+
116
+ def sum_minutes_of_requests(reqs)
117
+ sum = 0
118
+ reqs.each do |req|
119
+ sum += req["minutes"]
120
+ end
121
+ sum
122
+ end
123
+
124
+ def request_res(yearWeek, project, person, minutes, comment='')
125
+ puts "Requesting yearWeek=#{yearWeek}&project=#{project}&person=#{person}&minutes=#{minutes}&comment=#{comment}"
126
+ $conn.post("/web/allocation-requests/", "yearWeek=#{yearWeek}&project=#{project}&person=#{person}&minutes=#{minutes}&comment=#{comment}", $headers)
127
+ end
128
+
129
+ end
130
+ end
131
+
@@ -0,0 +1,3 @@
1
+ module Synrp
2
+ VERSION = "0.16.4"
3
+ end
data/lib/synrp.rb ADDED
@@ -0,0 +1,19 @@
1
+ #
2
+ # Library to use SynRP REST API
3
+ #
4
+ # Author
5
+ #
6
+ # Fabian Buch
7
+ #
8
+ #
9
+
10
+ require "synrp/version"
11
+ require "synrp/synrp"
12
+
13
+ module Synrp
14
+
15
+ def self.version_information
16
+ Nanoc::VERSION
17
+ end
18
+
19
+ end
data/synrp.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "synrp/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "synrp"
7
+ s.version = Synrp::VERSION
8
+ s.authors = ["Fabian Buch"]
9
+ s.email = ["buch@synyx.de"]
10
+ s.homepage = "https://github.com/Synyx/synRP"
11
+ s.summary = %q{Commandline Client for Synyx Resource Planner (synRP)}
12
+ s.description = %q{The synyx Resource Planner is a web application for managing work assignments. See https://github.com/Synyx/synRP for more information. This is a commandline client that uses its REST service.}
13
+
14
+ s.files = Dir['[A-Z]*'] + Dir['{bin,lib,tasks,test}/**/*'] + [ 'synrp.gemspec' ]
15
+ s.executables = [ 'synrp' ]
16
+ s.require_paths = [ 'lib' ]
17
+
18
+ s.add_runtime_dependency "cri", '~> 2.2'
19
+ s.add_runtime_dependency "json"
20
+
21
+ s.post_install_message = %q{------------------------------------------------------------------------------
22
+ run "synrp help" for usage information
23
+ ------------------------------------------------------------------------------
24
+ }
25
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: synrp
3
+ version: !ruby/object:Gem::Version
4
+ hash: 87
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 16
9
+ - 4
10
+ version: 0.16.4
11
+ platform: ruby
12
+ authors:
13
+ - Fabian Buch
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-04-11 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: cri
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 7
29
+ segments:
30
+ - 2
31
+ - 2
32
+ version: "2.2"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ description: The synyx Resource Planner is a web application for managing work assignments. See https://github.com/Synyx/synRP for more information. This is a commandline client that uses its REST service.
50
+ email:
51
+ - buch@synyx.de
52
+ executables:
53
+ - synrp
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - Gemfile.lock
60
+ - Gemfile
61
+ - Rakefile
62
+ - bin/synrp
63
+ - lib/synrp.rb
64
+ - lib/synrp/cli.rb
65
+ - lib/synrp/synrp.rb
66
+ - lib/synrp/version.rb
67
+ - synrp.gemspec
68
+ homepage: https://github.com/Synyx/synRP
69
+ licenses: []
70
+
71
+ post_install_message: |
72
+ ------------------------------------------------------------------------------
73
+ run "synrp help" for usage information
74
+ ------------------------------------------------------------------------------
75
+
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.10
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Commandline Client for Synyx Resource Planner (synRP)
105
+ test_files: []
106
+