1212# Released under The MIT License. Full text available via https://opensource.org/licenses/MIT
1313#
1414# Requires Python3
15+ import logging
1516from typing import Dict , List
17+
1618import requests
17- import os
18- import json
19- import sys
20- import datetime
21- import logging
19+
20+ from DuetWebAPI .api import DSFAPI , DWCAPI , DuetAPI
2221
2322
2423class DuetWebAPIFactory :
2524 def __init__ (self ) -> None :
2625 self ._creators = {}
27-
26+
2827 def __call__ (self , base_url : str ) -> DuetAPI :
29- self .get_api (base_url )
28+ api = self .get_api (base_url )
29+ wrapper = self .create_wrapper (api )
30+ return wrapper (base_url )
3031
3132 def register_api (self , name : str , creator : object , url_suffix : str ) -> None :
3233 self ._creators [name ] = {'creator' : creator , 'url_suffix' : url_suffix }
@@ -40,206 +41,19 @@ def get_api(self, base_url) -> DuetAPI:
4041 continue
4142 if r .ok :
4243 creator = api ['creator' ]
43- return creator ( base_url )
44+ return creator
4445
4546 logging .error (f'Can not get API for { base_url } ' )
4647 raise ValueError
4748
49+ def create_wrapper (self , creator : DuetAPI ):
50+ class DuetAPIWrapper (creator ):
51+ def demo (self ):
52+ print ('test' )
4853
49- class DuetAPI :
50- def __init__ (self , base_url ) -> None :
51- self ._base_url = base_url
52-
53- def get_model (self ):
54- raise NotImplementedError
55-
56- def post_code (self , code ):
57- raise NotImplementedError
58-
59- def get_file (self , filename , path ):
60- raise NotImplementedError
61-
62- def put_file (self , filename , path ):
63- raise NotImplementedError
64-
65- def get_fileinfo (self , filename ):
66- raise NotImplementedError
67-
68- def delete_file (self , filename ):
69- raise NotImplementedError
70-
71- def move_file (self , from_path , to_path , force = False ):
72- raise NotImplementedError
73-
74- def get_directory (self , directory ):
75- raise NotImplementedError
76-
77- def put_directory (self , directory ):
78- raise NotImplementedError
79-
80-
81- class DWCAPI (DuetAPI ):
82- def get_model (self , key = None ) -> Dict :
83- url = f'{ self ._base_url } /rr_model'
84- r = requests .get (url , {'flags' : 'd99vn' , 'key' : key })
85- if not r .ok :
86- raise ValueError
87- j = r .json ()
88- return j ['result' ]
89-
90- def post_code (self , code ) -> Dict :
91- url = f'{ self ._base_url } /rr_gcode'
92- r = requests .get (url , {'gcode' : code })
93- if not r .ok :
94- raise ValueError
95- return r .json ()
96-
97- def get_file (self , filename : str , directory : str = 'gcodes' ) -> str :
98- """
99- filename: name of the file you want to download including extension
100- directory: the folder that the file is in, options are ['gcodes', 'macros', 'sys']
101-
102- returns the file as a string
103- """
104- url = f'{ self ._base_url } /rr_download'
105- r = requests .get (url , {'name' : f'/{ directory } /{ filename } ' })
106- if not r .ok :
107- raise ValueError
108- return r .text
109-
110- def put_file (self , file : str , directory : str = 'gcodes' ):
111- file = os .path .abspath (file ).replace ('\\ ' , '/' )
112- filename = file .split ('/' )[- 1 ]
113- url = f'{ self ._base_url } /rr_upload?name=/{ directory } /{ filename } '
114- with open (file , 'rb' ) as f :
115- r = requests .post (url , data = f )
116- if not r .ok :
117- raise ValueError
118- return r .json ()
119-
120- def get_fileinfo (self , filename : str = None , directory : str = 'gcodes' ):
121- url = f'{ self ._base_url } /rr_fileinfo'
122- if filename :
123- r = requests .get (url , {'name' : f'/{ directory } /{ filename } ' })
124- else :
125- r = requests .get (url )
126- if not r .ok :
127- raise ValueError
128- return r .json ()
129-
130- def delete_file (self , filename : str , directory : str = 'gcodes' ):
131- url = f'{ self ._base_url } /rr_delete'
132- r = requests .get (url , {'name' : f'/{ directory } /{ filename } ' })
133- if not r .ok :
134- raise ValueError
135- return r .json ()
136-
137- def move_file (self , from_path , to_path , ** _ignored ):
138- url = f'{ self ._base_url } /rr_move'
139- r = requests .get (url , {'old' : f'{ from_path } ' , 'new' : f'{ to_path } ' })
140- if not r .ok :
141- raise ValueError
142- return r .json ()
143-
144- def get_directory (self , directory ) -> List [Dict ]:
145- url = f'{ self ._base_url } /rr_filelist'
146- r = requests .get (url , {'dir' : f'/{ directory } ' })
147- if not r .ok :
148- raise ValueError
149- return r .json ()['files' ]
150-
151- def put_directory (self , directory ):
152- url = f'{ self ._base_url } /rr_mkdir'
153- r = requests .get (url , {'dir' : f'/{ directory } ' })
154- if not r .ok :
155- raise ValueError
156- return r .json ()
157-
158-
159- class DSFAPI (DuetAPI ):
160- def get_model (self ) -> Dict :
161- url = f'{ self ._base_url } /machine/status'
162- r = requests .get (url )
163- j = r .json ()
164- return j
165-
166- def post_code (self , code ) -> str :
167- url = f'{ self ._base_url } /machine/code'
168- r = requests .post (url , data = code )
169- return r .text
170-
171- def get_file (self , filename : str , directory : str = 'gcodes' ) -> str :
172- """
173- filename: name of the file you want to download including extension
174- directory: the folder that the file is in, options are ['gcodes', 'macros', 'sys']
175-
176- returns the file as a string
177- """
178- url = f'{ self ._base_url } /machine/file/{ directory } /{ filename } '
179- r = requests .get (url )
180- if not r .ok :
181- raise ValueError
182- return r .text
183-
184- def put_file (self , file : str , directory : str = 'gcodes' ):
185- """
186- file: the path to the file you want to upload from your PC
187- directory: the folder that the file is in, options are ['gcodes', 'macros', 'sys']
188-
189- returns the file as a string
190- """
191- file = os .path .abspath (file ).replace ('\\ ' , '/' )
192- filename = file .split ('/' )[- 1 ]
193- url = f'{ self ._base_url } /machine/file/{ directory } /{ filename } '
194- with open (file , 'rb' ) as f :
195- r = requests .put (url , data = f , headers = {'Content-Type' : 'application/octet-stream' })
196- if not r .ok :
197- raise ValueError
198- return r .ok
199-
200- def get_fileinfo (self , filename : str , directory : str = 'gcodes' ):
201- url = f'{ self ._base_url } /machine/fileinfo/{ directory } /{ filename } '
202- r = requests .get (url )
203- if not r .ok :
204- raise ValueError
205- return r .json ()
206-
207- def delete_file (self , filename : str , directory : str = 'gcodes' ):
208- url = f'{ self ._base_url } /machine/file/{ directory } /{ filename } '
209- r = requests .delete (url )
210- if not r .ok :
211- raise ValueError
212- return r .text
213-
214- def move_file (self , from_path , to_path , force = False ):
215- url = f'{ self ._base_url } /machine/file/move'
216- r = requests .post (url , {'from' : f'{ from_path } ' , 'to' : f'{ to_path } ' , 'force' : force })
217- if not r .ok :
218- raise ValueError
219- return r .text
220-
221- def get_directory (self , directory ) -> List [Dict ]:
222- url = f'{ self ._base_url } /machine/directory/{ directory } '
223- r = requests .get (url )
224- if not r .ok :
225- raise ValueError
226- return r .json ()
227-
228- def put_directory (self , directory ):
229- url = f'{ self ._base_url } /machine/directory/{ directory } '
230- r = requests .put (url )
231- if not r .ok :
232- raise ValueError
233- return r .text
54+ return DuetAPIWrapper
23455
23556
23657DuetWebAPI = DuetWebAPIFactory ()
23758DuetWebAPI .register_api ('DWC' , DWCAPI , '/rr_model' )
23859DuetWebAPI .register_api ('DSF' , DSFAPI , '/machine/status' )
239-
240-
241- riley = DuetWebAPI ('http://riley' )
242- force_rig = DuetWebAPI ('http://forcerig' )
243- force_rig .put_file ('test.gcode' )
244- riley .put_file ('test.gcode' )
245- pass
0 commit comments