ruby-bugzilla 0.5.3 → 0.6.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0307f396074f4bfc609205e13921d0998140cdaf
4
- data.tar.gz: db4d1be9d736eb65ee0e71076bb9a4b03181b720
3
+ metadata.gz: 7f1b54d90d2ee896e2db7a4a7bdff393ab698fd8
4
+ data.tar.gz: 763e07f07701a042631ee927e72df2b5493aa46e
5
5
  SHA512:
6
- metadata.gz: af978391061ce95cce0f9e8ff1099f710861eee3800d634a6ef352e6a6530197bb0a93fa9e06899adea6786f83f52914fe48acdef4b6c21ad05edf61417f74e9
7
- data.tar.gz: f3c22d1e96bae90fca980d7ba769771263bdb350ee4531e5c6ad8f16f5317bb028bedea651b74d4313401bd82619e8c6535c75ff28f2b5fec36f12e929a08241
6
+ metadata.gz: dc22720a84cad9fb8db09d30a24129be68bf33b4cdc9142dd8ba978e1f0f27b609c8513a4cfd634b8f2b8469ca60d3506d4e033a9e29e3f9044731ea21fafe84
7
+ data.tar.gz: 724df22354b693e721a8599c0962e3fcaecfcb3e109457583c4d04904db5aa9db6df97989110df6da5343457ac774d0365b1e4cb53b7dca8cc1f6cadeb869f01
@@ -10,6 +10,34 @@ APIs are available:
10
10
  * Bugzilla::WebService::Product[http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Product.html]
11
11
  * Bugzilla::WebService::User[http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/User.html]
12
12
 
13
+
14
+ == bzconsole usage
15
+
16
+ as example, in the bin directory, we have a tool named bzconsole. with that, you can login, search and get a bug. some examples:
17
+
18
+ list all new bugs, from Novell, created after 2014-09-25, with product Security (SUSE Security Incidents):
19
+
20
+ ````
21
+ bzconsole search --status=NEW --create-time=2014-09-25 --product=Security --detailed-list nvbz
22
+ ````
23
+
24
+ similar for Red Hat:
25
+
26
+ ````
27
+ bzconsole search --status=NEW --create-time=2014-09-28 --product=Security --detailed-list rhbz
28
+ ````
29
+
30
+ search without login:
31
+
32
+ ````
33
+ bzconsole search --status=NEW --anonymous --create-time=2014-09-28 --product=Security --detailed-list rhbz
34
+ ````
35
+
36
+ get a specific bug:
37
+
38
+ ````
39
+ bzconsole getbug nvbz:889526
40
+ ````
13
41
  == Copyright
14
42
 
15
43
  Copyright (c) 2010-2014 Red Hat, Inc. See COPYING for details.
@@ -41,10 +41,29 @@ rescue LoadError
41
41
  require 'bugzilla/bug'
42
42
  end
43
43
 
44
+ module BzConsole
45
+ module Utils
46
+ def get_xmlrpc(conf = {},opts = {})
47
+ info = conf
48
+ uri = URI.parse(info[:URL])
49
+ host = uri.host
50
+ port = uri.port
51
+ path = uri.path.empty? ? nil : uri.path
52
+ proxy_host, proxy_port = get_proxy(info)
53
+ timeout = opts[:timeout].nil? ? 60 : opts[:timeout]
54
+ yield host if block_given? # if you want to run some pre hook
55
+ xmlrpc = Bugzilla::XMLRPC.new(host, port, path, proxy_host, proxy_port, timeout, uri.user, uri.password)
56
+ [xmlrpc,host]
57
+ end
58
+ end
59
+ end
60
+
44
61
  module BzConsole
45
62
 
46
63
  class CommandTemplate
47
64
 
65
+ include Utils
66
+
48
67
  def initialize(plugin)
49
68
  @n_args = 0
50
69
  @defaultyamlfile = File.join(ENV['HOME'], ".bzconsole.yml")
@@ -112,7 +131,6 @@ module BzConsole
112
131
 
113
132
  def initialize(plugin)
114
133
  super
115
-
116
134
  @n_args = 0
117
135
  end # def initialize
118
136
 
@@ -135,7 +153,8 @@ module BzConsole
135
153
  'RHEL3'=>'Red Hat Enterprise Linux 3',
136
154
  'RHEL4'=>'Red Hat Enterprise Linux 4',
137
155
  'RHEL5'=>'Red Hat Enterprise Linux 5',
138
- 'RHEL6'=>'Red Hat Enterprise Linux 6'
156
+ 'RHEL6'=>'Red Hat Enterprise Linux 6',
157
+ 'Security'=>'Security Response'
139
158
  },
140
159
  :Plugin=>"ruby-bugzilla/rhbugzilla.rb"
141
160
  },
@@ -156,6 +175,16 @@ module BzConsole
156
175
  :URL=>"https://bugzilla.mozilla.org",
157
176
  :User=>"account@example.com",
