Skip to content

Commit

Permalink
refactor: use pathlib
Browse files Browse the repository at this point in the history
  • Loading branch information
sigma67 committed Oct 5, 2024
1 parent 7d8a756 commit 0868e2f
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 29 deletions.
3 changes: 2 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
#
import os
import sys
from pathlib import Path

sys.path.insert(0, os.path.abspath("."))
sys.path.insert(0, Path().resolve().as_posix())
sys.path.insert(0, "../..")
from ytmusicapi import __version__

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ precision = 2
line-length = 110

[tool.ruff.lint]
ignore = [ "F403", "F405", "F821", "E731" ]
ignore = [ "F403", "F405", "F821", "E731", "PTH123" ]
extend-select = [
"I", # isort
"UP", # pyupgrade
"RUF", # ruff
"PTH", # pathlib
]

[tool.mypy]
Expand Down
3 changes: 1 addition & 2 deletions tests/auth/test_oauth.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import os
import tempfile
import time
from pathlib import Path
Expand Down Expand Up @@ -62,7 +61,7 @@ def test_setup_oauth(self, session_mock, json_mock, blank_code, config):
assert OAuthToken.is_oauth(oauth_token)

oauth_file.close()
os.unlink(oauth_filepath)
Path(oauth_file.name).unlink()

def test_oauth_tokens(self, oauth_filepath: str, yt_oauth: YTMusic):
# ensure instance initialized token
Expand Down
3 changes: 0 additions & 3 deletions ytmusicapi/auth/browser.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
import platform
from typing import Optional

Expand All @@ -7,8 +6,6 @@
from ytmusicapi.exceptions import YTMusicError, YTMusicUserError
from ytmusicapi.helpers import *

path = os.path.dirname(os.path.realpath(__file__)) + os.sep


def is_browser(headers: CaseInsensitiveDict) -> bool:
browser_structure = {"authorization", "cookie"}
Expand Down
14 changes: 7 additions & 7 deletions ytmusicapi/auth/oauth/token.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import json
import os
import time
import webbrowser
from dataclasses import dataclass
from pathlib import Path
from typing import Optional

from requests.structures import CaseInsensitiveDict
Expand Down Expand Up @@ -68,8 +68,8 @@ def is_expiring(self) -> bool:
return self.expires_at - int(time.time()) < 60

@classmethod
def from_json(cls, file_path: str) -> "OAuthToken":
if os.path.isfile(file_path):
def from_json(cls, file_path: Path) -> "OAuthToken":
if file_path.is_file():
with open(file_path) as json_file:
file_pack = json.load(json_file)

Expand All @@ -88,7 +88,7 @@ class RefreshingToken(OAuthToken):
credentials: Optional[Credentials] = None

#: protected/property attribute enables auto writing token values to new file location via setter
_local_cache: Optional[str] = None
_local_cache: Optional[Path] = None

def __getattribute__(self, item):
"""access token setter to auto-refresh if it is expiring"""
Expand All @@ -100,11 +100,11 @@ def __getattribute__(self, item):
return super().__getattribute__(item)

@property
def local_cache(self) -> Optional[str]:
def local_cache(self) -> Optional[Path]:
return self._local_cache

