mirror of
https://github.com/partitioncloud/partitioncloud-server.git
synced 2025-02-03 18:53:42 +01:00
Compare commits
No commits in common. "6f5031623c23b42cf901e602adbac718b2ebabfb" and "d54419fd357f5027acdf1dca2104dc3520d4a6d3" have entirely different histories.
6f5031623c
...
d54419fd35
@ -19,8 +19,3 @@ 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,27 +1,25 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
INSTANCE_PATH="instance"
|
|
||||||
|
|
||||||
init () {
|
init () {
|
||||||
mkdir -p "$INSTANCE_PATH"
|
mkdir -p "instance"
|
||||||
mkdir -p "$INSTANCE_PATH/partitions"
|
mkdir -p "partitioncloud/partitions"
|
||||||
mkdir -p "$INSTANCE_PATH/attachments"
|
mkdir -p "partitioncloud/attachments"
|
||||||
mkdir -p "$INSTANCE_PATH/search-partitions"
|
mkdir -p "partitioncloud/search-partitions"
|
||||||
mkdir -p "$INSTANCE_PATH/static/thumbnails"
|
mkdir -p "partitioncloud/static/thumbnails"
|
||||||
mkdir -p "$INSTANCE_PATH/static/search-thumbnails"
|
mkdir -p "partitioncloud/static/search-thumbnails"
|
||||||
|
|
||||||
if ! test -f "$INSTANCE_PATH/config.py"; then
|
if ! test -f "instance/config.py"; then
|
||||||
echo "SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex())')" > "$INSTANCE_PATH/config.py"
|
echo "SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex())')" > instance/config.py
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -f "$INSTANCE_PATH/partitioncloud.sqlite"; then
|
if test -f "instance/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_PATH/partitioncloud.sqlite" '.read partitioncloud/schema.sql'
|
sqlite3 "instance/partitioncloud.sqlite" '.read partitioncloud/schema.sql'
|
||||||
echo "Base de données créé"
|
echo "Base de données créé"
|
||||||
sqlite3 "$INSTANCE_PATH/partitioncloud.sqlite" '.read partitioncloud/init.sql'
|
sqlite3 "instance/partitioncloud.sqlite" '.read partitioncloud/init.sql'
|
||||||
echo "Utilisateur root:root ajouté"
|
echo "Utilisateur root:root ajouté"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +43,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_PATH/config.py" ]] && source "$INSTANCE_PATH/config.py"
|
[[ ! -x instance/config.py ]] && source "instance/config.py"
|
||||||
$1 ${*:2} # Call the function
|
$1 ${*:2} # Call the function
|
||||||
else
|
else
|
||||||
usage
|
usage
|
||||||
|
@ -3,10 +3,8 @@
|
|||||||
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
|
||||||
@ -18,48 +16,14 @@ from .modules.db import get_db
|
|||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
def load_config():
|
|
||||||
app.config.from_object('default_config')
|
|
||||||
app.instance_path = os.path.abspath(app.config["INSTANCE_PATH"])
|
|
||||||
|
|
||||||
if not os.path.exists(app.instance_path):
|
|
||||||
print("[ERROR] Instance path does not exist. Make sure to use an existing directory.")
|
|
||||||
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(
|
app.config.from_mapping(
|
||||||
DATABASE=os.path.join(app.instance_path, f"{__name__}.sqlite"),
|
DATABASE=os.path.join(app.instance_path, f"{__name__}.sqlite"),
|
||||||
)
|
)
|
||||||
|
app.config.from_object('default_config')
|
||||||
|
if os.path.exists("instance/config.py"):
|
||||||
def get_version():
|
app.config.from_object('instance.config')
|
||||||
try:
|
else:
|
||||||
result = subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE, check=True)
|
print("[WARNING] Using default config")
|
||||||
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)
|
||||||
@ -67,7 +31,13 @@ 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("/")
|
||||||
@ -129,7 +99,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 \
|
||||||
{app.instance_path}/search-partitions/{uuid}.pdf[0] \
|
partitioncloud/search-partitions/{uuid}.pdf[0] \
|
||||||
partitioncloud/static/search-thumbnails/{uuid}.jpg'
|
partitioncloud/static/search-thumbnails/{uuid}.jpg'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,16 +5,14 @@ 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
|
from .utils import User, Album, get_all_partitions, new_uuid, get_qrcode, format_uuid
|
||||||
from . import search, utils
|
from . import search
|
||||||
|
|
||||||
|
|
||||||
bp = Blueprint("albums", __name__, url_prefix="/albums")
|
bp = Blueprint("albums", __name__, url_prefix="/albums")
|
||||||
|
|
||||||
@ -42,8 +40,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(current_app.instance_path)
|
search.flush_cache()
|
||||||
partitions_local = search.local_search(query, utils.get_all_partitions())
|
partitions_local = search.local_search(query, get_all_partitions())
|
||||||
|
|
||||||
user = User(user_id=session.get("user_id"))
|
user = User(user_id=session.get("user_id"))
|
||||||
|
|
||||||
@ -52,7 +50,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, current_app.instance_path)
|
google_results = search.online_search(query, nb_queries)
|
||||||
else:
|
else:
|
||||||
google_results = []
|
google_results = []
|
||||||
|
|
||||||
@ -75,8 +73,8 @@ def get_album(uuid):
|
|||||||
album = Album(uuid=uuid)
|
album = Album(uuid=uuid)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
try:
|
try:
|
||||||
album = Album(uuid=utils.format_uuid(uuid))
|
album = Album(uuid=format_uuid(uuid))
|
||||||
return redirect(f"/albums/{utils.format_uuid(uuid)}")
|
return redirect(f"/albums/{format_uuid(uuid)}")
|
||||||
except LookupError:
|
except LookupError:
|
||||||
return abort(404)
|
return abort(404)
|
||||||
|
|
||||||
@ -103,12 +101,12 @@ def qr_code(uuid):
|
|||||||
"""
|
"""
|
||||||
Renvoie le QR Code d'un album
|
Renvoie le QR Code d'un album
|
||||||
"""
|
"""
|
||||||
return utils.get_qrcode(f"/albums/{uuid}")
|
return get_qrcode(f"/albums/{uuid}")
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/create-album", methods=["POST"])
|
@bp.route("/create-album", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def create_album_req():
|
def create_album():
|
||||||
"""
|
"""
|
||||||
Création d'un album
|
Création d'un album
|
||||||
"""
|
"""
|
||||||
@ -120,7 +118,18 @@ def create_album_req():
|
|||||||
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:
|
||||||
uuid = utils.create_album(name)
|
while True:
|
||||||
|
try:
|
||||||
|
uuid = new_uuid()
|
||||||
|
|
||||||
|
db.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO album (uuid, name)
|
||||||
|
VALUES (?, ?)
|
||||||
|
""",
|
||||||
|
(uuid, name),
|
||||||
|
)
|
||||||
|
db.commit()
|
||||||
album = Album(uuid=uuid)
|
album = Album(uuid=uuid)
|
||||||
db.execute(
|
db.execute(
|
||||||
"""
|
"""
|
||||||
@ -131,6 +140,10 @@ def create_album_req():
|
|||||||
)
|
)
|
||||||
db.commit()
|
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 {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@ -207,7 +220,7 @@ def delete_album(uuid):
|
|||||||
flash(error)
|
flash(error)
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
album.delete(current_app.instance_path)
|
album.delete()
|
||||||
|
|
||||||
flash("Album supprimé.")
|
flash("Album supprimé.")
|
||||||
return redirect("/albums")
|
return redirect("/albums")
|
||||||
@ -219,13 +232,6 @@ 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)
|
||||||
@ -239,9 +245,10 @@ 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:
|
||||||
|
error = "Aucun fichier n'a été fourni."
|
||||||
|
else:
|
||||||
partition_type = "uuid"
|
partition_type = "uuid"
|
||||||
search_uuid = request.form["partition-uuid"]
|
search_uuid = request.form["partition-uuid"]
|
||||||
data = db.execute(
|
data = db.execute(
|
||||||
@ -262,8 +269,14 @@ def add_partition(album_uuid):
|
|||||||
flash(error)
|
flash(error)
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
author = get_opt_string(request.form, "author")
|
if "author" in request.form:
|
||||||
body = get_opt_string(request.form, "body")
|
author = request.form["author"]
|
||||||
|
else:
|
||||||
|
author = ""
|
||||||
|
if "body" in request.form:
|
||||||
|
body = request.form["body"]
|
||||||
|
else:
|
||||||
|
body = ""
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@ -278,32 +291,20 @@ 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(partition_path)
|
file.save(f"partitioncloud/partitions/{partition_uuid}.pdf")
|
||||||
else:
|
else:
|
||||||
search_partition_path = os.path.join(
|
|
||||||
current_app.instance_path,
|
|
||||||
"search-partitions",
|
|
||||||
f"{search_uuid}.pdf"
|
|
||||||
)
|
|
||||||
|
|
||||||
shutil.copyfile(
|
shutil.copyfile(
|
||||||
search_partition_path,
|
f"partitioncloud/search-partitions/{search_uuid}.pdf",
|
||||||
partition_path
|
f"partitioncloud/partitions/{partition_uuid}.pdf"
|
||||||
)
|
)
|
||||||
|
|
||||||
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 \
|
||||||
{partition_path}[0] \
|
partitioncloud/partitions/{partition_uuid}.pdf[0] \
|
||||||
partitioncloud/static/thumbnails/{partition_uuid}.jpg'
|
partitioncloud/static/thumbnails/{partition_uuid}.jpg'
|
||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
@ -78,7 +78,6 @@ 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:
|
||||||
@ -97,7 +96,8 @@ def create_user(username: str, password: str) -> Optional[str]:
|
|||||||
# 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."
|
||||||
|
|
||||||
return error # may be None
|
if error is not None:
|
||||||
|
return error
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/register", methods=("GET", "POST"))
|
@bp.route("/register", methods=("GET", "POST"))
|
||||||
|
@ -4,7 +4,6 @@ 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
|
||||||
|
|
||||||
@ -82,7 +81,7 @@ class Album():
|
|||||||
).fetchall()
|
).fetchall()
|
||||||
|
|
||||||
|
|
||||||
def delete(self, instance_path):
|
def delete(self):
|
||||||
"""
|
"""
|
||||||
Supprimer l'album
|
Supprimer l'album
|
||||||
"""
|
"""
|
||||||
@ -130,9 +129,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(instance_path)
|
attachment.delete()
|
||||||
|
|
||||||
os.remove(f"{instance_path}/partitions/{partition['uuid']}.pdf")
|
os.remove(f"partitioncloud/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")
|
||||||
|
|
||||||
@ -164,26 +163,3 @@ 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, instance_path):
|
def delete(self):
|
||||||
db = get_db()
|
db = get_db()
|
||||||
db.execute(
|
db.execute(
|
||||||
"""
|
"""
|
||||||
@ -40,7 +40,7 @@ class Attachment():
|
|||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
os.remove(f"{instance_path}/attachments/{self.uuid}.{self.filetype}")
|
os.remove(f"partitioncloud/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, instance_path):
|
def delete(self):
|
||||||
"""
|
"""
|
||||||
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(instance_path)
|
album.delete()
|
||||||
|
|
||||||
|
|
||||||
def get_users(self):
|
def get_users(self):
|
||||||
|
@ -29,7 +29,7 @@ class Partition():
|
|||||||
else:
|
else:
|
||||||
raise LookupError
|
raise LookupError
|
||||||
|
|
||||||
def delete(self, instance_path):
|
def delete(self):
|
||||||
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"{instance_path}/partitions/{self.uuid}.pdf")
|
os.remove(f"partitioncloud/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(instance_path)
|
attachment.delete()
|
||||||
|
|
||||||
def update(self, name=None, author="", body=""):
|
def update(self, name=None, author="", body=""):
|
||||||
if name is None:
|
if name is None:
|
||||||
|
@ -3,12 +3,11 @@
|
|||||||
Groupe module
|
Groupe module
|
||||||
"""
|
"""
|
||||||
from flask import (Blueprint, abort, flash, redirect, render_template,
|
from flask import (Blueprint, abort, flash, redirect, render_template,
|
||||||
request, session, current_app)
|
request, session)
|
||||||
|
|
||||||
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
|
from .utils import User, Album, Groupe, new_uuid, get_qrcode, format_uuid
|
||||||
from . import utils
|
|
||||||
|
|
||||||
bp = Blueprint("groupe", __name__, url_prefix="/groupe")
|
bp = Blueprint("groupe", __name__, url_prefix="/groupe")
|
||||||
|
|
||||||
@ -27,8 +26,8 @@ def get_groupe(uuid):
|
|||||||
groupe = Groupe(uuid=uuid)
|
groupe = Groupe(uuid=uuid)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
try:
|
try:
|
||||||
groupe = Groupe(uuid=utils.format_uuid(uuid))
|
groupe = Groupe(uuid=format_uuid(uuid))
|
||||||
return redirect(f"/groupe/{utils.format_uuid(uuid)}")
|
return redirect(f"/groupe/{format_uuid(uuid)}")
|
||||||
except LookupError:
|
except LookupError:
|
||||||
return abort(404)
|
return abort(404)
|
||||||
|
|
||||||
@ -52,7 +51,7 @@ def get_groupe(uuid):
|
|||||||
|
|
||||||
@bp.route("/<uuid>/qr")
|
@bp.route("/<uuid>/qr")
|
||||||
def album_qr_code(uuid):
|
def album_qr_code(uuid):
|
||||||
return utils.get_qrcode(f"/groupe/{uuid}")
|
return get_qrcode(f"/groupe/{uuid}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ def create_groupe():
|
|||||||
if error is None:
|
if error is None:
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
uuid = utils.new_uuid()
|
uuid = new_uuid()
|
||||||
|
|
||||||
db.execute(
|
db.execute(
|
||||||
"""
|
"""
|
||||||
@ -155,7 +154,7 @@ def delete_groupe(uuid):
|
|||||||
flash(error)
|
flash(error)
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
groupe.delete(current_app.instance_path)
|
groupe.delete()
|
||||||
|
|
||||||
flash("Groupe supprimé.")
|
flash("Groupe supprimé.")
|
||||||
return redirect("/albums")
|
return redirect("/albums")
|
||||||
@ -163,7 +162,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_req(groupe_uuid):
|
def create_album(groupe_uuid):
|
||||||
try:
|
try:
|
||||||
groupe = Groupe(uuid=groupe_uuid)
|
groupe = Groupe(uuid=groupe_uuid)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
@ -182,7 +181,18 @@ def create_album_req(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:
|
||||||
uuid = utils.create_album(name)
|
while True:
|
||||||
|
try:
|
||||||
|
uuid = new_uuid()
|
||||||
|
|
||||||
|
db.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO album (uuid, name)
|
||||||
|
VALUES (?, ?)
|
||||||
|
""",
|
||||||
|
(uuid, name),
|
||||||
|
)
|
||||||
|
db.commit()
|
||||||
album = Album(uuid=uuid)
|
album = Album(uuid=uuid)
|
||||||
|
|
||||||
db.execute(
|
db.execute(
|
||||||
@ -194,6 +204,10 @@ def create_album_req(groupe_uuid):
|
|||||||
)
|
)
|
||||||
db.commit()
|
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 {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
@ -215,14 +229,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=utils.format_uuid(groupe_uuid))
|
groupe = Groupe(uuid=format_uuid(groupe_uuid))
|
||||||
return redirect(f"/groupe/{utils.format_uuid(groupe_uuid)}/{album_uuid}")
|
return redirect(f"/groupe/{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 = utils.format_uuid(album_uuid)
|
album_uuid = 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}")
|
||||||
@ -255,4 +269,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 utils.get_qrcode(f"/groupe/{groupe_uuid}/{album_uuid}")
|
return get_qrcode(f"/groupe/{groupe_uuid}/{album_uuid}")
|
||||||
|
@ -4,8 +4,7 @@ Partition module
|
|||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from flask import (Blueprint, abort, send_file, render_template,
|
from flask import Blueprint, abort, send_file, render_template, request, redirect, flash, session
|
||||||
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
|
||||||
@ -22,11 +21,9 @@ def get_partition(uuid):
|
|||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
|
||||||
return send_file(os.path.join(
|
return send_file(
|
||||||
current_app.instance_path,
|
os.path.join("partitions", f"{uuid}.pdf"),
|
||||||
"partitions",
|
download_name = f"{partition.name}.pdf"
|
||||||
f"{uuid}.pdf"
|
|
||||||
), download_name = f"{partition.name}.pdf"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@bp.route("/<uuid>/attachments")
|
@bp.route("/<uuid>/attachments")
|
||||||
@ -47,6 +44,7 @@ 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:
|
||||||
@ -54,7 +52,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 current_appartient pas")
|
flash("Cette partition ne vous appartient pas")
|
||||||
return redirect(request.referrer)
|
return redirect(request.referrer)
|
||||||
|
|
||||||
error = None # À mettre au propre
|
error = None # À mettre au propre
|
||||||
@ -68,6 +66,7 @@ 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]
|
||||||
@ -82,7 +81,6 @@ 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)
|
||||||
@ -93,11 +91,7 @@ def add_attachment(uuid):
|
|||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
file = request.files["file"]
|
file = request.files["file"]
|
||||||
file.save(os.path.join(
|
file.save(f"partitioncloud/attachments/{attachment_uuid}.{ext}")
|
||||||
current_app.instance_path,
|
|
||||||
"attachments",
|
|
||||||
f"{attachment_uuid}.{ext}"
|
|
||||||
))
|
|
||||||
break
|
break
|
||||||
|
|
||||||
except db.IntegrityError:
|
except db.IntegrityError:
|
||||||
@ -121,11 +115,9 @@ def get_attachment(uuid, filetype):
|
|||||||
|
|
||||||
assert filetype == attachment.filetype
|
assert filetype == attachment.filetype
|
||||||
|
|
||||||
return send_file(os.path.join(
|
return send_file(
|
||||||
current_app.instance_path,
|
os.path.join("attachments", f"{uuid}.{attachment.filetype}"),
|
||||||
"attachments",
|
download_name = f"{attachment.name}.{attachment.filetype}"
|
||||||
f"{uuid}.{attachment.filetype}"
|
|
||||||
), download_name = f"{attachment.name}.{attachment.filetype}"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -232,7 +224,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(current_app.instance_path)
|
partition.delete()
|
||||||
|
|
||||||
flash("Partition supprimée.")
|
flash("Partition supprimée.")
|
||||||
return redirect("/albums")
|
return redirect("/albums")
|
||||||
@ -254,13 +246,7 @@ 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, instance_path):
|
def download_search_result(element):
|
||||||
uuid = element["uuid"]
|
uuid = element["uuid"]
|
||||||
url = element["url"]
|
url = element["url"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
urllib.request.urlretrieve(url, f"{instance_path}/search-partitions/{uuid}.pdf")
|
urllib.request.urlretrieve(url, f"partitioncloud/search-partitions/{uuid}.pdf")
|
||||||
|
|
||||||
except (urllib.error.HTTPError, urllib.error.URLError):
|
except (urllib.error.HTTPError, urllib.error.URLError):
|
||||||
with open(f"{instance_path}/search-partitions/{uuid}.pdf", 'a', encoding="utf8") as _:
|
with open(f"partitioncloud/search-partitions/{uuid}.pdf", 'a', encoding="utf8") as _:
|
||||||
pass # Create empty file
|
pass # Create empty file
|
||||||
|
|
||||||
|
|
||||||
def online_search(query, num_queries, instance_path):
|
def online_search(query, num_queries):
|
||||||
"""
|
"""
|
||||||
Renvoie les 3 résultats les plus pertinents depuis google
|
Renvoie les 3 résultats les plus pertinents depuis google
|
||||||
"""
|
"""
|
||||||
@ -103,12 +103,7 @@ def online_search(query, num_queries, instance_path):
|
|||||||
except urllib.error.URLError: # Unable to access network
|
except urllib.error.URLError: # Unable to access network
|
||||||
return []
|
return []
|
||||||
|
|
||||||
threads = [
|
threads = [threading.Thread(target=download_search_result, args=(elem,)) for elem in partitions]
|
||||||
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()
|
||||||
@ -116,10 +111,10 @@ def online_search(query, num_queries, instance_path):
|
|||||||
for thread in threads:
|
for thread in threads:
|
||||||
thread.join()
|
thread.join()
|
||||||
|
|
||||||
for element in partitions.copy():
|
for element in partitions:
|
||||||
uuid = element["uuid"]
|
uuid = element["uuid"]
|
||||||
url = element["url"]
|
url = element["url"]
|
||||||
if os.stat(f"{instance_path}/search-partitions/{uuid}.pdf").st_size == 0:
|
if os.stat(f"partitioncloud/search-partitions/{uuid}.pdf").st_size == 0:
|
||||||
print("An error occured", url)
|
print("An error occured", url)
|
||||||
db.execute(
|
db.execute(
|
||||||
"""
|
"""
|
||||||
@ -130,14 +125,14 @@ def online_search(query, num_queries, instance_path):
|
|||||||
)
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
os.remove(f"{instance_path}/search-partitions/{uuid}.pdf")
|
os.remove(f"partitioncloud/search-partitions/{uuid}.pdf")
|
||||||
|
|
||||||
partitions.remove(element)
|
partitions.remove(element)
|
||||||
|
|
||||||
return partitions
|
return partitions
|
||||||
|
|
||||||
|
|
||||||
def flush_cache(instance_path):
|
def flush_cache():
|
||||||
"""
|
"""
|
||||||
Supprimer les résultats de recherche datant de plus de 15 minutes
|
Supprimer les résultats de recherche datant de plus de 15 minutes
|
||||||
"""
|
"""
|
||||||
@ -151,7 +146,7 @@ def flush_cache(instance_path):
|
|||||||
for element in expired_cache:
|
for element in expired_cache:
|
||||||
uuid = element["uuid"]
|
uuid = element["uuid"]
|
||||||
try:
|
try:
|
||||||
os.remove(f"{instance_path}/search-partitions/{uuid}.pdf")
|
os.remove(f"partitioncloud/search-partitions/{uuid}.pdf")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
|
@ -29,7 +29,6 @@ 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,5 +1,4 @@
|
|||||||
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
|
||||||
@ -143,21 +142,3 @@ 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,7 +33,6 @@ 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)])
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -87,10 +86,10 @@ def backup_instance(version, verbose=True):
|
|||||||
os.path.join(dest, "search-partitions"),
|
os.path.join(dest, "search-partitions"),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
for src, dst in paths: # Only the first one exists after v1.5.0
|
for src, dst in paths:
|
||||||
if os.path.exists(src):
|
if os.path.exists(src):
|
||||||
print_verbose(f"\tBacking up {src}")
|
print_verbose(f"\tBacking up {src}")
|
||||||
shutil.copytree(src, dst)
|
shutil.copy_tree(src, dst)
|
||||||
|
|
||||||
|
|
||||||
def print_hooks(hooks_list):
|
def print_hooks(hooks_list):
|
||||||
@ -109,7 +108,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)
|
||||||
@ -169,13 +168,13 @@ def restore(version):
|
|||||||
os.path.join(dest, "search-partitions"),
|
os.path.join(dest, "search-partitions"),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
for src, dst in paths: # Only the first one exists after v1.5.0
|
for src, dst in paths:
|
||||||
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.copytree(dst, src)
|
shutil.copy_tree(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…
x
Reference in New Issue
Block a user