158
177
  :Password=>"blahblahblah",
178
+ },
179
+ "nvbz"=>{
180
+ :Name=>"Novell Bugzilla",
181
+ :URL=>"https://bugzilla.novell.com",
182
+ :User=>"account@example.com",
183
+ :Password=>"blahblahblah",
184
+ :ProductAliases=>{
185
+ 'Security'=>'SUSE Security Incidents'
186
+ },
187
+ :Plugin=>"ruby-bugzilla/nvbugzilla.rb"
159
188
  }
160
189
  }
161
190
 
@@ -179,7 +208,6 @@ module BzConsole
179
208
 
180
209
  def initialize(plugin)
181
210
  super
182
-
183
211
  @n_args = 1
184
212
  end # def initialize
185
213
 
@@ -206,17 +234,12 @@ module BzConsole
206
234
  end
207
235
 
208
236
  info = conf[prefix]
209
- uri = URI.parse(info[:URL])
210
- host = uri.host
211
- port = uri.port
212
- path = uri.path.empty? ? nil : uri.path
213
237
  login = info[:User].nil? ? ask("Bugzilla ID: ") : info[:User]
214
238
  pass = info[:Password].nil? ? ask("Bugzilla password: ") {|q| q.echo = false} : info[:Password]
215
- proxy_host, proxy_port = get_proxy(info)
216
- timeout = opts[:timeout].nil? ? 60 : opts[:timeout]
217
239
 
218
- xmlrpc = Bugzilla::XMLRPC.new(host, port, path, proxy_host, proxy_port, timeout, uri.user, uri.password)
240
+ xmlrpc,host = get_xmlrpc(conf[prefix],opts)
219
241
  user = Bugzilla::User.new(xmlrpc)
242
+
220
243
  begin
221
244
  result = user.login({'login'=>login, 'password'=>pass, 'remember'=>true})
222
245
  cconf[host] = xmlrpc.cookie
@@ -285,7 +308,7 @@ module BzConsole
285
308
  printf("Comments:\t%d\n\n", result['comments'].length)
286
309
  i = 0
287
310
  result['comments'].each do |c|
288
- printf("Comment#%d%s %s %s\n", i, c['is_private'] == true ? "[private]" : "", c['author'], c['time'].to_time)
311
+ printf("Comment#%d%s %s %s\n", i, c['is_private'] == true ? "[private]" : "", c['creator'], c['creation_time'].to_time)
289
312
  printf("\n %s\n\n", c['text'].split("\n").join("\n "))
290
313
  i += 1
291
314
  end
@@ -310,18 +333,13 @@ module BzConsole
310
333
  end
311
334
 
312
335
  info = conf[prefix]
313
- uri = URI.parse(info[:URL])
314
- host = uri.host
315
- port = uri.port
316
- path = uri.path.empty? ? nil : uri.path
317
- login = opts[:command][:anonymous] == true ? nil : info[:User]
318
- pass = opts[:command][:anonymous] == true ? nil : info[:Password]
319
- proxy_host, proxy_port = get_proxy(info)
320
- timeout = opts[:timeout].nil? ? 60 : opts[:timeout]
336
+ login = info[:User].nil? ? ask("Bugzilla ID: ") : info[:User]
337
+ pass = info[:Password].nil? ? ask("Bugzilla password: ") {|q| q.echo = false} : info[:Password]
321
338
 
322
- @plugin.run(:pre, host, :getbug, opts)
339
+ xmlrpc,host = get_xmlrpc(conf[prefix],opts) do |h|
340
+ @plugin.run(:pre, h, :getbug, opts)
341
+ end
323
342
 
324
- xmlrpc = Bugzilla::XMLRPC.new(host, port, path, proxy_host, proxy_port, timeout, uri.user, uri.password)
325
343
  user = Bugzilla::User.new(xmlrpc)
326
344
  user.session(login, pass) do
327
345
  bug = Bugzilla::Bug.new(xmlrpc)
@@ -438,19 +456,19 @@ module BzConsole
438
456
  xmlrpc = Bugzilla::XMLRPC.new(host, port, path, proxy_host, proxy_port, timeout, uri.user, uri.password)
439
457
  user = Bugzilla::User.new(xmlrpc)
440
458
  user.session(login, pass) do
441
- bug = Bugzilla::Bug.new(xmlrpc)
442
-
443
- opts[:command][:query][:product].map! {|x| info.include?(:ProductAliases) && info[:ProductAliases].include?(x) ? info[:ProductAliases][x] : x} if opts[:command][:query].include?(:product)
459
+ bug = Bugzilla::Bug.new(xmlrpc)
460
+ opts[:command][:query][:product].map! { |x| info.include?(:ProductAliases) &&
461
+ info[:ProductAliases].include?(x) ? info[:ProductAliases][x] : x } if opts[:command][:query].include?(:product)
444
462
 