@local_cache.setter
def local_cache(self, path: str):
def local_cache(self, path: Path):
"""Update attribute and dump token to new path."""
self._local_cache = path
self.store_token()
Expand All @@ -130,7 +130,7 @@ def prompt_for_token(
ref_token = cls(credentials=credentials, **raw_token)
ref_token.update(ref_token.as_dict())
if to_file:
ref_token.local_cache = to_file
ref_token.local_cache = Path(to_file)
return ref_token

def store_token(self, path: Optional[str] = None) -> None:
Expand Down
16 changes: 8 additions & 8 deletions ytmusicapi/mixins/uploads.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import ntpath
import os
from pathlib import Path
from typing import Optional, Union

import requests
Expand Down Expand Up @@ -212,24 +211,25 @@ def upload_song(self, filepath: str) -> Union[ResponseStatus, requests.Response]
self._check_auth()
if not self.auth_type == AuthType.BROWSER:
raise YTMusicUserError("Please provide browser authentication before using this function")
if not os.path.isfile(filepath):
fp = Path(filepath)
if not fp.is_file():
raise YTMusicUserError("The provided file does not exist.")

supported_filetypes = ["mp3", "m4a", "wma", "flac", "ogg"]
if os.path.splitext(filepath)[1][1:] not in supported_filetypes:
if fp.suffix[1:] not in supported_filetypes:
raise YTMusicUserError(
"The provided file type is not supported by YouTube Music. Supported file types are "
+ ", ".join(supported_filetypes)
)

headers = self.headers.copy()
upload_url = f"https://upload.youtube.com/upload/usermusic/http?authuser={headers['x-goog-authuser']}"
filesize = os.path.getsize(filepath)
filesize = fp.stat().st_size
if filesize >= 314572800: # 300MB in bytes
msg = f"File {filepath} has size {filesize} bytes, which is larger than the limit of 300MB"
msg = f"File {fp} has size {filesize} bytes, which is larger than the limit of 300MB"
raise YTMusicUserError(msg)

body = ("filename=" + ntpath.basename(filepath)).encode("utf-8")
body = ("filename=" + fp.name).encode("utf-8")
headers.pop("content-encoding", None)
headers["content-type"] = "application/x-www-form-urlencoded;charset=utf-8"
headers["X-Goog-Upload-Command"] = "start"
Expand All @@ -239,7 +239,7 @@ def upload_song(self, filepath: str) -> Union[ResponseStatus, requests.Response]
headers["X-Goog-Upload-Command"] = "upload, finalize"
headers["X-Goog-Upload-Offset"] = "0"
upload_url = response.headers["X-Goog-Upload-URL"]
with open(filepath, "rb") as file:
with open(fp, "rb") as file:
response = requests.post(upload_url, data=file, headers=headers, proxies=self.proxies)

if response.status_code == 200:
Expand Down
13 changes: 6 additions & 7 deletions ytmusicapi/ytmusic.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import gettext
import json
import locale
import os
import time
from contextlib import suppress
from functools import partial
from pathlib import Path
from typing import Optional, Union

import requests
Expand Down Expand Up @@ -121,12 +121,11 @@ def __init__(
self.oauth_credentials = (
oauth_credentials if oauth_credentials is not None else OAuthCredentials()
)
auth_filepath: Optional[str] = None
auth_path: Optional[Path] = None
if isinstance(self.auth, str):
auth_str: str = self.auth
if os.path.isfile(auth_str):
with open(auth_str) as json_file:
auth_filepath = auth_str
if (auth_path := Path(auth_str)).is_file():
with open(auth_path) as json_file:
input_json = json.load(json_file)
else:
input_json = json.loads(auth_str)
Expand All @@ -137,7 +136,7 @@ def __init__(

if OAuthToken.is_oauth(self._input_dict):
self._token = RefreshingToken(
credentials=self.oauth_credentials, _local_cache=auth_filepath, **self._input_dict
credentials=self.oauth_credentials, _local_cache=auth_path, **self._input_dict
)
self.auth_type = AuthType.OAUTH_CUSTOM_CLIENT if oauth_credentials else AuthType.OAUTH_DEFAULT

Expand All @@ -161,7 +160,7 @@ def __init__(
with suppress(locale.Error):
locale.setlocale(locale.LC_ALL, "en_US.UTF-8")

locale_dir = os.path.abspath(os.path.dirname(__file__)) + os.sep + "locales"
locale_dir = Path(__file__).parent.resolve() / "locales"
self.lang = gettext.translation("base", localedir=locale_dir, languages=[language])
self.parser = Parser(self.lang)

Expand Down

0 comments on commit 0868e2f

Please sign in to comment.