2021-02-10 23:48:25 +13:00
|
|
|
import os
|
2023-12-08 21:39:11 +13:00
|
|
|
from enum import IntEnum
|
2021-02-10 23:48:25 +13:00
|
|
|
from logging import getLogger
|
2023-09-14 05:40:24 +12:00
|
|
|
from typing import List, Union, Type, Dict
|
2021-02-10 23:48:25 +13:00
|
|
|
|
2021-11-13 02:17:06 +13:00
|
|
|
import qtawesome
|
2021-12-01 08:32:45 +13:00
|
|
|
import requests
|
2021-12-24 22:09:50 +13:00
|
|
|
from PyQt5.QtCore import (
|
|
|
|
QObject,
|
|
|
|
QSettings,
|
|
|
|
QFile,
|
2023-02-08 00:41:59 +13:00
|
|
|
QDir,
|
|
|
|
Qt,
|
2021-12-24 22:09:50 +13:00
|
|
|
)
|
2023-02-08 00:41:59 +13:00
|
|
|
from PyQt5.QtGui import QPalette, QColor, QFontMetrics
|
|
|
|
from PyQt5.QtWidgets import qApp, QStyleFactory, QLabel
|
2023-01-27 02:51:45 +13:00
|
|
|
from PyQt5.sip import wrappertype
|
2021-05-19 21:06:00 +12:00
|
|
|
|
2023-02-08 00:41:59 +13:00
|
|
|
from rare.utils.paths import resources_path
|
2021-05-12 03:29:35 +12:00
|
|
|
|
2021-02-10 23:48:25 +13:00
|
|
|
logger = getLogger("Utils")
|
2021-03-19 00:45:59 +13:00
|
|
|
|
2023-12-08 21:39:11 +13:00
|
|
|
|
|
|
|
class ExitCodes(IntEnum):
|
|
|
|
EXIT = 0
|
|
|
|
LOGOUT = -133742
|
|
|
|
|
|
|
|
|
2023-09-14 05:40:24 +12:00
|
|
|
color_role_map: Dict[int, str] = {
|
2021-05-18 10:56:01 +12:00
|
|
|
0: "WindowText",
|
|
|
|
1: "Button",
|
|
|
|
2: "Light",
|
|
|
|
3: "Midlight",
|
|
|
|
4: "Dark",
|
|
|
|
5: "Mid",
|
|
|
|
6: "Text",
|
|
|
|
7: "BrightText",
|
|
|
|
8: "ButtonText",
|
|
|
|
9: "Base",
|
|
|
|
10: "Window",
|
|
|
|
11: "Shadow",
|
|
|
|
12: "Highlight",
|
|
|
|
13: "HighlightedText",
|
|
|
|
14: "Link",
|
|
|
|
15: "LinkVisited",
|
|
|
|
16: "AlternateBase",
|
|
|
|
# 17: "NoRole",
|
|
|
|
18: "ToolTipBase",
|
|
|
|
19: "ToolTipText",
|
|
|
|
20: "PlaceholderText",
|
|
|
|
# 21: "NColorRoles",
|
|
|
|
}
|
|
|
|
|
2023-09-14 05:40:24 +12:00
|
|
|
color_group_map: Dict[int, str] = {
|
2021-05-18 10:56:01 +12:00
|
|
|
0: "Active",
|
|
|
|
1: "Disabled",
|
|
|
|
2: "Inactive",
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-11-13 02:17:06 +13:00
|
|
|
def load_color_scheme(path: str) -> QPalette:
|
2021-05-22 08:45:33 +12:00
|
|
|
palette = QPalette()
|
2021-10-10 01:15:22 +13:00
|
|
|
scheme = QSettings(path, QSettings.IniFormat)
|
2021-05-18 10:56:01 +12:00
|
|
|
try:
|
2021-10-10 01:15:22 +13:00
|
|
|
scheme.beginGroup("ColorScheme")
|
2021-05-18 10:56:01 +12:00
|
|
|
for g in color_group_map:
|
2021-10-10 01:15:22 +13:00
|
|
|
scheme.beginGroup(color_group_map[g])
|
2021-05-18 10:56:01 +12:00
|
|
|
group = QPalette.ColorGroup(g)
|
|
|
|
for r in color_role_map:
|
|
|
|
role = QPalette.ColorRole(r)
|
2021-10-10 01:15:22 +13:00
|
|
|
color = scheme.value(color_role_map[r], None)
|
2021-05-22 08:45:33 +12:00
|
|
|
if color is not None:
|
|
|
|
palette.setColor(group, role, QColor(color))
|
|
|
|
else:
|
|
|
|
palette.setColor(group, role, palette.color(QPalette.Active, role))
|
2021-10-10 01:15:22 +13:00
|
|
|
scheme.endGroup()
|
|
|
|
scheme.endGroup()
|
2021-05-18 10:56:01 +12:00
|
|
|
except:
|
2021-05-22 08:45:33 +12:00
|
|
|
palette = None
|
|
|
|
return palette
|
2021-05-18 10:56:01 +12:00
|
|
|
|
|
|
|
|
2023-03-04 03:51:26 +13:00
|
|
|
def get_static_style() -> str:
|
|
|
|
file = QFile(":/static_css/stylesheet.qss")
|
|
|
|
file.open(QFile.ReadOnly)
|
|
|
|
static = file.readAll().data().decode("utf-8")
|
|
|
|
file.close()
|
|
|
|
return static
|
|
|
|
|
|
|
|
|
|
|
|
def set_color_pallete(color_scheme: str) -> None:
|
|
|
|
static = get_static_style()
|
|
|
|
|
2021-11-13 02:17:06 +13:00
|
|
|
if not color_scheme:
|
2022-06-19 09:01:56 +12:00
|
|
|
qApp.setStyle(QStyleFactory.create(qApp.property("rareDefaultQtStyle")))
|
|
|
|
qApp.setPalette(qApp.style().standardPalette())
|
2023-03-04 03:51:26 +13:00
|
|
|
qApp.setStyleSheet(static)
|
2021-11-13 02:17:06 +13:00
|
|
|
return
|
2023-03-04 03:51:26 +13:00
|
|
|
|
2022-06-19 09:01:56 +12:00
|
|
|
qApp.setStyle(QStyleFactory.create("Fusion"))
|
2021-12-10 09:59:07 +13:00
|
|
|
custom_palette = load_color_scheme(f":/schemes/{color_scheme}")
|
2021-11-13 02:17:06 +13:00
|
|
|
if custom_palette is not None:
|
2022-06-19 09:01:56 +12:00
|
|
|
qApp.setPalette(custom_palette)
|
2023-03-04 03:51:26 +13:00
|
|
|
qApp.setStyleSheet(static)
|
2022-06-19 09:01:56 +12:00
|
|
|
icon_color = qApp.palette().color(QPalette.Foreground).name()
|
|
|
|
qtawesome.set_defaults(color=icon_color)
|
2021-11-13 02:17:06 +13:00
|
|
|
|
|
|
|
|
|
|
|
def get_color_schemes() -> List[str]:
|
2021-05-18 10:56:01 +12:00
|
|
|
colors = []
|
2021-12-10 09:59:07 +13:00
|
|
|
for file in QDir(":/schemes"):
|
2022-02-01 15:16:29 +13:00
|
|
|
colors.append(file)
|
2021-05-18 10:56:01 +12:00
|
|
|
return colors
|
|
|
|
|
|
|
|
|
2023-03-04 03:51:26 +13:00
|
|
|
def set_style_sheet(style_sheet: str) -> None:
|
|
|
|
static = get_static_style()
|
2023-03-03 02:36:45 +13:00
|
|
|
|
2021-11-13 02:17:06 +13:00
|
|
|
if not style_sheet:
|
2022-06-19 09:01:56 +12:00
|
|
|
qApp.setStyle(QStyleFactory.create(qApp.property("rareDefaultQtStyle")))
|
2023-03-03 02:36:45 +13:00
|
|
|
qApp.setStyleSheet(static)
|
2021-11-13 02:17:06 +13:00
|
|
|
return
|
2023-03-03 02:36:45 +13:00
|
|
|
|
2022-06-19 09:01:56 +12:00
|
|
|
qApp.setStyle(QStyleFactory.create("Fusion"))
|
|
|
|
file = QFile(f":/stylesheets/{style_sheet}/stylesheet.qss")
|
2021-12-10 09:59:07 +13:00
|
|
|
file.open(QFile.ReadOnly)
|
|
|
|
stylesheet = file.readAll().data().decode("utf-8")
|
2023-03-03 02:36:45 +13:00
|
|
|
file.close()
|
|
|
|
qApp.setStyleSheet(stylesheet + static)
|
2021-12-10 09:59:07 +13:00
|
|
|
|
2022-06-19 09:01:56 +12:00
|
|
|
icon_color = qApp.palette().color(QPalette.Text).name()
|
|
|
|
qtawesome.set_defaults(color="#eeeeee")
|
2021-11-13 02:17:06 +13:00
|
|
|
|
|
|
|
|
|
|
|
def get_style_sheets() -> List[str]:
|
2021-05-18 10:56:01 +12:00
|
|
|
styles = []
|
2021-12-10 09:59:07 +13:00
|
|
|
for file in QDir(":/stylesheets/"):
|
|
|
|
styles.append(file)
|
2021-05-18 10:56:01 +12:00
|
|
|
return styles
|
|
|
|
|
|
|
|
|
2021-10-10 01:15:22 +13:00
|
|
|
def get_translations():
|
2021-02-20 00:57:55 +13:00
|
|
|
langs = ["en"]
|
2021-12-11 08:05:51 +13:00
|
|
|
for i in os.listdir(os.path.join(resources_path, "languages")):
|
|
|
|
if i.endswith(".qm") and not i.startswith("qt_"):
|
2021-02-20 00:57:55 +13:00
|
|
|
langs.append(i.split(".")[0])
|
|
|
|
return langs
|
2021-04-07 20:44:16 +12:00
|
|
|
|
|
|
|
|
|
|
|
def get_latest_version():
|
2021-04-20 01:44:28 +12:00
|
|
|
try:
|
2021-12-24 22:09:50 +13:00
|
|
|
resp = requests.get(
|
2023-12-08 21:39:11 +13:00
|
|
|
"https://api.github.com/repos/RareDevs/Rare/releases/latest",
|
|
|
|
timeout=2,
|
2021-12-24 22:09:50 +13:00
|
|
|
)
|
2021-06-12 10:04:09 +12:00
|
|
|
tag = resp.json()["tag_name"]
|
2021-04-20 01:44:28 +12:00
|
|
|
return tag
|
|
|
|
except requests.exceptions.ConnectionError:
|
|
|
|
return "0.0.0"
|
2021-04-12 07:02:56 +12:00
|
|
|
|
|
|
|
|
2023-02-02 11:02:46 +13:00
|
|
|
def path_size(path: Union[str, os.PathLike]) -> int:
|
|
|
|
return sum(
|
|
|
|
os.stat(os.path.join(dp, f)).st_size
|
|
|
|
for dp, dn, filenames in os.walk(path)
|
2023-12-08 21:39:11 +13:00
|
|
|
for f in filenames
|
|
|
|
if os.path.isfile(os.path.join(dp, f))
|
2023-02-02 11:02:46 +13:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2023-03-05 07:56:04 +13:00
|
|
|
def format_size(b: Union[int, float]) -> str:
|
2023-02-19 01:33:42 +13:00
|
|
|
for s in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei"]:
|
2021-04-12 07:02:56 +12:00
|
|
|
if b < 1024:
|
2023-02-19 01:33:42 +13:00
|
|
|
return f"{b:.2f} {s}B"
|
2021-04-12 07:02:56 +12:00
|
|
|
b /= 1024
|
2021-04-14 02:56:44 +12:00
|
|
|
|
|
|
|
|
2022-01-06 03:44:29 +13:00
|
|
|
def icon(icn_str: str, fallback: str = None, **kwargs):
|
|
|
|
try:
|
|
|
|
return qtawesome.icon(icn_str, **kwargs)
|
|
|
|
except Exception as e:
|
|
|
|
if not fallback:
|
2022-02-02 10:29:34 +13:00
|
|
|
logger.warning(f"{e} {icn_str}")
|
2022-01-06 03:44:29 +13:00
|
|
|
if fallback:
|
|
|
|
try:
|
|
|
|
return qtawesome.icon(fallback, **kwargs)
|
|
|
|
except Exception as e:
|
|
|
|
logger.error(str(e))
|
|
|
|
if kwargs.get("color"):
|
|
|
|
kwargs["color"] = "red"
|
|
|
|
return qtawesome.icon("ei.error", **kwargs)
|
2023-01-21 13:15:06 +13:00
|
|
|
|
|
|
|
|
2023-09-14 05:40:24 +12:00
|
|
|
def widget_object_name(widget: Union[QObject, wrappertype, Type], suffix: str) -> str:
|
2023-03-04 01:16:04 +13:00
|
|
|
suffix = f"_{suffix}" if suffix else ""
|
2023-01-27 02:51:45 +13:00
|
|
|
if isinstance(widget, QObject):
|
2023-03-04 01:16:04 +13:00
|
|
|
return f"{type(widget).__name__}{suffix}"
|
2023-03-04 03:51:26 +13:00
|
|
|
elif isinstance(widget, wrappertype) or isinstance(widget, type):
|
2023-03-04 01:16:04 +13:00
|
|
|
return f"{widget.__name__}{suffix}"
|
2023-01-27 02:51:45 +13:00
|
|
|
else:
|
|
|
|
raise RuntimeError(f"Argument {widget} not a QObject or type of QObject")
|
2023-01-25 02:24:50 +13:00
|
|
|
|
|
|
|
|
|
|
|
def elide_text(label: QLabel, text: str) -> str:
|
|
|
|
metrics = QFontMetrics(label.font())
|
2023-01-26 00:04:21 +13:00
|
|
|
return metrics.elidedText(text, Qt.ElideRight, label.sizeHint().width())
|
2023-09-15 23:22:27 +12:00
|
|
|
|
|
|
|
|
|
|
|
def style_hyperlink(link: str, title: str) -> str:
|
|
|
|
return "<a href='{}' style='color: #2980b9; text-decoration:none'>{}</a>".format(link, title)
|