445
- result = bug.search(opts[:command][:query])
463
+ result = bug.search(opts[:command][:query])
446
464
 
447
- @plugin.run(:post, host, :search, result)
465
+ @plugin.run(:post, host, :search, result)
448
466
 
449
- if result.include?('bugs') then
450
- result['bugs'].each do |r|
451
- yield r
467
+ if result.include?('bugs') then
468
+ result['bugs'].each do |r|
469
+ yield r
470
+ end
452
471
  end
453
- end
454
472
  end
455
473
  end
456
474
  end # def real_do
@@ -622,7 +640,7 @@ module BzConsole
622
640
  timeline = data[:label]
623
641
  data.delete(:label)
624
642
  def timeline.to_hash
625
- ret = {}
643
+ ret = {}
626
644
  (0..self.length-1).each do |i|
627
645
  ret[i] = self[i] unless self[i].nil?
628
646
  end
@@ -668,16 +686,11 @@ module BzConsole
668
686
  end
669
687
 
670
688
  info = conf[prefix]
671
- uri = URI.parse(info[:URL])
672
- host = uri.host
673
- port = uri.port
674
- path = uri.path.empty? ? nil : uri.path
675
- login = opts[:command][:anonymous] == true ? nil : info[:User]
676
- pass = opts[:command][:anonymous] == true ? nil : info[:Password]
677
- proxy_host, proxy_port = get_proxy(info)
678
- timeout = opts[:timeout].nil? ? 60 : opts[:timeout]
689
+ login = info[:User].nil? ? ask("Bugzilla ID: ") : info[:User]
690
+ pass = info[:Password].nil? ? ask("Bugzilla password: ") {|q| q.echo = false} : info[:Password]
679
691
 
680
- xmlrpc = Bugzilla::XMLRPC.new(host, port, path, proxy_host, proxy_port, timeout, uri.user, uri.password)
692
+
693
+ xmlrpc,host = get_xmlrpc(conf[prefix],opts)
681
694
  user = Bugzilla::User.new(xmlrpc)
682
695
  user.session(login, pass) do
683
696
  bug = Bugzilla::Bug.new(xmlrpc)
@@ -700,97 +713,95 @@ module BzConsole
700
713
 
701
714
  @plugin.run(:pre, host, :metrics, searchopts, opts[:metrics])
702
715
 
703
- if searchopts == opts[:command][:query] then
704
- raise NoMethodError, "No method to deal with the query"
705
- end
716
+ raise NoMethodError, "No method to deal with the query" if searchopts == opts[:command][:query]
706
717
 
707
718
  while ts < te do
708
- searchopts = opts[:command][:query].clone
709
-
710
- # don't rely on the status to deal with NEW bugs.
711
- # unable to estimate the case bugs closed quickly
712
- if opts[:command][:metrics][:x_coordinate] == :weekly then
713
- d = Date.new(ts.year, ts.month, ts.day)
714
- de = Date.commercial(d.year, d.cweek, 7)
715
- drange = [ts, Time.utc(de.year, de.month, de.day, 23, 59, 59)]
716
- else
717
- drange = [ts, Time.utc(ts.year, ts.month + 1, 1) - 1]
718
- end
719
- searchopts[:creation_time] = drange
719
+ searchopts = opts[:command][:query].clone
720
+
721
+ # don't rely on the status to deal with NEW bugs.
722
+ # unable to estimate the case bugs closed quickly
723
+ if opts[:command][:metrics][:x_coordinate] == :weekly then
724
+ d = Date.new(ts.year, ts.month, ts.day)
725
+ de = Date.commercial(d.year, d.cweek, 7)
726
+ drange = [ts, Time.utc(de.year, de.month, de.day, 23, 59, 59)]
727
+ else
728
+ drange = [ts, Time.utc(ts.year, ts.month + 1, 1) - 1]
729
+ end
720
730
 
721
- @plugin.run(:pre, host, :metrics, searchopts)
731
+ searchopts[:creation_time] = drange
722
732
 
723
- result = bug.search(searchopts)
733
+ @plugin.run(:pre, host, :metrics, searchopts)
724
734
 
725
- @plugin.run(:post, host, :search, result)
735
+ result = bug.search(searchopts)
726
736
 
727
- new = result.include?('bugs') ? result['bugs'].length : 0
737
+ @plugin.run(:post, host, :search, result)
728
738
 
729
- # for open bugs
730
- # what we are interested in here would be how many bugs still keeps open.
731
- searchopts = opts[:command][:query].clone
732
- searchopts[:last_change_time] = drange
733
- searchopts[:status] = '__open__'
739
+ new = result.include?('bugs') ? result['bugs'].length : 0
734
740
 
735
- @plugin.run(:pre, host, :metrics, searchopts)
741
+ # for open bugs
742
+ # what we are interested in here would be how many bugs still keeps open.
743
+ searchopts = opts[:command][:query].clone
744
+ searchopts[:last_change_time] = drange
745
+ searchopts[:status] = '__open__'
736
746
 
