zammad_api 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1430cf67f29761e9852ef05ae2e47dec4b8f6848
4
+ data.tar.gz: 71da04439cbcbcb0fba11d01d3af82336250a78e
5
+ SHA512:
6
+ metadata.gz: 9e141f9947064e2d7995fa458969af5ed35228c985fe56b42538887b1e226267ee371a21de4afaa34a30438717624d8f1a7e8f47aa733c6ddc3eba9f1c349ea2
7
+ data.tar.gz: 48fc482034cc42bdde3636de3c1208ee698e9882b229b6102fd5aa9e6a0aec67d83a4fd11ba16527743a902b519b44a33b15800661fcb29eabbea1eccf5e5e54
@@ -0,0 +1,53 @@
1
+ require 'zammad_api/log'
2
+ require 'zammad_api/transport'
3
+ require 'zammad_api/dispatcher'
4
+ require 'zammad_api/resources'
5
+
6
+ module ZammadAPI
7
+
8
+ class Client
9
+
10
+ def initialize(config)
11
+ @config = config
12
+ @logger = ZammadAPI::Log.new(@config)
13
+ @transport = ZammadAPI::Transport.new(@config, @logger)
14
+ check_config
15
+ end
16
+
17
+ def method_missing(method, *_args)
18
+ method = modulize( method.to_s )
19
+ class_name = "ZammadAPI::Resources::#{method}"
20
+ begin
21
+ class_object = Kernel.const_get(class_name)
22
+ rescue
23
+ raise "Resource for #{method} does not exist"
24
+ end
25
+ ZammadAPI::Dispatcher.new(@transport, class_object)
26
+ end
27
+
28
+ private
29
+
30
+ def check_config
31
+ raise 'missing url in config' if !@config[:url]
32
+ raise 'config url needs to start with http:// or https://' if @config[:url] !~ %r{^(http|https)://}
33
+
34
+ # check for token auth
35
+ return if @config[:http_token] && !@config[:http_token].empty?
36
+
37
+ if !@config[:user] || @config[:user].empty?
38
+ raise 'missing user in config'
39
+ end
40
+
41
+ return if @config[:password] && !@config[:password].empty?
42
+
43
+ raise 'missing password in config'
44
+ end
45
+
46
+ def modulize(string)
47
+ string.gsub(/__(.?)/) { "::#{$1.upcase}" }
48
+ .gsub(%r{/(.?)}) { "::#{$1.upcase}" }
49
+ .gsub(/(?:_+|-+)([a-z])/) { $1.upcase }
50
+ .gsub(/(\A|\s)([a-z])/) { $1 + $2.upcase }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,13 @@
1
+ module ZammadAPI
2
+ class Dispatcher
3
+
4
+ def initialize(transport, resource)
5
+ @transport = transport
6
+ @resource = resource
7
+ end
8
+
9
+ def method_missing(method, *args)
10
+ @resource.send(method, @transport, args[0])
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ require 'zammad_api/list_base'
2
+
3
+ module ZammadAPI
4
+ class ListAll < ListBase
5
+
6
+ private
7
+
8
+ def perform_request(parameter)
9
+ request('all', @url, parameter)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,85 @@
1
+ module ZammadAPI
2
+ class ListBase
3
+
4
+ def initialize(resource, transport, parameter = {})
5
+ @resource = resource
6
+ @url = @resource.get_url
7
+ @transport = transport
8
+ @parameter = {
9
+ page: 1,
10
+ per_page: 10,
11
+ expand: 'true',
12
+ }.merge(parameter)
13
+ end
14
+
15
+ def [](position)
16
+
17
+ local_parameter = @parameter.merge(
18
+ page: position + 1,
19
+ per_page: 1
20
+ )
21
+ perform_request(local_parameter)[0]
22
+ end
23
+
24
+ def page(page, per_page, &block)
25
+
26
+ @parameter[:page] = page
27
+ @parameter[:per_page] = per_page
28
+ fetch_and_yield_each(&block)
29
+ end
30
+
31
+ def page_next(&block)
32
+ @parameter[:page] += 1
33
+ fetch_and_yield_each(&block)
34
+ end
35
+
36
+ def page_prev(&block)
37
+ @parameter[:page] -= 1
38
+ fetch_and_yield_each(&block)
39
+ end
40
+
41
+ def each(&block)
42
+ fetch_and_yield_each(&block)
43
+ end
44
+
45
+ private
46
+
47
+ def fetch_and_yield_each
48
+ result = perform_request(@parameter)
49
+ result.each { |item|
50
+ yield item
51
+ }
52
+ end
53
+
54
+ def request(request, url, parameter)
55
+
56
+ # convert parameters into a GET query
57
+ url += '?' + parameter.map { |key, value|
58
+
59
+ if !value.is_a? String
60
+ value = value.to_s
61
+ end
62
+
63
+ "#{key}=#{CGI.escape value}"
64
+ }.join('&')
65
+
66
+ response = @transport.get(url: url)
67
+ data = JSON.parse(response.body)
68
+ if response.status != 200
69
+ raise "Can't get .#{request} of object (#{@resource.class.name}): #{data['error']}"
70
+ end
71
+
72
+ list = []
73
+ data.each { |local_data|
74
+ item = @resource.new(@transport, local_data)
75
+ item.new_instance = false
76
+ list.push item
77
+ }
78
+ list
79
+ end
80
+
81
+ def perform_request(_parameter)
82
+ raise "no perform_request implementation for #{self.class.name} found"
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,12 @@
1
+ require 'zammad_api/list_base'
2
+
3
+ module ZammadAPI
4
+ class ListSearch < ListBase
5
+
6
+ private
7
+
8
+ def perform_request(parameter)
9
+ request('search', "#{@url}/search", parameter)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module ZammadAPI
2
+ class Log
3
+
4
+ def initialize(config)
5
+ return if !config[:logger]
6
+ require 'logger'
7
+ @logger = Logger.new($stderr)
8
+ #@logger.level = Logger::WARN
9
+ @logger.level = Logger::DEBUG
10
+ end
11
+
12
+ def method_missing(method, *args)
13
+ return if !@logger
14
+ @logger.send(method, args)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,130 @@
1
+ require 'cgi'
2
+ require 'json'
3
+ require 'zammad_api/transport'
4
+
5
+ module ZammadAPI
6
+ module Resources
7
+ class Base
8
+ attr_accessor :new_instance, :url, :attributes
9
+ attr_reader :changes
10
+
11
+ def initialize(transport, attributes = {})
12
+ @new_instance = true
13
+ @transport = transport
14
+ @changes = {}
15
+ @url = self.class.get_url
16
+
17
+ if attributes.nil?
18
+ attributes = {}
19
+ end
20
+ @attributes = attributes
21
+ symbolize_keys_deep!(@attributes)
22
+ end
23
+
24
+ def method_missing(method, *args)
25
+ if method.to_s[-1, 1] == '='
26
+ method = method.to_s[0, method.length - 1].to_sym
27
+ @changes[method] = [@attributes[method], args[0]]
28
+ @attributes[method] = args[0]
29
+ end
30
+ @attributes[method]
31
+ end
32
+
33
+ def new_record?
34
+ @new_instance
35
+ end
36
+
37
+ def changed?
38
+ return false if @changes.empty?
39
+ true
40
+ end
41
+
42
+ def destroy
43
+ response = @transport.delete(url: "#{@url}/#{@attributes[:id]}")
44
+ if response.body.to_s != '' && response.body.to_s != ' '
45
+ data = JSON.parse(response.body)
46
+ end
47
+ if response.status != 200
48
+ raise "Can't destroy object (#{self.class.name}): #{data['error']}"
49
+ end
50
+ true
51
+ end
52
+
53
+ def save
54
+ if @new_instance
55
+ response = @transport.post(url: "#{@url}?expand=true", params: @attributes)
56
+ attributes = JSON.parse(response.body)
57
+ if response.status != 201
58
+ raise "Can't create new object (#{self.class.name}): #{attributes['error']}"
59
+ end
60
+ else
61
+ attributes_to_post = {}
62
+ @changes.each { |name, values|
63
+ attributes_to_post[name] = values[1]
64
+ }
65
+ response = @transport.put(url: "#{@url}/#{@attributes[:id]}?expand=true", params: attributes_to_post)
66
+ attributes = JSON.parse(response.body)
67
+ if response.status != 200
68
+ raise "Can't update new object (#{self.class.name}): #{attributes['error']}"
69
+ end
70
+ end
71
+ symbolize_keys_deep!(attributes)
72
+ attributes.delete(:article)
73
+ @attributes = attributes
74
+ @new_instance = false
75
+ @changes = {}
76
+ true
77
+ end
78
+
79
+ def self.get_url
80
+ @url
81
+ end
82
+
83
+ def self.url(value)
84
+ @url = value
85
+ end
86
+
87
+ def self.all(transport, _)
88
+ ZammadAPI::ListAll.new(self, transport, per_page: 100)
89
+ end
90
+
91
+ def self.search(transport, parameter)
92
+ ZammadAPI::ListSearch.new(self, transport, parameter)
93
+ end
94
+
95
+ def self.find(transport, id)
96
+ response = transport.get(url: "#{@url}/#{id}?expand=true")
97
+ data = JSON.parse(response.body)
98
+ if response.status != 200
99
+ raise "Can't find object (#{self.class.name}): #{data['error']}"
100
+ end
101
+ item = new(transport, data)
102
+ item.new_instance = false
103
+ item
104
+ end
105
+
106
+ def self.create(transport, data)
107
+ item = new(transport, data)
108
+ item.save
109
+ item
110
+ end
111
+
112
+ def self.destroy(transport, id)
113
+ item = find(transport, id)
114
+ item.destroy
115
+ true
116
+ end
117
+
118
+ private
119
+
120
+ def symbolize_keys_deep!(hash)
121
+ hash.keys.each do |key|
122
+ key_symbol = key.respond_to?(:to_sym) ? key.to_sym : key
123
+ hash[key_symbol] = hash.delete key # Preserve order even when key == key_symbol
124
+
125
+ symbolize_keys_deep! hash[key_symbol] if hash[key_symbol].is_a? Hash
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,3 @@
1
+ class ZammadAPI::Resources::Group < ZammadAPI::Resources::Base
2
+ url '/api/v1/groups'
3
+ end
@@ -0,0 +1,3 @@
1
+ class ZammadAPI::Resources::Organization < ZammadAPI::Resources::Base
2
+ url '/api/v1/organizations'
3
+ end
@@ -0,0 +1,26 @@
1
+ class ZammadAPI::Resources::Ticket < ZammadAPI::Resources::Base
2
+ url '/api/v1/tickets'
3
+
4
+ def articles
5
+ response = @transport.get(url: "/api/v1/ticket_articles/by_ticket/#{id}?expand=true")
6
+ data = JSON.parse(response.body)
7
+ if response.status != 200
8
+ raise "Can't get articles (#{self.class.name}): #{data['error']}"
9
+ end
10
+ articles = []
11
+ data.each { |raw|
12
+ item = ZammadAPI::Resources::TicketArticle.new(@transport, raw)
13
+ item.new_instance = false
14
+ articles.push item
15
+ }
16
+ articles
17
+ end
18
+
19
+ def article(data)
20
+ data['ticket_id'] = @attributes[:id]
21
+ item = ZammadAPI::Resources::TicketArticle.new(@transport, data)
22
+ item.save
23
+ item
24
+ end
25
+
26
+ end
@@ -0,0 +1,3 @@
1
+ class ZammadAPI::Resources::TicketArticle < ZammadAPI::Resources::Base
2
+ url '/api/v1/ticket_articles'
3
+ end
@@ -0,0 +1,3 @@
1
+ class ZammadAPI::Resources::TicketPriority < ZammadAPI::Resources::Base
2
+ url '/api/v1/ticket_priorities'
3
+ end
@@ -0,0 +1,3 @@
1
+ class ZammadAPI::Resources::TicketState < ZammadAPI::Resources::Base
2
+ url '/api/v1/ticket_states'
3
+ end
@@ -0,0 +1,3 @@
1
+ class ZammadAPI::Resources::User < ZammadAPI::Resources::Base
2
+ url '/api/v1/users'
3
+ end
@@ -0,0 +1,16 @@
1
+ require 'zammad_api/list_base'
2
+ require 'zammad_api/list_all'
3
+ require 'zammad_api/list_search'
4
+ require 'zammad_api/resources/base'
5
+ require 'zammad_api/resources/user'
6
+ require 'zammad_api/resources/group'
7
+ require 'zammad_api/resources/organization'
8
+ require 'zammad_api/resources/ticket'
9
+ require 'zammad_api/resources/ticket_article'
10
+ require 'zammad_api/resources/ticket_state'
11
+ require 'zammad_api/resources/ticket_priority'
12
+
13
+ module ZammadAPI
14
+ class Resource
15
+ end
16
+ end
@@ -0,0 +1,63 @@
1
+ require 'faraday'
2
+ require 'openssl'
3
+
4
+ module ZammadAPI
5
+ class Transport
6
+
7
+ attr_accessor :url, :user, :password
8
+
9
+ def initialize(config, logger)
10
+ @logger = logger
11
+ @logger.debug "Transport to #{config[:url]} with #{config[:user]}:#{config[:password]}"
12
+ @conn = Faraday.new(url: config[:url]) do |faraday|
13
+ #faraday.request :url_encoded # form-encode POST params
14
+ #faraday.response :logger # log requests to STDOUT
15
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
16
+ end
17
+ @conn.headers[:user_agent] = 'Zammad API Ruby'
18
+ if config[:http_token] && !config[:http_token].empty?
19
+ @conn.token_auth(config[:http_token])
20
+ else
21
+ @conn.basic_auth(config[:user], config[:password])
22
+ end
23
+ end
24
+
25
+ def get(param)
26
+ @logger.debug "GET: #{@url}#{param[:url]}"
27
+ response = @conn.get param[:url]
28
+ response
29
+ end
30
+
31
+ def post(param)
32
+ @logger.debug "POST: #{@url}#{param[:url]}"
33
+ @logger.debug "Params: #{param[:params].inspect}"
34
+ response = @conn.post do |req|
35
+ req.url param[:url]
36
+ req.headers['Content-Type'] = 'application/json'
37
+ req.body = param[:params].to_json
38
+ end
39
+ @logger.debug "Response: #{response.body}"
40
+ response
41
+ end
42
+
43
+ def put(param)
44
+ @logger.debug "PUT: #{@url}#{param[:url]}"
45
+ @logger.debug "Params: #{param[:params].inspect}"
46
+ response = @conn.put do |req|
47
+ req.url param[:url]
48
+ req.headers['Content-Type'] = 'application/json'
49
+ req.body = param[:params].to_json
50
+ end
51
+ @logger.debug "Response: #{response.body}"
52
+ response
53
+ end
54
+
55
+ def delete(param)
56
+ @logger.debug "DELETE: #{@url}#{param[:url]}"
57
+ response = @conn.delete param[:url]
58
+ @logger.debug "Response: #{response.body}"
59
+ response
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,3 @@
1
+ module ZammadAPI
2
+ VERSION = '0.9.1'.freeze
3
+ end
data/lib/zammad_api.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'zammad_api/version'
2
+ require 'zammad_api/client'
3
+
4
+ module ZammadAPI
5
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zammad_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.1
5
+ platform: ruby
6
+ authors:
7
+ - Martin Edenhofer
8
+ - Thorsten Eckel
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-10-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0.9'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0.9'
28
+ - !ruby/object:Gem::Dependency
29
+ name: logger
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.2'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.2'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.12'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.12'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '10.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '10.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '3.0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '3.0'
84
+ description: Ruby wrapper for the Zammad API v1.0.
85
+ email:
86
+ - support@zammad.org
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - lib/zammad_api.rb
92
+ - lib/zammad_api/client.rb
93
+ - lib/zammad_api/dispatcher.rb
94
+ - lib/zammad_api/list_all.rb
95
+ - lib/zammad_api/list_base.rb
96
+ - lib/zammad_api/list_search.rb
97
+ - lib/zammad_api/log.rb
98
+ - lib/zammad_api/resources.rb
99
+ - lib/zammad_api/resources/base.rb
100
+ - lib/zammad_api/resources/group.rb
101
+ - lib/zammad_api/resources/organization.rb
102
+ - lib/zammad_api/resources/ticket.rb
103
+ - lib/zammad_api/resources/ticket_article.rb
104
+ - lib/zammad_api/resources/ticket_priority.rb
105
+ - lib/zammad_api/resources/ticket_state.rb
106
+ - lib/zammad_api/resources/user.rb
107
+ - lib/zammad_api/transport.rb
108
+ - lib/zammad_api/version.rb
109
+ homepage: https://github.com/zammad/zammad_api_client_ruby
110
+ licenses: []
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.4.8
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Zammad API v1.0 client.
132
+ test_files: []