Initial QSfera import
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user