737
- result = bug.search(searchopts)
747
+ @plugin.run(:pre, host, :metrics, searchopts)
738
748
 
739
- @plugin.run(:post, host, :search, result)
749
+ result = bug.search(searchopts)
740
750
 
741
- assigned = result.include?('bugs') ? result['bugs'].map{|x| x['status'] == 'ASSIGNED' ? x : nil}.compact.length : 0
742
- modified = result.include?('bugs') ? result['bugs'].map{|x| x['status'] == 'MODIFIED' ? x : nil}.compact.length : 0
743
- on_qa = result.include?('bugs') ? result['bugs'].map{|x| x['status'] == 'ON_QA' ? x : nil}.compact.length : 0
751
+ @plugin.run(:post, host, :search, result)
744
752
 
745
- # send a separate query for closed.
746
- # just counting CLOSED the above is meaningless.
747
- # what we are interested in here would be how much bugs are
748
- # actually closed, but not how many closed bugs one worked on.
749
- searchopts = opts[:command][:query].clone
750
- searchopts[:last_change_time] = drange
751
- searchopts[:status] = 'CLOSED'
753
+ assigned = result.include?('bugs') ? result['bugs'].map{|x| x['status'] == 'ASSIGNED' ? x : nil}.compact.length : 0
754
+ modified = result.include?('bugs') ? result['bugs'].map{|x| x['status'] == 'MODIFIED' ? x : nil}.compact.length : 0
755
+ on_qa = result.include?('bugs') ? result['bugs'].map{|x| x['status'] == 'ON_QA' ? x : nil}.compact.length : 0
752
756
 
753
- @plugin.run(:pre, host, :metrics, searchopts)
757
+ # send a separate query for closed.
758
+ # just counting CLOSED the above is meaningless.
759
+ # what we are interested in here would be how much bugs are
760
+ # actually closed, but not how many closed bugs one worked on.
761
+ searchopts = opts[:command][:query].clone
762
+ searchopts[:last_change_time] = drange
763
+ searchopts[:status] = 'CLOSED'
754
764
 
755
- result = bug.search(searchopts)
765
+ @plugin.run(:pre, host, :metrics, searchopts)
756
766
 
757
- @plugin.run(:post, host, :search, result)
767
+ result = bug.search(searchopts)
758
768
 
759
- closed = result.include?('bugs') ? result['bugs'].length : 0
769
+ @plugin.run(:post, host, :search, result)
760
770
 
761
- # obtain the information for open bugs that closed now
762
- searchopts = opts[:command][:query].clone
763
- searchopts[:status] = 'CLOSED'
764
- searchopts[:metrics_closed_after] = drange[1] + 1
771
+ closed = result.include?('bugs') ? result['bugs'].length : 0
765
772
 
766
- @plugin.run(:pre, host, :metrics, searchopts)
773
+ # obtain the information for open bugs that closed now
774
+ searchopts = opts[:command][:query].clone
775
+ searchopts[:status] = 'CLOSED'
776
+ searchopts[:metrics_closed_after] = drange[1] + 1
767
777
 
768
- result = bug.search(searchopts)
778
+ @plugin.run(:pre, host, :metrics, searchopts)
769
779
 
770
- @plugin.run(:post, host, :search, result)
780
+ result = bug.search(searchopts)
771
781
 
772
- open_bugs = result.include?('bugs') ? result['bugs'].length : 0
782
+ @plugin.run(:post, host, :search, result)
773
783
 
774
- # obtain the information for open bugs
775
- searchopts = opts[:command][:query].clone
776
- searchopts[:metrics_not_closed] = drange[1]
784
+ open_bugs = result.include?('bugs') ? result['bugs'].length : 0
777
785
 
778
- @plugin.run(:pre, host, :metrics, searchopts)
786
+ # obtain the information for open bugs
787
+ searchopts = opts[:command][:query].clone
788
+ searchopts[:metrics_not_closed] = drange[1]
779
789
 
780
- result = bug.search(searchopts)
790
+ @plugin.run(:pre, host, :metrics, searchopts)
781
791
 
782
- @plugin.run(:post, host, :search, result)
792
+ result = bug.search(searchopts)
783
793
 
784
- open_bugs += result.include?('bugs') ? result['bugs'].length : 0
794
+ @plugin.run(:post, host, :search, result)
785
795
 
786
- yield ts, new, assigned, modified, on_qa, closed, open_bugs
796
+ open_bugs += result.include?('bugs') ? result['bugs'].length : 0
787
797
 
788
- ts = drange[1] + 1
789
- end
798
+ yield ts, new, assigned, modified, on_qa, closed, open_bugs
799
+
800
+ ts = drange[1] + 1
801
+ end #while
790
802
  end
791
803
  end
792
804
  end # def real_do
793
-
794
805
  end # class Metrics
795
806
 
796
807
  class Newbug < CommandTemplate
