python-seafile icon indicating copy to clipboard operation
python-seafile copied to clipboard

Upload a file

Open ChrisBtt opened this issue 11 months ago • 2 comments

Hey,

as far as I understand the documentation and the code of the class itself, no functionality for uploading a file is given.

I am able to connect to a Seafile server and create an empty file with this URL: file_name = os.path.basename(file_path) file_url = os.path.join(server_url, 'lib', repo_id, 'file', file_name)

Is there a better alternative implemented than using the existing requests library and simply post the file content? response = requests.post(file_url, files=files, headers=headers) with

auth_response = requests.post(f"{server_url}api2/auth-token/", data={'username': username, 'password': password})
token = auth_response.json().get('token')
headers = {'Authorization': f'Token {token}'}
files = {'file': (file_name, open(file_path, 'rb'))}

I am happy about any recommendations to some more detailed documentation or a code example. Later on, I can add the solution to the documentation for following users.

ChrisBtt avatar Feb 09 '25 16:02 ChrisBtt

Hey,

as far as I understand the documentation and the code of the class itself, no functionality for uploading a file is given.

I am able to connect to a Seafile server and create an empty file with this URL: file_name = os.path.basename(file_path) file_url = os.path.join(server_url, 'lib', repo_id, 'file', file_name)

Is there a better alternative implemented than using the existing requests library and simply post the file content? response = requests.post(file_url, files=files, headers=headers) with

auth_response = requests.post(f"{server_url}api2/auth-token/", data={'username': username, 'password': password})
token = auth_response.json().get('token')
headers = {'Authorization': f'Token {token}'}
files = {'file': (file_name, open(file_path, 'rb'))}

I am happy about any recommendations to some more detailed documentation or a code example. Later on, I can add the solution to the documentation for following users.

Hi,currently the seafileapi sdk has not provide a method for the file uploading. However, rest API may be a solution. Please referer to https://seafile-api.readme.io/.

For uploading a file you should: step 1: call the api for getting an upload link https://seafile-api.readme.io/reference/get_api2-repos-repo-id-upload-link step 2: upload the file by requesting the upload link https://seafile-api.readme.io/reference/post_seafhttp-upload-api-upload-token-ret-json-1

r350178982 avatar Feb 10 '25 02:02 r350178982

Ok, thanks for the hint. Based on your comment, I implemented the following script. Maybe my solution is also interesting for others.

import os
import requests
from seafileapi import SeafileAPI, Repo


class SeafileClient:
    def __init__(self, server_url, username, password, repo_id):
        self.server_url = server_url
        self.username = username
        self.password = password
        self.repo_id = repo_id
        self.client = SeafileAPI(username, password, server_url)
        self.token = None
        self.repo = None
        self.authenticate()
        self.initialize_repo()

    def authenticate(self):
        self.client.auth()
        self.token = "<seafile-auth-token>"  # Token sollte sicher verwaltet werden

    def initialize_repo(self):
        self.repo = self.client.get_repo(self.repo_id)
        print(f"Repo '{self.repo_id}' initialisiert.")
    
    def list_repositories(self):
        libraries = self.client.list_repos()
        print("Verfügbare Bibliotheken:")
        for library in libraries:
            print(f"- {library['name']} (ID: {library['id']})")
        return libraries
    
    def list_repo_contents(self, dir_path="/"):
        contents = self.repo.list_dir(dir_path=dir_path)
        print(f"Inhalt des Repos '{self.repo_id}' im Verzeichnis '{dir_path}': {contents}")
        return contents
    
    def upload_file(self, parent_dir, file_path):
        file_name = os.path.basename(file_path)
        upload_link_url = f"{self.server_url}/api2/repos/{self.repo_id}/upload-link/?p={parent_dir}"
        headers = {'Authorization': f'Token {self.token}'}
        
        response = requests.get(upload_link_url, headers=headers)
        if response.status_code != 200:
            print(f"Fehler beim Abrufen des Upload-Links: {response.text}")
            return False
        
        upload_link = response.text.strip('"')
        files = {'file': open(file_path, 'rb')}
        data = {'parent_dir': parent_dir}
        response = requests.post(upload_link, files=files, data=data)
        
        if response.status_code == 200:
            print(f"Datei '{file_name}' erfolgreich hochgeladen.")
            return True
        else:
            print(f"Fehler beim Hochladen der Datei: {response.text}")
            return False
    
    def list_and_download_files(self, dir_path):
        list_url = f"{self.server_url}/api2/repos/{self.repo_id}/dir/?p={dir_path}"
        headers = {'Authorization': f'Token {self.token}'}
        response = requests.get(list_url, headers=headers)
        
        if response.status_code != 200:
            print(f"Fehler beim Abrufen der Dateiliste: {response.text}")
            return []
        
        files = response.json()
        print(f"Inhalt des Ordners '{dir_path}':")
        for file in files:
            print(f"- {file['name']} ({'Ordner' if file['type'] == 'dir' else 'Datei'})")
        
        if files and files[0]['type'] == 'file':
            file_name = files[0]['name']
            self.download_file(dir_path, file_name)
        
        return files
    
    def download_file(self, dir_path, file_name):
        download_url = f"{self.server_url}/api2/repos/{self.repo_id}/file/?p={dir_path}/{file_name}"
        headers = {'Authorization': f'Token {self.token}'}
        response = requests.get(download_url, headers=headers)
        
        if response.status_code != 200:
            print(f"Fehler beim Abrufen der Download-URL: {response.text}")
            return False
        
        file_download_url = response.json()
        download_response = requests.get(file_download_url, headers=headers)
        
        if download_response.status_code == 200:
            with open(file_name, 'wb') as file:
                file.write(download_response.content)
            print(f"Datei '{file_name}' erfolgreich heruntergeladen.")
            return True
        else:
            print(f"Fehler beim Herunterladen der Datei: {download_response.text}")
            return False


if __name__ == "__main__":
    server_url = "https://url.to.seafile.server"
    username = "my_username"
    password = "my_password"
    repo_id = "repo_id"
    
    seafile = SeafileClient(server_url, username, password, repo_id)
    seafile.list_repositories()
    seafile.list_repo_contents()
    
    file_path = "<file_path>"
    parent_dir = "<parent_dir>"
    seafile.upload_file(parent_dir, file_path)
    
    seafile.list_and_download_files(parent_dir)

Unfortunately, I do not have time to create a sophisticated pull request appending your code though.

ChrisBtt avatar Feb 10 '25 08:02 ChrisBtt