11"""Session represents one connection to Nextcloud. All related stuff for these live here."""
2-
2+ import typing
33from abc import ABC , abstractmethod
44from base64 import b64encode
55from collections .abc import Iterator
@@ -132,6 +132,7 @@ def __init__(self, **kwargs):
132132
133133class NcSessionBasic (ABC ):
134134 adapter : Client
135+ adapter_dav : Client
135136 cfg : BasicConfig
136137 user : str
137138 custom_headers : dict
@@ -145,11 +146,14 @@ def __init__(self, **kwargs):
145146 self .custom_headers = kwargs .get ("headers" , {})
146147 self .limits = Limits (max_keepalive_connections = 20 , max_connections = 20 , keepalive_expiry = 60.0 )
147148 self .init_adapter ()
149+ self .init_adapter_dav ()
148150 self .response_headers = HttpxHeaders ()
149151
150152 def __del__ (self ):
151153 if hasattr (self , "adapter" ) and self .adapter :
152154 self .adapter .close ()
155+ if hasattr (self , "adapter_dav" ) and self .adapter_dav :
156+ self .adapter_dav .close ()
153157
154158 def get_stream (self , path : str , params : Optional [dict ] = None , ** kwargs ) -> Iterator [Response ]:
155159 headers = kwargs .pop ("headers" , {})
@@ -164,6 +168,24 @@ def _get_stream(self, path_params: str, headers: dict, **kwargs) -> Iterator[Res
164168 "GET" , f"{ self .cfg .endpoint } { path_params } " , headers = headers , timeout = timeout , ** kwargs
165169 )
166170
171+ def request_json (
172+ self ,
173+ method : str ,
174+ path : str ,
175+ params : Optional [dict ] = None ,
176+ data : Optional [Union [bytes , str ]] = None ,
177+ json : Optional [Union [dict , list ]] = None ,
178+ ** kwargs ,
179+ ) -> dict :
180+ method = method .upper ()
181+ if params is None :
182+ params = {}
183+ params .update ({"format" : "json" })
184+ headers = kwargs .pop ("headers" , {})
185+ data_bytes = self .__data_to_bytes (headers , data , json )
186+ r = self ._ocs (method , f"{ quote (path )} ?{ urlencode (params , True )} " , headers , data_bytes , not_parse = True )
187+ return loads (r .text ) if r .status_code != 304 else {}
188+
167189 def ocs (
168190 self ,
169191 method : str ,
@@ -178,12 +200,7 @@ def ocs(
178200 params = {}
179201 params .update ({"format" : "json" })
180202 headers = kwargs .pop ("headers" , {})
181- data_bytes = None
182- if data is not None :
183- data_bytes = data .encode ("UTF-8" ) if isinstance (data , str ) else data
184- elif json is not None :
185- headers .update ({"Content-Type" : "application/json" })
186- data_bytes = dumps (json ).encode ("utf-8" )
203+ data_bytes = self .__data_to_bytes (headers , data , json )
187204 return self ._ocs (method , f"{ quote (path )} ?{ urlencode (params , True )} " , headers , data = data_bytes , ** kwargs )
188205
189206 def _ocs (self , method : str , path_params : str , headers : dict , data : Optional [bytes ], ** kwargs ):
@@ -234,12 +251,7 @@ def dav(
234251 ** kwargs ,
235252 ) -> Response :
236253 headers = kwargs .pop ("headers" , {})
237- data_bytes = None
238- if data is not None :
239- data_bytes = data .encode ("UTF-8" ) if isinstance (data , str ) else data
240- elif json is not None :
241- headers .update ({"Content-Type" : "application/json" })
242- data_bytes = dumps (json ).encode ("utf-8" )
254+ data_bytes = self .__data_to_bytes (headers , data , json )
243255 return self ._dav (
244256 method ,
245257 quote (self .cfg .dav_url_suffix + path ) if isinstance (path , str ) else path ,
@@ -258,9 +270,9 @@ def dav_stream(
258270 return self ._dav_stream (method , quote (self .cfg .dav_url_suffix + path ), headers , data_bytes , ** kwargs )
259271
260272 def _dav (self , method : str , path : str , headers : dict , data : Optional [bytes ], ** kwargs ) -> Response :
261- self .init_adapter ()
273+ self .init_adapter_dav ()
262274 timeout = kwargs .pop ("timeout" , self .cfg .options .timeout_dav )
263- result = self .adapter .request (
275+ result = self .adapter_dav .request (
264276 method ,
265277 self .cfg .endpoint + path if isinstance (path , str ) else str (path ),
266278 headers = headers ,
@@ -272,9 +284,9 @@ def _dav(self, method: str, path: str, headers: dict, data: Optional[bytes], **k
272284 return result
273285
274286 def _dav_stream (self , method : str , path : str , headers : dict , data : Optional [bytes ], ** kwargs ) -> Iterator [Response ]:
275- self .init_adapter ()
287+ self .init_adapter_dav ()
276288 timeout = kwargs .pop ("timeout" , self .cfg .options .timeout_dav )
277- return self .adapter .stream (
289+ return self .adapter_dav .stream (
278290 method , self .cfg .endpoint + path , headers = headers , content = data , timeout = timeout , ** kwargs
279291 )
280292
@@ -290,6 +302,16 @@ def init_adapter(self, restart=False) -> None:
290302 self .adapter .cookies .set ("XDEBUG_SESSION" , options .XDEBUG_SESSION )
291303 self ._capabilities = {}
292304
305+ def init_adapter_dav (self , restart = False ) -> None :
306+ if getattr (self , "adapter_dav" , None ) is None or restart :
307+ if restart and hasattr (self , "adapter" ):
308+ self .adapter .close ()
309+ self .adapter_dav = self ._create_adapter ()
310+ if self .custom_headers :
311+ self .adapter_dav .headers .update (self .custom_headers )
312+ if options .XDEBUG_SESSION :
313+ self .adapter_dav .cookies .set ("XDEBUG_SESSION" , options .XDEBUG_SESSION )
314+
293315 @abstractmethod
294316 def _create_adapter (self ) -> Client :
295317 pass # pragma: no cover
@@ -321,6 +343,17 @@ def ae_url(self) -> str:
321343 """Return base url for the App Ecosystem endpoints."""
322344 return "/ocs/v1.php/apps/app_api/api/v1"
323345
346+ @staticmethod
347+ def __data_to_bytes (
348+ headers : dict , data : Optional [Union [bytes , str ]] = None , json : Optional [Union [dict , list ]] = None
349+ ) -> typing .Optional [bytes ]:
350+ if data is not None :
351+ return data .encode ("UTF-8" ) if isinstance (data , str ) else data
352+ if json is not None :
353+ headers .update ({"Content-Type" : "application/json" })
354+ return dumps (json ).encode ("utf-8" )
355+ return None
356+
324357
325358class NcSession (NcSessionBasic ):
326359 cfg : Config
0 commit comments