@@ -876,6 +887,132 @@ module BzConsole
876
887
 
877
888
  end # class Newbug
878
889
 
890
+ class Responsetime < CommandTemplate
891
+
892
+ def initialize(plugin)
893
+ super
894
+ @n_args = 1
895
+ end # def initialize
896
+
897
+ def parse(parser, argv, opts)
898
+ opts[:responsetime] = {}
899
+ opts[:query] = {}
900
+ parser.banner = sprintf("Usage: %s [global options] responsetime [command options] <prefix:bug number>...", File.basename(__FILE__))
901
+ parser.separator ""
902
+ parser.separator "Search options:"
903
+ parser.on('--alias=ALIASES', 'filter out the result by the alias') {|v| opts[:query][:alias] ||= []; opts[:query][:alias].push(*v.split(','))}
904
+ parser.on('-a', '--assignee=ASSIGNEES', 'filter out the result by the specific assignees') {|v| opts[:query][:assigned_to] ||= []; opts[:query][:assigned_to].push(*v.split(','))}
905
+ parser.on('--bug=BUGS', 'filter out the result by the specific bug number') {|v| opts[:query][:id] ||= []; opts[:query][:id].push(*v.split(','))}
906
+ parser.on('-c', '--component=COMPONENTS', 'filter out the result by the specific components') {|v| opts[:query][:component] ||= []; opts[:query][:component].push(*v.split(','))}
907
+ parser.on('--creator=CREATER', 'filter out the result by the specific user who reported bugs') {|v| opts[:query][:creator] ||= []; opts[:query][:creator].push(*v.split(','))}
908
+ parser.on('--op-sys=NAMES', 'filter out the result by the operating system') {|v| opts[:query][:op_sys] ||= []; opts[:query][:op_sys].push(*v.split(','))}
909
+ parser.on('--platform=PLATFORMS', 'filter out the result by the platform') {|v| opts[:query][:platform] ||= []; opts[:query][:platform].push(*v.split(','))}
910
+ parser.on('--priority=PRIORITY', 'filter out the result by the priority') {|v| opts[:query][:priority] ||= []; opts[:query][:priority].push(*v.split(','))}
911
+ parser.on('-p', '--product=PRODUCTS', 'filter out the result by the specific products') {|v| opts[:query][:product] ||= []; opts[:query][:product].push(*v.split(','))}
912
+ parser.on('--resolution=RESOLUSIONS', 'filter out the result by the resolusions') {|v| opts[:query][:resolution] ||= []; opts[:query][:resolusion].push(*v.split(','))}
913
+ parser.on('--severity=SEVERITY', 'filter out the result by the severity') {|v| opts[:query][:severity] ||= []; opts[:query][:severity].push(*v.split(','))}
914
+ parser.on('--summary=SUMMARY', 'filter out the result by the summary') {|v| opts[:query][:summary] ||= []; opts[:query][:summary] << v}
915
+ parser.on('--milestone=MILESTONE', 'filter out the result by the target milestone') {|v| opts[:query][:target_milestone] ||= []; opts[:query][:target_milestone].push(*v.split(','))}
916
+ parser.on('--whiteboard=STRING', 'filter out the result by the specific words in the status whiteboard') {|v| opts[:query][:whiteboard] ||= []; opts[:query][:whiteboard] << v}
917
+ parser.separator ""
918
+ parser.separator "Command Options:"
919
+ parser.on('--begin-date=DATE', 'Analyse the response time since DATE') {|v| x = Time.parse(v); opts[:responsetime][:begin_date] = Time.utc(x.year, x.month, x.day, 0, 0, 0)}
920
+ parser.on('--end-date=DATE', 'Analyse the response time until DATE') {|v| x = Time.parse(v); opts[:responsetime][:end_date] = Time.utc(x.year, x.month, x.day, 23, 59, 59)}
921
+ parser.on('--anonymous','access to Bugzilla anonymously') {|v| opts[:anonymous] = true}
922
+
923
+ super
924
+ end # def parse
925
+
926
+ def do(argv, opts)
927
+ real_do(argv, opts) do |ts, te, login, user, bug|
928
+ printf("Bug#%s: [%s] - [%s] [%s] %s - %d comments\n", bug['id'], bug['product'], bug['component'], bug['status'], bug['summary'], bug['comments'].length)
929
+
930
+ ucache = {}
931
+ st = nil
932
+ total = 0
933
+ notyetrespond = false
934
+ ncomment = 0
935
+ n = 0
936
+ over = ""
937
+ bug['comments'].each do |comment|
938
+ u = nil
939
+ if ucache.include?(comment['creator']) then
940
+ u = ucache[comment['creator']]
941
+ else
942
+ u = user.get_userinfo(comment['creator'])
943
+ u = u[0] #FIXME
944
+ ucache[comment['creator']] = u
945
+ end
946
+ printf(" #%d. On %s, %s wrote\n", comment['count'], comment['creation_time'].to_time, comment['creator'].include?('@') ? sprintf("%s <%s>", u['real_name'], comment['creator']) : comment['creator'])
947
+ if comment['creator'] != login then
948
+ if !notyetrespond then
949
+ st = comment['creation_time'].to_time
950
+ notyetrespond = true
951
+ end
952
+ else
953
+ ncomment += 1
954
+ et = comment['creation_time'].to_time
955
+ if !st.nil? then
956
+ total += (et - st)
957
+ end
958
+ st = et
959
+ notyetrespond = false
960
+ end
961
+ n += 1
962
+ end
963
+ x = ncomment
964
+ if notyetrespond && bug['bug_status'] != 'CLOSED' then
965
+ total += (te - st)
966
+ over = '>'
967
+ x = 1 if x == 0
968
+ end
969
+ printf(" Own comment#: %d - avg. response time: %s%.f days\n", ncomment, over, total.to_f / x / 86400.0)
970
+ end
971
+ end # def do
972
+
973
+ def real_do(argv, opts)
974
+ conf = read_config(opts)
975
+ conf.freeze
976
+ argv.each do |prefix|
977
+ unless conf.include?(prefix) then
978
+ raise RuntimeError, sprintf("No host information for %s", prefix)
979
+ end
980
+
981
+ info = conf[prefix]
982
+ login = info[:User].nil? ? ask("Bugzilla ID: ") : info[:User]
983
+ pass = info[:Password].nil? ? ask("Bugzilla password: ") {|q| q.echo = false} : info[:Password]
984
+
985
+ xmlrpc, host = get_xmlrpc(conf[prefix], opts)
986
+ user = Bugzilla::User.new(xmlrpc)
987
+ user.session(login, pass) do
988
+ bug = Bugzilla::Bug.new(xmlrpc)
989
+
990
+ opts[:command][:query][:product].map! {|x| info.include?(:ProductAliases) && info[:ProductAliases].include?(x) ? info[:ProductAliases][x] : x} if opts[:command][:query].include?(:product)
991
+ ts = opts[:command][:responsetime][:begin_date] || Time.utc(Time.new.year, 1, 1)
992
+ te = opts[:command][:responsetime][:end_date] || Time.utc(Time.new.year+1, 1, 1) - 1
993
+ searchopts = opts[:command][:query].clone
994
+ searchopts[:last_change_time] = [ts, te]
995
+
996
+ @plugin.run(:pre, host, :metrics, searchopts)
997
+
998
+ result = bug.search(searchopts)
999
+
1000
+ @plugin.run(:post, host, :search, result)
1001
+
1002
+ if result.include?('bugs') then
1003
+ ids = result['bugs'].map {|x| x['id']}
1004
+ res = bug.get_bugs(ids, nil)
1005
+ res.each do |r|
1006
+ yield ts, te, login, user, r
1007
+ end
1008
+ end
1009
+ end
1010
+ end
1011
+ end # def real_do
1012
+
1013
+
1014
+ end # class
1015
+
879
1016
  end # module BzConsole
