crossmark-jotform-api 0.0.5__tar.gz
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.
- crossmark_jotform_api-0.0.5/LICENSE +19 -0
- crossmark_jotform_api-0.0.5/PKG-INFO +32 -0
- crossmark_jotform_api-0.0.5/pyproject.toml +23 -0
- crossmark_jotform_api-0.0.5/setup.cfg +4 -0
- crossmark_jotform_api-0.0.5/src/crossmark_jotform_api/jotForm.py +249 -0
- crossmark_jotform_api-0.0.5/src/crossmark_jotform_api.egg-info/PKG-INFO +32 -0
- crossmark_jotform_api-0.0.5/src/crossmark_jotform_api.egg-info/SOURCES.txt +7 -0
- crossmark_jotform_api-0.0.5/src/crossmark_jotform_api.egg-info/dependency_links.txt +1 -0
- crossmark_jotform_api-0.0.5/src/crossmark_jotform_api.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2018 The Python Packaging Authority
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: crossmark_jotform_api
|
|
3
|
+
Version: 0.0.5
|
|
4
|
+
Summary: Jotform api integration dedicated for server usage which limits calls and calling form only if there is a new submission
|
|
5
|
+
Author-email: Renas Mirkan Kilic <mirkanbaba1@gmail.com>
|
|
6
|
+
License: Copyright (c) 2018 The Python Packaging Authority
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|
|
25
|
+
Project-URL: Homepage, https://github.com/mirkan1/crossmark_jotform_api
|
|
26
|
+
Project-URL: Bug Tracker, https://github.com/mirkan1/crossmark_jotform_api/issues
|
|
27
|
+
Classifier: Programming Language :: Python :: 3
|
|
28
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
29
|
+
Classifier: Operating System :: OS Independent
|
|
30
|
+
Requires-Python: >=3.6
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0","requests>=2.22.0","wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "crossmark_jotform_api"
|
|
7
|
+
version = "0.0.5"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="Renas Mirkan Kilic", email="mirkanbaba1@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
description = "Jotform api integration dedicated for server usage which limits calls and calling form only if there is a new submission"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
license = { file="LICENSE" }
|
|
14
|
+
requires-python = ">=3.6"
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
"Homepage" = "https://github.com/mirkan1/crossmark_jotform_api"
|
|
23
|
+
"Bug Tracker" = "https://github.com/mirkan1/crossmark_jotform_api/issues"
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
import requests
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class JotForm(ABC):
|
|
7
|
+
version = 1.2
|
|
8
|
+
|
|
9
|
+
def __init__(self, api_key, form_id):
|
|
10
|
+
self.update_timestamp = datetime.now().timestamp()
|
|
11
|
+
self.api_key = api_key
|
|
12
|
+
self.form_id = form_id
|
|
13
|
+
self.url = "https://api.jotform.com/form/" + form_id + \
|
|
14
|
+
"/submissions?limit=1000&apiKey=" + api_key
|
|
15
|
+
self.submission_ids = []
|
|
16
|
+
self.submission_data = {}
|
|
17
|
+
self.updating_process = False
|
|
18
|
+
self.set_data()
|
|
19
|
+
self.get_submission_ids()
|
|
20
|
+
|
|
21
|
+
def __set_submission_data(self, submission_data):
|
|
22
|
+
submissions_dict = {}
|
|
23
|
+
for i in submission_data:
|
|
24
|
+
submissions_dict[i["id"]] = jotFormSubmission(i)
|
|
25
|
+
return submissions_dict
|
|
26
|
+
|
|
27
|
+
def get_submission_ids(self):
|
|
28
|
+
self.update()
|
|
29
|
+
for submission in self.submissions:
|
|
30
|
+
self.submission_ids.append(submission["id"])
|
|
31
|
+
return self.submission_ids
|
|
32
|
+
|
|
33
|
+
def get_submission_data(self):
|
|
34
|
+
self.update()
|
|
35
|
+
return self.submission_data
|
|
36
|
+
|
|
37
|
+
def get_submission_count(self):
|
|
38
|
+
self.update()
|
|
39
|
+
return self.submission_count
|
|
40
|
+
|
|
41
|
+
def get_submission_answers(self, submission_id):
|
|
42
|
+
self.update()
|
|
43
|
+
return self.submission_data["submissions"][submission_id].answers
|
|
44
|
+
|
|
45
|
+
def get_submission_by_request(self, submission_id):
|
|
46
|
+
requests.get("https://api.jotform.com/submission/" +
|
|
47
|
+
submission_id + "?apiKey=" + self.api_key, timeout=15)
|
|
48
|
+
|
|
49
|
+
def get_submission(self, submission_id):
|
|
50
|
+
self.update()
|
|
51
|
+
return self.submission_data["submissions"][submission_id]
|
|
52
|
+
|
|
53
|
+
def get_submission_id_by_text(self, text):
|
|
54
|
+
self.update()
|
|
55
|
+
for submission in self.submissions:
|
|
56
|
+
_id = submission['id']
|
|
57
|
+
submission_object = self.get_submission(_id)
|
|
58
|
+
if submission_object.get_answer_by_text(text):
|
|
59
|
+
return submission_object
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
def get_submission_by_case_id(self, case_id):
|
|
63
|
+
self.update()
|
|
64
|
+
for submission in self.submissions:
|
|
65
|
+
_id = submission['id']
|
|
66
|
+
submission_object = self.get_submission(_id)
|
|
67
|
+
if submission_object.case_id == case_id:
|
|
68
|
+
return submission_object
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
def get_answer_by_text(self, submission_id, text):
|
|
72
|
+
self.update()
|
|
73
|
+
return self.get_submission(submission_id).get_answer_by_text(text)
|
|
74
|
+
|
|
75
|
+
def get_answer_by_name(self, submission_id, name):
|
|
76
|
+
self.update()
|
|
77
|
+
return self.get_submission(submission_id).get_answer_by_name(name)
|
|
78
|
+
|
|
79
|
+
def get_answer_by_key(self, submission_id, key):
|
|
80
|
+
self.update()
|
|
81
|
+
return self.get_submission(submission_id).get_answer_by_key(key)
|
|
82
|
+
|
|
83
|
+
def get_submission_answers_by_question(self, submission_id):
|
|
84
|
+
self.update()
|
|
85
|
+
submission_answers = self.get_submission_answers(submission_id)
|
|
86
|
+
submission_answers_by_question = {}
|
|
87
|
+
for answer in submission_answers:
|
|
88
|
+
submission_answers_by_question[answer["id"]] = answer["answer"]
|
|
89
|
+
return submission_answers_by_question
|
|
90
|
+
|
|
91
|
+
def get_submission_answers_by_question_id(self, submission_id):
|
|
92
|
+
self.update()
|
|
93
|
+
submission_answers = self.get_submission_answers(submission_id)
|
|
94
|
+
submission_answers_by_question_id = {}
|
|
95
|
+
for answer in submission_answers:
|
|
96
|
+
submission_answers_by_question_id[answer["id"]] = answer["answer"]
|
|
97
|
+
|
|
98
|
+
def update_submission_answer(self, submission_id, answer_id, answer):
|
|
99
|
+
self.update()
|
|
100
|
+
query = f'submission[{answer_id}]={answer}'
|
|
101
|
+
# &submission[{rsrEmailFieldId}]={email}&submission[{actionerSupervisorEmailField}]={actionerSupervisorEmail.lower()}&submission[{actionerSupervisorNameField}]={actionerSupervisorName.lower()}'
|
|
102
|
+
url = f"https://api.jotform.com/submission/{submission_id}?apiKey={self.api_key}&{query}"
|
|
103
|
+
response = requests.request("POST", url, timeout=15)
|
|
104
|
+
if response.status_code == 200:
|
|
105
|
+
return True
|
|
106
|
+
else:
|
|
107
|
+
return False
|
|
108
|
+
|
|
109
|
+
def set_url_param(self, key, value):
|
|
110
|
+
if key in self.url:
|
|
111
|
+
params = self.url.split("&")
|
|
112
|
+
# also set the value next to the key
|
|
113
|
+
for i in range(len(params)):
|
|
114
|
+
if key in params[i]:
|
|
115
|
+
params[i] = key + "=" + value
|
|
116
|
+
self.url = "&".join(params)
|
|
117
|
+
else:
|
|
118
|
+
self.url += "&" + key + "=" + value
|
|
119
|
+
|
|
120
|
+
def set_data(self):
|
|
121
|
+
self.data = requests.get(self.url, timeout=15).json()
|
|
122
|
+
re_count = self.data['resultSet']['count']
|
|
123
|
+
if re_count == self.data['resultSet']['limit']:
|
|
124
|
+
if self.data['resultSet']['offset'] == 0:
|
|
125
|
+
self.set_url_param(
|
|
126
|
+
"offset", self.data['resultSet']['offset']+1)
|
|
127
|
+
self.submission_count = re_count
|
|
128
|
+
self.submissions = self.data['content']
|
|
129
|
+
self.submission_data["submissions"] = self.__set_submission_data(
|
|
130
|
+
self.submissions)
|
|
131
|
+
return self.set_data()
|
|
132
|
+
else:
|
|
133
|
+
self.set_url_param(
|
|
134
|
+
"offset", self.data['resultSet']['offset']+1)
|
|
135
|
+
self.submission_count += re_count
|
|
136
|
+
self.submissions += self.data['content']
|
|
137
|
+
self.submission_data["submissions"].update(
|
|
138
|
+
self.__set_submission_data(
|
|
139
|
+
self.submissions
|
|
140
|
+
)
|
|
141
|
+
)
|
|
142
|
+
return self.set_data()
|
|
143
|
+
else:
|
|
144
|
+
self.submission_count = re_count
|
|
145
|
+
self.submissions = self.data['content']
|
|
146
|
+
self.submission_data["submissions"] = self.__set_submission_data(
|
|
147
|
+
self.submissions)
|
|
148
|
+
self.get_submission_ids()
|
|
149
|
+
|
|
150
|
+
def get_form(self):
|
|
151
|
+
url = f"https://api.jotform.com/form/{self.form_id}?apiKey={self.api_key}"
|
|
152
|
+
response = requests.request("GET", url, timeout=15)
|
|
153
|
+
if response.status_code == 200:
|
|
154
|
+
return response.json()
|
|
155
|
+
else:
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
def update(self):
|
|
159
|
+
form = self.get_form()
|
|
160
|
+
if not self.updating_process and form:
|
|
161
|
+
self.updating_process = True
|
|
162
|
+
count = int(form['content']['count'])
|
|
163
|
+
if count <= self.submission_count:
|
|
164
|
+
print("[INFO] No new submissions.")
|
|
165
|
+
return
|
|
166
|
+
now = datetime.now().timestamp()
|
|
167
|
+
its_been = now - self.update_timestamp
|
|
168
|
+
print(
|
|
169
|
+
f"[INFO] Its been {int(its_been/60)} minutes. Updating submission data...")
|
|
170
|
+
self.set_data()
|
|
171
|
+
self.update_timestamp = now
|
|
172
|
+
self.updating_process = False
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
class jotFormSubmission(ABC):
|
|
176
|
+
def __init__(self, submission_object):
|
|
177
|
+
self.id = submission_object['id']
|
|
178
|
+
self.form_id = submission_object['form_id']
|
|
179
|
+
self.ip = submission_object['ip']
|
|
180
|
+
self.created_at = submission_object['created_at']
|
|
181
|
+
self.status = submission_object['status']
|
|
182
|
+
self.new = submission_object['new']
|
|
183
|
+
self.flag = submission_object['flag']
|
|
184
|
+
self.notes = submission_object['notes']
|
|
185
|
+
self.updated_at = submission_object['updated_at']
|
|
186
|
+
self.answers = submission_object['answers']
|
|
187
|
+
self.answers_arr = self.set_answers(self.answers)
|
|
188
|
+
self.case_id = self.get_answer_by_text('CASE')['answer']
|
|
189
|
+
self.editor = self.get_answer_by_text('EDITOR')['answer']
|
|
190
|
+
self.status = self.get_answer_by_text('STATUS')['answer']
|
|
191
|
+
self.store = self.get_answer_by_text('STORE')['answer']
|
|
192
|
+
self.GUID = self.get_answer_by_text('GUID')['answer']
|
|
193
|
+
self.client = self.get_answer_by_text('CLIENT')['answer']
|
|
194
|
+
|
|
195
|
+
def set_answers(self, answers):
|
|
196
|
+
answers_arr = []
|
|
197
|
+
for key, value in answers.items():
|
|
198
|
+
if 'name' in value:
|
|
199
|
+
name = value['name']
|
|
200
|
+
else:
|
|
201
|
+
name = None
|
|
202
|
+
if 'answer' in value:
|
|
203
|
+
answer = value['answer']
|
|
204
|
+
else:
|
|
205
|
+
answer = None
|
|
206
|
+
if 'type' in value:
|
|
207
|
+
_type = value['type']
|
|
208
|
+
else:
|
|
209
|
+
_type = None
|
|
210
|
+
if 'text' in value:
|
|
211
|
+
text = value['text']
|
|
212
|
+
else:
|
|
213
|
+
text = None
|
|
214
|
+
if 'file' in value:
|
|
215
|
+
file = value['file']
|
|
216
|
+
else:
|
|
217
|
+
file = None
|
|
218
|
+
if 'selectedFields' in value:
|
|
219
|
+
selectedFields = value['selectedFields']
|
|
220
|
+
else:
|
|
221
|
+
selectedFields = None
|
|
222
|
+
answers_arr.append({
|
|
223
|
+
'key': key,
|
|
224
|
+
'name': name,
|
|
225
|
+
'answer': answer,
|
|
226
|
+
'type': _type,
|
|
227
|
+
'text': text,
|
|
228
|
+
'file': file,
|
|
229
|
+
'selectedFields': selectedFields
|
|
230
|
+
})
|
|
231
|
+
return answers_arr
|
|
232
|
+
|
|
233
|
+
def get_answers(self):
|
|
234
|
+
return self.answers_arr
|
|
235
|
+
|
|
236
|
+
def get_answer_by_text(self, text):
|
|
237
|
+
for answer in self.answers_arr:
|
|
238
|
+
if answer['text'] and text and answer['text'].upper() == text.upper():
|
|
239
|
+
return answer
|
|
240
|
+
|
|
241
|
+
def get_answer_by_name(self, name):
|
|
242
|
+
for answer in self.answers_arr:
|
|
243
|
+
if answer['name'] and name and answer['name'] == name:
|
|
244
|
+
return answer
|
|
245
|
+
|
|
246
|
+
def get_answer_by_key(self, key):
|
|
247
|
+
for answer in self.answers_arr:
|
|
248
|
+
if answer['key'] and key and answer['key'] == key:
|
|
249
|
+
return answer
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: crossmark-jotform-api
|
|
3
|
+
Version: 0.0.5
|
|
4
|
+
Summary: Jotform api integration dedicated for server usage which limits calls and calling form only if there is a new submission
|
|
5
|
+
Author-email: Renas Mirkan Kilic <mirkanbaba1@gmail.com>
|
|
6
|
+
License: Copyright (c) 2018 The Python Packaging Authority
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|
|
25
|
+
Project-URL: Homepage, https://github.com/mirkan1/crossmark_jotform_api
|
|
26
|
+
Project-URL: Bug Tracker, https://github.com/mirkan1/crossmark_jotform_api/issues
|
|
27
|
+
Classifier: Programming Language :: Python :: 3
|
|
28
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
29
|
+
Classifier: Operating System :: OS Independent
|
|
30
|
+
Requires-Python: >=3.6
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
License-File: LICENSE
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
crossmark_jotform_api
|