summaryrefslogtreecommitdiff
path: root/tidal_dl_ng/__init__.py
blob: 17739c743bde50bc83680a9623db822ec39843bd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/bin/env python
# Apply mpegdash patch before any tidalapi imports to fix TIDAL manifest parsing
# See: https://github.com/FunWarry/tidal-dl-ng-For-DJ/issues/15
from tidal_dl_ng.helper.mpegdash_patch import apply_mpegdash_patch

apply_mpegdash_patch()

import importlib.metadata
from pathlib import Path
from urllib.parse import urlparse

import requests
import toml

from tidal_dl_ng.constants import REQUESTS_TIMEOUT_SEC
from tidal_dl_ng.model.meta import ProjectInformation, ReleaseLatest


def metadata_project() -> ProjectInformation:
    result: ProjectInformation
    file_path: Path = Path(__file__)
    tmp_result: dict = {}

    paths: list[Path] = [
        file_path.parent,
        file_path.parent.parent,
        file_path.parent.parent.parent,
    ]

    for pyproject_toml_dir in paths:
        pyproject_toml_file: Path = pyproject_toml_dir / "pyproject.toml"

        if pyproject_toml_file.is_file():
            tmp_result = toml.load(pyproject_toml_file)

            break

    if tmp_result:
        result = ProjectInformation(
            version=tmp_result["project"]["version"], repository_url=tmp_result["project"]["urls"]["repository"]
        )
    else:
        try:
            meta_info = importlib.metadata.metadata(name_package())
            repo_url = meta_info["Home-page"]

            if not repo_url:
                urls = meta_info.get_all("Project-URL")
                # attempt to parse, else use hardcoded fallback
                repo_url = next(
                    (url.split(", ")[1] for url in urls if url.startswith("Repository")),
                    "https://github.com/FunWarry/tidal-dl-ng-For-DJ",
                )

            result = ProjectInformation(version=meta_info["Version"], repository_url=repo_url)
        except Exception:
            result = ProjectInformation(version="0.0.0", repository_url="https://anerroroccur.ed/sorry/for/that")

    return result


def version_app() -> str:
    metadata: ProjectInformation = metadata_project()
    version: str = metadata.version

    return version


def repository_url() -> str:
    metadata: ProjectInformation = metadata_project()
    url_repo: str = metadata.repository_url

    return url_repo


def repository_path() -> str:
    url_repo: str = repository_url()
    url_path: str = urlparse(url_repo).path

    return url_path


def latest_version_information() -> ReleaseLatest:
    release_info: ReleaseLatest
    repo_path: str = repository_path()
    url: str = f"https://api.github.com/repos{repo_path}/releases/latest"

    try:
        response = requests.get(url, timeout=REQUESTS_TIMEOUT_SEC)
        release_info_json: dict = response.json()

        release_info = ReleaseLatest(
            version=release_info_json["tag_name"],
            url=release_info_json["html_url"],
            release_info=release_info_json["body"],
        )
    except Exception:
        release_info = ReleaseLatest(
            version="v0.0.0",
            url=url,
            release_info=f"Something went wrong calling {url}. Check your internet connection.",
        )

    return release_info


def name_package() -> str:
    package_name: str = __package__ or __name__

    return package_name


def is_dev_env() -> bool:
    package_name: str = name_package()
    result: bool = False

    # Check if package is running from source code == dev mode
    # If package is not running in Nuitka environment, try to import it from pip libraries.
    # If this also fails, it is dev mode.
    if "__compiled__" not in globals():
        try:
            importlib.metadata.version(package_name)
        except Exception:
            # If package is not installed
            result = True

    return result


def name_app() -> str:
    app_name: str = name_package()
    is_dev: bool = is_dev_env()

    if is_dev:
        app_name += "-dev"

    return app_name


__name_display__ = name_app()
__version__ = version_app()


def update_available() -> tuple[bool, ReleaseLatest]:
    latest_info: ReleaseLatest = latest_version_information()
    version_current: str = f"v{__version__}"

    result = version_current not in [latest_info.version, "v0.0.0"]
    return result, latest_info