keytechkit 0.3.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +9 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +146 -0
- data/LICENSE +21 -0
- data/README.md +60 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/keytechKit.gemspec +30 -0
- data/lib/keytechKit/classes/classdefinition.rb +38 -0
- data/lib/keytechKit/classes/classes.rb +47 -0
- data/lib/keytechKit/classes/layout/control.rb +35 -0
- data/lib/keytechKit/classes/layout/layout.rb +22 -0
- data/lib/keytechKit/classes/layouts.rb +78 -0
- data/lib/keytechKit/classes/subarea.rb +12 -0
- data/lib/keytechKit/elements/bom/bom_element.rb +42 -0
- data/lib/keytechKit/elements/bom/bom_element_list.rb +29 -0
- data/lib/keytechKit/elements/data_dictionary/data_dictionary_definition.rb +23 -0
- data/lib/keytechKit/elements/data_dictionary/data_dictionary_handler.rb +50 -0
- data/lib/keytechKit/elements/element.rb +81 -0
- data/lib/keytechKit/elements/element_files/element_file.rb +19 -0
- data/lib/keytechKit/elements/element_files/element_file_handler.rb +181 -0
- data/lib/keytechKit/elements/element_handler.rb +183 -0
- data/lib/keytechKit/elements/group_by.rb +16 -0
- data/lib/keytechKit/elements/notes/note.rb +31 -0
- data/lib/keytechKit/elements/notes/note_handler.rb +35 -0
- data/lib/keytechKit/elements/search_response_header.rb +47 -0
- data/lib/keytechKit/search.rb +46 -0
- data/lib/keytechKit/serverinfo.rb +33 -0
- data/lib/keytechKit/serverinfo_handler.rb +23 -0
- data/lib/keytechKit/targetlink.rb +26 -0
- data/lib/keytechKit/tools.rb +14 -0
- data/lib/keytechKit/user.rb +79 -0
- data/lib/keytechKit/version.rb +15 -0
- data/lib/keytechKit.rb +98 -0
- metadata +153 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'keytechKit/elements/data_dictionary/data_dictionary_definition'
|
2
|
+
|
3
|
+
module KeytechKit
|
4
|
+
class DataDictionaryHandler
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
attr_accessor :keytechkit
|
8
|
+
|
9
|
+
def initialize(keytechkit, base_url, username, password)
|
10
|
+
self.class.base_uri(base_url)
|
11
|
+
@auth = { username: username, password: password }
|
12
|
+
@keytechkit = keytechkit
|
13
|
+
end
|
14
|
+
|
15
|
+
def getDefinition(datadictionary_id)
|
16
|
+
# /DataDictionaries/{ID}|{Name}
|
17
|
+
parameter = { basic_auth: @auth }
|
18
|
+
|
19
|
+
response = self.class.get("/datadictionaries/#{datadictionary_id}", parameter)
|
20
|
+
if response.success?
|
21
|
+
parse_dataDictionaryDefinition(response['AttributeDefinition'])
|
22
|
+
else
|
23
|
+
raise response.response
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns a hashed value with data
|
28
|
+
def getData(datadictionary_id)
|
29
|
+
# /DataDictionaries/{ID}|{Name}/data
|
30
|
+
parameter = { basic_auth: @auth }
|
31
|
+
|
32
|
+
response = self.class.get("/datadictionaries/#{datadictionary_id}/data", parameter)
|
33
|
+
if response.success?
|
34
|
+
response['Data']
|
35
|
+
else
|
36
|
+
raise response.response
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def parse_dataDictionaryDefinition(definitionArray)
|
43
|
+
definition = []
|
44
|
+
definitionArray.each do |definitionData|
|
45
|
+
definition.push DataDictionaryDefinition.new(definitionData)
|
46
|
+
end
|
47
|
+
definition
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
|
2
|
+
module KeytechKit
|
3
|
+
##
|
4
|
+
# Represents a single element
|
5
|
+
class Element
|
6
|
+
attr_accessor :key # unique key of this element
|
7
|
+
attr_accessor :name
|
8
|
+
|
9
|
+
# a array of {key:, value:} pairs
|
10
|
+
attr_accessor :keyValueList
|
11
|
+
|
12
|
+
attr_accessor :createdByLong
|
13
|
+
attr_accessor :createdBy
|
14
|
+
attr_accessor :createdAt
|
15
|
+
|
16
|
+
attr_accessor :changedAt
|
17
|
+
attr_accessor :changedByLong
|
18
|
+
attr_accessor :changedBy
|
19
|
+
|
20
|
+
attr_accessor :displayname # localized DisplayName
|
21
|
+
attr_accessor :thumbnailHint
|
22
|
+
attr_accessor :hasVersions
|
23
|
+
attr_accessor :classDisplayName
|
24
|
+
attr_accessor :status
|
25
|
+
attr_accessor :version
|
26
|
+
attr_accessor :description
|
27
|
+
|
28
|
+
def initialize(data)
|
29
|
+
self.key = data['Key']
|
30
|
+
self.name = data['Name']
|
31
|
+
set_key_value_list(data['KeyValueList'])
|
32
|
+
|
33
|
+
self.displayname = data['DisplayName']
|
34
|
+
self.classDisplayName = data['ClassDisplayName']
|
35
|
+
self.version = data['Version']
|
36
|
+
self.status = data['Status']
|
37
|
+
self.description = data['Description']
|
38
|
+
|
39
|
+
self.changedBy = data['ChangedBy']
|
40
|
+
self.changedByLong = data['ChangedByLong']
|
41
|
+
self.changedAt = data['ChangedAt']
|
42
|
+
|
43
|
+
self.createdBy = data['CreatedBy']
|
44
|
+
self.createdByLong = data['CreatedByLong']
|
45
|
+
self.createdAt = data['CreatedAt']
|
46
|
+
|
47
|
+
self.thumbnailHint = data['ThumbnailHint']
|
48
|
+
self.hasVersions = data['HasVersions']
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_hash
|
52
|
+
{ Key: key, Name: name, keyValueList: keytechKeyValueObject }
|
53
|
+
end
|
54
|
+
|
55
|
+
# This is keytech - Style: key and value in different elements-
|
56
|
+
# No easy parsable hash!
|
57
|
+
# Sorry it was me. I was young and needed the money ;-)
|
58
|
+
# {
|
59
|
+
# "Key": "au_do__categorylocalized",
|
60
|
+
# "Value": "Blaue Kategorie"
|
61
|
+
# }
|
62
|
+
def keytechKeyValueObject
|
63
|
+
arrayOfKeyValuePairs = []
|
64
|
+
keyValueList.each do |key, value|
|
65
|
+
arrayOfKeyValuePairs.push ({ Key: key, Value: value })
|
66
|
+
end
|
67
|
+
arrayOfKeyValuePairs
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def set_key_value_list(kv_data)
|
73
|
+
self.keyValueList = ({})
|
74
|
+
if kv_data
|
75
|
+
kv_data.each do |kvPair|
|
76
|
+
keyValueList[kvPair['Key'].to_s] = kvPair['Value']
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module KeytechKit
|
2
|
+
##
|
3
|
+
# A single file representation
|
4
|
+
class ElementFile
|
5
|
+
attr_accessor :changedAt
|
6
|
+
attr_accessor :fileName
|
7
|
+
attr_accessor :fileSize
|
8
|
+
attr_accessor :fileStorageType
|
9
|
+
attr_accessor :fileId
|
10
|
+
|
11
|
+
def initialize(data)
|
12
|
+
self.changedAt = data['FileLastChangedAt']
|
13
|
+
self.fileSize = data['FileSize']
|
14
|
+
self.fileName = data['FileName']
|
15
|
+
self.fileId = data['FileID']
|
16
|
+
self.fileStorageType = data['FileStorageType']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'keytechKit/tools'
|
2
|
+
require 'keytechKit/elements/element_files/element_file'
|
3
|
+
|
4
|
+
module KeytechKit
|
5
|
+
##
|
6
|
+
# Element File handler
|
7
|
+
class ElementFileHandler
|
8
|
+
include HTTParty
|
9
|
+
|
10
|
+
def initialize(base_url, username, password)
|
11
|
+
self.class.base_uri(base_url)
|
12
|
+
@auth = { username: username, password: password }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns true or false if a masterfile exist
|
16
|
+
def masterfile?(element_key)
|
17
|
+
if Tools.classType(element_key) == 'DO' # Only DO Types can have a file
|
18
|
+
file_list = load(element_key)
|
19
|
+
unless file_list.nil?
|
20
|
+
file_list.each do |file|
|
21
|
+
return true if file.fileStorageType.casecmp('master').zero?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns information about masterfile
|
29
|
+
def masterfile_info(element_key)
|
30
|
+
if Tools.classType(element_key) == 'DO' # Only DO Types can have a file
|
31
|
+
file_list = load(element_key)
|
32
|
+
unless file_list.nil?
|
33
|
+
file_list.each do |file|
|
34
|
+
return file if file.fileStorageType.casecmp('master').zero?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the name of a masterfile if present
|
42
|
+
def masterfile_name(element_key)
|
43
|
+
file_list = load(element_key)
|
44
|
+
unless file_list.nil?
|
45
|
+
file_list.each do |file|
|
46
|
+
return file.fileName if file.fileStorageType.downcase! == 'master'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
''
|
50
|
+
end
|
51
|
+
|
52
|
+
# Loads the filelist
|
53
|
+
# Returns a full list of file data
|
54
|
+
def load(element_key)
|
55
|
+
parameter = { basic_auth: @auth }
|
56
|
+
response = self.class.get("/elements/#{element_key}/files", parameter)
|
57
|
+
parse_files(response['FileInfos']) if response.success?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Loads the masterfile directly
|
61
|
+
def load_masterfile(element_key)
|
62
|
+
parameter = { basic_auth: @auth }
|
63
|
+
response = self.class.get("/elements/#{element_key}/files/masterfile", parameter)
|
64
|
+
return response if response.success?
|
65
|
+
end
|
66
|
+
|
67
|
+
# Masterfile is the main file attached to a document
|
68
|
+
#
|
69
|
+
def upload_masterfile(element_key, file, original_filename)
|
70
|
+
# file, elementkey , name??
|
71
|
+
content_length = file.size
|
72
|
+
content_type = 'application/octet-stream; charset=utf-8'
|
73
|
+
parameter = { basic_auth: @auth,
|
74
|
+
headers: { 'Content-Type' => content_type,
|
75
|
+
'Content-Length' => content_length.to_s,
|
76
|
+
'storageType' => 'MASTER',
|
77
|
+
'filename' => original_filename.to_s },
|
78
|
+
body: file.read }
|
79
|
+
upload_file element_key, parameter
|
80
|
+
end
|
81
|
+
|
82
|
+
# The preview is a larger preview file. It must not have the same type as the masterfile,
|
83
|
+
# But should allow a sneak preview to its contents.
|
84
|
+
# e.g.: You have a large (200MB) CAD file, then der prebview may represent a
|
85
|
+
# 2D Drawing of the large fole.
|
86
|
+
# You can have more than one preview file
|
87
|
+
def upload_preview(element_key, file, original_filename)
|
88
|
+
# file, elementkey , name??
|
89
|
+
content_length = file.size
|
90
|
+
content_type = 'application/octet-stream; charset=utf-8'
|
91
|
+
|
92
|
+
parameter = { basic_auth: @auth,
|
93
|
+
headers: { 'Content-Type' => content_type,
|
94
|
+
'Content-Length' => content_length.to_s,
|
95
|
+
'storageType' => 'PREVIEW',
|
96
|
+
'filename' => original_filename.to_s },
|
97
|
+
body: file.read }
|
98
|
+
upload_file element_key, parameter
|
99
|
+
end
|
100
|
+
|
101
|
+
# A Quickpreview is mostly a smaller image file. Best is to make a image_file
|
102
|
+
# from the quickpreview. Respect modern retina displays - so dont be shy
|
103
|
+
# to upload image files of at least 800x600 pixels in size
|
104
|
+
def upload_quickpreview(element_key, file, original_filename)
|
105
|
+
# file, elementkey , name??
|
106
|
+
content_length = file.size
|
107
|
+
content_type = 'application/octet-stream; charset=utf-8'
|
108
|
+
|
109
|
+
parameter = { basic_auth: @auth,
|
110
|
+
headers: { 'Content-Type' => content_type,
|
111
|
+
'Content-Length' => content_length.to_s,
|
112
|
+
'storageType' => 'QUICKPREVIEW',
|
113
|
+
'filename' => original_filename.to_s },
|
114
|
+
body: file.read }
|
115
|
+
upload_file element_key, parameter
|
116
|
+
end
|
117
|
+
|
118
|
+
def remove_masterfile(element_key)
|
119
|
+
file_list = load(element_key)
|
120
|
+
if !file_list.nil?
|
121
|
+
file_list.each do |file|
|
122
|
+
return remove_file(element_key, file.fileId) if file.fileStorageType.casecmp('master').zero?
|
123
|
+
end
|
124
|
+
end
|
125
|
+
{ success: true, message: "No file found" }
|
126
|
+
end
|
127
|
+
|
128
|
+
def remove_preview(element_key)
|
129
|
+
file_list = load(element_key)
|
130
|
+
if !file_list.nil?
|
131
|
+
file_list.each do |file|
|
132
|
+
return remove_file(element_key, file.fileId) if file.fileStorageType.casecmp('preview').zero?
|
133
|
+
end
|
134
|
+
end
|
135
|
+
{ success: true, message: "No file found" }
|
136
|
+
end
|
137
|
+
|
138
|
+
def remove_quickpreview(element_key)
|
139
|
+
file_list = load(element_key)
|
140
|
+
if !file_list.nil?
|
141
|
+
file_list.each do |file|
|
142
|
+
return remove_file(element_key, file.fileId) if file.fileStorageType.casecmp('quickpreview').zero?
|
143
|
+
end
|
144
|
+
end
|
145
|
+
{ success: true, message: "No file found" }
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def remove_file(element_key, file_id)
|
151
|
+
parameter = { basic_auth: @auth }
|
152
|
+
response = self.class.delete("/elements/#{element_key}/files/#{file_id}", parameter)
|
153
|
+
if response.success?
|
154
|
+
{ success: true }
|
155
|
+
else
|
156
|
+
{ success: false, error: response.headers['x-errordescription'].to_s }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def upload_file(element_key, parameter)
|
161
|
+
response = self.class.post("/elements/#{element_key}/files", parameter)
|
162
|
+
parse_response(response)
|
163
|
+
end
|
164
|
+
|
165
|
+
def parse_response(response)
|
166
|
+
if response.success?
|
167
|
+
{ success: true, location: response.headers['location'].to_s }
|
168
|
+
else
|
169
|
+
{ success: false, error: response.headers['x-errordescription'].to_s }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def parse_files(files_result)
|
174
|
+
files = []
|
175
|
+
files_result.each do |file_data|
|
176
|
+
files.push ElementFile.new(file_data)
|
177
|
+
end
|
178
|
+
files
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'keytechKit/elements/element'
|
2
|
+
require 'keytechKit/elements/search_response_header'
|
3
|
+
require 'keytechKit/elements/bom/bom_element_list'
|
4
|
+
|
5
|
+
module KeytechKit
|
6
|
+
##
|
7
|
+
# All operations for a element is here
|
8
|
+
class ElementHandler
|
9
|
+
include HTTParty
|
10
|
+
|
11
|
+
attr_accessor :keytechkit
|
12
|
+
|
13
|
+
def initialize(keytechkit, base_url, username, password)
|
14
|
+
self.class.base_uri(base_url)
|
15
|
+
@auth = { username: username, password: password }
|
16
|
+
@keytechkit = keytechkit
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Find an existing element with +elementkey+ in form of classkey:<nummeric>
|
21
|
+
# e.g.: MISC_FILE:1234
|
22
|
+
# +options+ is one of attributes=ALL|NONE|EDITOR
|
23
|
+
# It returns nil if no element with this elementKey was found
|
24
|
+
def load(element_key, options = {})
|
25
|
+
parameter = { query: options }
|
26
|
+
parameter[:basic_auth] = @auth
|
27
|
+
|
28
|
+
response = self.class.get("/elements/#{element_key}", parameter)
|
29
|
+
|
30
|
+
if response.success?
|
31
|
+
searchResponseHeader = SearchResponseHeader.new(response)
|
32
|
+
searchResponseHeader.elementList.first
|
33
|
+
# TODO: Can we do better if element was not found?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# It returns a element prototype with the given elementKey
|
38
|
+
# you can check valid elementkeys with the classdefinition
|
39
|
+
def new_element(key)
|
40
|
+
Element.new('Key' => key)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Saves a element to keytech web api and returns the saved element.
|
44
|
+
# If anything goes wrong - a http response is returned
|
45
|
+
def save(element)
|
46
|
+
elementHash = element.to_hash
|
47
|
+
parameter = { basic_auth: @auth,
|
48
|
+
body: elementHash.to_json,
|
49
|
+
headers: { 'Content-Type' => 'application/json; charset=utf-8
' } }
|
50
|
+
save_response = self.class.post('/elements', parameter)
|
51
|
+
if save_response.success?
|
52
|
+
Element.new(save_response.parsed_response)
|
53
|
+
else
|
54
|
+
puts "Could not save element: #{save_response.headers['x-errordescription']}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Saves a element to keytech web api and returns the saved element.
|
59
|
+
# If anything goes wrong - a http response is returned
|
60
|
+
def update(element)
|
61
|
+
elementHash = element.to_hash
|
62
|
+
parameter = { basic_auth: @auth,
|
63
|
+
body: elementHash.to_json,
|
64
|
+
headers: { 'Content-Type' => 'application/json; charset=utf-8
' } }
|
65
|
+
save_response = self.class.put("/elements/#{element.key}", parameter)
|
66
|
+
if save_response.success?
|
67
|
+
Element.new(save_response.parsed_response)
|
68
|
+
else
|
69
|
+
puts "Could not save element: #{save_response.headers['x-errordescription']}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Deletes an element with the key
|
74
|
+
# It returns the http response.
|
75
|
+
def delete(element_key)
|
76
|
+
parameter = { basic_auth: @auth }
|
77
|
+
response = self.class.delete("/elements/#{element_key}", parameter)
|
78
|
+
unless response.success?
|
79
|
+
puts "Could not save element: #{response.headers['x-errordescription']}"
|
80
|
+
end
|
81
|
+
response
|
82
|
+
end
|
83
|
+
|
84
|
+
# Loads the structure
|
85
|
+
# +options+ can have these values: size, page, attribute = ALL|NONE|GLOBALLISTER|SECONDARY|EXPLORER
|
86
|
+
# Returns a list of elements
|
87
|
+
# It returns nil if no element with this elementKey was found
|
88
|
+
def structure(element_key, options = {})
|
89
|
+
parameter = { query: options }
|
90
|
+
parameter[:basic_auth] = @auth
|
91
|
+
response = self.class.get("/elements/#{element_key}/structure", parameter)
|
92
|
+
if response.success?
|
93
|
+
searchResponseHeader = SearchResponseHeader.new(response)
|
94
|
+
return searchResponseHeader.elementList
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Loads the parent elements
|
99
|
+
# +options+ can have these values: size, page, attribute = ALL|NONE|GLOBALLISTER|SECONDARY|EXPLORER
|
100
|
+
# Returns a list of elements
|
101
|
+
# It returns nil if no element with this elementKey was found
|
102
|
+
def whereused(element_key, options = {})
|
103
|
+
parameter = { query: options }
|
104
|
+
parameter[:basic_auth] = @auth
|
105
|
+
|
106
|
+
response = self.class.get("/elements/#{element_key}/whereused", parameter)
|
107
|
+
if response.success?
|
108
|
+
searchResponseHeader = SearchResponseHeader.new(response)
|
109
|
+
return searchResponseHeader.elementList
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Loads the bill of meterial on articles
|
114
|
+
# +options+ can have these values: size, page, attribute = ALL|NONE|GLOBALLISTER|SECONDARY|EXPLORER
|
115
|
+
# Returns a list of elements
|
116
|
+
# It returns nil if no element with this elementKey was found
|
117
|
+
def billOfMaterial(element_key, options = {})
|
118
|
+
parameter = { query: options }
|
119
|
+
parameter[:basic_auth] = @auth
|
120
|
+
|
121
|
+
response = self.class.get("/elements/#{element_key}/bom", parameter)
|
122
|
+
if response.success?
|
123
|
+
bom_list = BomElementList.new(response)
|
124
|
+
return bom_list.bomElementList
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
# Loads the list of mails on folders,
|
129
|
+
# +options+ can have these values: size, page, attribute = ALL|NONE|GLOBALLISTER|SECONDARY|EXPLORER
|
130
|
+
# Returns a list of elements
|
131
|
+
# It returns nil if no element with this elementKey was found
|
132
|
+
def mails(element_key, options = {})
|
133
|
+
parameter = { query: options }
|
134
|
+
parameter[:basic_auth] = @auth
|
135
|
+
|
136
|
+
response = self.class.get("/elements/#{element_key}/mails", parameter)
|
137
|
+
return response['ElementList'] if response.success?
|
138
|
+
end
|
139
|
+
|
140
|
+
# It returns the notes of an element if anything are given
|
141
|
+
# Notes list can be empty
|
142
|
+
# It returns nil if no element with this elementKey was found
|
143
|
+
def notes(element_key)
|
144
|
+
parameter = { basic_auth: @auth }
|
145
|
+
|
146
|
+
response = self.class.get("/elements/#{element_key}/notes", parameter)
|
147
|
+
if response.success?
|
148
|
+
search_response_header = SearchResponseHeader.new(response)
|
149
|
+
search_response_header.elementList
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Returns Notes resource.
|
154
|
+
# Every Element can have zero, one or more notes.
|
155
|
+
# You can notes only access in context of its element which ownes the notes
|
156
|
+
def note_handler
|
157
|
+
@_note_handler = NoteHandler.new(keytechkit.base_url, keytechkit.username, keytechkit.password) if @_note_handler.nil?
|
158
|
+
@_note_handler
|
159
|
+
end
|
160
|
+
|
161
|
+
# Returns the file object.
|
162
|
+
# Every element can have a Masterfile and one or more preview files
|
163
|
+
def file_handler
|
164
|
+
@_element_file_handler = ElementFileHandler.new(keytechkit.base_url, keytechkit.username, keytechkit.password) if @_element_file_handler.nil?
|
165
|
+
@_element_file_handler
|
166
|
+
end
|
167
|
+
|
168
|
+
# Loads the preview image. This is a size limited image version of the files
|
169
|
+
# content. Text documents often show the first Page.
|
170
|
+
# Make no assumtions about the image size
|
171
|
+
def preview(element_key)
|
172
|
+
parameter = { basic_auth: @auth }
|
173
|
+
self.class.get("/elements/#{element_key}/preview", parameter)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Loads a small thumbnail. Thumbnails are like file type icons.
|
177
|
+
# They normaly show the type of a document, not its content
|
178
|
+
def thumbnail(element_key)
|
179
|
+
parameter = { basic_auth: @auth }
|
180
|
+
self.class.get("/elements/#{element_key}/thumbnail", parameter)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module KeytechKit
|
2
|
+
##
|
3
|
+
# A key - values list that conatins a Name and a list of values
|
4
|
+
#
|
5
|
+
class GroupBy
|
6
|
+
attr_accessor :attributeName
|
7
|
+
attr_accessor :attributeDisplayName
|
8
|
+
attr_accessor :values
|
9
|
+
|
10
|
+
def initialize(data)
|
11
|
+
self.attributeName = data['AttributeName']
|
12
|
+
self.attributeDisplayName = data['AttributeDisplayName']
|
13
|
+
self.values = data['Values']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module KeytechKit
|
2
|
+
##
|
3
|
+
# A single note
|
4
|
+
class Note
|
5
|
+
attr_accessor :changedAt
|
6
|
+
attr_accessor :changedBy
|
7
|
+
attr_accessor :changedByLong
|
8
|
+
attr_accessor :createdAt
|
9
|
+
attr_accessor :createdBy
|
10
|
+
attr_accessor :createdByLong
|
11
|
+
attr_accessor :id
|
12
|
+
attr_accessor :noteType
|
13
|
+
attr_accessor :subject
|
14
|
+
attr_accessor :text
|
15
|
+
|
16
|
+
def initialize(data)
|
17
|
+
self.changedAt = data['ChangedAt']
|
18
|
+
self.changedBy = data['ChangedBy']
|
19
|
+
self.changedByLong = data['ChangedByLong']
|
20
|
+
|
21
|
+
self.createdAt = data['CreatedAt']
|
22
|
+
self.createdBy = data['CreatedBy']
|
23
|
+
self.createdByLong = data['CreatedByLong']
|
24
|
+
|
25
|
+
self.id = data['ID']
|
26
|
+
self.noteType = data['NoteType']
|
27
|
+
self.subject = data['Subject']
|
28
|
+
self.text = data['Text']
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'keytechKit/elements/notes/note'
|
2
|
+
|
3
|
+
module KeytechKit
|
4
|
+
##
|
5
|
+
# Notes
|
6
|
+
class NoteHandler
|
7
|
+
include HTTParty
|
8
|
+
|
9
|
+
def initialize(base_url, username, password)
|
10
|
+
self.class.base_uri(base_url)
|
11
|
+
@auth = { username: username, password: password }
|
12
|
+
end
|
13
|
+
|
14
|
+
def load(elementKey)
|
15
|
+
parameter = { basic_auth: @auth }
|
16
|
+
|
17
|
+
response = self.class.get("/elements/#{elementKey}/notes", parameter)
|
18
|
+
if response.success?
|
19
|
+
parse_notes(response['NotesList'])
|
20
|
+
else
|
21
|
+
raise response.response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def parse_notes(notesResult)
|
28
|
+
notes = []
|
29
|
+
notesResult.each do |notedata|
|
30
|
+
notes.push Note.new(notedata)
|
31
|
+
end
|
32
|
+
notes
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'keytechKit/elements/element'
|
2
|
+
require 'keytechKit/elements/group_by'
|
3
|
+
module KeytechKit
|
4
|
+
##
|
5
|
+
# Represents the header from search results
|
6
|
+
#
|
7
|
+
class SearchResponseHeader
|
8
|
+
attr_accessor :pageNumber
|
9
|
+
attr_accessor :pageSize
|
10
|
+
attr_accessor :totalRecords
|
11
|
+
attr_accessor :elementList # list of elements
|
12
|
+
attr_accessor :groupBy
|
13
|
+
|
14
|
+
def initialize(response)
|
15
|
+
parseResponse(response)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def parseResponse(response)
|
21
|
+
@pageNumber = response['PageNumber']
|
22
|
+
@pageSize = response['PageSize']
|
23
|
+
@totalRecords = response['Totalrecords']
|
24
|
+
@elementList = parseElementList(response['ElementList'])
|
25
|
+
@groupBy = parseGroupBy(response['GroupBy'])
|
26
|
+
end
|
27
|
+
|
28
|
+
def parseGroupBy(groupByResults)
|
29
|
+
if groupByResults
|
30
|
+
groupByArray = []
|
31
|
+
groupByResults.each do |groupBy|
|
32
|
+
groupByArray.push GroupBy.new(groupBy)
|
33
|
+
end
|
34
|
+
groupByArray.first
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def parseElementList(elementResults)
|
39
|
+
elements = []
|
40
|
+
elementResults.each do |elementData|
|
41
|
+
element = Element.new(elementData)
|
42
|
+
elements.push element
|
43
|
+
end
|
44
|
+
@elementList = elements
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'keytechKit/elements/element'
|
2
|
+
require 'keytechKit/elements/search_response_header'
|
3
|
+
|
4
|
+
module KeytechKit
|
5
|
+
##
|
6
|
+
# Can search the API by fulltext, fields, element types
|
7
|
+
# Can search by a predefined 'stored' query by its queryID
|
8
|
+
# Can sort the results
|
9
|
+
# Can group the results
|
10
|
+
class Search
|
11
|
+
include HTTParty
|
12
|
+
|
13
|
+
attr_accessor :response
|
14
|
+
|
15
|
+
def initialize(base_url, username, password)
|
16
|
+
self.class.base_uri(base_url)
|
17
|
+
@auth = { username: username, password: password }
|
18
|
+
end
|
19
|
+
|
20
|
+
# options = {};
|
21
|
+
#:q = searchtext - optional parameter: makes a fulltext search, (unusable on very large data)
|
22
|
+
#:size
|
23
|
+
#:page
|
24
|
+
#:attributes = "ALL","None","Lister", "Editor", "GlobalLister", "System", "Secondary", "Explorer"
|
25
|
+
#:reload = true
|
26
|
+
#:classes = "DEFAULT_DO","DEFAULT_FD", "DEFAULT_MI", "DEFAULT_MAIL","DEFAULT_TASK"
|
27
|
+
#:fields = [<attribute><operator><value>:] - as_do__created_by=jgrant:as_do_changed_by=pmiller - finds all elememnts cerated by jgrant and changed by pmiller
|
28
|
+
# Remember: dates must be send in epoch format! "/date(1464127200000)/"
|
29
|
+
def query(options = {})
|
30
|
+
parameter = { query: options }
|
31
|
+
parameter[:basic_auth] = @auth
|
32
|
+
response = self.class.get('/search', parameter)
|
33
|
+
if response.success?
|
34
|
+
parse_response(response)
|
35
|
+
else
|
36
|
+
puts "Could not execute query: #{parse_response.headers['x-errordescription']}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def parse_response(response)
|
43
|
+
SearchResponseHeader.new(response)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|