Compare commits

...

4 Commits

Author SHA1 Message Date
8c54fd318a make final log message contain total duration and size for whole run 2023-06-09 10:18:41 +02:00
22f5c05d92 fix formatting 2023-06-09 10:18:14 +02:00
721d96101f show size and duration after sync 2023-06-09 10:07:05 +02:00
e061c160fd add REUSE API badge 2023-06-09 09:14:42 +02:00
3 changed files with 46 additions and 9 deletions

View File

@@ -6,6 +6,8 @@ SPDX-License-Identifier: Apache-2.0
# Seafile Mirror
[![REUSE status](https://api.reuse.software/badge/src.mehl.mx/mxmehl/seafile-mirror)](https://api.reuse.software/info/src.mehl.mx/mxmehl/seafile-mirror)
A Python tool to handle clean read-only (re-)syncs of
[Seafile](https://www.seafile.com) libraries with the intention to mirror them.
@@ -40,7 +42,8 @@ Seafile servers!
The tool depends on the following applications:
* `Python 3` and its library `yaml`
* [`seafile-cli`](https://help.seafile.com/syncing_client/linux-cli/), available e.g. in [Debian](https://packages.debian.org/bullseye/seafile-cli)
* [`seafile-cli`](https://help.seafile.com/syncing_client/linux-cli/), available
e.g. in [Debian](https://packages.debian.org/bullseye/seafile-cli)
You can execute the tool with `python3 seafile_mirror.py`. The `--help` flag
informs you about the required and available commands.
@@ -49,13 +52,17 @@ There is also an [Ansible
role](https://src.mehl.mx/mxmehl/seafile-mirror-ansible) that takes care of
installing the tool, setting up a systemd service, and running it daily.
To keep the Seafile daemon that is required for `seafile-cli` running in the background, check out this [exemplary systemd service](examples/seaf-daemon.service).
To keep the Seafile daemon that is required for `seafile-cli` running in the
background, check out this [exemplary systemd
service](examples/seaf-daemon.service).
## Configuration
Configuration is done in a YAML file called `seafile_mirror.conf.yaml`. You can find an example [here](examples/seafile_mirror.conf.yaml).
Configuration is done in a YAML file called `seafile_mirror.conf.yaml`. You can
find an example [here](examples/seafile_mirror.conf.yaml).
If that configuration file resides in the same location as the `seafile_mirror.py` file you are running, you should provide `--configdir ./`.
If that configuration file resides in the same location as the
`seafile_mirror.py` file you are running, you should provide `--configdir ./`.
## Logging and caching

View File

@@ -39,3 +39,14 @@ def findstring(text, string):
def countlines(string: str) -> int:
"""Count number of lines in a variable"""
return len(string.splitlines())
def convert_bytes(size):
"""Convert bytes to KB, MB etc depending on size"""
power = 1024
level = 0
labels = {0 : 'B', 1: 'KB', 2: 'MB', 3: 'GB', 4: 'TB'}
while size > power:
size /= power
level += 1
return f"{round(size, 2)} {labels[level]}"

View File

@@ -15,7 +15,7 @@ from time import sleep
import yaml
from functions.cachedb import db_read
from functions.helpers import findstring, get_lock
from functions.helpers import convert_bytes, findstring, get_lock
from functions.seafile import (
sf_bump_cache_status,
sf_desync_all,
@@ -86,7 +86,7 @@ def main():
sf_desync_all(cache)
# Create list of libraries we handle(d) for final output
libsdone = []
libsdone = {"libs": [], "bytes": 0, "time": 0}
# Go through users in config
for access in config:
@@ -183,15 +183,34 @@ def main():
)
sf_runcmd(None, "desync", "-d", libdir)
# Get size of directory (libdir) in bytes
# Note: this is not fully equivalent with what `du` would show. It's
# caused by the fact that `du` considers filesystem block sizes
libdirsize = sum(
f.stat().st_size for f in libdir.glob("**/*") if f.is_file()
)
# Update libsdone and cache
libsdone.append(libname)
libsdone["libs"].append(libname)
libsdone["bytes"] += libdirsize
libsdone["time"] += syncduration
sf_bump_cache_status(cache, libid, status="synced", duration=syncduration)
logging.info(
"Library %s (%s) has been re-synced to %s", libname, libid, libdir
"Library %s (%s) has been re-synced to %s. Duration: %s minutes. Size: %s",
libname,
libid,
libdir,
round(syncduration),
convert_bytes(libdirsize),
)
logging.info("Fully re-synced the following libraries: %s", ", ".join(libsdone))
logging.info(
"Fully re-synced the following libraries: %s. Total duration: %s minutes. Total size: %s",
", ".join(libsdone["libs"]),
round(libsdone["time"]),
convert_bytes(libsdone["bytes"]),
)
if __name__ == "__main__":