Skip to content

Commit 66ad38a

Browse files
authored
Plugin import phase 1 (#22)
* Added import plugin * Tests passed
1 parent 9c362e0 commit 66ad38a

10 files changed

Lines changed: 236 additions & 28 deletions

File tree

.gitignore

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,167 @@
1-
21
dist/
32
.env
43
*.pyc
54
.DS_Store
65
*.xslx
6+
tests/test.xml
7+
8+
# Byte-compiled / optimized / DLL files
9+
__pycache__/
10+
*.py[cod]
11+
*$py.class
12+
13+
# C extensions
14+
*.so
15+
16+
# Distribution / packaging
17+
.Python
18+
build/
19+
develop-eggs/
20+
dist/
21+
downloads/
22+
eggs/
23+
.eggs/
24+
lib/
25+
lib64/
26+
parts/
27+
sdist/
28+
var/
29+
wheels/
30+
share/python-wheels/
31+
*.egg-info/
32+
.installed.cfg
33+
*.egg
34+
MANIFEST
35+
36+
# PyInstaller
37+
# Usually these files are written by a python script from a template
38+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
39+
*.manifest
40+
*.spec
41+
42+
# Installer logs
43+
pip-log.txt
44+
pip-delete-this-directory.txt
45+
46+
# Unit test / coverage reports
47+
htmlcov/
48+
.tox/
49+
.nox/
50+
.coverage
51+
.coverage.*
52+
.cache
53+
nosetests.xml
54+
coverage.xml
55+
*.cover
56+
*.py,cover
57+
.hypothesis/
58+
.pytest_cache/
59+
cover/
60+
61+
# Translations
62+
*.mo
63+
*.pot
64+
65+
# Django stuff:
66+
*.log
67+
local_settings.py
68+
db.sqlite3
69+
db.sqlite3-journal
70+
71+
# Flask stuff:
72+
instance/
73+
.webassets-cache
74+
75+
# Scrapy stuff:
76+
.scrapy
77+
78+
# Sphinx documentation
79+
docs/_build/
80+
81+
# PyBuilder
82+
.pybuilder/
83+
target/
84+
85+
# Jupyter Notebook
86+
.ipynb_checkpoints
87+
88+
# IPython
89+
profile_default/
90+
ipython_config.py
91+
92+
# pyenv
93+
# For a library or package, you might want to ignore these files since the code is
94+
# intended to run in multiple environments; otherwise, check them in:
95+
# .python-version
96+
97+
# pipenv
98+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
99+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
100+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
101+
# install all needed dependencies.
102+
#Pipfile.lock
103+
104+
# poetry
105+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
106+
# This is especially recommended for binary packages to ensure reproducibility, and is more
107+
# commonly ignored for libraries.
108+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
109+
#poetry.lock
110+
111+
# pdm
112+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113+
#pdm.lock
114+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
115+
# in version control.
116+
# https://pdm.fming.dev/#use-with-ide
117+
.pdm.toml
118+
119+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
120+
__pypackages__/
121+
122+
# Celery stuff
123+
celerybeat-schedule
124+
celerybeat.pid
125+
126+
# SageMath parsed files
127+
*.sage.py
128+
129+
# Environments
130+
.env
131+
.venv
132+
env/
133+
venv/
134+
ENV/
135+
env.bak/
136+
venv.bak/
137+
138+
# Spyder project settings
139+
.spyderproject
140+
.spyproject
141+
142+
# Rope project settings
143+
.ropeproject
144+
145+
# mkdocs documentation
146+
/site
147+
148+
# mypy
149+
.mypy_cache/
150+
.dmypy.json
151+
dmypy.json
152+
153+
# Pyre type checker
154+
.pyre/
155+
156+
# pytype static type analyzer
157+
.pytype/
158+
159+
# Cython debug symbols
160+
cython_debug/
161+
162+
# PyCharm
163+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
164+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
165+
# and can be added to the global gitignore or merged into this file. For a more nuclear
166+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
167+
#.idea/

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,21 @@ Experimental:
7171

7272
### Metadata / Properties
7373
get_properties (self, offset=0, limit=100, response_type=FULL_RESPONSE)
74-
get_property(self, label: str, response_type=JSON_RESPONSE):
74+
get_property(self, label: str, response_type=JSON_RESPONSE)
7575
create_or_replace_property(self, property: Property, response_type=JSON_RESPONSE)
7676

7777
### Metadata / Workskills
7878
get_workskills (self, offset=0, limit=100, response_type=FULL_RESPONSE)
7979
get_workskill(self, label: str, response_type=FULL_RESPONSE)
8080
create_or_update_workskill(self, skill: Workskill, response_type=FULL_RESPONSE)
8181
delete_workskill(self, label: str, response_type=FULL_RESPONSE)
82-
get_workskill_conditions(self, response_type=FULL_RESPONSE):
82+
get_workskill_conditions(self, response_type=FULL_RESPONSE)
8383
replace_workskill_conditions(self, data: WorskillConditionList, response_type=FULL_RESPONSE
8484

85+
### Metadata / Plugins
86+
import_plugin(self, plugin: str)
87+
import_plugin_file(self, plugin: Path)
88+
8589
### Metadata / Resource Types
8690
get_resource_types(self, response_type=JSON_RESPONSE):
8791

@@ -96,6 +100,7 @@ OFS REST API Version | PyOFSC
96100
21A| 1.8, 1.8,1, 1.9
97101
21D| 1.15
98102
22B| 1.16, 1.17
103+
22D| 1.18
99104

100105
## Deprecation Warning
101106

ofsc/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@ class OFSC:
1515

1616
API_PORTAL = "https://api.etadirect.com"
1717

18-
def __init__(self, clientID, companyName, secret, baseUrl=API_PORTAL):
18+
def __init__(self, clientID, companyName, secret, root=None, baseUrl=API_PORTAL):
1919
self._config = OFSConfig(
20-
baseURL=baseUrl, clientID=clientID, secret=secret, companyName=companyName
20+
baseURL=baseUrl,
21+
clientID=clientID,
22+
secret=secret,
23+
companyName=companyName,
2124
)
2225
self.headers = {}
2326
self.headers["Authorization"] = "Basic " + self._config.authString.decode(

ofsc/metadata.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import json
33
import logging
44
import urllib
5+
from pathlib import Path
56
from typing import List
67
from urllib.parse import urljoin
78

@@ -252,3 +253,24 @@ def get_resource_types(self):
252253
url = urljoin(self.baseUrl, "/rest/ofscMetadata/v1/resourceTypes")
253254
response = requests.get(url, headers=self.headers)
254255
return response
256+
257+
# 202212 Import plugin
258+
@wrap_return(response_type=FULL_RESPONSE, expected=[204])
259+
def import_plugin_file(self, plugin: Path):
260+
url = urljoin(
261+
self.baseUrl, f"/rest/ofscMetadata/v1/plugins/custom-actions/import"
262+
)
263+
headers = self.headers
264+
files = [("pluginFile", (plugin.name, plugin.read_text(), "text/xml"))]
265+
response = requests.post(url, headers=self.headers, files=files)
266+
return response
267+
268+
# 202212 Import plugin
269+
@wrap_return(response_type=FULL_RESPONSE, expected=[204])
270+
def import_plugin(self, plugin: str):
271+
url = urljoin(
272+
self.baseUrl, f"/rest/ofscMetadata/v1/plugins/custom-actions/import"
273+
)
274+
files = [("pluginFile", ("noname.xml", plugin, "text/xml"))]
275+
response = requests.post(url, headers=self.headers, files=files)
276+
return response

ofsc/models.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class OFSConfig(BaseModel):
1212
clientID: str
1313
secret: str
1414
companyName: str
15-
root: str
15+
root: Optional[str]
1616

1717
@property
1818
def authString(self):
@@ -44,6 +44,7 @@ class SharingEnum(str, Enum):
4444
minimal = "minimal"
4545
summary = "summary"
4646

47+
4748
class EntityEnum(str, Enum):
4849
activity = "activity"
4950
inventory = "inventory"
@@ -83,7 +84,7 @@ class Workskill(BaseModel):
8384
active: bool = True
8485
name: str = ""
8586
sharing: SharingEnum
86-
translations: TranslationList = []
87+
translations: Optional[TranslationList]
8788

8889
@validator("translations", always=True)
8990
def set_default(cls, field_value, values):
@@ -144,6 +145,7 @@ def __iter__(self):
144145
def __getitem__(self, item):
145146
return self.__root__[item]
146147

148+
147149
class Property(BaseModel):
148150
label: str
149151
name: str
@@ -236,4 +238,3 @@ def __iter__(self):
236238

237239
def __getitem__(self, item):
238240
return self.__root__[item]
239-

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "ofsc"
3-
version = "1.17.4.15"
3+
version = "1.18.0.0"
44
license = "MIT"
55
description = "Python wrapper for Oracle Field Service API"
66
authors = ["Borja Toron <borja.toron@gmail.com>"]

tests/OFSC_metadata_test.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,6 @@ def setUp(self):
2727
)
2828
self.date = os.environ.get("OFSC_TEST_DATE")
2929

30-
# Test M.P.01 Get Properties
31-
def test_get_properties(self):
32-
self.logger.info("...M.P.01 Get Properties")
33-
instance = self.instance
34-
logger = self.logger
35-
raw_response = instance.get_properties(response_type=FULL_RESPONSE)
36-
logging.debug(self.pp.pformat(raw_response.json()))
37-
response = raw_response.json()
38-
logger.debug(self.pp.pformat(response))
39-
self.assertIsNotNone(response["totalResults"])
40-
self.assertEqual(response["totalResults"], 453) # 22.B
41-
self.assertEqual(response["items"][0]["label"], "ITEM_NUMBER")
42-
4330
# Test C.P.10 Get File Property 01
4431
def test_get_file_property_01(self):
4532
self.logger.info("...C.P.01 Get File Property")

tests/OFSC_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ def setUp(self):
2121
self.pp = pprint.PrettyPrinter(indent=4)
2222
self.logger.setLevel(logging.DEBUG)
2323
# todo add credentials to test run
24-
logging.warning("Here {}".format(os.environ.get("OFSC_CLIENT_ID")))
24+
logging.info("ClientID {}".format(os.environ.get("OFSC_CLIENT_ID")))
2525
self.instance = OFSC(
2626
clientID=os.environ.get("OFSC_CLIENT_ID"),
2727
secret=os.environ.get("OFSC_CLIENT_SECRET"),
2828
companyName=os.environ.get("OFSC_COMPANY"),
29+
root=os.environ.get("OFSC_ROOT"),
2930
)
3031
self.date = os.environ.get("OFSC_TEST_DATE")
3132

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def instance():
1717
clientID=os.environ.get("OFSC_CLIENT_ID"),
1818
secret=os.environ.get("OFSC_CLIENT_SECRET"),
1919
companyName=os.environ.get("OFSC_COMPANY"),
20+
root=os.environ.get("OFSC_ROOT"),
2021
)
2122
return instance
2223

0 commit comments

Comments
 (0)