Compare commits
1 Commits
v0.2.0
..
eaa92ea2d2
| Author | SHA1 | Date | |
|---|---|---|---|
| eaa92ea2d2 |
@@ -1,19 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 DB Systel GmbH
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: "Reusable Poetry build workflow"
|
||||
inputs:
|
||||
poetry_install_args:
|
||||
default: ""
|
||||
description: "Value for additional poetry install arguments"
|
||||
required: false
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Install poetry
|
||||
run: pip install poetry
|
||||
- name: Install poetry package
|
||||
run: poetry install --no-interaction ${{ inputs.poetry_install_args }}
|
||||
shell: bash
|
||||
@@ -1,41 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Python Linters
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
pylint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install dependencies
|
||||
uses: ./.gitea/actions/poetrybuild
|
||||
- name: Lint with pylint
|
||||
run: poetry run pylint seafile_mirror
|
||||
|
||||
formatting:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install dependencies
|
||||
uses: ./.gitea/actions/poetrybuild
|
||||
- name: Test formatting with isort and black
|
||||
run: |
|
||||
poetry run isort --check seafile_mirror/
|
||||
poetry run black .
|
||||
|
||||
mypy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install dependencies
|
||||
uses: ./.gitea/actions/poetrybuild
|
||||
- name: Test typing with mypy
|
||||
run: poetry run mypy
|
||||
@@ -1,18 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Python package
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build and publish to PyPI
|
||||
uses: https://github.com/JRubics/poetry-publish@v1.17
|
||||
with:
|
||||
pypi_token: ${{ secrets.PYPI_TOKEN }}
|
||||
@@ -1,19 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: REUSE Compliance
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
reuse:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Check REUSE Compliance
|
||||
uses: https://github.com/fsfe/reuse-action@v2
|
||||
@@ -1,57 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 DB Systel GmbH
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Selftests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
# Test building the package and installing it via pip3
|
||||
test-build-install:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install poetry
|
||||
run: pip install poetry
|
||||
- name: Build package
|
||||
run: poetry build
|
||||
- name: Install package
|
||||
run: pip3 install dist/seafile_mirror-*.tar.gz
|
||||
- name: Run package
|
||||
run: |
|
||||
seafile-mirror --version
|
||||
seafile-mirror --help
|
||||
|
||||
# Run tool and sync a test library
|
||||
test-sync:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
uses: ./.gitea/actions/poetrybuild
|
||||
# using minimal set of dependencies
|
||||
with:
|
||||
poetry_install_args: "--without dev"
|
||||
- name: Install seaf-cli
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y seafile-cli
|
||||
- name: Configure seaf-cli and start daemon
|
||||
run: |
|
||||
seaf-cli init -d /tmp
|
||||
seaf-cli start
|
||||
- name: Fill configuration for test library
|
||||
run: |
|
||||
sed -i "s|__seafile_server__|${{ secrets.SEAFILE_SERVER }}|" tests/seafile_mirror.conf.yaml
|
||||
sed -i "s|__seafile_user__|${{ secrets.SEAFILE_USER }}|" tests/seafile_mirror.conf.yaml
|
||||
sed -i "s|__seafile_pass__|${{ secrets.SEAFILE_PASS }}|" tests/seafile_mirror.conf.yaml
|
||||
- name: Sync the library
|
||||
run: poetry run seafile-mirror -c tests -v
|
||||
- name: Attempt to find expected string in library
|
||||
run: grep "__ci_test_expect__" tests/ci-test/testfile.txt
|
||||
+1
-9
@@ -1,11 +1,3 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
dist/
|
||||
venv/
|
||||
.seafile_mirror.db.json
|
||||
/seafile_mirror.conf.yaml
|
||||
.seafile_backup.db.json
|
||||
__pycache__/
|
||||
*.log
|
||||
tests/ci-test/
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,89 +0,0 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
|
||||
# Seafile Mirror
|
||||
|
||||
[](https://api.reuse.software/info/src.mehl.mx/mxmehl/seafile-mirror)
|
||||
[](https://pypi.org/project/seafile-mirror/)
|
||||
[](https://pypi.org/project/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.
|
||||
|
||||
## Overview
|
||||
|
||||
If you have Seafile libraries, you may want to back them up in a safe place
|
||||
automatically.
|
||||
|
||||
One option is to snapshot/backup the whole server on which the library is
|
||||
stored. However, in some situations, this may not be feasible or even not
|
||||
possible.
|
||||
|
||||
This is why this repository offers a different way: you can define one or
|
||||
multiple Seafile libraries that shall be downloaded to a local directory. These
|
||||
libraries can belong to the same or a different user, and even on different
|
||||
Seafile servers!
|
||||
|
||||
## Features
|
||||
|
||||
* Download/sync defined libraries in customisable intervals
|
||||
* De-sync libaries immediately after they have been downloaded to avoid sync
|
||||
errors
|
||||
* Allow to force-re-sync a library even if its re-sync interval hasn't reached
|
||||
yet
|
||||
* Extensive informative and error logging
|
||||
* Created with automation in mind so you can run it in cronjobs or systemd
|
||||
triggers
|
||||
* Deal with the numerous caveats of `seaf-cli` and Seafile in general
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
The tool depends on the following applications:
|
||||
* `Python 3`
|
||||
* [`seafile-cli`](https://help.seafile.com/syncing_client/linux-cli/), available
|
||||
e.g. in [Debian](https://packages.debian.org/bullseye/seafile-cli)
|
||||
|
||||
You can install the latest release via `pip3 install seafile-mirror`.
|
||||
|
||||
The tool is executable by `seafile-mirror`. The `--help` flag informs you about
|
||||
the required and available commands.
|
||||
|
||||
There is also an [Ansible
|
||||
role](https://src.mehl.mx/mxmehl/seafile-mirror-ansible) that takes care of
|
||||
installing the tool via `pipx`, 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).
|
||||
|
||||
## Configuration
|
||||
|
||||
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 your current working
|
||||
directory, you should provide `--configdir ./`.
|
||||
|
||||
## Logging and caching
|
||||
|
||||
The tool creates `seafile_mirror.log` in addition to the log to the standard
|
||||
output in the configuration directory. With `-v` you can print DEBUG messages
|
||||
that will help you in case of problems.
|
||||
|
||||
It also caches the current status of synced libraries and their latest full
|
||||
download in the file `.seafile_mirror.db.json`. Do not delete this file unless
|
||||
you don't mind that the tool will re-sync all libraries in the next run.
|
||||
|
||||
## Contribute and Development
|
||||
|
||||
Contributions are welcome! The development is easiest with `poetry`: `poetry
|
||||
install` and `poetry run seafile-mirror` will get you started.
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0, Copyright Max Mehl
|
||||
@@ -1,22 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
[Unit]
|
||||
Description=Seafile Daemon
|
||||
After=network.target
|
||||
After=nfs-client.target
|
||||
StartLimitIntervalSec=60
|
||||
StartLimitBurst=3
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/seaf-daemon -c /home/seafile/.ccnet -d /home/seafile/config/seafile-data -w /home/seafile/config/seafile
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
# Restart every day
|
||||
RuntimeMaxSec=1d
|
||||
SyslogIdentifier=seaf-daemon
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -1,22 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Example configuration file for seafile-mirror
|
||||
- server: https://my-seafile-server.tld
|
||||
user: user@example.com
|
||||
password: mysecretpassword
|
||||
# The default resync interval
|
||||
resync_interval_days: 7
|
||||
# Define the libraries which shall be synced
|
||||
libs:
|
||||
- name: Documents
|
||||
# ID of the Seafile library (can be seen in the web UI)
|
||||
id: 53976f13-9d24-4d4a-967b-efb598d542ea
|
||||
# local directory where the mirror shall be created
|
||||
dir: /backup/Documents
|
||||
- name: Pictures
|
||||
id: 12346f13-9d24-4d4a-1234-efb598d555fa
|
||||
dir: /backup/Pictures
|
||||
# A library-specific resync interval
|
||||
resync_interval_days: 31
|
||||
Executable
@@ -1,7 +1,3 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
"""Functions for cache DB for seafile mirror"""
|
||||
|
||||
import json
|
||||
@@ -43,7 +39,9 @@ def db_update(dbdict, libid, **kwargs):
|
||||
if libid not in dbdict:
|
||||
dbdict[libid] = {}
|
||||
for key, value in kwargs.items():
|
||||
logging.debug("Updating '%s' of library '%s' in in-memory cache dictionary", key, libid)
|
||||
logging.debug(
|
||||
"Updating '%s' of library '%s' in in-memory cache dictionary", key, libid
|
||||
)
|
||||
dbdict[libid][key] = value
|
||||
|
||||
db_write(dbdict)
|
||||
@@ -1,7 +1,3 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
"""Misc helper functions for seafile mirror"""
|
||||
|
||||
import logging
|
||||
@@ -39,14 +35,3 @@ 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]}"
|
||||
@@ -1,7 +1,3 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
"""Functions specific to Seafile for seafile mirror"""
|
||||
|
||||
import datetime
|
||||
@@ -10,7 +6,7 @@ import subprocess
|
||||
import sys
|
||||
from time import sleep
|
||||
|
||||
from ._cachedb import db_get_library_key, db_update
|
||||
from .cachedb import db_get_library_key, db_update
|
||||
|
||||
# Constants
|
||||
# Seafile CLI command
|
||||
@@ -38,7 +34,7 @@ def sf_runcmd(auth: list, *arguments: str) -> str:
|
||||
# check for errors
|
||||
if ret.returncode != 0:
|
||||
logging.error("The command '%s' returned an error: %s", ret.args, ret.stderr)
|
||||
return ""
|
||||
return False
|
||||
|
||||
return ret.stdout.decode("UTF-8")
|
||||
|
||||
@@ -50,20 +46,20 @@ def sf_parse(output: str, fromcommand: str) -> list:
|
||||
for lib in output.splitlines()[1:]:
|
||||
# If list, split is by " ", and structure is name,id,dir
|
||||
if fromcommand == "list":
|
||||
lib_info = [x.strip() for x in lib.split(" ")]
|
||||
lib_dict = {"name": lib_info[0], "id": lib_info[1], "dir": lib_info[2]}
|
||||
libs.append(lib_dict)
|
||||
lib = [x.strip() for x in lib.split(" ")]
|
||||
lib = {"name": lib[0], "id": lib[1], "dir": lib[2]}
|
||||
libs.append(lib)
|
||||
# If status, split is by "\t", and structure is name,status,progress
|
||||
elif fromcommand == "status":
|
||||
lib_tmp = [x.strip() for x in lib.split("\t")]
|
||||
lib_dict = {"name": lib_tmp[0], "status": lib_tmp[1]}
|
||||
lib = {"name": lib_tmp[0], "status": lib_tmp[1]}
|
||||
# Add progress if it exists
|
||||
try:
|
||||
lib_dict["progress"] = lib_tmp[2]
|
||||
lib["progress"] = lib_tmp[2]
|
||||
except IndexError:
|
||||
lib_dict["progress"] = ""
|
||||
lib["progress"] = None
|
||||
|
||||
libs.append(lib_dict)
|
||||
libs.append(lib)
|
||||
|
||||
return libs
|
||||
|
||||
@@ -71,8 +67,8 @@ def sf_parse(output: str, fromcommand: str) -> list:
|
||||
def sf_getstatus(libname: str) -> dict:
|
||||
"""Return the current status of a library (name, status, progress)"""
|
||||
# Get output of `status` and parse it
|
||||
libsstatus_cmd = sf_runcmd([], "status")
|
||||
libsstatus = sf_parse(libsstatus_cmd, "status")
|
||||
libsstatus = sf_runcmd(None, "status")
|
||||
libsstatus = sf_parse(libsstatus, "status")
|
||||
|
||||
# In the list of statuses, get the one for the requested library. None if no match
|
||||
status = next((item for item in libsstatus if item["name"] == libname), None)
|
||||
@@ -140,10 +136,10 @@ def sf_desync_all(cache):
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def sf_waitforsynced(libname) -> float:
|
||||
def sf_waitforsynced(libname) -> int:
|
||||
"""Regularly check status of the library that started to sync"""
|
||||
libsynced = False
|
||||
syncwaitmins: float = 0
|
||||
syncwaitmins = 0
|
||||
nostatus, nostatus_limit = 0, 10
|
||||
while libsynced is not True:
|
||||
libstatus = sf_getstatus(libname)
|
||||
@@ -183,8 +179,8 @@ def sf_waitforsynced(libname) -> float:
|
||||
libname,
|
||||
nostatus_limit,
|
||||
)
|
||||
sf_runcmd([], "stop")
|
||||
sf_runcmd([], "start")
|
||||
sf_runcmd(None, "stop")
|
||||
sf_runcmd(None, "start")
|
||||
|
||||
# If library not synced yet or no status available, wait
|
||||
if not libsynced:
|
||||
Generated
-434
@@ -1,434 +0,0 @@
|
||||
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "astroid"
|
||||
version = "3.0.2"
|
||||
description = "An abstract syntax tree for Python with inference support."
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "astroid-3.0.2-py3-none-any.whl", hash = "sha256:d6e62862355f60e716164082d6b4b041d38e2a8cf1c7cd953ded5108bac8ff5c"},
|
||||
{file = "astroid-3.0.2.tar.gz", hash = "sha256:4a61cf0a59097c7bb52689b0fd63717cd2a8a14dc9f1eee97b82d814881c8c91"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""}
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "23.12.1"
|
||||
description = "The uncompromising code formatter."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"},
|
||||
{file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"},
|
||||
{file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"},
|
||||
{file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"},
|
||||
{file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"},
|
||||
{file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"},
|
||||
{file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"},
|
||||
{file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"},
|
||||
{file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"},
|
||||
{file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"},
|
||||
{file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"},
|
||||
{file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"},
|
||||
{file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"},
|
||||
{file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"},
|
||||
{file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"},
|
||||
{file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"},
|
||||
{file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"},
|
||||
{file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"},
|
||||
{file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"},
|
||||
{file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"},
|
||||
{file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"},
|
||||
{file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=8.0.0"
|
||||
mypy-extensions = ">=0.4.3"
|
||||
packaging = ">=22.0"
|
||||
pathspec = ">=0.9.0"
|
||||
platformdirs = ">=2"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
colorama = ["colorama (>=0.4.3)"]
|
||||
d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
|
||||
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||
uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.7"
|
||||
description = "Composable command line interface toolkit"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
|
||||
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dill"
|
||||
version = "0.3.7"
|
||||
description = "serialize all of Python"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "dill-0.3.7-py3-none-any.whl", hash = "sha256:76b122c08ef4ce2eedcd4d1abd8e641114bfc6c2867f49f3c41facf65bf19f5e"},
|
||||
{file = "dill-0.3.7.tar.gz", hash = "sha256:cc1c8b182eb3013e24bd475ff2e9295af86c1a38eb1aff128dac8962a9ce3c03"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
graph = ["objgraph (>=1.7.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
version = "5.13.2"
|
||||
description = "A Python utility / library to sort Python imports."
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"},
|
||||
{file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
colors = ["colorama (>=0.4.6)"]
|
||||
|
||||
[[package]]
|
||||
name = "mccabe"
|
||||
version = "0.7.0"
|
||||
description = "McCabe checker, plugin for flake8"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
|
||||
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "1.8.0"
|
||||
description = "Optional static typing for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"},
|
||||
{file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"},
|
||||
{file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"},
|
||||
{file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"},
|
||||
{file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"},
|
||||
{file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"},
|
||||
{file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"},
|
||||
{file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"},
|
||||
{file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"},
|
||||
{file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"},
|
||||
{file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"},
|
||||
{file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"},
|
||||
{file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"},
|
||||
{file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"},
|
||||
{file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"},
|
||||
{file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"},
|
||||
{file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"},
|
||||
{file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"},
|
||||
{file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"},
|
||||
{file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"},
|
||||
{file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"},
|
||||
{file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"},
|
||||
{file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"},
|
||||
{file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"},
|
||||
{file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"},
|
||||
{file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"},
|
||||
{file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
mypy-extensions = ">=1.0.0"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
typing-extensions = ">=4.1.0"
|
||||
|
||||
[package.extras]
|
||||
dmypy = ["psutil (>=4.0)"]
|
||||
install-types = ["pip"]
|
||||
mypyc = ["setuptools (>=50)"]
|
||||
reports = ["lxml"]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.1"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"},
|
||||
{file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.11.2"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"},
|
||||
{file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "3.10.0"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"},
|
||||
{file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "pycodestyle"
|
||||
version = "2.11.0"
|
||||
description = "Python style guide checker"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pycodestyle-2.11.0-py2.py3-none-any.whl", hash = "sha256:5d1013ba8dc7895b548be5afb05740ca82454fd899971563d2ef625d090326f8"},
|
||||
{file = "pycodestyle-2.11.0.tar.gz", hash = "sha256:259bcc17857d8a8b3b4a2327324b79e5f020a13c16074670f9c8c8f872ea76d0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydocstyle"
|
||||
version = "6.3.0"
|
||||
description = "Python docstring style checker"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"},
|
||||
{file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
snowballstemmer = ">=2.2.0"
|
||||
|
||||
[package.extras]
|
||||
toml = ["tomli (>=1.2.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyflakes"
|
||||
version = "3.1.0"
|
||||
description = "passive checker of Python programs"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"},
|
||||
{file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pylama"
|
||||
version = "8.4.1"
|
||||
description = "Code audit tool for python"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "pylama-8.4.1-py3-none-any.whl", hash = "sha256:5bbdbf5b620aba7206d688ed9fc917ecd3d73e15ec1a89647037a09fa3a86e60"},
|
||||
{file = "pylama-8.4.1.tar.gz", hash = "sha256:2d4f7aecfb5b7466216d48610c7d6bad1c3990c29cdd392ad08259b161e486f6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
mccabe = ">=0.7.0"
|
||||
pycodestyle = ">=2.9.1"
|
||||
pydocstyle = ">=6.1.1"
|
||||
pyflakes = ">=2.5.0"
|
||||
|
||||
[package.extras]
|
||||
all = ["eradicate", "mypy", "pylint", "radon", "vulture"]
|
||||
eradicate = ["eradicate"]
|
||||
mypy = ["mypy"]
|
||||
pylint = ["pylint"]
|
||||
radon = ["radon"]
|
||||
tests = ["eradicate (>=2.0.0)", "mypy", "pylama-quotes", "pylint (>=2.11.1)", "pytest (>=7.1.2)", "pytest-mypy", "radon (>=5.1.0)", "toml", "types-setuptools", "types-toml", "vulture"]
|
||||
toml = ["toml (>=0.10.2)"]
|
||||
vulture = ["vulture"]
|
||||
|
||||
[[package]]
|
||||
name = "pylint"
|
||||
version = "3.0.3"
|
||||
description = "python code static checker"
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "pylint-3.0.3-py3-none-any.whl", hash = "sha256:7a1585285aefc5165db81083c3e06363a27448f6b467b3b0f30dbd0ac1f73810"},
|
||||
{file = "pylint-3.0.3.tar.gz", hash = "sha256:58c2398b0301e049609a8429789ec6edf3aabe9b6c5fec916acd18639c16de8b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
astroid = ">=3.0.1,<=3.1.0-dev0"
|
||||
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
|
||||
dill = [
|
||||
{version = ">=0.2", markers = "python_version < \"3.11\""},
|
||||
{version = ">=0.3.6", markers = "python_version >= \"3.11\""},
|
||||
{version = ">=0.3.7", markers = "python_version >= \"3.12\""},
|
||||
]
|
||||
isort = ">=4.2.5,<5.13.0 || >5.13.0,<6"
|
||||
mccabe = ">=0.6,<0.8"
|
||||
platformdirs = ">=2.2.0"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
tomlkit = ">=0.10.1"
|
||||
|
||||
[package.extras]
|
||||
spelling = ["pyenchant (>=3.2,<4.0)"]
|
||||
testutils = ["gitpython (>3)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.1"
|
||||
description = "YAML parser and emitter for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
|
||||
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
|
||||
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
||||
{file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
|
||||
{file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
|
||||
{file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
|
||||
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
|
||||
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
|
||||
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snowballstemmer"
|
||||
version = "2.2.0"
|
||||
description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
|
||||
{file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tomlkit"
|
||||
version = "0.12.1"
|
||||
description = "Style preserving TOML library"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"},
|
||||
{file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "types-pyyaml"
|
||||
version = "6.0.12.11"
|
||||
description = "Typing stubs for PyYAML"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "types-PyYAML-6.0.12.11.tar.gz", hash = "sha256:7d340b19ca28cddfdba438ee638cd4084bde213e501a3978738543e27094775b"},
|
||||
{file = "types_PyYAML-6.0.12.11-py3-none-any.whl", hash = "sha256:a461508f3096d1d5810ec5ab95d7eeecb651f3a15b71959999988942063bf01d"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.8.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
|
||||
{file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
|
||||
]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "332efc80877eca1b272474c2e628ab22411accbcd37e72188e0e26bd618fba32"
|
||||
@@ -1,3 +0,0 @@
|
||||
SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
@@ -1,43 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
[tool.poetry]
|
||||
name = "seafile-mirror"
|
||||
version = "0.2.0"
|
||||
description = "Handle clean read-only (re-)syncs of Seafile libraries to mirror them"
|
||||
authors = ["Max Mehl <mail@mehl.mx>"]
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
repository = "https://src.mehl.mx/mxmehl/seafile-mirror"
|
||||
packages = [{ include = "seafile_mirror" }]
|
||||
|
||||
[tool.poetry.scripts]
|
||||
seafile-mirror = 'seafile_mirror.seafile_mirror:main'
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
pyyaml = "^6.0.1"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pylint = "^3.0.0"
|
||||
isort = "^5.12.0"
|
||||
black = "^23.9.1"
|
||||
mypy = "^1.5.1"
|
||||
pylama = "^8.4.1"
|
||||
types-pyyaml = "^6.0.12.11"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
# FORMATTING settings
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
|
||||
# MYPY settings
|
||||
[tool.mypy]
|
||||
files = ["seafile_mirror/*.py"]
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
$schema: "https://docs.renovatebot.com/renovate-schema.json",
|
||||
extends: ["local>renovate-bot/renovate-config"],
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
@@ -1,9 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
"""Handle clean read-only (re-)syncs of Seafile libraries to mirror them"""
|
||||
|
||||
import argparse
|
||||
@@ -14,10 +9,9 @@ from time import sleep
|
||||
|
||||
import yaml
|
||||
|
||||
from . import __version__
|
||||
from ._cachedb import db_read
|
||||
from ._helpers import convert_bytes, findstring, get_lock
|
||||
from ._seafile import (
|
||||
from functions.cachedb import db_read
|
||||
from functions.helpers import findstring, get_lock
|
||||
from functions.seafile import (
|
||||
sf_bump_cache_status,
|
||||
sf_desync_all,
|
||||
sf_lastsync_old_enough,
|
||||
@@ -49,18 +43,10 @@ parser.add_argument(
|
||||
default=False,
|
||||
help="Print and log DEBUG messages",
|
||||
)
|
||||
parser.add_argument("--version", action="version", version="%(prog)s " + __version__)
|
||||
|
||||
|
||||
def main(): # pylint: disable=too-many-locals, too-many-statements
|
||||
def main():
|
||||
"""Main function"""
|
||||
args = parser.parse_args()
|
||||
# Set files depending on configdir
|
||||
configdir = args.configdir.rstrip("/") + "/"
|
||||
configfile = configdir + "seafile_mirror.conf.yaml"
|
||||
cachefile = configdir + ".seafile_mirror.db.json"
|
||||
logfile = configdir + "seafile_mirror.log"
|
||||
|
||||
# Logging
|
||||
log = logging.getLogger()
|
||||
logging.basicConfig(
|
||||
@@ -95,7 +81,7 @@ def main(): # pylint: disable=too-many-locals, too-many-statements
|
||||
sf_desync_all(cache)
|
||||
|
||||
# Create list of libraries we handle(d) for final output
|
||||
libsdone = {"libs": [], "bytes": 0, "time": 0}
|
||||
libsdone = []
|
||||
|
||||
# Go through users in config
|
||||
for access in config:
|
||||
@@ -123,12 +109,16 @@ def main(): # pylint: disable=too-many-locals, too-many-statements
|
||||
libid = lib["id"]
|
||||
# Set resync interval if there is a lib-specific setting. Otherwise default
|
||||
libresyncinterval = (
|
||||
lib["resync_interval_days"] if "resync_interval_days" in lib else resyncinterval
|
||||
lib["resync_interval_days"]
|
||||
if "resync_interval_days" in lib
|
||||
else resyncinterval
|
||||
)
|
||||
|
||||
# Check if last sync of library is older than resync_interval_days
|
||||
if sf_lastsync_old_enough(cache, libid, args.force, libresyncinterval):
|
||||
logging.info("Starting to re-sync library %s (%s) to %s", libname, libid, libdir)
|
||||
logging.info(
|
||||
"Starting to re-sync library %s (%s) to %s", libname, libid, libdir
|
||||
)
|
||||
else:
|
||||
logging.info(
|
||||
"Local mirror of library %s (%s) at %s is still recent enough. Skipping it.",
|
||||
@@ -188,33 +178,22 @@ def main(): # pylint: disable=too-many-locals, too-many-statements
|
||||
)
|
||||
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["libs"].append(libname)
|
||||
libsdone["bytes"] += libdirsize
|
||||
libsdone["time"] += syncduration
|
||||
libsdone.append(libname)
|
||||
sf_bump_cache_status(cache, libid, status="synced", duration=syncduration)
|
||||
|
||||
logging.info(
|
||||
"Library %s (%s) has been re-synced to %s. Duration: %s minutes. Size: %s",
|
||||
libname,
|
||||
libid,
|
||||
libdir,
|
||||
round(syncduration),
|
||||
convert_bytes(libdirsize),
|
||||
"Library %s (%s) has been re-synced to %s", libname, libid, libdir
|
||||
)
|
||||
|
||||
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"]),
|
||||
)
|
||||
logging.info("Fully re-synced the following libraries: %s", ", ".join(libsdone))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parser.parse_args()
|
||||
# Set files depending on configdir
|
||||
configdir = args.configdir.rstrip("/") + "/"
|
||||
configfile = configdir + "seafile_mirror.conf.yaml"
|
||||
cachefile = configdir + ".seafile_mirror.db.json"
|
||||
logfile = configdir + "seafile_mirror.log"
|
||||
main()
|
||||
@@ -1,10 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
||||
"""Global init file"""
|
||||
|
||||
from importlib.metadata import version
|
||||
|
||||
__version__ = version("seafile-mirror")
|
||||
@@ -1,18 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2023 Max Mehl <https://mehl.mx>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Configuration file for seafile-mirror which will be filled in and applied in
|
||||
# the CI test
|
||||
- server: __seafile_server__
|
||||
user: __seafile_user__
|
||||
password: __seafile_pass__
|
||||
# The default resync interval
|
||||
resync_interval_days: 7
|
||||
# Define the libraries which shall be synced
|
||||
libs:
|
||||
- name: ci-test
|
||||
# ID of the Seafile library (can be seen in the web UI)
|
||||
id: 558667f5-cee2-443d-8f8e-668e70a23e9f
|
||||
# local directory where the mirror shall be created
|
||||
dir: tests/ci-test
|
||||
Reference in New Issue
Block a user