trackinator 0.0.2 → 0.0.4

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/trackinate CHANGED
@@ -9,9 +9,9 @@ opts = Trollop::options do
9
9
  opt :youtrack_password, "Your YouTrack password", :type => :string, :short => "p"
10
10
  opt :google_username, "Your Google username", :type => :string, :short => "g"
11
11
  opt :google_password, "Your Google password", :type => :string, :short => "a"
12
- opt :youtrack_host, "YouTrack host", :type => :string, :short => "o"
13
- opt :youtrack_port, "YouTrack port", :type => :int, :default => 80, :short => "r"
14
- opt :youtrack_path_prefix, "YouTrack path prefix (e.g. '/youtrack/')", :type => :string, :default => "/", :short =>"e"
12
+ opt :host, "YouTrack host", :type => :string, :short => "o"
13
+ opt :port, "YouTrack port", :type => :int, :default => 80, :short => "r"
14
+ opt :path_prefix, "YouTrack path prefix (e.g. '/youtrack/')", :type => :string, :default => "/", :short =>"e"
15
15
  opt :create_rc, "Create a .trackinatorrc file in your home dir", :default => false, :short => "c"
16
16
  end
17
17
 
@@ -32,7 +32,7 @@ Trollop::die :youtrack_username, "is required" if opts[:youtrack_username].nil?
32
32
  Trollop::die :youtrack_password, "is required" if opts[:youtrack_password].nil?
33
33
  Trollop::die :google_username, "is required" if opts[:google_username].nil?
34
34
  Trollop::die :google_password, "is required" if opts[:google_password].nil?
35
- Trollop::die :youtrack_host, "is required" if opts[:youtrack_host].nil?
35
+ Trollop::die :host, "is required" if opts[:host].nil?
36
36
 
37
37
  if opts[:create_rc]
38
38
  unless File.exists?("#{Etc.getpwuid.dir}/.trackinatorrc")
@@ -0,0 +1,43 @@
1
+ module Trackinator
2
+ class Google
3
+ @client
4
+
5
+ def initialize opts
6
+ @client = GData::Client::Spreadsheets.new
7
+ @client.clientlogin(opts[:google_username], opts[:google_password])
8
+ end
9
+
10
+ def get_tickets file_name
11
+ spreadsheet_feed = @client.get("http://spreadsheets.google.com/feeds/worksheets/#{get_spreadsheet_key(file_name)}/private/full").to_xml
12
+ spreadsheet_list_data = @client.get(spreadsheet_feed.elements[1, 'entry'].elements[1, 'content'].attributes['src']).to_xml
13
+
14
+ tickets = []
15
+
16
+ spreadsheet_list_data.elements.each('entry') do |entry|
17
+ tickets << get_ticket_data(entry)
18
+ end
19
+
20
+ tickets
21
+ end
22
+
23
+ def get_spreadsheet_key file_name
24
+ doc_feed = @client.get("http://spreadsheets.google.com/feeds/spreadsheets/private/full").to_xml
25
+
26
+ doc_feed.elements.each ('entry') do |entry|
27
+ if entry.elements['title'].text.eql? file_name
28
+ return entry.elements[1].text[/spreadsheets\/(.*)/, 1]
29
+ end
30
+ end
31
+ end
32
+
33
+ def get_ticket_data entry
34
+ data = {}
35
+
36
+ REXML::XPath.match(entry, 'gsx:*').each do |col|
37
+ data[col.name] = URI.escape(col.text) unless col.text.nil?
38
+ end
39
+
40
+ data
41
+ end
42
+ end
43
+ end
@@ -3,174 +3,25 @@ require 'CSV'
3
3
 
4
4
  require 'gdata'
5
5
 
6
+ require 'trackinator/google'
7
+ require 'trackinator/you_track'
8
+
6
9
  module Trackinator
7
10
  class Importer
8
- @youtrack_cookie
9
- @youtrack_connection
10
-
11
- @google_headers
12
- @stack
13
-
14
- @col_count
15
-
16
- @youtrack_host
17
- @youtrack_port
18
- @youtrack_path_prefix
11
+ @you_track
19
12
 
20
13
  def initialize opts
21
- @stack = []
22
- @google_connection = Net::HTTP
23
- @google_client = GData::Client::Spreadsheets.new
24
-
25
- google_login = opts[:google_username]
26
- youtrack_login = opts[:youtrack_username]
27
-
28
- @youtrack_host = opts[:youtrack_host]
29
- @youtrack_port = opts[:youtrack_port]
30
- @youtrack_path_prefix = opts[:youtrack_path_prefix]
31
-
32
- google_password = opts[:google_password]
33
- youtrack_password = opts[:youtrack_password]
34
-
35
- login_youtrack youtrack_login, youtrack_password
36
-
37
- @google_client.clientlogin(google_login, google_password)
14
+ @you_track = YouTrack.new opts
15
+ @google = Google.new opts
38
16
  end