880
1017
 
881
1018
  begin
@@ -289,10 +289,10 @@ See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bug.html
289
289
  if args[0].kind_of?(Hash) then
290
290
  params = args[0]
291
291
  elsif args[0].kind_of?(Array) then
292
- params['ids'] = args[0]
292
+ params['ids'] = args[0]
293
293
  elsif args[0].kind_of?(Integer) ||
294
- args[0].kind_of?(String) then
295
- params['ids'] = [args[0]]
294
+ args[0].kind_of?(String) then
295
+ params['ids'] = [args[0]]
296
296
  else
297
297
  raise ArgumentError, "Invalid parameters"
298
298
  end
@@ -316,7 +316,7 @@ See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/Bug.html
316
316
 
317
317
  res = check_version("3.0.4")
318
318
  unless res[0] then
319
- required_fields.push(*defaulted_fields)
319
+ required_fields.push(*defaulted_fields)
320
320
  end
321
321
  required_fields.each do |f|
322
322
  raise ArgumentError, sprintf("Required fields isn't given: %s", f) unless args[0].include?(f)
@@ -38,20 +38,20 @@ module Bugzilla
38
38
  @@plugins = []
39
39
 
40
40
  def initialize
41
- @hostname = nil
41
+ @hostname = nil
42
42
  end # def initialize
43
43
 
44
44
  attr_reader :hostname
45
45
 
46
46
  def Template.inherited(subclass)
47
- @@plugins << subclass
47
+ @@plugins << subclass
48
48
  end # def inherited
49
49
 
50
50
  def run(hook, host, *args)
51
51
  @@plugins.each do |k|
52
- i = k.new
53
- if i.hostname == host || host.nil? then
54
- case hook
52
+ i = k.new
53
+ if i.hostname == host || host.nil? then
54
+ case hook
55
55
  when :parser
56
56
  i.parserhook(*args)
57
57
  when :pre
