mtm 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/tm +2 -0
- data/lib/mtm/tm.rb +251 -0
- data/lib/mtm/version.rb +1 -1
- metadata +7 -9
- data/.gitignore +0 -17
- data/Gemfile +0 -7
- data/LICENSE.txt +0 -22
- data/Rakefile +0 -1
- data/mtm.gemspec +0 -19
data/bin/tm
ADDED
data/lib/mtm/tm.rb
ADDED
@@ -0,0 +1,251 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
####################################################################################
|
4
|
+
############################### start parse value ##################################
|
5
|
+
####################################################################################
|
6
|
+
# please fill these fields: ###
|
7
|
+
sf_username = '' # Salesforce user name ###
|
8
|
+
sf_password = '' # Salesforce password ###
|
9
|
+
sf_security_token = '' # Salesforce password security token(option) ###
|
10
|
+
####################################################################################
|
11
|
+
############################## end parse value #####################################
|
12
|
+
####################################################################################
|
13
|
+
|
14
|
+
=begin
|
15
|
+
How to use this script?
|
16
|
+
0. Opens your teminal and input:$: gem install restforce
|
17
|
+
$: gem install ruby-progressbar
|
18
|
+
|
19
|
+
1. Puts this file to '/usr/bin' folder
|
20
|
+
$: cd /user/bin
|
21
|
+
$: chmod 755 tm
|
22
|
+
2. Opens this file and paste your user name and password.
|
23
|
+
3. Opens your teminal and input: tm -p 'Project name' -c 'Change name' -h 8 -d 'Tested some pages' -u bruce.yue:password
|
24
|
+
The default hours is 8 and default description is "Tested some pages and fixed some bugs."
|
25
|
+
If step 2 have been done, '-u' is not required in the step 3.
|
26
|
+
For example:
|
27
|
+
Project "Silver Peak Development Requests", Its change is "Automate Upload of Build Records"
|
28
|
+
$: tm -p 'Peak Development' -c 'Build Records' -h 6 -d 'Added exception process logic.'
|
29
|
+
|
30
|
+
If there is no change. just paste
|
31
|
+
$: tm -p 'Peak Development' -h 6 -d 'Added exception process logic.'
|
32
|
+
|
33
|
+
Fill your time card at some time.
|
34
|
+
$: at 9pm today tm -p 'Peak Development' -h 6 -d 'Added exception process logic.'
|
35
|
+
=end
|
36
|
+
|
37
|
+
# salesforce remote app client id
|
38
|
+
sf_client_id = '3MVG9Y6d_Btp4xp6SWO6yPlUURnycVbOfuH7I_NH2bjaw0yeoguRatNzKRpEVaIvmX7TcQbVVjuQUCZ006pwN'
|
39
|
+
sf_client_secret = '5339957415407001741' # salesforce remote app client secret
|
40
|
+
user_name_suffix = '@pm.meginfo.com'
|
41
|
+
sf_project = '' # project name
|
42
|
+
sf_project_number = nil # project number
|
43
|
+
sf_change = '' # change name
|
44
|
+
sf_change_number = nil # change number
|
45
|
+
sf_hour = 8 # time card hours
|
46
|
+
|
47
|
+
require 'rubygems'
|
48
|
+
require 'restforce' # gem install restforce
|
49
|
+
require 'optparse/date'
|
50
|
+
require 'ruby-progressbar'
|
51
|
+
|
52
|
+
@pb = ProgressBar.create(:title => 'Logging', :starting_at => 40, :total => 100, :progress_mark => '*', :format => '%w %%')
|
53
|
+
|
54
|
+
# for date format argv
|
55
|
+
def parse_days_or_date(d)
|
56
|
+
if d.to_s =~ /^\d+$/
|
57
|
+
d.to_i
|
58
|
+
else
|
59
|
+
Date.parse(d)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Parse arguments
|
64
|
+
options = {}
|
65
|
+
options[:user_name] = sf_username
|
66
|
+
options[:password] = sf_password
|
67
|
+
options[:security_token] = sf_security_token
|
68
|
+
options[:test] = false
|
69
|
+
options[:host] = 'login.salesforce.com'
|
70
|
+
options[:tm_list] = false
|
71
|
+
options[:tm_project] = sf_project
|
72
|
+
options[:tm_p_number] = sf_project_number
|
73
|
+
options[:tm_change] = sf_change
|
74
|
+
options[:tm_c_number] = sf_change_number
|
75
|
+
options[:tm_hour] = sf_hour
|
76
|
+
options[:tm_date] = DateTime.now.to_date
|
77
|
+
options[:tm_description] = 'Tested some pages and fixed some bugs.'
|
78
|
+
|
79
|
+
op = OptionParser.new do |opts|
|
80
|
+
opts.banner = <<-BANNER
|
81
|
+
Timecard Solution
|
82
|
+
Usage: tm -p project -c change -h 6 -d 'Added exception process logic.'
|
83
|
+
BANNER
|
84
|
+
opts.separator ''
|
85
|
+
|
86
|
+
opts.on("-u", "--user username:password", "The user name and password.") do |u|
|
87
|
+
options[:up] = u
|
88
|
+
options[:user_name] = options[:up].split(':').first << user_name_suffix
|
89
|
+
options[:password] = options[:up].split(':').last
|
90
|
+
end
|
91
|
+
|
92
|
+
opts.on("-T", "--token token", "The password security token.") do |token|
|
93
|
+
options[:security_token] = token
|
94
|
+
end
|
95
|
+
|
96
|
+
opts.on("-s", "Change to sandbox environment.") do |test|
|
97
|
+
options[:test] = test
|
98
|
+
options[:host] = 'test.salesforce.com'
|
99
|
+
end
|
100
|
+
|
101
|
+
opts.on("-l", "List all your not closed projects and chnages.") do |list|
|
102
|
+
options[:tm_list] = list
|
103
|
+
end
|
104
|
+
|
105
|
+
opts.on("-p ProjectName", "The project full Name or part name.") do |project|
|
106
|
+
options[:tm_project] = project
|
107
|
+
end
|
108
|
+
|
109
|
+
opts.on("-N ProjectNumber", "The project number.") do |number_p|
|
110
|
+
options[:tm_p_number] = number_p
|
111
|
+
end
|
112
|
+
|
113
|
+
opts.on("-c ChangeName", String, "Full change name or part.") do |c|
|
114
|
+
options[:tm_change] = c
|
115
|
+
end
|
116
|
+
|
117
|
+
opts.on("-n ChangeNumber", "The change number.") do |number_c|
|
118
|
+
options[:tm_c_number] = number_c
|
119
|
+
end
|
120
|
+
|
121
|
+
opts.on("-t Hours", Float, "Total hours of todays work.") do |h|
|
122
|
+
options[:tm_hour] = h
|
123
|
+
end
|
124
|
+
|
125
|
+
opts.on("-d", "--date YYYY-MM-DD", "Timecard Date, default: TODAY", "Enter date in (YYYY-MM-DD) format.") do |d|
|
126
|
+
options[:tm_date] = parse_days_or_date(d)
|
127
|
+
end
|
128
|
+
|
129
|
+
opts.on("-e Description", "Timecard detail information, describle today's work.") do |desc|
|
130
|
+
options[:tm_description] = desc
|
131
|
+
end
|
132
|
+
|
133
|
+
opts.on_tail("-h", "--help", "Show help message") do
|
134
|
+
puts op
|
135
|
+
exit
|
136
|
+
end
|
137
|
+
end
|
138
|
+
op.parse(ARGV)
|
139
|
+
|
140
|
+
if ARGV.size < 1
|
141
|
+
puts op
|
142
|
+
exit
|
143
|
+
end
|
144
|
+
|
145
|
+
# login to salesforce.com
|
146
|
+
begin
|
147
|
+
@client = Restforce.new :client_id => sf_client_id,
|
148
|
+
:client_secret => sf_client_secret,
|
149
|
+
:username => options[:user_name],
|
150
|
+
:password => options[:password],
|
151
|
+
:security_token => options[:security_token],
|
152
|
+
:host => options[:host]
|
153
|
+
response = @client.authenticate!
|
154
|
+
info = @client.get(response.id).body
|
155
|
+
@sf_user_id = info.user_id
|
156
|
+
rescue Exception => e
|
157
|
+
puts e.message
|
158
|
+
abort 'Failed to connect to Salesforce.'
|
159
|
+
end
|
160
|
+
|
161
|
+
# list all projects and its changes
|
162
|
+
if options[:tm_list]
|
163
|
+
40.times { sleep(0.05); @pb.increment }
|
164
|
+
projects = @client.query("select Id, Name, ProjectNumber__c, (select Id, Name, ChangeNumber__c from Changes__r
|
165
|
+
where Status__c != 'Closed') from MProject__c where Status__c != 'Closed'")
|
166
|
+
projects.each do |p|
|
167
|
+
puts
|
168
|
+
puts p.ProjectNumber__c + ': ' + p.Name
|
169
|
+
if p.Changes__r != nil
|
170
|
+
p.Changes__r.each do |c|
|
171
|
+
puts ' '+ c.ChangeNumber__c + ': ' + c.Name
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
@pb.finish
|
176
|
+
abort
|
177
|
+
end
|
178
|
+
|
179
|
+
# Creates time card
|
180
|
+
def create_timecard(*args)
|
181
|
+
@tm = @client.create!('TimeCard__c', Project__c: args[0],
|
182
|
+
Change__c: args[1],
|
183
|
+
Date__c: args[2],
|
184
|
+
Hours__c: args[3],
|
185
|
+
TeamMember__c: args[4],
|
186
|
+
Description__c: args[5])
|
187
|
+
puts
|
188
|
+
puts "Timecrad created successfully. Hour: '#{args[3]}', Project: '#{args[6]}'"
|
189
|
+
end
|
190
|
+
|
191
|
+
msg = 'Project not found'
|
192
|
+
begin
|
193
|
+
if options[:tm_project] != ''
|
194
|
+
projects = @client.query("select Id, Name, (select Id, Name from Changes__r where Status__c != 'Closed' and
|
195
|
+
Name like '%#{options[:tm_change]}%') from MProject__c where Status__c != 'Closed'
|
196
|
+
and Name like '%#{options[:tm_project]}%'")
|
197
|
+
end
|
198
|
+
if options[:tm_p_number] != nil
|
199
|
+
projects = @client.query("select Id, Name, (select Id, Name from Changes__r where Status__c != 'Closed'
|
200
|
+
and ChangeNumber__c = '#{options[:tm_c_number]}')
|
201
|
+
from MProject__c where Status__c != 'Closed' and ProjectNumber__c = '#{options[:tm_p_number]}'")
|
202
|
+
end
|
203
|
+
30.times { sleep(0.05); @pb.increment }
|
204
|
+
rescue Exception => e
|
205
|
+
puts
|
206
|
+
puts e.message
|
207
|
+
abort msg
|
208
|
+
end
|
209
|
+
|
210
|
+
if options[:tm_project] == '' && options[:tm_p_number] == nil
|
211
|
+
puts
|
212
|
+
abort "You must enter -p ProjectName or -N ProjectNumber to specify a project."
|
213
|
+
end
|
214
|
+
|
215
|
+
if projects.first == nil
|
216
|
+
puts
|
217
|
+
abort msg
|
218
|
+
end
|
219
|
+
|
220
|
+
begin
|
221
|
+
if projects.size == 1
|
222
|
+
team_member = @client.query("select Id from TeamMember__c where Project__c = '#{projects.first.Id}' and User__c = '#{@sf_user_id}'");
|
223
|
+
if(options[:tm_change] == '' && options[:tm_c_number] == nil)
|
224
|
+
create_timecard(projects.first.Id, nil, options[:tm_date], options[:tm_hour],
|
225
|
+
team_member.first.Id, options[:tm_description], projects.first.Name)
|
226
|
+
else
|
227
|
+
if (projects.first.Changes__r != nil && projects.first.Changes__r.size == 1)
|
228
|
+
create_timecard(projects.first.Id, projects.first.Changes__r.first.Id,
|
229
|
+
options[:tm_date], options[:tm_hour], team_member.first.Id,
|
230
|
+
options[:tm_description], projects.first.Name)
|
231
|
+
elsif projects.first.Changes__r == nil
|
232
|
+
puts
|
233
|
+
puts 'No change found.'
|
234
|
+
else
|
235
|
+
puts
|
236
|
+
puts 'Please select a change to continue:'
|
237
|
+
projects.first.Changes__r.each { |c| puts c.Name }
|
238
|
+
end
|
239
|
+
end
|
240
|
+
else
|
241
|
+
puts
|
242
|
+
puts 'Please select a project to continue:'
|
243
|
+
projects.each { |p| puts p.Name }
|
244
|
+
end
|
245
|
+
rescue Exception => e
|
246
|
+
puts
|
247
|
+
puts e.message
|
248
|
+
abort 'Failed to create timecard.'
|
249
|
+
end
|
250
|
+
|
251
|
+
@pb.finish
|
data/lib/mtm/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mtm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -14,18 +14,16 @@ dependencies: []
|
|
14
14
|
description: Timecard solution
|
15
15
|
email:
|
16
16
|
- bruce.yue@meginfo.com
|
17
|
-
executables:
|
17
|
+
executables:
|
18
|
+
- tm
|
18
19
|
extensions: []
|
19
20
|
extra_rdoc_files: []
|
20
21
|
files:
|
21
|
-
- .
|
22
|
-
- Gemfile
|
23
|
-
- LICENSE.txt
|
24
|
-
- README.md
|
25
|
-
- Rakefile
|
26
|
-
- lib/mtm.rb
|
22
|
+
- lib/mtm/tm.rb
|
27
23
|
- lib/mtm/version.rb
|
28
|
-
- mtm.
|
24
|
+
- lib/mtm.rb
|
25
|
+
- README.md
|
26
|
+
- bin/tm
|
29
27
|
homepage: http://www.sharealltech.com
|
30
28
|
licenses: []
|
31
29
|
post_install_message:
|
data/.gitignore
DELETED
data/Gemfile
DELETED
data/LICENSE.txt
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2013 Bruce Yue
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
data/mtm.gemspec
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'mtm/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |gem|
|
7
|
-
gem.name = "mtm"
|
8
|
-
gem.version = Mtm::VERSION
|
9
|
-
gem.authors = ["Bruce Yue"]
|
10
|
-
gem.email = ["bruce.yue@meginfo.com"]
|
11
|
-
gem.description = %q{Timecard solution}
|
12
|
-
gem.summary = %q{Timecard}
|
13
|
-
gem.homepage = "http://www.sharealltech.com"
|
14
|
-
|
15
|
-
gem.files = `git ls-files`.split($/)
|
16
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
-
gem.require_paths = ["lib"]
|
19
|
-
end
|