fiddler 0.0.1 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +70 -0
- data/lib/fiddler.rb +5 -1
- data/lib/fiddler/attachment.rb +142 -0
- data/lib/fiddler/configuration.rb +7 -2
- data/lib/fiddler/connection_manager.rb +62 -20
- data/lib/fiddler/errors.rb +1 -0
- data/lib/fiddler/extensions.rb +2 -0
- data/lib/fiddler/extensions/file.rb +5 -0
- data/lib/fiddler/extensions/hash.rb +15 -0
- data/lib/fiddler/formatters/base_formatter.rb +3 -0
- data/lib/fiddler/formatters/search_request_formatter.rb +2 -2
- data/lib/fiddler/history.rb +32 -0
- data/lib/fiddler/parsers.rb +3 -1
- data/lib/fiddler/parsers/attachment_parser.rb +54 -0
- data/lib/fiddler/parsers/base_parser.rb +41 -3
- data/lib/fiddler/parsers/history_parser.rb +72 -0
- data/lib/fiddler/parsers/ticket_parser.rb +52 -21
- data/lib/fiddler/ticket.rb +141 -43
- data/lib/fiddler/version.rb +1 -1
- data/spec/attachment_spec.rb +26 -0
- data/spec/cassettes/change-ownership-take.yml +98 -0
- data/spec/cassettes/get-tickets.yml +89087 -0
- data/spec/cassettes/reply-to-tickets.yml +232 -0
- data/spec/cassettes/root-request.yml +79 -0
- data/spec/cassettes/search-tickets.yml +38249 -0
- data/spec/cassettes/ticket-histories-count.yml +2195 -0
- data/spec/cassettes/ticket-histories.yml +954 -0
- data/spec/connection_manager_spec.rb +5 -1
- data/spec/formatters/search_request_formatter_spec.rb +13 -0
- data/spec/parsers/attachment_parser_spec.rb +29 -0
- data/spec/parsers/base_parser_spec.rb +16 -0
- data/spec/parsers/history_parser_spec.rb +32 -0
- data/spec/parsers/ticket_parser_spec.rb +5 -1
- data/spec/spec_helper.rb +9 -0
- data/spec/ticket_spec.rb +188 -6
- metadata +80 -9
data/README.md
CHANGED
@@ -3,6 +3,76 @@ Fiddler
|
|
3
3
|
|
4
4
|
Ruby gem to provide an easy interface to Request Tracker Installation.
|
5
5
|
|
6
|
+
Installation
|
7
|
+
-------------
|
8
|
+
|
9
|
+
Install the gem using this commands
|
10
|
+
|
11
|
+
`gem install fiddler`
|
12
|
+
|
13
|
+
or you can include it in your Gemfile.
|
14
|
+
|
15
|
+
`gem 'fiddler'`
|
16
|
+
|
17
|
+
Configuration
|
18
|
+
--------------
|
19
|
+
|
20
|
+
For a Rails app, create an initializer files and for any other app, include this before using the gem.
|
21
|
+
<pre>
|
22
|
+
<code>
|
23
|
+
Fiddler.configure do |config|
|
24
|
+
config.server_url = "request_tracker_url"
|
25
|
+
config.username = "some_user"
|
26
|
+
config.password = "some_password"
|
27
|
+
end
|
28
|
+
</code>
|
29
|
+
</pre>
|
30
|
+
|
31
|
+
You can modify the settings on the fly as well using `Fiddler.configuration` variable.
|
32
|
+
|
33
|
+
Attachments
|
34
|
+
-----------
|
35
|
+
|
36
|
+
Fiddler saves the attachments object in a folder specified by
|
37
|
+
`Fiddler.configuration.attachments_path`. This is relative to the rails
|
38
|
+
root.
|
39
|
+
|
40
|
+
Using Cookies
|
41
|
+
-------------
|
42
|
+
|
43
|
+
Make sure you have RT-External-Auth configured properly to use cookies with Request Tracker.
|
44
|
+
Once that part has been done, change the config file to the following format.
|
45
|
+
|
46
|
+
<pre>
|
47
|
+
<code>
|
48
|
+
Fiddler.configure do |config|
|
49
|
+
config.server_url = "request_tracker_url"
|
50
|
+
config.use_cookies = true
|
51
|
+
config.cookie_domain = ".domainname"
|
52
|
+
config.request_tracker_key = "loginCookieValue"
|
53
|
+
end
|
54
|
+
</code>
|
55
|
+
</pre>
|
56
|
+
|
57
|
+
Once the configuration is done, cookie value can be set using
|
58
|
+
`Fiddler.configuration.cookie_value` method (appropriate place for that
|
59
|
+
would be somewhere like ApplicationController where it can set
|
60
|
+
dynamically).
|
61
|
+
|
62
|
+
Debugging Response
|
63
|
+
------------------
|
64
|
+
|
65
|
+
You can set the config option `Fiddler.configuration.debug_response` to
|
66
|
+
`true` to start debugging the responses from RT. If using in rails, it
|
67
|
+
will log to the current environment log otherwise print it to the stdout.
|
68
|
+
|
69
|
+
SSL Verification
|
70
|
+
----------------
|
71
|
+
|
72
|
+
SSL certificate verification can be turned off by using
|
73
|
+
`Fiddler.configuration.ssl_verify` option. This is very helpful in jruby
|
74
|
+
implementations where ssl is bit of a pain.
|
75
|
+
|
6
76
|
Supported Versions of Request Tracker
|
7
77
|
-------------------------------------
|
8
78
|
* 4.0.4
|
data/lib/fiddler.rb
CHANGED
@@ -2,7 +2,11 @@ require 'fiddler/configuration'
|
|
2
2
|
require 'fiddler/errors'
|
3
3
|
require 'fiddler/parsers'
|
4
4
|
require 'fiddler/formatters'
|
5
|
-
require 'fiddler/
|
5
|
+
require 'fiddler/extensions'
|
6
6
|
require 'fiddler/connection_manager'
|
7
7
|
|
8
|
+
require 'fiddler/ticket'
|
9
|
+
require 'fiddler/history'
|
10
|
+
require 'fiddler/attachment'
|
11
|
+
|
8
12
|
require 'active_support/all'
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'active_attr'
|
2
|
+
module Fiddler
|
3
|
+
class AttachmentCollection < Array
|
4
|
+
def to_payload
|
5
|
+
hash = Hash.new
|
6
|
+
self.each_with_index do |attach, index|
|
7
|
+
hash["attachment_#{index+1}"] = attach
|
8
|
+
end
|
9
|
+
hash
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.fill(*args)
|
13
|
+
AttachmentCollection.new Array(args.compact).flatten.map { |attachment|
|
14
|
+
if attachment.is_a?(File)
|
15
|
+
AttachmentFile.new(attachment.path)
|
16
|
+
elsif attachment.is_a?(String)
|
17
|
+
AttachmentFile.new(attachment)
|
18
|
+
elsif attachment.is_a?(ActionDispatch::Http::UploadedFile)
|
19
|
+
AttachmentFile.new(attachment.tempfile.path, attachment.original_filename)
|
20
|
+
end
|
21
|
+
}.compact
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class AttachmentFile < File
|
26
|
+
attr_accessor :name
|
27
|
+
|
28
|
+
def initialize(path,name=nil)
|
29
|
+
super(path)
|
30
|
+
@name = name || File.basename(path)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# the attachment in itself
|
35
|
+
class Attachment
|
36
|
+
include ActiveAttr::Model
|
37
|
+
|
38
|
+
attribute :id
|
39
|
+
attribute :subject
|
40
|
+
attribute :creator
|
41
|
+
attribute :created
|
42
|
+
attribute :transaction
|
43
|
+
attribute :parent
|
44
|
+
attribute :message_id
|
45
|
+
attribute :filename
|
46
|
+
attribute :content_type
|
47
|
+
attribute :content_encoding
|
48
|
+
attribute :headers
|
49
|
+
|
50
|
+
attr_accessor :ticket_id, :content, :path
|
51
|
+
|
52
|
+
# Public class method to get an attachment
|
53
|
+
def self.get(id, ticket_id)
|
54
|
+
url = "/ticket/#{ticket_id}/attachments/#{id}"
|
55
|
+
response = Fiddler::ConnectionManager.get(url)
|
56
|
+
attachment = Fiddler::Parsers::AttachmentParser.parse_single(response)
|
57
|
+
attachment.ticket_id = ticket_id
|
58
|
+
attachment
|
59
|
+
end
|
60
|
+
|
61
|
+
def content_length
|
62
|
+
length = header_value_for_key("Content-Length")
|
63
|
+
if !length.nil?
|
64
|
+
length.to_i
|
65
|
+
elsif @content.nil?
|
66
|
+
-1
|
67
|
+
else
|
68
|
+
@content.length
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def content
|
73
|
+
populate_data
|
74
|
+
@content
|
75
|
+
end
|
76
|
+
|
77
|
+
def path
|
78
|
+
populate_data
|
79
|
+
@path
|
80
|
+
end
|
81
|
+
|
82
|
+
def has_text_content
|
83
|
+
if content_type == "text/plain" or content_type == "text/html"
|
84
|
+
return true
|
85
|
+
else
|
86
|
+
return false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
protected
|
91
|
+
|
92
|
+
def populate_data
|
93
|
+
@data_populated ||= false
|
94
|
+
unless @data_populated
|
95
|
+
if content_length != 0
|
96
|
+
if has_text_content
|
97
|
+
load_content
|
98
|
+
@path = nil
|
99
|
+
else
|
100
|
+
@path = full_path_for_filename
|
101
|
+
if File.exists?(@path)
|
102
|
+
@content = ""
|
103
|
+
else
|
104
|
+
load_content
|
105
|
+
save_content_to_file
|
106
|
+
end
|
107
|
+
end
|
108
|
+
else
|
109
|
+
@content = ""
|
110
|
+
end
|
111
|
+
@data_populated = true
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def load_content
|
116
|
+
url = "/ticket/#{ticket_id}/attachments/#{id}/content"
|
117
|
+
response = Fiddler::ConnectionManager.get(url)
|
118
|
+
@content = Fiddler::Parsers::AttachmentParser.parse_content(response)
|
119
|
+
end
|
120
|
+
|
121
|
+
def header_value_for_key(header_key)
|
122
|
+
final_value = nil
|
123
|
+
headers.each do |header_line|
|
124
|
+
(key,value) = header_line.split(":")
|
125
|
+
if header_key == key
|
126
|
+
final_value = value
|
127
|
+
break
|
128
|
+
end
|
129
|
+
end
|
130
|
+
return final_value
|
131
|
+
end
|
132
|
+
|
133
|
+
def save_content_to_file
|
134
|
+
File.open(full_path_for_filename, "w") { |f| f.write(@content) }
|
135
|
+
@content = ""
|
136
|
+
end
|
137
|
+
|
138
|
+
def full_path_for_filename
|
139
|
+
"#{Fiddler.configuration.attachments_path}/#{id}-#{filename}"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -1,11 +1,16 @@
|
|
1
1
|
module Fiddler
|
2
2
|
# Based on the Clearance gem configuration - https://github.com/thoughtbot/clearance/blob/master/lib/clearance/configuration.rb
|
3
3
|
class Configuration
|
4
|
-
attr_accessor :server_url, :username, :password, :use_cookies, :cookie_domain, :ssl_verify
|
4
|
+
attr_accessor :server_url, :username, :password, :use_cookies, :cookie_domain, :cookie_value, :request_tracker_key, :ssl_verify, :attachments_path, :debug_response
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
@use_cookies = false
|
8
8
|
@ssl_verify = true
|
9
|
+
@attachments_path = "attachments"
|
10
|
+
@cookie_value = nil
|
11
|
+
@cookie_domain = nil
|
12
|
+
@request_tracker_key = "loginCookieValue"
|
13
|
+
@debug_response = false
|
9
14
|
end
|
10
15
|
end
|
11
16
|
|
@@ -17,4 +22,4 @@ module Fiddler
|
|
17
22
|
self.configuration ||= Configuration.new
|
18
23
|
yield configuration
|
19
24
|
end
|
20
|
-
end
|
25
|
+
end
|
@@ -1,33 +1,67 @@
|
|
1
1
|
require 'httpclient'
|
2
|
+
require 'awesome_print'
|
2
3
|
|
3
4
|
module Fiddler
|
4
5
|
module ConnectionManager
|
5
6
|
|
6
7
|
class Connection
|
7
|
-
attr_accessor :client
|
8
|
+
attr_accessor :client, :logged_in
|
9
|
+
|
8
10
|
def initialize
|
9
11
|
@client = HTTPClient.new
|
10
12
|
@client.set_cookie_store("cookies.dat")
|
13
|
+
@logged_in = false
|
11
14
|
end
|
12
15
|
|
13
|
-
def
|
14
|
-
|
16
|
+
def get(path,options)
|
17
|
+
login! unless @logged_in
|
18
|
+
@client.get(url_for(path),options).content
|
15
19
|
end
|
16
20
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
20
|
-
@client.get(url,options).content
|
21
|
+
def post(path,options)
|
22
|
+
login! unless @logged_in
|
23
|
+
@client.post(url_for(path),options).content
|
21
24
|
end
|
22
25
|
|
23
|
-
def
|
24
|
-
|
25
|
-
@client.
|
26
|
+
def post_content(path,options)
|
27
|
+
login! unless @logged_in
|
28
|
+
@client.post_content(url_for(path),options)
|
26
29
|
end
|
27
30
|
|
28
|
-
|
31
|
+
private
|
32
|
+
|
33
|
+
def login!
|
29
34
|
unless Fiddler.configuration.use_cookies
|
30
|
-
|
35
|
+
unless @logged_in
|
36
|
+
@client.post(url_for(base_url), :user => Fiddler.configuration.username, :pass => Fiddler.configuration.password )
|
37
|
+
@logged_in = true
|
38
|
+
end
|
39
|
+
else
|
40
|
+
@client.cookie_manager.cookies = []
|
41
|
+
cookie = WebAgent::Cookie.new
|
42
|
+
cookie.name = Fiddler.configuration.request_tracker_key
|
43
|
+
cookie.value = Fiddler.configuration.cookie_value
|
44
|
+
cookie.url = URI.parse(Fiddler.configuration.server_url)
|
45
|
+
cookie.domain_orig = Fiddler.configuration.cookie_domain
|
46
|
+
@client.cookie_manager.add(cookie)
|
47
|
+
@logged_in = false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def base_url
|
52
|
+
server_url = Fiddler.configuration.server_url
|
53
|
+
if server_url =~ /\/$/
|
54
|
+
"#{Fiddler.configuration.server_url}REST/1.0"
|
55
|
+
else
|
56
|
+
"#{Fiddler.configuration.server_url}/REST/1.0"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def url_for(path)
|
61
|
+
if path =~ /^\//
|
62
|
+
"#{base_url}#{path}"
|
63
|
+
else
|
64
|
+
"#{base_url}/#{path}"
|
31
65
|
end
|
32
66
|
end
|
33
67
|
end
|
@@ -37,16 +71,17 @@ module Fiddler
|
|
37
71
|
|
38
72
|
def get(url,options={})
|
39
73
|
check_config
|
40
|
-
|
41
|
-
debug(response)
|
42
|
-
response
|
74
|
+
debug connection.get(url,options)
|
43
75
|
end
|
44
76
|
|
45
77
|
def post(url,options={})
|
46
78
|
check_config
|
47
|
-
|
48
|
-
|
49
|
-
|
79
|
+
debug connection.post(url,options)
|
80
|
+
end
|
81
|
+
|
82
|
+
def post_content(url,options={})
|
83
|
+
check_config
|
84
|
+
debug connection.post_content(url,options)
|
50
85
|
end
|
51
86
|
|
52
87
|
protected
|
@@ -55,7 +90,7 @@ module Fiddler
|
|
55
90
|
config = Fiddler.configuration
|
56
91
|
raise InvalidConfigurationError if config.server_url.blank?
|
57
92
|
if config.username.blank? or config.password.blank?
|
58
|
-
raise InvalidConfigurationError unless config.use_cookies
|
93
|
+
raise InvalidConfigurationError unless config.use_cookies and config.request_tracker_key and config.cookie_value and config.cookie_domain
|
59
94
|
end
|
60
95
|
end
|
61
96
|
|
@@ -64,7 +99,14 @@ module Fiddler
|
|
64
99
|
end
|
65
100
|
|
66
101
|
def debug(response)
|
67
|
-
|
102
|
+
if ENV['DEBUG'] or Fiddler.configuration.debug_response
|
103
|
+
if defined?(Rails)
|
104
|
+
Rails.logger.debug response
|
105
|
+
else
|
106
|
+
ap response
|
107
|
+
end
|
108
|
+
end
|
109
|
+
return response
|
68
110
|
end
|
69
111
|
end # end class method definitions
|
70
112
|
end # end ConnectionManager module definition
|
data/lib/fiddler/errors.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
class Hash
|
2
|
+
def to_content_format
|
3
|
+
fields = self.map do |key,value|
|
4
|
+
unless value.nil?
|
5
|
+
value = Fiddler::Formatters::BaseFormatter.format_string(value.to_s)
|
6
|
+
if key.to_s.match(/^cf_.+/)
|
7
|
+
"CF-#{key.to_s[3..key.to_s.length].gsub(/_/, " ").camelize.humanize}: #{value}"
|
8
|
+
else
|
9
|
+
"#{key.to_s.camelize}: #{value}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
content = fields.compact.sort.join("\n")
|
14
|
+
end
|
15
|
+
end
|
@@ -51,8 +51,8 @@ module Fiddler
|
|
51
51
|
end
|
52
52
|
query_array << '( ' + parts.join(" AND ") + ' )'
|
53
53
|
elsif value.is_a?(String)
|
54
|
-
# special case for
|
55
|
-
if key == "Owner"
|
54
|
+
# special case for the owner field
|
55
|
+
if key == "Owner"
|
56
56
|
query_array << "#{key} = '#{value}'"
|
57
57
|
else
|
58
58
|
query_array << "#{key} LIKE '#{value}'"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'active_attr'
|
2
|
+
module Fiddler
|
3
|
+
class History
|
4
|
+
include ActiveAttr::Model
|
5
|
+
|
6
|
+
attribute :id
|
7
|
+
attribute :ticket
|
8
|
+
attribute :time_taken
|
9
|
+
attribute :type
|
10
|
+
attribute :field
|
11
|
+
attribute :old_value
|
12
|
+
attribute :new_value
|
13
|
+
attribute :data
|
14
|
+
attribute :description
|
15
|
+
attribute :content
|
16
|
+
attribute :creator
|
17
|
+
attribute :created
|
18
|
+
attribute :attachment_ids
|
19
|
+
|
20
|
+
attr_reader :attachments
|
21
|
+
|
22
|
+
def attachments
|
23
|
+
if @attachments == nil
|
24
|
+
@attachments = []
|
25
|
+
attachment_ids.each do |id|
|
26
|
+
@attachments << Fiddler::Attachment.get(id,ticket)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
@attachments
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|