39
17
 
40
18
  def import file_name
41
- spreadsheet_feed = @google_client.get("http://spreadsheets.google.com/feeds/worksheets/#{get_spreadsheet_key(file_name)}/private/full").to_xml
42
- spreadsheet_list_data = @google_client.get(spreadsheet_feed.elements[1, 'entry'].elements[1, 'content'].attributes['src']).to_xml
43
-
44
- spreadsheet_list_data.elements.each('entry') do |entry|
45
- ticket_data = get_ticket_data entry
46
- issue_id = is_issue_exists? ticket_data
47
- false unless !issue_id.nil? ? update_ticket(issue_id, ticket_data) : create_ticket(ticket_data)
48
- end
49
- end
50
-
51
- private
52
-
53
- # Google API methods
54
-
55
- def get_spreadsheet_key file_name
56
- doc_feed = @google_client.get("http://spreadsheets.google.com/feeds/spreadsheets/private/full").to_xml
19
+ ticket_data = @google.get_tickets file_name
57
20
 
58
- doc_feed.elements.each ('entry') do |entry|
59
- if entry.elements['title'].text.eql? file_name
60
- return entry.elements[1].text[/spreadsheets\/(.*)/, 1]
61
- end
21
+ ticket_data.each do |entry|
22
+ issue_id = @you_track.is_issue_exists? entry
23
+ false unless !issue_id.nil? ? @you_track.update_ticket(issue_id, entry) : @you_track.create_ticket(entry)
62
24
  end
63
25
  end
