docker-seafile-client/dsc/client.py

108 lines
3.5 KiB
Python
Raw Normal View History

2019-12-05 12:57:59 +00:00
import logging
2019-09-06 18:41:43 +00:00
import os
import subprocess
import time
2022-01-30 15:27:37 +00:00
from typing import Optional
2020-08-25 20:17:58 +00:00
from urllib.parse import urlparse
2019-09-06 18:41:43 +00:00
2022-01-30 15:27:37 +00:00
from cached_property import cached_property_with_ttl
2019-09-06 18:41:43 +00:00
import requests
2022-01-30 15:27:37 +00:00
from dsc import consts
from dsc.misc import create_dir
2019-09-06 18:41:43 +00:00
2022-01-30 15:27:37 +00:00
_lg = logging.getLogger(__name__)
2019-12-05 12:57:59 +00:00
2019-09-06 18:41:43 +00:00
class SeafileClient:
2020-08-25 18:16:05 +00:00
def __init__(self, host: str, user: str, passwd: str):
2020-08-25 20:17:58 +00:00
up = urlparse(requests.get(f"http://{host}").url)
self.url = f"{up.scheme}://{up.netloc}"
2019-09-06 18:41:43 +00:00
self.user = user
self.password = passwd
self.__token = None
def __str__(self):
return f"SeafileClient({self.user}@{self.url})"
@property
def token(self):
if self.__token is None:
url = f"{self.url}/api2/auth-token/"
r = requests.post(url, data={"username": self.user,
"password": self.password})
if r.status_code != 200:
raise RuntimeError(f"Can't get token: {r.text}")
self.__token = r.json()['token']
return self.__token
2022-01-30 15:27:37 +00:00
@cached_property_with_ttl(ttl=60)
def remote_libraries(self) -> dict:
url = f"{self.url}/api2/repos/"
2019-09-06 18:41:43 +00:00
auth_header = {"Authorization": f"Token {self.token}"}
r = requests.get(url, headers=auth_header)
if r.status_code != 200:
raise RuntimeError(r.text)
2022-01-30 15:27:37 +00:00
r_libs = {lib["id"]: lib["name"] for lib in r.json()}
return r_libs
def get_library_id(self, library) -> Optional[str]:
for lib_id, lib_name in self.remote_libraries.items():
if library in (lib_id, lib_name):
return lib_id
return None
2019-09-06 18:41:43 +00:00
def sync_lib(self, lib_id: str, data_dir: str):
2022-01-30 15:27:37 +00:00
lib_name = self.remote_libraries[lib_id]
2019-09-06 18:41:43 +00:00
lib_dir = os.path.join(data_dir, lib_name.replace(' ', '_'))
create_dir(lib_dir)
cmd = ['seaf-cli', 'sync',
'-l', lib_id,
'-s', self.url,
'-d', lib_dir,
'-u', self.user,
'-p', self.password]
cmd = ' '.join(cmd)
2022-01-30 15:27:37 +00:00
subprocess.run(['su', '-', consts.DEFAULT_USERNAME, '-c', cmd])
2019-09-06 18:41:43 +00:00
def get_status(self):
cmd = 'seaf-cli status'
2022-01-30 15:27:37 +00:00
out = subprocess.check_output(['su', '-', consts.DEFAULT_USERNAME, '-c', cmd])
2019-09-06 18:41:43 +00:00
out = out.decode().splitlines()
statuses = dict()
for line in out:
if line.startswith('#') or not line.strip():
continue
lib, status = line.split(sep='\t', maxsplit=1)
2019-12-05 12:57:59 +00:00
lib = lib.strip()
status = " ".join(status.split())
2019-09-06 18:41:43 +00:00
statuses[lib] = status
return statuses
def watch_status(self):
prev_status = dict()
while True:
2022-01-30 15:27:37 +00:00
time.sleep(consts.STATUS_POLL_PERIOD)
2019-09-06 18:41:43 +00:00
cur_status = self.get_status()
for folder, state in cur_status.items():
if state != prev_status.get(folder):
2022-01-30 15:27:37 +00:00
logging.info("Library %s:\t%s", folder, state)
2019-09-06 18:41:43 +00:00
prev_status[folder] = cur_status[folder]
2022-01-30 15:27:37 +00:00
def get_local_libraries(self) -> set:
cmd = 'seaf-cli list'
out = subprocess.check_output(['su', '-', consts.DEFAULT_USERNAME, '-c', cmd])
out = out.decode().splitlines()[1:] # first line is a header
local_libs = set()
for line in out:
lib_name, lib_id, lib_path = line.rsplit(maxsplit=3)
local_libs.add(lib_id)
return local_libs
2019-09-06 18:41:43 +00:00
def start_seaf_daemon():
cmd = 'seaf-cli start'
2022-01-30 15:27:37 +00:00
subprocess.run(['su', '-', consts.DEFAULT_USERNAME, '-c', cmd])