Initial QSfera import

This commit is contained in:
Курнат Андрей
2026-06-07 10:20:04 +03:00
commit 2315f25754
16485 changed files with 4826827 additions and 0 deletions
+188
View File
@@ -0,0 +1,188 @@
import os
import re
import shutil
from pathlib import Path
from pypdf import PdfReader
from docx import Document
from pptx import Presentation
from openpyxl import load_workbook
from helpers.ConfigHelper import is_windows, get_config
def build_conflicted_regex(filename):
if "." in filename:
# TODO: improve this for complex filenames
namepart = filename.split(".")[0]
extpart = filename.split(".")[1]
# pylint: disable=anomalous-backslash-in-string
return rf"{namepart} \(conflicted copy \d{{4}}-\d{{2}}-\d{{2}} \d{{6}}\)\.{extpart}"
# pylint: disable=anomalous-backslash-in-string
return rf"{filename} \(conflicted copy \d{{4}}-\d{{2}}-\d{{2}} \d{{6}}\)"
def sanitize_path(path):
return path.replace("//", "/")
def prefix_path_namespace(path):
if is_windows():
# https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#win32-file-namespaces
# disable string parsing
# - long path
# - trailing whitespaces
return f"\\\\?\\{path}"
return path
def can_read(resource):
read = False
try:
with open(resource, encoding="utf-8") as f:
read = True
except:
pass
return read and os.access(resource, os.R_OK)
def can_write(resource):
write = False
try:
with open(resource, "w", encoding="utf-8") as f:
write = True
except:
pass
return write and os.access(resource, os.W_OK)
def read_file_content(file):
with open(file, "r", encoding="utf-8") as f:
content = f.read()
return content
def is_empty_sync_folder(folder):
ignore_files = ["Desktop.ini"]
for item in os.listdir(folder):
# do not count the hidden files as they are ignored by the client
if not item.startswith(".") and not item in ignore_files:
return False
return True
def get_size_in_bytes(size):
match = re.match(r"(\d+)((?: )?[KkMmGgBb]{0,2})?", str(size))
units = ["b", "kb", "mb", "gb"]
multiplier = 1024
if match:
size_num = int(match.group(1))
size_unit = match.group(2)
if not (size_unit := size_unit.lower()):
return size_num
if size_unit in units:
if size_unit == "b":
return size_num
if size_unit == "kb":
return size_num * multiplier
if size_unit == "mb":
return size_num * (multiplier**2)
if size_unit == "gb":
return size_num * (multiplier**3)
raise ValueError("Invalid size: " + size)
def get_file_size(resource_path):
return os.stat(resource_path).st_size
# temp paths created outside the temporary directory during the test
CREATED_PATHS = []
def remember_path(path):
CREATED_PATHS.append(path)
def cleanup_created_paths():
global CREATED_PATHS
for path in CREATED_PATHS:
if os.path.exists(path):
if os.path.isdir(path):
shutil.rmtree(prefix_path_namespace(path))
else:
os.unlink(prefix_path_namespace(path))
CREATED_PATHS = []
def get_file_for_upload(file_name):
base_upload_dir = get_config("files_for_upload")
return os.path.join(base_upload_dir, file_name)
def convert_path_separators_for_os(path):
"""
Convert path separators to match the current operating system.
On Windows, converts forward slashes to backslashes.
On other systems, returns the path unchanged.
"""
if is_windows():
return path.replace("/", "\\")
return path
def get_pdf_content(pdf_file):
reader = PdfReader(pdf_file)
content = ""
for page in reader.pages:
if page_text := page.extract_text():
content += page_text
return content
def get_docs_content(docs_file):
doc = Document(docs_file)
content = "\n".join(p.text for p in doc.paragraphs)
return content
def get_presentation_content(ppt_file):
presentation = Presentation(ppt_file)
text = []
for slide in presentation.slides:
for shape in slide.shapes:
if hasattr(shape, "text"):
text.append(shape.text)
return "\n".join(text)
def get_excel_content(excel_file):
# parse with read_only mode
workbook = load_workbook(excel_file, read_only=True, data_only=True)
text = []
for sheet in workbook.worksheets:
for row in sheet.iter_rows(values_only=True):
for cell in row:
if cell is not None:
text.append(str(cell))
return "\n".join(text)
def get_document_content(document):
content = ""
doc_ext = Path(document).suffix.lower().lstrip(".")
if doc_ext == "pdf":
content = get_pdf_content(document)
elif doc_ext == "docx":
content = get_docs_content(document)
elif doc_ext == "pptx":
content = get_presentation_content(document)
elif doc_ext == "xlsx":
content = get_excel_content(document)
elif doc_ext in ["txt", "md"]:
with open(document, "r", encoding="utf-8") as f:
content = f.read()
else:
raise ValueError(f"Unsupported document format: {doc_ext}")
return content