class NextCloudIntegration: def __init__(self, url, username, password): self.url = url self.username = username self.password = password to_js = True self.nxc = NextCloud(endpoint=url, user=username, password=password, json_output=to_js) def get_list_folder(self, path_name=None, file_name=None, with_files=True): if file_name is not None: path_name = os.path.join(path_name, file_name) list_folders_response = self.nxc.list_folders(self.username, path=path_name, all_properties=True) if not list_folders_response.is_ok: return None if with_files is False: return list( filter(lambda x: x['resource_type'] == 'collection', list_folders_response.data)) return list_folders_response.data def get_list_relative_folder(self, path_name=None, file_name=None, with_files=True): folders = self.get_list_folder(path_name, file_name, with_files) if folders is None: return folders for folder in folders: k = folder['href'].find(self.username) folder['href'] = folder['href'][(k + len(self.username) + 1):] return folders def get_file_list(self, path_name=None): folders = self.get_list_folder(path_name) if folders is None: return None return list(filter(lambda x: x['resource_type'] is None, folders)) def download_file(self, file_path, destination_path=None): folders = self.get_list_folder(file_path) if folders is None: return None if folders[0]['href'] is None: return None local_file_path = self.nxc.download_file(self.username, file_path, destination_path) return local_file_path
def get_available_groups(): nc = NextCloud(endpoint=settings.NEXTCLOUD_URL, user=settings.NEXTCLOUD_USER, password=settings.NEXTCLOUD_PASSWORD, json_output=True) groups_res = nc.get_groups() if groups_res.status_code == 100: groups = groups_res.data['groups'] return ((group, group) for group in groups) else: raise ValueError("Could not retrieve groups from NextCloud: Error {}".format(groups_res.status_code))
def __init__(self, url, username, password): self.url = url self.username = username self.password = password to_js = True self.nxc = NextCloud(endpoint=url, user=username, password=password, json_output=to_js)
def __init__(self, domain, username, password, remote_directory): #self.oc = owncloud.Client(domain) #self.oc.login(username, password) self.username = username self.remote_directory = remote_directory self.nc = NextCloud(domain, username, password, json_output=True) self.cache_thread_running = False self.remote_directory = remote_directory print("Filling cache...") self.file_cache = (datetime.datetime.now(), self.get_dirs()) self.link_cache = {} print("Cache Done!")
def _get_client(self, url: Optional[str] = None, username: Optional[str] = None, password: Optional[str] = None, raise_on_empty: bool = False): from nextcloud import NextCloud if not url: if not self.conf.url: if raise_on_empty: raise AssertionError('No url/username/password provided') return None return NextCloud(endpoint=self.conf.url, user=self.conf.username, password=self.conf.password, json_output=True) return NextCloud(endpoint=url, user=username, password=password, json_output=True)
def exec(self): try: nextcloud_client = NextCloud(endpoint=self.NEXTCLOUD_URL, user=self.NEXTCLOUD_USERNAME, password=self.NEXTCLOUD_PASSWORD, json_output=True) ret = nextcloud_client.upload_file(self.NEXTCLOUD_USERNAME, self.NEXTCLOUD_LOCAL_FILEPATH, self.NEXTCLOUD_UPLOAD_FILEPATH) if re.search('Status: Failed', str(ret)): raise SystemExit(1) except IOError as e: print(e) raise SystemExit(2)
def get_nextcloud(): """ Create if doesn't exist or return edap from flask g object """ if 'nextcloud' not in g: g.nextcloud = NextCloud( endpoint=current_app.config['NEXTCLOUD_HOST'], user=current_app.config['NEXTCLOUD_USER'], password=current_app.config['NEXTCLOUD_PASSWORD']) return g.nextcloud
def setUp(self): super(LocalNxcUserMixin, self).setUp() user_password = self.get_random_string(length=8) self.user_username = self.create_new_user('test_user_', password=user_password) self.nxc_local = self.nxc_local = NextCloud(NEXTCLOUD_URL, self.user_username, user_password, json_output=True) # make user admin self.nxc.add_to_group(self.user_username, 'admin')
class Nextcloud: def __init__(self, server, user, password): self.server = server self.user = user self.client = NextCloud(endpoint=server, user=user, password=password) def upload(self, folder, name, local_fn=None, url=None): res = self.client.list_folders(self.user, path=folder) if not res.is_ok: return False, f"error accessing folder: {folder} {res}" listing = res.data if url: tmpfile = tempfile.NamedTemporaryFile() urllib.request.urlretrieve(url, tmpfile.name) local_fn = tmpfile.name file_size = os.stat(local_fn).st_size filenames = { urllib.parse.unquote(os.path.basename(entry['href'])): entry for entry in listing[1:] } if name in filenames: if os.stat(local_fn).st_size == int( filenames[name]['content_length']): return True, f"file already present: {name}" # Choose new name, if the old one is already i = 1 base, ext = os.path.splitext(name) while name in filenames: name = f"{base} ({i}){ext}" i += 1 target = os.path.join(folder, name) res = self.client.upload_file(self.user, local_fn, target) if not res.is_ok: return False, f"error uploading file: {target} {res}" mbytes = file_size / 1024. / 1024. return True, f"file upload ok: {folder}{name} ({mbytes:.2f}mB)"
def servidorlibreuam_sync(): FILE = 0 DIR = 1 nxc = NextCloud(endpoint=NEXTCLOUD_URL, user=NEXTCLOUD_USERNAME, password=NEXTCLOUD_PASSWORD, json_output=True) folders = [] # Explore the root folder first root = nxc.list_folders(NEXTCLOUD_USERNAME, path="Descarga").data for res in root[1:]: if res["resource_type"] == "collection": res_type = DIR else: res_type = FILE res_path = res["href"].replace( "/remote.php/dav/files/" + NEXTCLOUD_USERNAME + "/", "") folders.append((res_type, res_path)) # Download files and explore folders for res_type, res_path in folders: print(f"{res_type} - {unquote(res_path)}") local_path = unquote( res_path.replace("Descarga/", NEXTCLOUD_DOWNLOAD_FOLDER)) if res_type == FILE: # Download the file nxc.download_file(NEXTCLOUD_USERNAME, res_path, NEXTCLOUD_DOWNLOAD_FOLDER, overwrite=True) elif res_type == DIR: # Create the dir locally os.makedirs(local_path, exist_ok=True) # Add the files inside this dir root = nxc.list_folders(NEXTCLOUD_USERNAME, path=res_path).data for res in root[1:]: if res["resource_type"] == "collection": r_type = DIR else: r_type = FILE r_path = res["href"].replace( "/remote.php/dav/files/" + NEXTCLOUD_USERNAME + "/", "") folders.append((r_type, r_path))
def create_account(self): nc = NextCloud(endpoint=settings.NEXTCLOUD_URL, user=settings.NEXTCLOUD_USER, password=settings.NEXTCLOUD_PASSWORD, json_output=True) username = self.cleaned_data['username'] password = self.cleaned_data['password'] display_name = self.cleaned_data['display_name'] new_user_res = nc.add_user(username, password) if new_user_res.status_code != 100: try: msg = { 101: "invalid input data", 102: "username already exists", 103: "unknown error occurred whilst adding the user", 104: "group does not exist", 105: "insufficient privileges for group", 106: "no group specified (required for subadmins)", 107: "all errors that contain a hint - for example “Password is among the 1,000,000 most common ones. Please make it unique.” (this code was added in 12.0.6 & 13.0.1)", 108: "password and email empty. Must set password or an email", 109: "invitation email cannot be send", }[new_user_res.status_code] if new_user_res.status_code == 107: msg = new_user_res.full_data['ocs']['meta']['message'] except KeyError: msg = "An unknown error occurred. Please try again later" return False, msg # Invalidate invite code code = InviteCode.objects.get(code=self.cleaned_data['invite_code']) code.used = True code.used_by = username code.save() # Set user parameters and add to wanted group edit_display_res = nc.edit_user(username, 'displayname', display_name) if code.groups: groups = code.groups.split(",") results = [] for group in groups: add_viewers_res = nc.add_to_group(username, group) results.append((group, add_viewers_res)) else: add_viewers_res = nc.add_to_group(username, settings.NEXTCLOUD_GROUP_NAME) results = [(settings.NEXTCLOUD_GROUP_NAME, add_viewers_res)] if edit_display_res.status_code == 100 and all([x[1].status_code == 100 for x in results]): return True, "" reasons = [] if edit_display_res.status_code == 101: reasons.append("Could not update display name, user not found.") elif edit_display_res.status_code == 102: reasons.append("Could not update display name, invalid display name.") else: reasons.append("Could not update display name, unknown error.") for group, result in results: if result.status_code == 101: reasons.append("Could not add user to group '{}', group not specified.".format(group)) elif result.status_code == 102: reasons.append("Could not add user to group '{}', groep does not exist.".format(group)) elif result.status_code == 103: reasons.append("Could not add user to group '{}', user does not exist.".format(group)) elif result.status_code == 104: reasons.append("Could not add user to group '{}', insufficient privileges.".format(group)) elif result.status_code == 105: reasons.append("Could not add user to group '{}', failed to add user to group.".format(group)) else: reasons.append("Could not add user to group '{}', unknown error.".format(group)) return True, "\n".join(reasons)
def setUp(self): self.username = NEXTCLOUD_USERNAME self.nxc = NextCloud(NEXTCLOUD_URL, NEXTCLOUD_USERNAME, NEXTCLOUD_PASSWORD, json_output=True)
class BaseTestCase(TestCase): SUCCESS_CODE = 100 INVALID_INPUT_CODE = 101 USERNAME_ALREADY_EXISTS_CODE = 102 UNKNOWN_ERROR_CODE = 103 NOT_FOUND_CODE = 404 def setUp(self): self.username = NEXTCLOUD_USERNAME self.nxc = NextCloud(NEXTCLOUD_URL, NEXTCLOUD_USERNAME, NEXTCLOUD_PASSWORD, json_output=True) def create_new_user(self, username_prefix, password=None): """ Helper method to create new user """ new_user_username = username_prefix + self.get_random_string(length=4) user_password = password or self.get_random_string(length=8) res = self.nxc.add_user(new_user_username, user_password) assert res.is_ok return new_user_username def delete_user(self, username): """ Helper method to delete user by username """ res = self.nxc.delete_user(username) assert res.is_ok def clear(self, nxc=None, user_ids=None, group_ids=None, share_ids=None, group_folder_ids=None): """ Delete created objects during tests Args: nxc (NextCloud object): (optional) Nextcloud instance, if not given - self.nxc is used user_ids (list): list of user ids group_ids (list): list of group ids share_ids (list): list of shares ids Returns: """ nxc = nxc or self.nxc if share_ids: for share_id in share_ids: res = nxc.delete_share(share_id) assert res.is_ok if group_ids: for group_id in group_ids: res = nxc.delete_group(group_id) assert res.is_ok if user_ids: for user_id in user_ids: res = nxc.delete_user(user_id) assert res.is_ok if group_folder_ids: for group_folder_id in group_folder_ids: res = nxc.delete_group_folder(group_folder_id) assert res.is_ok def get_random_string(self, length=6): """ Helper method to get random string with set length """ return ''.join( random.choice(string.ascii_letters + string.digits) for _ in range(length))
from os.path import dirname from os.path import join sys.path.insert(0, join(dirname(__file__), 'src')) from nextcloud import NextCloud NEXTCLOUD_URL = "http://{}:80".format(os.environ['NEXTCLOUD_HOSTNAME']) NEXTCLOUD_USERNAME = os.environ.get('NEXTCLOUD_ADMIN_USER') NEXTCLOUD_PASSWORD = os.environ.get('NEXTCLOUD_ADMIN_PASSWORD') # True if you want to get response as JSON # False if you want to get response as XML to_js = True nxc = NextCloud(endpoint=NEXTCLOUD_URL, user=NEXTCLOUD_USERNAME, password=NEXTCLOUD_PASSWORD, json_output=to_js) # Quick start nxc.get_users() new_user_id = "new_user_username" add_user_res = nxc.add_user(new_user_id, "new_user_password321_123") group_name = "new_group_name" add_group_res = nxc.add_group(group_name) add_to_group_res = nxc.add_to_group(new_user_id, group_name) # End quick start assert add_group_res.status_code == 100 assert new_user_id in nxc.get_group(group_name).data['users'] assert add_user_res.status_code == 100 assert add_to_group_res.status_code == 100
# in this example we disable SSL import urllib3 urllib3.disable_warnings() from nextcloud import NextCloud NEXTCLOUD_URL = "http://{}:8080".format(os.environ['NEXTCLOUD_HOSTNAME']) NEXTCLOUD_USERNAME = os.environ.get('NEXTCLOUD_ADMIN_USER') NEXTCLOUD_PASSWORD = os.environ.get('NEXTCLOUD_ADMIN_PASSWORD') # see api_wrappers/webdav.py File definition to see attributes of a file # see api_wrappers/systemtags.py Tag definition to see attributes of a tag with NextCloud( NEXTCLOUD_URL, user=NEXTCLOUD_USERNAME, password=NEXTCLOUD_PASSWORD, session_kwargs={ 'verify': False # to disable ssl }) as nxc: # list folder (get file path, file_id, and ressource_type that say if the file is a folder) pprint(nxc.list_folders('/').data) # list folder with additionnal infos (the owner, if the file is a favorite…) pprint(nxc.list_folders('/', all_properties=True).data) # list folder content of another user # print(dir(nxc)) pprint( nxc.with_attr(user="******", password="******").list_folders('/').data) # get activity pprint(nxc.get_activities('files'))
def __init__(self, server, user, password): self.server = server self.user = user self.client = NextCloud(endpoint=server, user=user, password=password)
NEXTCLOUD_URL = os.environ.get('NEXTCLOUD_URL') NEXTCLOUD_USERNAME = os.environ.get('NEXTCLOUD_USER') NEXTCLOUD_PASSWORD = os.environ.get('NEXTCLOUD_PASSWORD') assert NEXTCLOUD_URL, "EnvVar NEXTCLOUD_URL not set" assert NEXTCLOUD_USERNAME, "EnvVar NEXTCLOUD_USER not set" assert NEXTCLOUD_PASSWORD, "EnvVar NEXTCLOUD_PASSWORd not set" shinobooru_dir = "Shinobooru" shinobooru_waifu2x_dir = "ShinobooruWaifu2x" # True if you want to get response as JSON # False if you want to get response as XML to_js = True nxc = NextCloud(endpoint=NEXTCLOUD_URL, user=NEXTCLOUD_USERNAME, password=NEXTCLOUD_PASSWORD, json_output=to_js) def href_to_path(href): return href.replace("/remote.php/dav/files/"+NEXTCLOUD_USERNAME+"/", "") def do_in_shinobooru_dir(func): if not os.path.exists(shinobooru_dir): os.mkdir(shinobooru_dir) def wrapper(): os.chdir(shinobooru_dir) func() os.chdir("..") return wrapper
import string from unittest import TestCase from nextcloud import NextCloud from nextcloud.api_wrappers import WebDAV # global nextcloud-related variables try: NEXTCLOUD_URL = "https://{}".format(os.environ.get('NEXTCLOUD_HOSTNAME', 'localhost')) except KeyError: print("ERR -- Nextcloud hostname was not found!") # DO NOT HARD_CODE PASSWORDS IN PLAINTEXT! -- VC user_username = input("Enter your username: "******"Enter your password: "******"r") else: f = open(file_name, "w") f.write(str(file_content)) f.close() file_local_path = os.path.abspath(file_name)
class Nextcloud: def __init__(self, domain, username, password, remote_directory): #self.oc = owncloud.Client(domain) #self.oc.login(username, password) self.username = username self.remote_directory = remote_directory self.nc = NextCloud(domain, username, password, json_output=True) self.cache_thread_running = False self.remote_directory = remote_directory print("Filling cache...") self.file_cache = (datetime.datetime.now(), self.get_dirs()) self.link_cache = {} print("Cache Done!") def link_from_server(self, folder, expire_days=7): expire_date = datetime_to_expire_date(datetime.datetime.now() + datetime.timedelta( days=expire_days)) link = self.nc.create_share(folder, share_type=ShareType.PUBLIC_LINK.value) if link.is_ok: link_id = link.data['id'] link_permissions = link.data['permissions'] updated_link = self.nc.update_share(link_id, expire_date=expire_date) if updated_link.is_ok: log_data = updated_link.data with open('links.log', 'a') as log_file: logput = str(datetime.datetime.now()) + " -> " logput += " id: " + log_data['id'] logput += " expiration: " + log_data['expiration'] logput += " url: " + log_data['url'] logput += "\n" log_file.write(logput) return updated_link.data['url'] return None def get_dirs(self): raw = self.nc.list_folders(self.username, path=self.remote_directory).data output_list = [] for dir in raw: strings = unquote(dir['href']).split("/")[5:-1] output_string = "" for s in strings: output_string += "/" + s output_string += "/" output_list.append(output_string) return output_list[1:] def get_links(self, lectures, link_expire_in_days=7, accuracy=8, cache_callback=None, recursion=True): try: cache_time = datetime.datetime.now() - self.file_cache[0] print("Cache lifetime:", cache_time) if cache_time.total_seconds() > config.directory_cache_time: print("not using cache") self.file_cache = (datetime.datetime.now(), self.get_dirs()) else: print("using cache") if cache_callback is not None and recursion and not self.cache_thread_running: link_cache_emtpy = len(self.link_cache) == 0 if not link_cache_emtpy: first_link_key = list(self.link_cache.keys())[0] first_link_time = self.link_cache[first_link_key][0] link_cached_time = (datetime.datetime.now() - first_link_time).total_seconds() cache_too_old = link_cached_time > config.file_cache_time if link_cache_emtpy or cache_too_old: self.cache_thread_running = True cache_callback( "The cache is being recreated, your request is processed parallel" ) try: params = ([""], link_expire_in_days, accuracy, cache_callback, False) threading._start_new_thread(self.get_links, params) except Exception as e: print(e) files = self.file_cache[1] cache_counter = 0 fetch_counter = 0 except Exception as ex: print(ex) traceback.print_exc() print("Done...") output = {} for lecture in lectures: print("Searching for:", lecture) counter = 1 for f in files: split_path = f.split("/") lecture_name_server = split_path[-2] modified_lecture_name_server = lecture_name_server.replace( "-", "") modified_lecture = lecture.replace("-", "") distance = stein.distance(modified_lecture, modified_lecture_name_server) if distance < accuracy or modified_lecture.lower( ) in modified_lecture_name_server.lower(): if distance <= 0: distance = 1 if lecture_name_server in self.link_cache and ( datetime.datetime.now() - self.link_cache[str(lecture_name_server)][0] ).total_seconds() < config.file_cache_time: print("Using cached Link") cache_counter += 1 output[lecture_name_server] = ( self.link_cache[str(lecture_name_server)][1], 1 / float(math.sqrt(distance))) else: if not recursion: print( "Fetching link from server (cache thread) -> " + lecture_name_server) if recursion: print("Fetching link from server (request)-> " + lecture_name_server) fetch_counter += 1 link_info = self.link_from_server( f, expire_days=link_expire_in_days) print("Done fetching") if not recursion: percentage = "{:.2f}".format( (counter / len(files)) * 100) + "%" # cache_callback("Caching progress: "+percentage) counter += 1 self.link_cache[str(lecture_name_server)] = ( datetime.datetime.now(), link_info) output[lecture_name_server] = ( link_info, 1 / float(math.sqrt(distance))) if not recursion: self.cache_thread_running = False cache_callback("The cache has been recreated!") return output, cache_counter, fetch_counter