64
-
65
- def get_ticket_data entry
66
- data = {}
67
-
68
- REXML::XPath.match(entry, 'gsx:*').each do |col|
69
- data[col.name] = URI.escape(col.text) unless col.text.nil?
70
- end
71
-
72
- data
73
- end
74
-
75
- # YouTrack API methods
76
-
77
- def login_youtrack user_name, password
78
- @youtrack_connection = Net::HTTP.new @youtrack_host, @youtrack_port
79
- response = @youtrack_connection.post "#{@youtrack_path_prefix}rest/user/login", "login=#{user_name}&password=#{password}"
80
- @youtrack_cookie = response.response['Set-Cookie'].split('; ')[0]
81
- end
82
-
83
- def create_ticket data
84
- issue_id, create_response = create_youtrack_ticket data
85
- success = create_response.eql? "Created"
86
-
87
- success ? (success = update_ticket(issue_id, data)) : (return success)
88
- success ? update_dependencies([issue_id, data['id']]) : success
89
- end
90
-
91
- def update_ticket issue_id, data
92
- success = set_platform(issue_id, data['platform'])
93
- success ? (success = set_summary_and_description(issue_id, data['summary'], data['description'])) : (return success)
94
- success ? (success = set_type(issue_id, data['type'])) : (return success)
95
- success ? (success = set_import_identifier(issue_id, "#{data['project']}-#{data['id']}")) : (return success)
96
- success ? (success = set_design_reference(issue_id, "#{data['references']}")) : (return success) unless data['references'].nil?
97
-
98
- success
99
- end
100
-
101
- def update_dependencies issue
102
- issue_id = issue[0]
103
- issue_level = issue[1]
104
-
105
- if @stack.empty?
106
- @stack.push [issue_id, issue_level]
107
- else
108
- last_issue = @stack.last
109
- last_issue_id = last_issue[0]
110
- last_issue_level = last_issue[1]
111
-
112
- if issue_level.length <= last_issue_level.length
113
- @stack.pop
114
- update_dependencies issue
115
- else
116
- success = create_dependency last_issue_id, issue_id
117
- @stack.push issue
118
-
119
- success
120
- end
121
- end
122
- end
123
-
124
- # YouTrack API calls
125
-
126
- def is_issue_exists? data
127
- find_response_xml = REXML::Document.new(@youtrack_connection.get("#{@youtrack_path_prefix}rest/issue/byproject/#{data['project']}?filter=Import+Identifier:+#{data['project']}-#{data['id']}", { 'Cookie' => @youtrack_cookie, 'Content-Type' => 'text/plain; charset=utf-8' }).body)
128
- find_response_xml.elements['issues'].length > 0 ? find_response_xml.elements['issues/issue'].attributes['id'] : nil
129
- end
130
-
131
- def create_youtrack_ticket data
132
- response = @youtrack_connection.put("#{@youtrack_path_prefix}rest/issue?project=#{data['project']}&summary=#{data['summary']}&description=#{data['description']}&priority=#{data['priority']}", nil, { 'Cookie' => @youtrack_cookie, 'Content-Type' => 'text/plain; charset=utf-8' })
133
- return response.header["Location"].split("/").last, response.header.msg
134
- end
135
-
136
- def create_dependency parent_id, child_id
137
- response = @youtrack_connection.post("#{@youtrack_path_prefix}rest/issue/#{parent_id}/execute?command=parent+for+#{child_id}&disableNotifications=true", nil, { 'Cookie' => @youtrack_cookie })
138
- response.header.msg.eql? "OK"
139
- end
140
-
141
- def set_summary_and_description issue_id, summary, description
142
- return true if summary.nil?
143
-
144
- response = @youtrack_connection.post("#{@youtrack_path_prefix}rest/issue/#{issue_id}/?summary=#{summary}&description=#{description}&disableNotifications=true", nil, { 'Cookie' => @youtrack_cookie })
145
- response.header.msg.eql? "OK"
146
- end
147
-
148
- def set_platform issue_id, platform
149
- return true if platform.nil?
150
-
151
- response = @youtrack_connection.post("#{@youtrack_path_prefix}rest/issue/#{issue_id}/execute?command=Platform+#{platform}&disableNotifications=true", nil, { 'Cookie' => @youtrack_cookie })
152
- response.header.msg.eql? "OK"
153
- end
154
-
155
- def set_type issue_id, type
156
- return true if type.nil?
157
-
158
- response = @youtrack_connection.post("#{@youtrack_path_prefix}rest/issue/#{issue_id}/execute?command=Type+#{type}&disableNotifications=true", nil, { 'Cookie' => @youtrack_cookie })
159
- response.header.msg.eql? "OK"
160
- end
161
-
162
- def set_import_identifier issue_id, import_id
163
- return true if import_id.nil?
164
-
165
- response = @youtrack_connection.post("#{@youtrack_path_prefix}rest/issue/#{issue_id}/execute?command=Import+Identifier+#{import_id}&disableNotifications=true", nil, { 'Cookie' => @youtrack_cookie })
166
- response.header.msg.eql? "OK"
167
- end
168
-
169
- def set_design_reference issue_id, reference
170
- return true if reference.nil?
171
-
172
- response = @youtrack_connection.post("#{@youtrack_path_prefix}rest/issue/#{issue_id}/execute?command=Design+Reference+#{reference}&disableNotifications=true", nil, { 'Cookie' => @youtrack_cookie })
173
- response.header.msg.eql? "OK"
174
- end
175
26
  end
176
27
  end