@@ -89,6 +89,35 @@ Keeps the bugzilla session during doing something in the block.
89
89
 
90
90
  =begin rdoc
91
91
 
92
+ ==== Bugzilla::User#get_userinfo(params)
93
+
94
+ =end
95
+
96
+ def get_userinfo(user)
97
+ p = {}
98
+ ids = []
99
+ names = []
100
+
101
+ if user.kind_of?(Array) then
102
+ user.each do |u|
103
+ names << u if u.kind_of?(String)
104
+ id << u if u.kind_of?(Integer)
105
+ end
106
+ elsif user.kind_of?(String) then
107
+ names << user
108
+ elsif user.kind_of?(Integer) then
109
+ ids << user
110
+ else
111
+ raise ArgumentError, sprintf("Unknown type of arguments: %s", user.class)
112
+ end
113
+
114
+ result = get({'ids'=>ids, 'names'=>names})
115
+
116
+ result['users']
117
+ end # def get_userinfo
118
+
119
+ =begin rdoc
120
+
92
121
  ==== Bugzilla::User#login(params)
93
122
 
94
123
  Raw Bugzilla API to log into Bugzilla.
@@ -136,8 +165,11 @@ See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/User.html
136
165
  # FIXME
137
166
  end # def _update
138
167
 
139
- def __get(cmd, *args)
168
+ def _get(cmd, *args)
169
+ raise ArgumentError, "Invalid parameters" unless args[0].kind_of?(Hash)
170
+
140
171
  requires_version(cmd, 3.4)
172
+ res = @iface.call(cmd, args[0])
141
173
  # FIXME
142
174
  end # def _get
143
175
 
@@ -1,5 +1,5 @@
1
1
  # user.rb
2
- # Copyright (C) 2010-2012 Red Hat, Inc.
2
+ # Copyright (C) 2010-2014 Red Hat, Inc.
3
3
  #
4
4
  # Authors:
5
5
  # Akira TAGOH <tagoh@redhat.com>
@@ -52,36 +52,39 @@ Keeps the bugzilla session during doing something in the block.
52
52
  else
53
53
  fname = File.join(ENV['HOME'], '.ruby-bugzilla-cookie.yml')
54
54
  end
55
+ host = @iface.instance_variable_get(:@xmlrpc).instance_variable_get(:@host)
56
+ val = nil
57
+
55
58
  if File.exist?(fname) && File.lstat(fname).mode & 0600 == 0600 then
56
59
  conf = YAML.load(File.open(fname).read)
57
- host = @iface.instance_variable_get(:@xmlrpc).instance_variable_get(:@host)
58
60
  val = conf[host]
59
- unless val.nil? then
60
- if key == :token then
61
- print "Using token\n"
62
- @iface.token = val
63
- else
64
- print "Using cookie\n"
65
- @iface.cookie = cookie
66
- end
67
- yield
68
- if key == :token then
69
- conf[host] = @iface.token
70
- else
71
- conf[host] = @iface.cookie
72
- end
73
- File.open(fname, 'w') {|f| f.chmod(0600); f.write(conf.to_yaml)}
74
- return
75
- end
61
+ else
62
+ conf = {}
76
63
  end
77
- if user.nil? || password.nil? then
64
+ if !val.nil? then
65
+ if key == :token then
66
+ print "Using token\n"
67
+ @iface.token = val
68
+ else
69
+ print "Using cookie\n"
70
+ @iface.cookie = cookie
71
+ end
72
+ yield
73
+ elsif user.nil? || password.nil? then
78
74
  yield
75
+ return
79
76
  else
80
77
  login({'login'=>user, 'password'=>password, 'remember'=>true})
81
78
  yield
82
- logout
83
79
  end
84
-
80
+ if key == :token then
81
+ conf[host] = @iface.token
82
+ else
83
+ conf[host] = @iface.cookie
84
+ end
85
+ File.open(fname, 'w') {|f| f.chmod(0600); f.write(conf.to_yaml)}
86
+
87
+ return key
85
88
  end # def session
86
89
 
87
90
  =begin rdoc
@@ -109,7 +112,12 @@ See http://www.bugzilla.org/docs/tip/en/html/api/Bugzilla/WebService/User.html
109
112
  def _login(cmd, *args)
110
113
  raise ArgumentError, "Invalid parameters" unless args[0].kind_of?(Hash)
111
114
 
112
- @iface.call(cmd,args[0])
115
+ res = @iface.call(cmd,args[0])
116
+ unless res['token'].nil? then
117
+ @iface.token = res['token']
118
+ end
119
+
120
+ return res
113
121
  end # def _login
114
122
 
115
123
  def _logout(cmd, *args)
@@ -1,5 +1,5 @@
1
1
  # version.rb
2
- # Copyright (C) 2010-2014 Red Hat, Inc.
2
+ # Copyright (C) 2010-2015 Red Hat, Inc.
3
3
  #
4
4
  # Authors:
