Source code for ess.nextcloud

import os
import getpass
import webdav3.client as wc
import tempfile
import shutil


[docs]class nextcloud: """ Class to simplify the connection to the ESS Nextcloud instance The class use webdav to connect, and transfers files to a temporary folder which is deleted on exit. Authors: - Yngve Levinsen - Emanuele Laface (original idea) """ def _request_password(self, username): self.password = getpass.getpass("Password for {}:".format(username)) def __init__(self, username=None): self.server = "https://nextcloud.esss.lu.se" self.username = username while self.username is None: for key in ["JUPYTERHUB_USER", "USER", "LOGNAME"]: if key in os.environ: self.username = os.environ[key] self._request_password(self.username) self.tmpfolder = tempfile.mkdtemp() def __del__(self): shutil.rmtree(self.tmpfolder)
[docs] def connect(self): """ Connect to the server. This must be called after a new class has been initialized. """ options = { "webdav_hostname": self.server, "webdav_login": self.username, "webdav_password": self.password, "webdav_root": "/remote.php/webdav", } self.client = wc.Client(options)
[docs] def get_resource(self, filepath): """ Copy the file in filepath to a local temporary folder Parameters ---------- filepath: path to the file returns ------- str full path to the local copy of the file """ check = self.client.check(filepath) if check: folder_path = os.path.join(self.tmpfolder, os.path.dirname(filepath)) if not os.path.exists(folder_path): os.makedirs(folder_path) local_filepath = os.path.join(folder_path, os.path.basename(filepath)) self.client.download_sync(remote_path=filepath, local_path=local_filepath) return local_filepath
[docs] def get_filelist(self, filepath="."): """ Lists files in a folder Parameters ---------- filepath: str path to list of files from returns ------- list list of files in filepath """ check = self.client.check(filepath) if check: return self.client.list(filepath) else: return []
def _globsearch(self, current, remainders): """ A recursive search through a list of paths that are expected to be a folder path. Each folder/file may include regular expressions used in re.search() Start a call to this function by self._globsearch('', folders) Parameters ---------- current: str The current file path remainders: list The remaining list of folders in the glob search Returns ------- list A list of full paths to all matching files """ import re paths = [] for i in range(len(remainders)): folder = remainders[i] if "*" not in folder: current = os.path.join(current, folder) else: for path in self.client.list(current): if re.search(folder, path): if i + 1 == len(remainders): paths.append(os.path.join(current, path)) else: new_current = os.path.join(current, path) paths.extend(self._globsearch(new_current, remainders[i + 1 :])) break return paths
[docs] def get_filelist_glob(self, filepath): """ Lists files in a path which can include * (may match multiple folders) Parameters ---------- filepath: str glob file path to look for files in Returns ------- list list of all files that match the pattern """ # First we need to split in a list of each folder folders = [] while 1: filepath, folder = os.path.split(filepath) if folder != "": folders.append(folder) else: if filepath != "": folders.append(filepath) break folders.reverse() all_paths = self._globsearch("", folders) return all_paths