@@ -1,3 +1,3 @@
1
1
  module Trackinator
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -0,0 +1,122 @@
1
+ module Trackinator
2
+ class YouTrack
3
+ @stack
4
+
5
+ @cookie
6
+ @connection
7
+
8
+ @host
9
+ @port
10
+ @path_prefix
11
+
12
+ def initialize opts
13
+ @stack = []
14
+
15
+ @host = opts[:host]
16
+ @port = opts[:port]
17
+ @path_prefix = opts[:path_prefix]
18
+
19
+ login opts[:youtrack_username], opts[:youtrack_password]
20
+ end
21
+
22
+ def login username, password
23
+ @connection = Net::HTTP.new @host, @port
24
+ response = @connection.post "#{@path_prefix}rest/user/login", "login=#{username}&password=#{password}"
25
+ @cookie = response.response['Set-Cookie'].split('; ')[0]
26
+ end
27
+
28
+ def create_ticket data
29
+ issue_id, create_response = create_youtrack_ticket data
30
+ success = create_response.eql? "Created"
31
+
32
+ success ? (success = update_ticket(issue_id, data)) : (return success)
33
+ success ? update_dependencies([issue_id, data['id']]) : success
34
+ end
35
+
36
+ def update_ticket issue_id, data
37
+ success = set_platform(issue_id, data['platform'])
38
+ success ? (success = set_summary_and_description(issue_id, data['summary'], data['description'])) : (return success)
39
+ success ? (success = set_type(issue_id, data['type'])) : (return success)
40
+ success ? (success = set_import_identifier(issue_id, "#{data['project']}-#{data['id']}")) : (return success)
41
+ success ? (success = set_design_reference(issue_id, "#{data['references']}")) : (return success) unless data['references'].nil?
42
+
43
+ success
44
+ end
45
+
46
+ def update_dependencies issue
47
+ issue_id = issue[0]
48
+ issue_level = issue[1]
49
+
50
+ if @stack.empty?
51
+ @stack.push [issue_id, issue_level]
52
+ else
53
+ last_issue = @stack.last
54
+ last_issue_id = last_issue[0]
55
+ last_issue_level = last_issue[1]
56
+
57
+ if issue_level.length <= last_issue_level.length
58
+ @stack.pop
59
+ update_dependencies issue
60
+ else
61
+ success = create_dependency last_issue_id, issue_id
62
+ @stack.push issue
63
+
64
+ success
65
+ end
66
+ end
67
+ end
68
+
69
+ # YouTrack API calls
70
+
71
+ def is_issue_exists? data
72
+ find_response_xml = REXML::Document.new(@connection.get("#{@path_prefix}rest/issue/byproject/#{data['project']}?filter=Import+Identifier:+#{data['project']}-#{data['id']}", { 'Cookie' => @cookie, 'Content-Type' => 'text/plain; charset=utf-8' }).body)
73
+ find_response_xml.elements['issues'].length > 0 ? find_response_xml.elements['issues/issue'].attributes['id'] : nil
74
+ end
75
+
76
+ def create_youtrack_ticket data
77
+ response = @connection.put("#{@path_prefix}rest/issue?project=#{data['project']}&summary=#{data['summary']}&description=#{data['description']}&priority=#{data['priority']}", nil, { 'Cookie' => @cookie, 'Content-Type' => 'text/plain; charset=utf-8' })
78
+ return response.header["Location"].split("/").last, response.header.msg
79
+ end
80
+
81
+ def create_dependency parent_id, child_id
82
+ response = @connection.post("#{@path_prefix}rest/issue/#{parent_id}/execute?command=parent+for+#{child_id}&disableNotifications=true", nil, { 'Cookie' => @cookie })
83
+ response.header.msg.eql? "OK"
84
+ end
85
+
86
+ def set_summary_and_description issue_id, summary, description
87
+ return true if summary.nil? || description.nil?
88
+
89
+ response = @connection.post("#{@path_prefix}rest/issue/#{issue_id}/?summary=#{summary}&description=#{description}&disableNotifications=true", nil, { 'Cookie' => @cookie })
90
+ response.header.msg.eql? "OK"
91
+ end
92
+
93
+ def set_platform issue_id, platform
94
+ return true if platform.nil?
95
+
96
+ response = @connection.post("#{@path_prefix}rest/issue/#{issue_id}/execute?command=Platform+#{platform}&disableNotifications=true", nil, { 'Cookie' => @cookie })
97
+ response.header.msg.eql? "OK"
98
+ end
99
+
100
+ def set_type issue_id, type
101
+ return true if type.nil?
102
+
103
+ response = @connection.post("#{@path_prefix}rest/issue/#{issue_id}/execute?command=Type+#{type}&disableNotifications=true", nil, { 'Cookie' => @cookie })
104
+ response.header.msg.eql? "OK"
105
+ end
106
+
107
+ def set_import_identifier issue_id, import_id
108
+ return true if import_id.nil?
109
+
110
+ response = @connection.post("#{@path_prefix}rest/issue/#{issue_id}/execute?command=Import+Identifier+#{import_id}&disableNotifications=true", nil, { 'Cookie' => @cookie })
111
+ response.header.msg.eql? "OK"
112
+ end
113
+
114
+ def set_design_reference issue_id, reference
115
+ return true if reference.nil?
116
+
117
+ response = @connection.post("#{@path_prefix}rest/issue/#{issue_id}/execute?command=Design+Reference+#{reference}&disableNotifications=true", nil, { 'Cookie' => @cookie })
118
+ response.header.msg.eql? "OK"
119
+ end
120
+
121
+ end
122
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trackinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-31 00:00:00.000000000 Z
12
+ date: 2012-08-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gdata_19
@@ -62,8 +62,10 @@ files:
62
62
  - Rakefile
63
63
  - bin/trackinate
64
64
  - lib/trackinator.rb
65
+ - lib/trackinator/google.rb
65
66
  - lib/trackinator/importer.rb
66
67
  - lib/trackinator/version.rb
68
+ - lib/trackinator/you_track.rb
67
69
  - trackinator.gemspec
68
70
  homepage: https://github.com/justincbeck/trackinator
69
71
  licenses: []