mirror of
https://github.com/partitioncloud/partitioncloud-server.git
synced 2025-02-02 13:49:40 +01:00
Compare commits
2 Commits
d54419fd35
...
6f5031623c
Author | SHA1 | Date | |
---|---|---|---|
6f5031623c | |||
f43b1e1090 |
@ -19,3 +19,8 @@ BASE_URL="http://localhost:5000"
|
|||||||
|
|
||||||
# Session expiration, in days
|
# Session expiration, in days
|
||||||
MAX_AGE=31
|
MAX_AGE=31
|
||||||
|
|
||||||
|
# Instance path ie. where are all the files + the database stored
|
||||||
|
# Keep in mind that this config option can only be loaded from default_config.py,
|
||||||
|
# as the custom config is stored in $INSTANCE_PATH/
|
||||||
|
INSTANCE_PATH="instance"
|
||||||
|
26
make.sh
26
make.sh
@ -1,25 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
INSTANCE_PATH="instance"
|
||||||
|
|
||||||
init () {
|
init () {
|
||||||
mkdir -p "instance"
|
mkdir -p "$INSTANCE_PATH"
|
||||||
mkdir -p "partitioncloud/partitions"
|
mkdir -p "$INSTANCE_PATH/partitions"
|
||||||
mkdir -p "partitioncloud/attachments"
|
mkdir -p "$INSTANCE_PATH/attachments"
|
||||||
mkdir -p "partitioncloud/search-partitions"
|
mkdir -p "$INSTANCE_PATH/search-partitions"
|
||||||
mkdir -p "partitioncloud/static/thumbnails"
|
mkdir -p "$INSTANCE_PATH/static/thumbnails"
|
||||||
mkdir -p "partitioncloud/static/search-thumbnails"
|
mkdir -p "$INSTANCE_PATH/static/search-thumbnails"
|
||||||
|
|
||||||
if ! test -f "instance/config.py"; then
|
if ! test -f "$INSTANCE_PATH/config.py"; then
|
||||||
echo "SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex())')" > instance/config.py
|
echo "SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex())')" > "$INSTANCE_PATH/config.py"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -f "instance/partitioncloud.sqlite"; then
|
if test -f "$INSTANCE_PATH/partitioncloud.sqlite"; then
|
||||||
printf "Souhaitez vous supprimer la base de données existante ? [y/n] "
|
printf "Souhaitez vous supprimer la base de données existante ? [y/n] "
|
||||||
read -r CONFIRMATION
|
read -r CONFIRMATION
|
||||||
[[ $CONFIRMATION == y ]] || exit 1
|
[[ $CONFIRMATION == y ]] || exit 1
|
||||||
fi
|
fi
|
||||||
sqlite3 "instance/partitioncloud.sqlite" '.read partitioncloud/schema.sql'
|
sqlite3 "$INSTANCE_PATH/partitioncloud.sqlite" '.read partitioncloud/schema.sql'
|
||||||
echo "Base de données créé"
|
echo "Base de données créé"
|
||||||
sqlite3 "instance/partitioncloud.sqlite" '.read partitioncloud/init.sql'
|
sqlite3 "$INSTANCE_PATH/partitioncloud.sqlite" '.read partitioncloud/init.sql'
|
||||||
echo "Utilisateur root:root ajouté"
|
echo "Utilisateur root:root ajouté"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ usage () {
|
|||||||
if [[ $1 && $(type "$1") = *"is a"*"function"* || $(type "$1") == *"est une fonction"* ]]; then
|
if [[ $1 && $(type "$1") = *"is a"*"function"* || $(type "$1") == *"est une fonction"* ]]; then
|
||||||
# Import config
|
# Import config
|
||||||
source "default_config.py"
|
source "default_config.py"
|
||||||
[[ ! -x instance/config.py ]] && source "instance/config.py"
|
[[ ! -x" $INSTANCE_PATH/config.py" ]] && source "$INSTANCE_PATH/config.py"
|
||||||
$1 ${*:2} # Call the function
|
$1 ${*:2} # Call the function
|
||||||
else
|
else
|
||||||
usage
|
usage
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
Main file
|
Main file
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import datetime
|
import datetime
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import importlib.util
|
||||||
|
|
||||||
from flask import Flask, g, redirect, render_template, request, send_file, flash, session, abort
|
from flask import Flask, g, redirect, render_template, request, send_file, flash, session, abort
|
||||||
from werkzeug.security import generate_password_hash
|
from werkzeug.security import generate_password_hash
|
||||||
@ -16,14 +18,48 @@ from .modules.db import get_db
|
|||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
app.config.from_mapping(
|
|
||||||
DATABASE=os.path.join(app.instance_path, f"{__name__}.sqlite"),
|
def load_config():
|
||||||
)
|
app.config.from_object('default_config')
|
||||||
app.config.from_object('default_config')
|
app.instance_path = os.path.abspath(app.config["INSTANCE_PATH"])
|
||||||
if os.path.exists("instance/config.py"):
|
|
||||||
app.config.from_object('instance.config')
|
if not os.path.exists(app.instance_path):
|
||||||
else:
|
print("[ERROR] Instance path does not exist. Make sure to use an existing directory.")
|
||||||
print("[WARNING] Using default config")
|
sys.exit(1)
|
||||||
|
|
||||||
|
if os.path.exists(f"{app.instance_path}/config.py"):
|
||||||
|
# Load module from instance_path/config.py in user_config object
|
||||||
|
spec = importlib.util.spec_from_file_location(
|
||||||
|
".",
|
||||||
|
os.path.join(app.instance_path, "config.py")
|
||||||
|
)
|
||||||
|
user_config = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(user_config)
|
||||||
|
|
||||||
|
app.config.from_object(user_config)
|
||||||
|
|
||||||
|
if os.path.abspath(app.config["INSTANCE_PATH"]) != app.instance_path:
|
||||||
|
print("[ERROR] Using two different instance path. \
|
||||||
|
\nPlease modify INSTANCE_PATH only in default_config.py and remove it from $INSTANCE_PATH/config.py")
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
print("[WARNING] Using default config")
|
||||||
|
|
||||||
|
app.config.from_mapping(
|
||||||
|
DATABASE=os.path.join(app.instance_path, f"{__name__}.sqlite"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_version():
|
||||||
|
try:
|
||||||
|
result = subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE, check=True)
|
||||||
|
return result.stdout.decode('utf8')
|
||||||
|
except (FileNotFoundError, subprocess.CalledProcessError):
|
||||||
|
# In case git not found or any platform specific weird error
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
|
||||||
|
load_config()
|
||||||
|
|
||||||
app.register_blueprint(auth.bp)
|
app.register_blueprint(auth.bp)
|
||||||
app.register_blueprint(admin.bp)
|
app.register_blueprint(admin.bp)
|
||||||
@ -31,13 +67,7 @@ app.register_blueprint(groupe.bp)
|
|||||||
app.register_blueprint(albums.bp)
|
app.register_blueprint(albums.bp)
|
||||||
app.register_blueprint(partition.bp)
|
app.register_blueprint(partition.bp)
|
||||||
|
|
||||||
|
__version__ = get_version()
|
||||||
try:
|
|
||||||
result = subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE, check=True)
|
|
||||||
__version__ = result.stdout.decode('utf8')
|
|
||||||
except (FileNotFoundError, subprocess.CalledProcessError):
|
|
||||||
# In case git not found or any platform specific weird error
|
|
||||||
__version__ = "unknown"
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
@ -99,7 +129,7 @@ def search_thumbnail(uuid):
|
|||||||
f'/usr/bin/convert -thumbnail\
|
f'/usr/bin/convert -thumbnail\
|
||||||
"178^>" -background white -alpha \
|
"178^>" -background white -alpha \
|
||||||
remove -crop 178x178+0+0 \
|
remove -crop 178x178+0+0 \
|
||||||
partitioncloud/search-partitions/{uuid}.pdf[0] \
|
{app.instance_path}/search-partitions/{uuid}.pdf[0] \
|
||||||
partitioncloud/static/search-thumbnails/{uuid}.jpg'
|
partitioncloud/static/search-thumbnails/{uuid}.jpg'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,14 +5,16 @@ Albums module
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
from flask import (Blueprint, abort, flash, redirect, render_template,
|
from flask import (Blueprint, abort, flash, redirect, render_template,
|
||||||
request, session, current_app)
|
request, session, current_app)
|
||||||
|
|
||||||
from .auth import login_required
|
from .auth import login_required
|
||||||
from .db import get_db
|
from .db import get_db
|
||||||
from .utils import User, Album, get_all_partitions, new_uuid, get_qrcode, format_uuid
|
from .utils import User, Album
|
||||||
from . import search
|
from . import search, utils
|
||||||
|
|
||||||
|
|
||||||
bp = Blueprint("albums", __name__, url_prefix="/albums")
|
bp = Blueprint("albums", __name__, url_prefix="/albums")
|
||||||
|
|
||||||
@ -40,8 +42,8 @@ def search_page():
|
|||||||
|
|
||||||
query = request.form["query"]
|
query = request.form["query"]
|
||||||
nb_queries = abs(int(request.form["nb-queries"]))
|
nb_queries = abs(int(request.form["nb-queries"]))
|
||||||
search.flush_cache()
|
search.flush_cache(current_app.instance_path)
|
||||||
partitions_local = search.local_search(query, get_all_partitions())
|
partitions_local = search.local_search(query, utils.get_all_partitions())
|
||||||
|
|
||||||
user = User(user_id=session.get("user_id"))
|
user = User(user_id=session.get("user_id"))
|
||||||
|
|
||||||
@ -50,7 +52,7 @@ def search_page():
|
|||||||
nb_queries = min(current_app.config["MAX_ONLINE_QUERIES"], nb_queries)
|
nb_queries = min(current_app.config["MAX_ONLINE_QUERIES"], nb_queries)
|
||||||
else:
|
else:
|
||||||
nb_queries = min(10, nb_queries) # Query limit is 10 for an admin
|
nb_queries = min(10, nb_queries) # Query limit is 10 for an admin
|
||||||
google_results = search.online_search(query, nb_queries)
|
google_results = search.online_search(query, nb_queries, current_app.instance_path)
|
||||||
else:
|
else:
|
||||||
google_results = []
|
google_results = []
|
||||||
|
|
||||||
@ -73,8 +75,8 @@ def get_album(uuid):
|
|||||||
album = Album(uuid=uuid)
|
album = Album(uuid=uuid)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
try:
|
try:
|
||||||
album = Album(uuid=format_uuid(uuid))
|
album = Album(uuid=utils.format_uuid(uuid))
|
||||||
return redirect(f"/albums/{format_uuid(uuid)}")
|
return redirect(f"/albums/{utils.format_uuid(uuid)}")
|
||||||
except LookupError:
|
except LookupError:
|
||||||
return abort(404)
|
return abort(404)
|
||||||
|
|
||||||
@ -101,12 +103,12 @@ def qr_code(uuid):
|
|||||||
"""
|
"""
|
||||||
Renvoie le QR Code d'un album
|
Renvoie le QR Code d'un album
|
||||||
"""
|
"""
|
||||||
return get_qrcode(f"/albums/{uuid}")
|
return utils.get_qrcode(f"/albums/{uuid}")
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/create-album", methods=["POST"])
|
@bp.route("/create-album", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def create_album():
|
def create_album_req():
|
||||||
"""
|
"""
|
||||||
Création d'un album
|
Création d'un album
|
||||||
"""
|
"""
|
||||||
@ -118,31 +120,16 @@ def create_album():
|
|||||||
error = "Un nom est requis. L'album n'a pas été créé"
|
error = "Un nom est requis. L'album n'a pas été créé"
|
||||||
|
|
||||||
if error is None:
|
if error is None:
|
||||||
while True:
|
uuid = utils.create_album(name)
|
||||||
try:
|
album = Album(uuid=uuid)
|
||||||
uuid = new_uuid()
|
db.execute(
|
||||||
|
"""
|
||||||
db.execute(
|
INSERT INTO contient_user (user_id, album_id)
|
||||||
"""
|
VALUES (?, ?)
|
||||||
INSERT INTO album (uuid, name)
|
""",
|
||||||
VALUES (?, ?)
|
(session.get("user_id"), album.id),
|
||||||
""",
|
)
|
||||||
(uuid, name),
|
db.commit()
|
||||||
)
|
|
||||||
db.commit()
|
|
||||||
album = Album(uuid=uuid)
|
|
||||||
db.execute(
|
|
||||||
"""
|
|
||||||
INSERT INTO contient_user (user_id, album_id)
|
|
||||||
VALUES (?, ?)
|
|
||||||
""",
|
|
||||||
(session.get("user_id"), album.id),
|
|
||||||
)
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
break
|
|
||||||
except db.IntegrityError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if "response" in request.args and request.args["response"] == "json":
|
if "response" in request.args and request.args["response"] == "json":
|
||||||
return {
|
return {
|
||||||
@ -220,7 +207,7 @@ def delete_album(uuid):
|
|||||||
flash(error)
|
flash(error)
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
album.delete()
|
album.delete(current_app.instance_path)
|
||||||
|
|
||||||
flash("Album supprimé.")
|
flash("Album supprimé.")
|
||||||
return redirect("/albums")
|
return redirect("/albums")
|
||||||
@ -232,6 +219,13 @@ def add_partition(album_uuid):
|
|||||||
"""
|
"""
|
||||||
Ajouter une partition à un album (par upload)
|
Ajouter une partition à un album (par upload)
|
||||||
"""
|
"""
|
||||||
|
T = TypeVar("T")
|
||||||
|
def get_opt_string(dictionary: dict[T, str], key: T):
|
||||||
|
"""Renvoie '' si la clé n'existe pas dans le dictionnaire"""
|
||||||
|
if key in dictionary:
|
||||||
|
return dictionary[key]
|
||||||
|
return ""
|
||||||
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
user = User(user_id=session.get("user_id"))
|
user = User(user_id=session.get("user_id"))
|
||||||
album = Album(uuid=album_uuid)
|
album = Album(uuid=album_uuid)
|
||||||
@ -245,23 +239,22 @@ def add_partition(album_uuid):
|
|||||||
|
|
||||||
if "name" not in request.form:
|
if "name" not in request.form:
|
||||||
error = "Un titre est requis."
|
error = "Un titre est requis."
|
||||||
|
elif "file" not in request.files and "partition-uuid" not in request.form:
|
||||||
|
error = "Aucun fichier n'a été fourni."
|
||||||
elif "file" not in request.files:
|
elif "file" not in request.files:
|
||||||
if "partition-uuid" not in request.form:
|
partition_type = "uuid"
|
||||||
error = "Aucun fichier n'a été fourni."
|
search_uuid = request.form["partition-uuid"]
|
||||||
|
data = db.execute(
|
||||||
|
"""
|
||||||
|
SELECT * FROM search_results
|
||||||
|
WHERE uuid = ?
|
||||||
|
""",
|
||||||
|
(search_uuid,)
|
||||||
|
).fetchone()
|
||||||
|
if data is None:
|
||||||
|
error = "Les résultats de la recherche ont expiré."
|
||||||
else:
|
else:
|
||||||
partition_type = "uuid"
|
source = data["url"]
|
||||||
search_uuid = request.form["partition-uuid"]
|
|
||||||
data = db.execute(
|
|
||||||
"""
|
|
||||||
SELECT * FROM search_results
|
|
||||||
WHERE uuid = ?
|
|
||||||
""",
|
|
||||||
(search_uuid,)
|
|
||||||
).fetchone()
|
|
||||||
if data is None:
|
|
||||||
error = "Les résultats de la recherche ont expiré."
|
|
||||||
else:
|
|
||||||
source = data["url"]
|
|
||||||
else:
|
else:
|
||||||
partition_type = "file"
|
partition_type = "file"
|
||||||
|
|
||||||
@ -269,14 +262,8 @@ def add_partition(album_uuid):
|
|||||||
flash(error)
|
flash(error)
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
if "author" in request.form:
|
author = get_opt_string(request.form, "author")
|
||||||
author = request.form["author"]
|
body = get_opt_string(request.form, "body")
|
||||||
else:
|
|
||||||
author = ""
|
|
||||||
if "body" in request.form:
|
|
||||||
body = request.form["body"]
|
|
||||||
else:
|
|
||||||
body = ""
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@ -291,20 +278,32 @@ def add_partition(album_uuid):
|
|||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
partition_path = os.path.join(
|
||||||
|
current_app.instance_path,
|
||||||
|
"partitions",
|
||||||
|
f"{partition_uuid}.pdf"
|
||||||
|
)
|
||||||
|
|
||||||
if partition_type == "file":
|
if partition_type == "file":
|
||||||
file = request.files["file"]
|
file = request.files["file"]
|
||||||
file.save(f"partitioncloud/partitions/{partition_uuid}.pdf")
|
file.save(partition_path)
|
||||||
else:
|
else:
|
||||||
|
search_partition_path = os.path.join(
|
||||||
|
current_app.instance_path,
|
||||||
|
"search-partitions",
|
||||||
|
f"{search_uuid}.pdf"
|
||||||
|
)
|
||||||
|
|
||||||
shutil.copyfile(
|
shutil.copyfile(
|
||||||
f"partitioncloud/search-partitions/{search_uuid}.pdf",
|
search_partition_path,
|
||||||
f"partitioncloud/partitions/{partition_uuid}.pdf"
|
partition_path
|
||||||
)
|
)
|
||||||
|
|
||||||
os.system(
|
os.system(
|
||||||
f'/usr/bin/convert -thumbnail\
|
f'/usr/bin/convert -thumbnail\
|
||||||
"178^>" -background white -alpha \
|
"178^>" -background white -alpha \
|
||||||
remove -crop 178x178+0+0 \
|
remove -crop 178x178+0+0 \
|
||||||
partitioncloud/partitions/{partition_uuid}.pdf[0] \
|
{partition_path}[0] \
|
||||||
partitioncloud/static/thumbnails/{partition_uuid}.jpg'
|
partitioncloud/static/thumbnails/{partition_uuid}.jpg'
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
@ -78,6 +78,7 @@ def load_logged_in_user():
|
|||||||
|
|
||||||
def create_user(username: str, password: str) -> Optional[str]:
|
def create_user(username: str, password: str) -> Optional[str]:
|
||||||
"""Adds a new user to the database"""
|
"""Adds a new user to the database"""
|
||||||
|
error = None
|
||||||
if not username:
|
if not username:
|
||||||
error = "Un nom d'utilisateur est requis."
|
error = "Un nom d'utilisateur est requis."
|
||||||
elif not password:
|
elif not password:
|
||||||
@ -95,9 +96,8 @@ def create_user(username: str, password: str) -> Optional[str]:
|
|||||||
# The username was already taken, which caused the
|
# The username was already taken, which caused the
|
||||||
# commit to fail. Show a validation error.
|
# commit to fail. Show a validation error.
|
||||||
error = f"Le nom d'utilisateur {username} est déjà pris."
|
error = f"Le nom d'utilisateur {username} est déjà pris."
|
||||||
|
|
||||||
if error is not None:
|
return error # may be None
|
||||||
return error
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/register", methods=("GET", "POST"))
|
@bp.route("/register", methods=("GET", "POST"))
|
||||||
|
@ -4,6 +4,7 @@ Classe Album
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from ..db import get_db
|
from ..db import get_db
|
||||||
|
from ..utils import new_uuid
|
||||||
|
|
||||||
from .attachment import Attachment
|
from .attachment import Attachment
|
||||||
|
|
||||||
@ -81,7 +82,7 @@ class Album():
|
|||||||
).fetchall()
|
).fetchall()
|
||||||
|
|
||||||
|
|
||||||
def delete(self):
|
def delete(self, instance_path):
|
||||||
"""
|
"""
|
||||||
Supprimer l'album
|
Supprimer l'album
|
||||||
"""
|
"""
|
||||||
@ -129,9 +130,9 @@ class Album():
|
|||||||
attachments = [Attachment(data=i) for i in data]
|
attachments = [Attachment(data=i) for i in data]
|
||||||
|
|
||||||
for attachment in attachments:
|
for attachment in attachments:
|
||||||
attachment.delete()
|
attachment.delete(instance_path)
|
||||||
|
|
||||||
os.remove(f"partitioncloud/partitions/{partition['uuid']}.pdf")
|
os.remove(f"{instance_path}/partitions/{partition['uuid']}.pdf")
|
||||||
if os.path.exists(f"partitioncloud/static/thumbnails/{partition['uuid']}.jpg"):
|
if os.path.exists(f"partitioncloud/static/thumbnails/{partition['uuid']}.jpg"):
|
||||||
os.remove(f"partitioncloud/static/thumbnails/{partition['uuid']}.jpg")
|
os.remove(f"partitioncloud/static/thumbnails/{partition['uuid']}.jpg")
|
||||||
|
|
||||||
@ -163,3 +164,26 @@ class Album():
|
|||||||
(partition_uuid, self.id),
|
(partition_uuid, self.id),
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def create(name: str) -> str:
|
||||||
|
"""Créer un nouvel album"""
|
||||||
|
db = get_db()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
uuid = new_uuid()
|
||||||
|
|
||||||
|
db.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO album (uuid, name)
|
||||||
|
VALUES (?, ?)
|
||||||
|
""",
|
||||||
|
(uuid, name),
|
||||||
|
)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
break
|
||||||
|
except db.IntegrityError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return uuid
|
||||||
|
@ -29,7 +29,7 @@ class Attachment():
|
|||||||
self.filetype = data["filetype"]
|
self.filetype = data["filetype"]
|
||||||
self.partition_uuid = data["partition_uuid"]
|
self.partition_uuid = data["partition_uuid"]
|
||||||
|
|
||||||
def delete(self):
|
def delete(self, instance_path):
|
||||||
db = get_db()
|
db = get_db()
|
||||||
db.execute(
|
db.execute(
|
||||||
"""
|
"""
|
||||||
@ -40,7 +40,7 @@ class Attachment():
|
|||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
os.remove(f"partitioncloud/attachments/{self.uuid}.{self.filetype}")
|
os.remove(f"{instance_path}/attachments/{self.uuid}.{self.filetype}")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"{self.name}.{self.filetype}"
|
return f"{self.name}.{self.filetype}"
|
||||||
|
@ -21,7 +21,7 @@ class Groupe():
|
|||||||
self.albums = None
|
self.albums = None
|
||||||
self.admins = None
|
self.admins = None
|
||||||
|
|
||||||
def delete(self):
|
def delete(self, instance_path):
|
||||||
"""
|
"""
|
||||||
Supprime le groupe, et les albums laissés orphelins (sans utilisateur)
|
Supprime le groupe, et les albums laissés orphelins (sans utilisateur)
|
||||||
"""
|
"""
|
||||||
@ -63,7 +63,7 @@ class Groupe():
|
|||||||
|
|
||||||
for i in data:
|
for i in data:
|
||||||
album = Album(id=i["id"])
|
album = Album(id=i["id"])
|
||||||
album.delete()
|
album.delete(instance_path)
|
||||||
|
|
||||||
|
|
||||||
def get_users(self):
|
def get_users(self):
|
||||||
|
@ -29,7 +29,7 @@ class Partition():
|
|||||||
else:
|
else:
|
||||||
raise LookupError
|
raise LookupError
|
||||||
|
|
||||||
def delete(self):
|
def delete(self, instance_path):
|
||||||
self.load_attachments()
|
self.load_attachments()
|
||||||
|
|
||||||
db = get_db()
|
db = get_db()
|
||||||
@ -42,7 +42,7 @@ class Partition():
|
|||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
os.remove(f"partitioncloud/partitions/{self.uuid}.pdf")
|
os.remove(f"{instance_path}/partitions/{self.uuid}.pdf")
|
||||||
if os.path.exists(f"partitioncloud/static/thumbnails/{self.uuid}.jpg"):
|
if os.path.exists(f"partitioncloud/static/thumbnails/{self.uuid}.jpg"):
|
||||||
os.remove(f"partitioncloud/static/thumbnails/{self.uuid}.jpg")
|
os.remove(f"partitioncloud/static/thumbnails/{self.uuid}.jpg")
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ class Partition():
|
|||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
for attachment in self.attachments:
|
for attachment in self.attachments:
|
||||||
attachment.delete()
|
attachment.delete(instance_path)
|
||||||
|
|
||||||
def update(self, name=None, author="", body=""):
|
def update(self, name=None, author="", body=""):
|
||||||
if name is None:
|
if name is None:
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
Groupe module
|
Groupe module
|
||||||
"""
|
"""
|
||||||
from flask import (Blueprint, abort, flash, redirect, render_template,
|
from flask import (Blueprint, abort, flash, redirect, render_template,
|
||||||
request, session)
|
request, session, current_app)
|
||||||
|
|
||||||
from .auth import login_required
|
from .auth import login_required
|
||||||
from .db import get_db
|
from .db import get_db
|
||||||
from .utils import User, Album, Groupe, new_uuid, get_qrcode, format_uuid
|
from .utils import User, Album, Groupe
|
||||||
|
from . import utils
|
||||||
|
|
||||||
bp = Blueprint("groupe", __name__, url_prefix="/groupe")
|
bp = Blueprint("groupe", __name__, url_prefix="/groupe")
|
||||||
|
|
||||||
@ -26,8 +27,8 @@ def get_groupe(uuid):
|
|||||||
groupe = Groupe(uuid=uuid)
|
groupe = Groupe(uuid=uuid)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
try:
|
try:
|
||||||
groupe = Groupe(uuid=format_uuid(uuid))
|
groupe = Groupe(uuid=utils.format_uuid(uuid))
|
||||||
return redirect(f"/groupe/{format_uuid(uuid)}")
|
return redirect(f"/groupe/{utils.format_uuid(uuid)}")
|
||||||
except LookupError:
|
except LookupError:
|
||||||
return abort(404)
|
return abort(404)
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ def get_groupe(uuid):
|
|||||||
|
|
||||||
@bp.route("/<uuid>/qr")
|
@bp.route("/<uuid>/qr")
|
||||||
def album_qr_code(uuid):
|
def album_qr_code(uuid):
|
||||||
return get_qrcode(f"/groupe/{uuid}")
|
return utils.get_qrcode(f"/groupe/{uuid}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ def create_groupe():
|
|||||||
if error is None:
|
if error is None:
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
uuid = new_uuid()
|
uuid = utils.new_uuid()
|
||||||
|
|
||||||
db.execute(
|
db.execute(
|
||||||
"""
|
"""
|
||||||
@ -154,7 +155,7 @@ def delete_groupe(uuid):
|
|||||||
flash(error)
|
flash(error)
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
groupe.delete()
|
groupe.delete(current_app.instance_path)
|
||||||
|
|
||||||
flash("Groupe supprimé.")
|
flash("Groupe supprimé.")
|
||||||
return redirect("/albums")
|
return redirect("/albums")
|
||||||
@ -162,7 +163,7 @@ def delete_groupe(uuid):
|
|||||||
|
|
||||||
@bp.route("/<groupe_uuid>/create-album", methods=["POST"])
|
@bp.route("/<groupe_uuid>/create-album", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def create_album(groupe_uuid):
|
def create_album_req(groupe_uuid):
|
||||||
try:
|
try:
|
||||||
groupe = Groupe(uuid=groupe_uuid)
|
groupe = Groupe(uuid=groupe_uuid)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
@ -181,32 +182,17 @@ def create_album(groupe_uuid):
|
|||||||
error ="Vous n'êtes pas administrateur de ce groupe"
|
error ="Vous n'êtes pas administrateur de ce groupe"
|
||||||
|
|
||||||
if error is None:
|
if error is None:
|
||||||
while True:
|
uuid = utils.create_album(name)
|
||||||
try:
|
album = Album(uuid=uuid)
|
||||||
uuid = new_uuid()
|
|
||||||
|
|
||||||
db.execute(
|
db.execute(
|
||||||
"""
|
"""
|
||||||
INSERT INTO album (uuid, name)
|
INSERT INTO groupe_contient_album (groupe_id, album_id)
|
||||||
VALUES (?, ?)
|
VALUES (?, ?)
|
||||||
""",
|
""",
|
||||||
(uuid, name),
|
(groupe.id, album.id)
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
album = Album(uuid=uuid)
|
|
||||||
|
|
||||||
db.execute(
|
|
||||||
"""
|
|
||||||
INSERT INTO groupe_contient_album (groupe_id, album_id)
|
|
||||||
VALUES (?, ?)
|
|
||||||
""",
|
|
||||||
(groupe.id, album.id)
|
|
||||||
)
|
|
||||||
db.commit()
|
|
||||||
|
|
||||||
break
|
|
||||||
except db.IntegrityError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if "response" in request.args and request.args["response"] == "json":
|
if "response" in request.args and request.args["response"] == "json":
|
||||||
return {
|
return {
|
||||||
@ -229,14 +215,14 @@ def get_album(groupe_uuid, album_uuid):
|
|||||||
groupe = Groupe(uuid=groupe_uuid)
|
groupe = Groupe(uuid=groupe_uuid)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
try:
|
try:
|
||||||
groupe = Groupe(uuid=format_uuid(groupe_uuid))
|
groupe = Groupe(uuid=utils.format_uuid(groupe_uuid))
|
||||||
return redirect(f"/groupe/{format_uuid(groupe_uuid)}/{album_uuid}")
|
return redirect(f"/groupe/{utils.format_uuid(groupe_uuid)}/{album_uuid}")
|
||||||
except LookupError:
|
except LookupError:
|
||||||
return abort(404)
|
return abort(404)
|
||||||
|
|
||||||
album_list = [a for a in groupe.get_albums() if a.uuid == album_uuid]
|
album_list = [a for a in groupe.get_albums() if a.uuid == album_uuid]
|
||||||
if len(album_list) == 0:
|
if len(album_list) == 0:
|
||||||
album_uuid = format_uuid(album_uuid)
|
album_uuid = utils.format_uuid(album_uuid)
|
||||||
album_list = [a for a in groupe.get_albums() if a.uuid == album_uuid]
|
album_list = [a for a in groupe.get_albums() if a.uuid == album_uuid]
|
||||||
if len(album_list) != 0:
|
if len(album_list) != 0:
|
||||||
return redirect(f"/groupe/{groupe_uuid}/{album_uuid}")
|
return redirect(f"/groupe/{groupe_uuid}/{album_uuid}")
|
||||||
@ -269,4 +255,4 @@ def get_album(groupe_uuid, album_uuid):
|
|||||||
|
|
||||||
@bp.route("/<groupe_uuid>/<album_uuid>/qr")
|
@bp.route("/<groupe_uuid>/<album_uuid>/qr")
|
||||||
def groupe_qr_code(groupe_uuid, album_uuid):
|
def groupe_qr_code(groupe_uuid, album_uuid):
|
||||||
return get_qrcode(f"/groupe/{groupe_uuid}/{album_uuid}")
|
return utils.get_qrcode(f"/groupe/{groupe_uuid}/{album_uuid}")
|
||||||
|
@ -4,7 +4,8 @@ Partition module
|
|||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from flask import Blueprint, abort, send_file, render_template, request, redirect, flash, session
|
from flask import (Blueprint, abort, send_file, render_template,
|
||||||
|
request, redirect, flash, session, current_app)
|
||||||
|
|
||||||
from .db import get_db
|
from .db import get_db
|
||||||
from .auth import login_required, admin_required
|
from .auth import login_required, admin_required
|
||||||
@ -21,9 +22,11 @@ def get_partition(uuid):
|
|||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
|
||||||
return send_file(
|
return send_file(os.path.join(
|
||||||
os.path.join("partitions", f"{uuid}.pdf"),
|
current_app.instance_path,
|
||||||
download_name = f"{partition.name}.pdf"
|
"partitions",
|
||||||
|
f"{uuid}.pdf"
|
||||||
|
), download_name = f"{partition.name}.pdf"
|
||||||
)
|
)
|
||||||
|
|
||||||
@bp.route("/<uuid>/attachments")
|
@bp.route("/<uuid>/attachments")
|
||||||
@ -44,7 +47,6 @@ def attachments(uuid):
|
|||||||
@bp.route("/<uuid>/add-attachment", methods=["POST"])
|
@bp.route("/<uuid>/add-attachment", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def add_attachment(uuid):
|
def add_attachment(uuid):
|
||||||
db = get_db()
|
|
||||||
try:
|
try:
|
||||||
partition = Partition(uuid=uuid)
|
partition = Partition(uuid=uuid)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
@ -52,7 +54,7 @@ def add_attachment(uuid):
|
|||||||
user = User(user_id=session.get("user_id"))
|
user = User(user_id=session.get("user_id"))
|
||||||
|
|
||||||
if user.id != partition.user_id and user.access_level != 1:
|
if user.id != partition.user_id and user.access_level != 1:
|
||||||
flash("Cette partition ne vous appartient pas")
|
flash("Cette partition ne vous current_appartient pas")
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
error = None # À mettre au propre
|
error = None # À mettre au propre
|
||||||
@ -66,7 +68,6 @@ def add_attachment(uuid):
|
|||||||
|
|
||||||
if name == "":
|
if name == "":
|
||||||
error = "Pas de nom de fichier"
|
error = "Pas de nom de fichier"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
filename = request.files["file"].filename
|
filename = request.files["file"].filename
|
||||||
ext = filename.split(".")[-1]
|
ext = filename.split(".")[-1]
|
||||||
@ -81,6 +82,7 @@ def add_attachment(uuid):
|
|||||||
try:
|
try:
|
||||||
attachment_uuid = str(uuid4())
|
attachment_uuid = str(uuid4())
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
db.execute(
|
db.execute(
|
||||||
"""
|
"""
|
||||||
INSERT INTO attachments (uuid, name, filetype, partition_uuid, user_id)
|
INSERT INTO attachments (uuid, name, filetype, partition_uuid, user_id)
|
||||||
@ -91,7 +93,11 @@ def add_attachment(uuid):
|
|||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
file = request.files["file"]
|
file = request.files["file"]
|
||||||
file.save(f"partitioncloud/attachments/{attachment_uuid}.{ext}")
|
file.save(os.path.join(
|
||||||
|
current_app.instance_path,
|
||||||
|
"attachments",
|
||||||
|
f"{attachment_uuid}.{ext}"
|
||||||
|
))
|
||||||
break
|
break
|
||||||
|
|
||||||
except db.IntegrityError:
|
except db.IntegrityError:
|
||||||
@ -115,9 +121,11 @@ def get_attachment(uuid, filetype):
|
|||||||
|
|
||||||
assert filetype == attachment.filetype
|
assert filetype == attachment.filetype
|
||||||
|
|
||||||
return send_file(
|
return send_file(os.path.join(
|
||||||
os.path.join("attachments", f"{uuid}.{attachment.filetype}"),
|
current_app.instance_path,
|
||||||
download_name = f"{attachment.name}.{attachment.filetype}"
|
"attachments",
|
||||||
|
f"{uuid}.{attachment.filetype}"
|
||||||
|
), download_name = f"{attachment.name}.{attachment.filetype}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -224,7 +232,7 @@ def delete(uuid):
|
|||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
return render_template("partition/delete.html", partition=partition, user=user)
|
return render_template("partition/delete.html", partition=partition, user=user)
|
||||||
|
|
||||||
partition.delete()
|
partition.delete(current_app.instance_path)
|
||||||
|
|
||||||
flash("Partition supprimée.")
|
flash("Partition supprimée.")
|
||||||
return redirect("/albums")
|
return redirect("/albums")
|
||||||
@ -246,7 +254,13 @@ def partition_search(uuid):
|
|||||||
abort(404)
|
abort(404)
|
||||||
if request.args.get("redirect") == "true" and partition["url"] is not None:
|
if request.args.get("redirect") == "true" and partition["url"] is not None:
|
||||||
return redirect(partition["url"])
|
return redirect(partition["url"])
|
||||||
return send_file(os.path.join("search-partitions", f"{uuid}.pdf"))
|
|
||||||
|
return send_file(os.path.join(
|
||||||
|
current_app.instance_path,
|
||||||
|
"search-partitions",
|
||||||
|
f"{uuid}.pdf"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/")
|
@bp.route("/")
|
||||||
|
@ -49,19 +49,19 @@ def local_search(query, partitions):
|
|||||||
return selection
|
return selection
|
||||||
|
|
||||||
|
|
||||||
def download_search_result(element):
|
def download_search_result(element, instance_path):
|
||||||
uuid = element["uuid"]
|
uuid = element["uuid"]
|
||||||
url = element["url"]
|
url = element["url"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
urllib.request.urlretrieve(url, f"partitioncloud/search-partitions/{uuid}.pdf")
|
urllib.request.urlretrieve(url, f"{instance_path}/search-partitions/{uuid}.pdf")
|
||||||
|
|
||||||
except (urllib.error.HTTPError, urllib.error.URLError):
|
except (urllib.error.HTTPError, urllib.error.URLError):
|
||||||
with open(f"partitioncloud/search-partitions/{uuid}.pdf", 'a', encoding="utf8") as _:
|
with open(f"{instance_path}/search-partitions/{uuid}.pdf", 'a', encoding="utf8") as _:
|
||||||
pass # Create empty file
|
pass # Create empty file
|
||||||
|
|
||||||
|
|
||||||
def online_search(query, num_queries):
|
def online_search(query, num_queries, instance_path):
|
||||||
"""
|
"""
|
||||||
Renvoie les 3 résultats les plus pertinents depuis google
|
Renvoie les 3 résultats les plus pertinents depuis google
|
||||||
"""
|
"""
|
||||||
@ -103,7 +103,12 @@ def online_search(query, num_queries):
|
|||||||
except urllib.error.URLError: # Unable to access network
|
except urllib.error.URLError: # Unable to access network
|
||||||
return []
|
return []
|
||||||
|
|
||||||
threads = [threading.Thread(target=download_search_result, args=(elem,)) for elem in partitions]
|
threads = [
|
||||||
|
threading.Thread(
|
||||||
|
target=download_search_result,
|
||||||
|
args=(elem, instance_path)
|
||||||
|
) for elem in partitions
|
||||||
|
]
|
||||||
|
|
||||||
for thread in threads:
|
for thread in threads:
|
||||||
thread.start()
|
thread.start()
|
||||||
@ -111,10 +116,10 @@ def online_search(query, num_queries):
|
|||||||
for thread in threads:
|
for thread in threads:
|
||||||
thread.join()
|
thread.join()
|
||||||
|
|
||||||
for element in partitions:
|
for element in partitions.copy():
|
||||||
uuid = element["uuid"]
|
uuid = element["uuid"]
|
||||||
url = element["url"]
|
url = element["url"]
|
||||||
if os.stat(f"partitioncloud/search-partitions/{uuid}.pdf").st_size == 0:
|
if os.stat(f"{instance_path}/search-partitions/{uuid}.pdf").st_size == 0:
|
||||||
print("An error occured", url)
|
print("An error occured", url)
|
||||||
db.execute(
|
db.execute(
|
||||||
"""
|
"""
|
||||||
@ -125,14 +130,14 @@ def online_search(query, num_queries):
|
|||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
os.remove(f"partitioncloud/search-partitions/{uuid}.pdf")
|
os.remove(f"{instance_path}/search-partitions/{uuid}.pdf")
|
||||||
|
|
||||||
partitions.remove(element)
|
partitions.remove(element)
|
||||||
|
|
||||||
return partitions
|
return partitions
|
||||||
|
|
||||||
|
|
||||||
def flush_cache():
|
def flush_cache(instance_path):
|
||||||
"""
|
"""
|
||||||
Supprimer les résultats de recherche datant de plus de 15 minutes
|
Supprimer les résultats de recherche datant de plus de 15 minutes
|
||||||
"""
|
"""
|
||||||
@ -146,7 +151,7 @@ def flush_cache():
|
|||||||
for element in expired_cache:
|
for element in expired_cache:
|
||||||
uuid = element["uuid"]
|
uuid = element["uuid"]
|
||||||
try:
|
try:
|
||||||
os.remove(f"partitioncloud/search-partitions/{uuid}.pdf")
|
os.remove(f"{instance_path}/search-partitions/{uuid}.pdf")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
|
@ -29,6 +29,7 @@ from .classes.album import Album
|
|||||||
from .classes.groupe import Groupe
|
from .classes.groupe import Groupe
|
||||||
from .classes.partition import Partition
|
from .classes.partition import Partition
|
||||||
from .classes.attachment import Attachment
|
from .classes.attachment import Attachment
|
||||||
|
from .classes.album import create as create_album
|
||||||
|
|
||||||
|
|
||||||
def get_all_partitions():
|
def get_all_partitions():
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import sqlite3
|
import sqlite3
|
||||||
from hooks import utils
|
from hooks import utils
|
||||||
from colorama import Fore, Style
|
from colorama import Fore, Style
|
||||||
@ -142,3 +143,21 @@ def base_url_parameter_added():
|
|||||||
|
|
||||||
def install_qrcode():
|
def install_qrcode():
|
||||||
os.system("pip install qrcode -qq")
|
os.system("pip install qrcode -qq")
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
v1.5.*
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def move_instance():
|
||||||
|
paths = [
|
||||||
|
"attachments",
|
||||||
|
"partitions",
|
||||||
|
"search-partitions"
|
||||||
|
]
|
||||||
|
for path in paths:
|
||||||
|
shutil.move(
|
||||||
|
os.path.join("partitioncloud", path),
|
||||||
|
os.path.join("instance", path)
|
||||||
|
)
|
@ -33,6 +33,7 @@ hooks = [
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
("v1.4.1", [("Install qrcode", v1_hooks.install_qrcode)]),
|
("v1.4.1", [("Install qrcode", v1_hooks.install_qrcode)]),
|
||||||
|
("v1.5.0", [("Move to instance directory", v1_hooks.move_instance)])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -86,10 +87,10 @@ def backup_instance(version, verbose=True):
|
|||||||
os.path.join(dest, "search-partitions"),
|
os.path.join(dest, "search-partitions"),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
for src, dst in paths:
|
for src, dst in paths: # Only the first one exists after v1.5.0
|
||||||
if os.path.exists(src):
|
if os.path.exists(src):
|
||||||
print_verbose(f"\tBacking up {src}")
|
print_verbose(f"\tBacking up {src}")
|
||||||
shutil.copy_tree(src, dst)
|
shutil.copytree(src, dst)
|
||||||
|
|
||||||
|
|
||||||
def print_hooks(hooks_list):
|
def print_hooks(hooks_list):
|
||||||
@ -108,7 +109,7 @@ def apply_hooks(hooks_list):
|
|||||||
|
|
||||||
|
|
||||||
def migrate(current, target, skip_backup=False, prog_name="scripts/migration.py"):
|
def migrate(current, target, skip_backup=False, prog_name="scripts/migration.py"):
|
||||||
""""""
|
"""Migrate from one version to another"""
|
||||||
print(f"Trying to migrate from {current} to {target}")
|
print(f"Trying to migrate from {current} to {target}")
|
||||||
|
|
||||||
assert is_newer(target, current)
|
assert is_newer(target, current)
|
||||||
@ -132,7 +133,7 @@ def migrate(current, target, skip_backup=False, prog_name="scripts/migration.py"
|
|||||||
)
|
)
|
||||||
print(
|
print(
|
||||||
f"If something goes wrong, recover with {Style.BRIGHT}{Fore.BLUE}{prog_name}\
|
f"If something goes wrong, recover with {Style.BRIGHT}{Fore.BLUE}{prog_name}\
|
||||||
--restore {current}{Style.RESET_ALL}"
|
--restore {current}{Style.RESET_ALL}"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print("Skipping automatic backup")
|
print("Skipping automatic backup")
|
||||||
@ -168,13 +169,13 @@ def restore(version):
|
|||||||
os.path.join(dest, "search-partitions"),
|
os.path.join(dest, "search-partitions"),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
for src, dst in paths:
|
for src, dst in paths: # Only the first one exists after v1.5.0
|
||||||
if os.path.exists(src):
|
if os.path.exists(src):
|
||||||
shutil.rmtree(src)
|
shutil.rmtree(src)
|
||||||
|
|
||||||
if os.path.exists(dst):
|
if os.path.exists(dst):
|
||||||
print(f"\tRestoring {src}")
|
print(f"\tRestoring {src}")
|
||||||
shutil.copy_tree(dst, src)
|
shutil.copytree(dst, src)
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
f"\t{Fore.RED}No available backup for {src}, \
|
f"\t{Fore.RED}No available backup for {src}, \
|
||||||
|
Loading…
Reference in New Issue
Block a user