mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-06-07 11:45:35 +00:00
add utility to remove prod names from track titles
+ move code to handle args and print startup info to other files + update app version number
This commit is contained in:
parent
29e766b60a
commit
509c22c736
113
app/arg_handler.py
Normal file
113
app/arg_handler.py
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
"""
|
||||||
|
Handles arguments passed to the program.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from configparser import ConfigParser
|
||||||
|
import PyInstaller.__main__ as bundler
|
||||||
|
|
||||||
|
from app import settings
|
||||||
|
from app.print_help import HELP_MESSAGE
|
||||||
|
from app.utils import is_windows
|
||||||
|
|
||||||
|
config = ConfigParser()
|
||||||
|
config.read("pyinstaller.config.ini")
|
||||||
|
|
||||||
|
ALLARGS = settings.ALLARGS
|
||||||
|
ARGS = sys.argv[1:]
|
||||||
|
|
||||||
|
|
||||||
|
class HandleArgs:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.handle_build()
|
||||||
|
self.handle_host()
|
||||||
|
self.handle_port()
|
||||||
|
self.handle_no_feat()
|
||||||
|
self.handle_remove_prod()
|
||||||
|
self.handle_help()
|
||||||
|
self.handle_version()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def handle_build():
|
||||||
|
"""
|
||||||
|
Runs Pyinstaller.
|
||||||
|
"""
|
||||||
|
if ALLARGS.build in ARGS:
|
||||||
|
with open("pyinstaller.config.ini", "w", encoding="utf-8") as file:
|
||||||
|
config["DEFAULT"]["BUILD"] = "True"
|
||||||
|
config.write(file)
|
||||||
|
|
||||||
|
_s = ";" if is_windows() else ":"
|
||||||
|
|
||||||
|
bundler.run(
|
||||||
|
[
|
||||||
|
"manage.py",
|
||||||
|
"--onefile",
|
||||||
|
"--name",
|
||||||
|
"swingmusic",
|
||||||
|
"--clean",
|
||||||
|
f"--add-data=assets{_s}assets",
|
||||||
|
f"--add-data=client{_s}client",
|
||||||
|
f"--add-data=pyinstaller.config.ini{_s}.",
|
||||||
|
"-y",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
with open("pyinstaller.config.ini", "w", encoding="utf-8") as file:
|
||||||
|
config["DEFAULT"]["BUILD"] = "False"
|
||||||
|
config.write(file)
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def handle_port():
|
||||||
|
if ALLARGS.port in ARGS:
|
||||||
|
index = ARGS.index(ALLARGS.port)
|
||||||
|
try:
|
||||||
|
port = ARGS[index + 1]
|
||||||
|
except IndexError:
|
||||||
|
print("ERROR: Port not specified")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
try:
|
||||||
|
settings.FLASKVARS.FLASK_PORT = int(port) # type: ignore
|
||||||
|
except ValueError:
|
||||||
|
print("ERROR: Port should be a number")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def handle_host():
|
||||||
|
if ALLARGS.host in ARGS:
|
||||||
|
index = ARGS.index(ALLARGS.host)
|
||||||
|
|
||||||
|
try:
|
||||||
|
host = ARGS[index + 1]
|
||||||
|
except IndexError:
|
||||||
|
print("ERROR: Host not specified")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
settings.FLASKVARS.FLASK_HOST = host # type: ignore
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def handle_no_feat():
|
||||||
|
# if ArgsEnum.no_feat in ARGS:
|
||||||
|
if any((a in ARGS for a in ALLARGS.show_feat)):
|
||||||
|
settings.EXTRACT_FEAT = False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def handle_remove_prod():
|
||||||
|
if any((a in ARGS for a in ALLARGS.show_prod)):
|
||||||
|
settings.REMOVE_PROD = False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def handle_help():
|
||||||
|
if any((a in ARGS for a in ALLARGS.help)):
|
||||||
|
print(HELP_MESSAGE)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def handle_version():
|
||||||
|
if any((a in ARGS for a in ALLARGS.version)):
|
||||||
|
print(settings.APP_VERSION)
|
||||||
|
sys.exit(0)
|
@ -61,17 +61,22 @@ class Track:
|
|||||||
self.og_title = self.title
|
self.og_title = self.title
|
||||||
if self.artist is not None:
|
if self.artist is not None:
|
||||||
artists = utils.split_artists(self.artist)
|
artists = utils.split_artists(self.artist)
|
||||||
|
new_title = self.title
|
||||||
|
|
||||||
if settings.EXTRACT_FEAT:
|
if settings.EXTRACT_FEAT:
|
||||||
featured, new_title = utils.parse_feat_from_title(self.title)
|
featured, new_title = utils.parse_feat_from_title(self.title)
|
||||||
original_lower = "-".join([a.lower() for a in artists])
|
original_lower = "-".join([a.lower() for a in artists])
|
||||||
artists.extend([a for a in featured if a.lower() not in original_lower])
|
artists.extend([a for a in featured if a.lower() not in original_lower])
|
||||||
|
|
||||||
self.title = new_title
|
if settings.REMOVE_PROD:
|
||||||
|
new_title = utils.remove_prod(new_title)
|
||||||
|
|
||||||
|
# if track is a single
|
||||||
if self.og_title == self.album:
|
if self.og_title == self.album:
|
||||||
self.album = new_title
|
self.album = new_title
|
||||||
|
|
||||||
|
self.title = new_title
|
||||||
|
|
||||||
self.artist_hashes = [utils.create_hash(a, decode=True) for a in artists]
|
self.artist_hashes = [utils.create_hash(a, decode=True) for a in artists]
|
||||||
|
|
||||||
self.artist = [Artist(a) for a in artists]
|
self.artist = [Artist(a) for a in artists]
|
||||||
|
18
app/print_help.py
Normal file
18
app/print_help.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from app.settings import ALLARGS
|
||||||
|
|
||||||
|
args = ALLARGS
|
||||||
|
|
||||||
|
HELP_MESSAGE = f"""
|
||||||
|
Usage: swingmusic [options]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
{args.build}: Build the application (in development)
|
||||||
|
{args.host}: Set the host
|
||||||
|
{args.port}: Set the port
|
||||||
|
|
||||||
|
{', '.join(args.show_feat)}: Do not extract featured artists from the song title
|
||||||
|
{', '.join(args.show_prod)}: Do not hide producers in the song title
|
||||||
|
|
||||||
|
{', '.join(args.help)}: Show this help message
|
||||||
|
{', '.join(args.version)}: Show the app version
|
||||||
|
"""
|
@ -28,7 +28,7 @@ def get_xdg_config_dir():
|
|||||||
# ------- HELPER METHODS --------
|
# ------- HELPER METHODS --------
|
||||||
|
|
||||||
|
|
||||||
APP_VERSION = "v.1.1.0.beta"
|
APP_VERSION = "v1.1.0"
|
||||||
|
|
||||||
# paths
|
# paths
|
||||||
XDG_CONFIG_DIR = get_xdg_config_dir()
|
XDG_CONFIG_DIR = get_xdg_config_dir()
|
||||||
@ -76,22 +76,34 @@ USER_DATA_DB_NAME = "userdata.db"
|
|||||||
APP_DB_PATH = os.path.join(APP_DIR, APP_DB_NAME)
|
APP_DB_PATH = os.path.join(APP_DIR, APP_DB_NAME)
|
||||||
USERDATA_DB_PATH = os.path.join(APP_DIR, USER_DATA_DB_NAME)
|
USERDATA_DB_PATH = os.path.join(APP_DIR, USER_DATA_DB_NAME)
|
||||||
|
|
||||||
HELP_MESSAGE = """
|
|
||||||
Usage: swingmusic [options]
|
|
||||||
|
|
||||||
Options:
|
class FLASKVARS:
|
||||||
--build: Build the application
|
FLASK_PORT = 1970
|
||||||
--host: Set the host
|
FLASK_HOST = "localhost"
|
||||||
--port: Set the port
|
|
||||||
--no-feat: Do not extract featured artists from the song title
|
|
||||||
--help, -h: Show this help message
|
class ALLARGS:
|
||||||
--version, -v: Show the version
|
|
||||||
"""
|
"""
|
||||||
|
Enumerates the possible app arguments.
|
||||||
|
"""
|
||||||
|
|
||||||
|
build = "--build"
|
||||||
|
port = "--port"
|
||||||
|
host = "--host"
|
||||||
|
show_feat = ["--show-feat", "-sf"]
|
||||||
|
show_prod = ["--show-prod", "-sp"]
|
||||||
|
help = ["--help", "-h"]
|
||||||
|
version = ["--version", "-v"]
|
||||||
|
|
||||||
|
|
||||||
EXTRACT_FEAT = True
|
EXTRACT_FEAT = True
|
||||||
"""
|
"""
|
||||||
Whether to extract the featured artists from the song title.
|
Whether to extract the featured artists from the song title.
|
||||||
Changed using the `--no-feat` flag
|
"""
|
||||||
|
|
||||||
|
REMOVE_PROD = True
|
||||||
|
"""
|
||||||
|
Whether to remove the producers from the song title.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
51
app/start_info_logger.py
Normal file
51
app/start_info_logger.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from app.utils import get_ip
|
||||||
|
from app.settings import TCOLOR, APP_VERSION, FLASKVARS, APP_DIR
|
||||||
|
from app import settings
|
||||||
|
|
||||||
|
|
||||||
|
def log_startup_info():
|
||||||
|
lines = "------------------------------"
|
||||||
|
# clears terminal 👇
|
||||||
|
os.system("cls" if os.name == "nt" else "echo -e \\\\033c")
|
||||||
|
|
||||||
|
print(lines)
|
||||||
|
print(f"{TCOLOR.HEADER}SwingMusic {APP_VERSION} {TCOLOR.ENDC}")
|
||||||
|
|
||||||
|
adresses = [FLASKVARS.FLASK_HOST]
|
||||||
|
|
||||||
|
if FLASKVARS.FLASK_HOST == "0.0.0.0":
|
||||||
|
adresses = ["localhost", get_ip()]
|
||||||
|
|
||||||
|
print("Started app on:")
|
||||||
|
for address in adresses:
|
||||||
|
# noinspection HttpUrlsUsage
|
||||||
|
print(
|
||||||
|
f"➤ {TCOLOR.OKGREEN}http://{address}:{FLASKVARS.FLASK_PORT}{TCOLOR.ENDC}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(lines)
|
||||||
|
print("\n")
|
||||||
|
|
||||||
|
to_print = [
|
||||||
|
[
|
||||||
|
"Extract featured artists from titles",
|
||||||
|
settings.EXTRACT_FEAT
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"Remove prod. from titles",
|
||||||
|
settings.REMOVE_PROD
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
for item in to_print:
|
||||||
|
print(
|
||||||
|
f"{item[0]}: {TCOLOR.FAIL}{item[1]}{TCOLOR.ENDC}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{TCOLOR.YELLOW}Data folder: {APP_DIR}{TCOLOR.ENDC}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print("\n")
|
25
app/utils.py
25
app/utils.py
@ -279,6 +279,7 @@ def parse_feat_from_title(title: str) -> tuple[list[str], str]:
|
|||||||
|
|
||||||
artists = match.group(1)
|
artists = match.group(1)
|
||||||
artists = split_artists(artists, with_and=True)
|
artists = split_artists(artists, with_and=True)
|
||||||
|
print(artists)
|
||||||
|
|
||||||
# remove "feat" group from title
|
# remove "feat" group from title
|
||||||
new_title = re.sub(regex, "", title, flags=re.IGNORECASE)
|
new_title = re.sub(regex, "", title, flags=re.IGNORECASE)
|
||||||
@ -334,10 +335,26 @@ def parse_title_from_filename(title: str):
|
|||||||
return title
|
return title
|
||||||
|
|
||||||
res = match.group(1)
|
res = match.group(1)
|
||||||
# remove text in brackets starting with "official" case insensitive
|
# remove text in brackets starting with "official" case-insensitive
|
||||||
res = re.sub(r"\s*\([^)]*official[^)]*\)", "", res, flags=re.IGNORECASE)
|
res = re.sub(r"\s*\([^)]*official[^)]*\)", "", res, flags=re.IGNORECASE)
|
||||||
return res.strip()
|
return res.strip()
|
||||||
|
|
||||||
# for title in sample_titles:
|
|
||||||
# print(parse_artist_from_filename(title))
|
def remove_prod(title: str) -> str:
|
||||||
# print(parse_title_from_filename(title))
|
"""
|
||||||
|
Removes the producer string in a track title using regex.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# check if title contain title, if not return it.
|
||||||
|
if not ("prod." in title.lower()):
|
||||||
|
return title
|
||||||
|
|
||||||
|
# check if title has brackets
|
||||||
|
if re.search(r'[()\[\]]', title):
|
||||||
|
regex = r'\s?(\(|\[)prod\..*?(\)|\])\s?'
|
||||||
|
else:
|
||||||
|
regex = r'\s?\bprod\.\s*\S+'
|
||||||
|
|
||||||
|
# remove the producer string
|
||||||
|
title = re.sub(regex, "", title, flags=re.IGNORECASE)
|
||||||
|
return title.strip()
|
||||||
|
165
manage.py
165
manage.py
@ -2,35 +2,22 @@
|
|||||||
This file is used to run the application.
|
This file is used to run the application.
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
from configparser import ConfigParser
|
|
||||||
|
|
||||||
import PyInstaller.__main__ as bundler
|
|
||||||
|
|
||||||
from app import settings
|
|
||||||
from app.api import create_api
|
from app.api import create_api
|
||||||
|
from app.arg_handler import HandleArgs
|
||||||
from app.functions import run_periodic_checks
|
from app.functions import run_periodic_checks
|
||||||
from app.lib.watchdogg import Watcher as WatchDog
|
from app.lib.watchdogg import Watcher as WatchDog
|
||||||
from app.settings import APP_VERSION, HELP_MESSAGE, TCOLOR
|
from app.settings import FLASKVARS
|
||||||
from app.setup import run_setup
|
from app.setup import run_setup
|
||||||
from app.utils import background, get_home_res_path, get_ip, is_windows
|
from app.start_info_logger import log_startup_info
|
||||||
|
from app.utils import background, get_home_res_path
|
||||||
|
|
||||||
werkzeug = logging.getLogger("werkzeug")
|
werkzeug = logging.getLogger("werkzeug")
|
||||||
werkzeug.setLevel(logging.ERROR)
|
werkzeug.setLevel(logging.ERROR)
|
||||||
|
|
||||||
|
|
||||||
class Variables:
|
|
||||||
FLASK_PORT = 1970
|
|
||||||
FLASK_HOST = "localhost"
|
|
||||||
|
|
||||||
|
|
||||||
app = create_api()
|
app = create_api()
|
||||||
app.static_folder = get_home_res_path("client")
|
app.static_folder = get_home_res_path("client")
|
||||||
|
|
||||||
config = ConfigParser()
|
|
||||||
config.read("pyinstaller.config.ini")
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/<path:path>")
|
@app.route("/<path:path>")
|
||||||
def serve_client_files(path):
|
def serve_client_files(path):
|
||||||
@ -48,110 +35,6 @@ def serve_client():
|
|||||||
return app.send_static_file("index.html")
|
return app.send_static_file("index.html")
|
||||||
|
|
||||||
|
|
||||||
ARGS = sys.argv[1:]
|
|
||||||
|
|
||||||
|
|
||||||
class ArgsEnum:
|
|
||||||
"""
|
|
||||||
Enumerates the possible file arguments.
|
|
||||||
"""
|
|
||||||
|
|
||||||
build = "--build"
|
|
||||||
port = "--port"
|
|
||||||
host = "--host"
|
|
||||||
no_feat = "--no-feat"
|
|
||||||
help = ["--help", "-h"]
|
|
||||||
version = ["--version", "-v"]
|
|
||||||
|
|
||||||
|
|
||||||
class HandleArgs:
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.handle_build()
|
|
||||||
self.handle_host()
|
|
||||||
self.handle_port()
|
|
||||||
self.handle_no_feat()
|
|
||||||
self.handle_help()
|
|
||||||
self.handle_version()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def handle_build():
|
|
||||||
"""
|
|
||||||
Runs Pyinstaller.
|
|
||||||
"""
|
|
||||||
if ArgsEnum.build in ARGS:
|
|
||||||
with open("pyinstaller.config.ini", "w", encoding="utf-8") as file:
|
|
||||||
config["DEFAULT"]["BUILD"] = "True"
|
|
||||||
config.write(file)
|
|
||||||
|
|
||||||
_s = ";" if is_windows() else ":"
|
|
||||||
|
|
||||||
bundler.run(
|
|
||||||
[
|
|
||||||
"manage.py",
|
|
||||||
"--onefile",
|
|
||||||
"--name",
|
|
||||||
"swingmusic",
|
|
||||||
"--clean",
|
|
||||||
f"--add-data=assets{_s}assets",
|
|
||||||
f"--add-data=client{_s}client",
|
|
||||||
f"--add-data=pyinstaller.config.ini{_s}.",
|
|
||||||
"-y",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
with open("pyinstaller.config.ini", "w", encoding="utf-8") as file:
|
|
||||||
config["DEFAULT"]["BUILD"] = "False"
|
|
||||||
config.write(file)
|
|
||||||
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def handle_port():
|
|
||||||
if ArgsEnum.port in ARGS:
|
|
||||||
index = ARGS.index(ArgsEnum.port)
|
|
||||||
try:
|
|
||||||
port = ARGS[index + 1]
|
|
||||||
except IndexError:
|
|
||||||
print("ERROR: Port not specified")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
try:
|
|
||||||
Variables.FLASK_PORT = int(port) # type: ignore
|
|
||||||
except ValueError:
|
|
||||||
print("ERROR: Port should be a number")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def handle_host():
|
|
||||||
if ArgsEnum.host in ARGS:
|
|
||||||
index = ARGS.index(ArgsEnum.host)
|
|
||||||
|
|
||||||
try:
|
|
||||||
host = ARGS[index + 1]
|
|
||||||
except IndexError:
|
|
||||||
print("ERROR: Host not specified")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
Variables.FLASK_HOST = host # type: ignore
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def handle_no_feat():
|
|
||||||
if ArgsEnum.no_feat in ARGS:
|
|
||||||
settings.EXTRACT_FEAT = False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def handle_help():
|
|
||||||
if any((a in ARGS for a in ArgsEnum.help)):
|
|
||||||
print(HELP_MESSAGE)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def handle_version():
|
|
||||||
if any((a in ARGS for a in ArgsEnum.version)):
|
|
||||||
print(APP_VERSION)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
@background
|
@background
|
||||||
def run_bg_checks() -> None:
|
def run_bg_checks() -> None:
|
||||||
run_setup()
|
run_setup()
|
||||||
@ -163,41 +46,6 @@ def start_watchdog():
|
|||||||
WatchDog().run()
|
WatchDog().run()
|
||||||
|
|
||||||
|
|
||||||
def log_startup_info():
|
|
||||||
lines = "------------------------------"
|
|
||||||
# clears terminal 👇
|
|
||||||
os.system("cls" if os.name == "nt" else "echo -e \\\\033c")
|
|
||||||
|
|
||||||
print(lines)
|
|
||||||
print(f"{TCOLOR.HEADER}SwingMusic {APP_VERSION} {TCOLOR.ENDC}")
|
|
||||||
|
|
||||||
adresses = [Variables.FLASK_HOST]
|
|
||||||
|
|
||||||
if Variables.FLASK_HOST == "0.0.0.0":
|
|
||||||
adresses = ["localhost", get_ip()]
|
|
||||||
|
|
||||||
print("Started app on:")
|
|
||||||
for address in adresses:
|
|
||||||
# noinspection HttpUrlsUsage
|
|
||||||
print(
|
|
||||||
f"➤ {TCOLOR.OKGREEN}http://{address}:{Variables.FLASK_PORT}{TCOLOR.ENDC}"
|
|
||||||
)
|
|
||||||
|
|
||||||
print(lines)
|
|
||||||
print("\n")
|
|
||||||
|
|
||||||
if not settings.EXTRACT_FEAT:
|
|
||||||
print(
|
|
||||||
f"{TCOLOR.OKBLUE}Extracting featured artists from track titles: {TCOLOR.FAIL}DISABLED!{TCOLOR.ENDC}"
|
|
||||||
)
|
|
||||||
|
|
||||||
print(
|
|
||||||
f"{TCOLOR.OKBLUE}App data folder: {settings.APP_DIR}{TCOLOR.OKGREEN}{TCOLOR.ENDC}"
|
|
||||||
)
|
|
||||||
|
|
||||||
print("\n")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
HandleArgs()
|
HandleArgs()
|
||||||
log_startup_info()
|
log_startup_info()
|
||||||
@ -207,10 +55,9 @@ if __name__ == "__main__":
|
|||||||
app.run(
|
app.run(
|
||||||
debug=False,
|
debug=False,
|
||||||
threaded=True,
|
threaded=True,
|
||||||
host=Variables.FLASK_HOST,
|
host=FLASKVARS.FLASK_HOST,
|
||||||
port=Variables.FLASK_PORT,
|
port=FLASKVARS.FLASK_PORT,
|
||||||
use_reloader=False,
|
use_reloader=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: Find a way to verify the host string
|
|
||||||
# TODO: Organize code in this file: move args to new file, etc.
|
# TODO: Organize code in this file: move args to new file, etc.
|
||||||
|
@ -24,7 +24,7 @@ def test_extract_featured_artists_from_title():
|
|||||||
]
|
]
|
||||||
|
|
||||||
for title, expected in zip(test_titles, results):
|
for title, expected in zip(test_titles, results):
|
||||||
assert parse_feat_from_title(title) == expected
|
assert parse_feat_from_title(title)[0] == expected
|
||||||
|
|
||||||
|
|
||||||
# === HYPOTHESIS GHOSTWRITER TESTS ===
|
# === HYPOTHESIS GHOSTWRITER TESTS ===
|
||||||
|
Loading…
x
Reference in New Issue
Block a user