""" We are implementing transport to and from nextcloud (just like s3) """ import os import sys from transport.common import IEncoder import pandas as pd from io import StringIO import json import nextcloud_client as nextcloud class Nextcloud : __template__={"url":None,"token":None,"uid":None,"file":None} def __init__(self,**_args): pass self._delimiter = None self._handler = nextcloud.Client(_args['url']) _uid = _args['uid'] _token = _args['token'] self._uri = _args['folder'] if 'folder' in _args else './' if self._uri.endswith('/') : self._uri = self._uri[:-1] self._file = None if 'file' not in _args else _args['file'] self._handler.login(_uid,_token) def close(self): try: self._handler.logout() except Exception as e: pass class Reader(Nextcloud): def __init__(self,**_args): # self._file = [] if 'file' not in _args else _args['file'] super().__init__(**_args) pass def read(self,**_args): _filename = self._file if 'file' not in _args else _args['file'] # # @TODO: if _filename is none, an exception should be raised # _uri = '/'.join([self._uri,_filename]) if self._handler.get_file(_uri) : # # _info = self._handler.file_info(_uri) _content = self._handler.get_file_contents(_uri).decode('utf8') if _info.get_content_type() == 'text/csv' : # # @TODO: enable handling of csv, xls, parquet, pickles _file = StringIO(_content) return pd.read_csv(_file) else: # # if it is neither a structured document like csv, we will return the content as is return _content return None class Writer (Nextcloud): """ This class will write data to an instance of nextcloud """ def __init__(self,**_args) : super().__init__(**_args) self def write(self,_data,**_args): """ This function will upload a file to a given destination :file has the uri of the location of the file """ _filename = self._file if 'file' not in _args else _args['file'] _uri = '/'.join([self._uri,_filename]) if type(_data) == pd.DataFrame : f = StringIO() _data.to_csv(f,index=False) _content = f.getvalue() elif type(_data) == dict : _content = json.dumps(_data,cls=IEncoder) else: _content = str(_data) self._handler.put_file_contents(_uri,_content)