5
5
  # Akira TAGOH <tagoh@redhat.com>
@@ -26,6 +26,6 @@
26
26
 
27
27
  module Bugzilla
28
28
 
29
- VERSION = "0.5.3"
29
+ VERSION = "0.6.0"
30
30
 
31
31
  end # module Bugzilla
@@ -0,0 +1,55 @@
1
+ # nvbugzilla.rb
2
+ # Copyright (C) 2014 Novell, Inc.
3
+ #
4
+ # Authors:
5
+ # Victor Pereira <vpereira@suse.com>
6
+ #
7
+ # This library is free software: you can redistribute it and/or
8
+ # modify it under the terms of the GNU Lesser General Public
9
+ # License as published by the Free Software Foundation, either
10
+ # version 3 of the License, or (at your option) any later version.
11
+ #
12
+ # This library is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ require 'rubygems'
21
+
22
+ #begin
23
+ # gem 'ruby-bugzilla'
24
+ #rescue Gem::LoadError
25
+ # require File.join(File.dirname(__FILE__), "..", "bugzilla.rb")
26
+ #end
27
+
28
+ module Bugzilla
29
+
30
+ module Plugin
31
+
32
+ class Novell < ::Bugzilla::Plugin::Template
33
+
34
+ def initialize
35
+ super
36
+ @hostname = "bugzilla.novell.com"
37
+ end # def initialize
38
+
39
+ def parserhook(*args)
40
+ super
41
+ end # def parserhook
42
+
43
+ def prehook(*args)
44
+ super
45
+ end # def prehook
46
+
47
+ def posthook(*args)
48
+ super
49
+ end # def posthook
50
+
51
+ end # class Novell
52
+
53
+ end # module Plugin
54
+
55
+ end # module Bugzilla
metadata CHANGED
@@ -1,83 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-bugzilla
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akira TAGOH
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-17 00:00:00.000000000 Z
11
+ date: 2015-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '2.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: gruff
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: highline
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rmagick
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '1.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.0'
83
83
  description: This aims to provide similar features to access to Bugzilla through WebService
@@ -89,27 +89,28 @@ executables:
89
89
  extensions: []
90
90
  extra_rdoc_files: []
91
91
  files:
92
- - lib/bugzilla/version.rb
92
+ - COPYING
93
+ - README.md
94
+ - bin/bzconsole
95
+ - lib/bugzilla.rb
96
+ - lib/bugzilla/api_tmpl.rb
97
+ - lib/bugzilla/bug.rb
98
+ - lib/bugzilla/bugzilla.rb
93
99
  - lib/bugzilla/bugzilla.rb~
100
+ - lib/bugzilla/classification.rb
101
+ - lib/bugzilla/group.rb
102
+ - lib/bugzilla/plugin.rb
94
103
  - lib/bugzilla/product.rb
95
104
  - lib/bugzilla/skeleton.rb
105
+ - lib/bugzilla/skeleton.rb~
96
106
  - lib/bugzilla/user.rb
107
+ - lib/bugzilla/user.rb~
108
+ - lib/bugzilla/version.rb
109
+ - lib/bugzilla/version.rb~
97
110
  - lib/bugzilla/xmlrpc.rb
98
111
  - lib/bugzilla/xmlrpc.rb~
99
- - lib/bugzilla/skeleton.rb~
100
- - lib/bugzilla/group.rb
101
- - lib/bugzilla/plugin.rb
102
- - lib/bugzilla/version.rb~
103
- - lib/bugzilla/bugzilla.rb
104
- - lib/bugzilla/user.rb~
105
- - lib/bugzilla/classification.rb
106
- - lib/bugzilla/bug.rb
107
- - lib/bugzilla/api_tmpl.rb
108
- - lib/bugzilla.rb
112
+ - lib/ruby-bugzilla/nvbugzilla.rb
109
113
  - lib/ruby-bugzilla/rhbugzilla.rb
110
- - README.rdoc
111
- - COPYING
112
- - bin/bzconsole
113
114
  homepage: http://rubygems.org/gems/ruby-bugzilla
114
115
  licenses: []
115
116
  metadata: {}
@@ -119,17 +120,17 @@ require_paths:
119
120
  - lib
120
121
  required_ruby_version: !ruby/object:Gem::Requirement
121
122
  requirements:
122
- - - '>='
123
+ - - ">="
123
124
  - !ruby/object:Gem::Version
124
125
  version: '0'
125
126
  required_rubygems_version: !ruby/object:Gem::Requirement
126
127
  requirements:
127
- - - '>='
128
+ - - ">="
128
129
  - !ruby/object:Gem::Version
129
130
  version: 1.3.6
130
131
  requirements: []
131
132
  rubyforge_project:
132
- rubygems_version: 2.1.11
133
+ rubygems_version: 2.2.2
133
134
  signing_key:
134
135
  specification_version: 4
135
136
  summary: Ruby binding for Bugzilla WebService APIs