mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-12 15:50:01 -08:00
feat: experimental search using fzf reload
This commit is contained in:
@@ -1633,7 +1633,9 @@ def media_actions_menu(
|
||||
return
|
||||
|
||||
relations = relations[1]["data"]["Media"]["relations"] # pyright:ignore
|
||||
relations["nodes"] = [node for node in relations["nodes"] if node.get("type") == "ANIME"]
|
||||
relations["nodes"] = [
|
||||
node for node in relations["nodes"] if node.get("type") == "ANIME"
|
||||
]
|
||||
fastanime_runtime_state.anilist_results_data = {
|
||||
"data": {"Page": {"media": relations["nodes"]}} # pyright:ignore
|
||||
}
|
||||
@@ -1940,6 +1942,8 @@ def _anilist_search(config: "Config", page=1):
|
||||
# TODO: Add filters and other search features
|
||||
if config.use_rofi:
|
||||
search_term = str(Rofi.ask("Search for"))
|
||||
elif config.use_fzf:
|
||||
search_term = fzf.search_for_anime()
|
||||
else:
|
||||
search_term = Prompt.ask("[cyan]Search for[/]")
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from click import clear
|
||||
from rich import print
|
||||
|
||||
from ...cli.utils.tools import exit_app
|
||||
from .scripts import FETCH_ANIME_SCRIPT
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -129,7 +130,7 @@ class FZF:
|
||||
encoding="utf-8",
|
||||
)
|
||||
if not result or result.returncode != 0 or not result.stdout:
|
||||
if result.returncode == 130: # fzf terminated by ctrl-c
|
||||
if result.returncode == 130: # fzf terminated by ctrl-c
|
||||
exit_app()
|
||||
|
||||
print("sth went wrong :confused:")
|
||||
@@ -198,9 +199,50 @@ class FZF:
|
||||
# os.environ["FZF_DEFAULT_OPTS"] = ""
|
||||
return result
|
||||
|
||||
def search_for_anime(self):
|
||||
|
||||
commands = [
|
||||
"--preview",
|
||||
f"{FETCH_ANIME_SCRIPT}fetch_anime_details {{}}",
|
||||
"--prompt",
|
||||
"Search For Anime: ",
|
||||
"--header",
|
||||
"Type to search, results are dynamically loaded, enter to select",
|
||||
"--bind",
|
||||
f"change:reload({FETCH_ANIME_SCRIPT}fetch_anime_for_fzf {{q}})",
|
||||
"--preview-window",
|
||||
"wrap",
|
||||
# "--bind",
|
||||
# f"enter:become(echo {{}})",
|
||||
"--reverse",
|
||||
]
|
||||
|
||||
if not self.FZF_EXECUTABLE:
|
||||
raise Exception("fzf executable not found")
|
||||
os.environ["SHELL"] = "bash"
|
||||
|
||||
result = subprocess.run(
|
||||
[self.FZF_EXECUTABLE, *commands],
|
||||
input="",
|
||||
stdout=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
)
|
||||
if not result or result.returncode != 0 or not result.stdout:
|
||||
if result.returncode == 130: # fzf terminated by ctrl-c
|
||||
exit_app()
|
||||
|
||||
print("sth went wrong :confused:")
|
||||
input("press enter to try again...")
|
||||
clear()
|
||||
clear()
|
||||
|
||||
return result.stdout.strip().split("|")[0].strip()
|
||||
|
||||
|
||||
fzf = FZF()
|
||||
|
||||
if __name__ == "__main__":
|
||||
action = fzf.run([*os.listdir(), "exit"], "Prompt: ", "Header", preview="bat {}")
|
||||
print(action)
|
||||
print(fzf.search_for_anime())
|
||||
exit()
|
||||
|
||||
76
fastanime/libs/fzf/scripts.py
Normal file
76
fastanime/libs/fzf/scripts.py
Normal file
@@ -0,0 +1,76 @@
|
||||
FETCH_ANIME_SCRIPT = r"""
|
||||
fetch_anime_for_fzf() {
|
||||
local search_term="$1"
|
||||
if [ -z "$search_term" ]; then exit 0; fi
|
||||
|
||||
local query='
|
||||
query ($search: String) {
|
||||
Page(page: 1, perPage: 25) {
|
||||
media(search: $search, type: ANIME, sort: [SEARCH_MATCH]) {
|
||||
id
|
||||
title { romaji english }
|
||||
meanScore
|
||||
format
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
'
|
||||
|
||||
local json_payload
|
||||
json_payload=$(jq -n --arg query "$query" --arg search "$search_term" \
|
||||
'{query: $query, variables: {search: $search}}')
|
||||
|
||||
curl --silent \
|
||||
--header "Content-Type: application/json" \
|
||||
--header "Accept: application/json" \
|
||||
--request POST \
|
||||
--data "$json_payload" \
|
||||
https://graphql.anilist.co | \
|
||||
jq -r '.data.Page.media[]? | select(.title.romaji) |
|
||||
"\(.title.english // .title.romaji) | Score: \(.meanScore // "N/A") | ID: \(.id)"'
|
||||
}
|
||||
fetch_anime_details() {
|
||||
local anime_id
|
||||
anime_id=$(echo "$1" | sed -n 's/.*ID: \([0-9]*\).*/\1/p')
|
||||
if [ -z "$anime_id" ]; then echo "Select an item to see details..."; return; fi
|
||||
|
||||
local query='
|
||||
query ($id: Int) {
|
||||
Media(id: $id, type: ANIME) {
|
||||
title { romaji english }
|
||||
description(asHtml: false)
|
||||
genres
|
||||
meanScore
|
||||
episodes
|
||||
status
|
||||
format
|
||||
season
|
||||
seasonYear
|
||||
studios(isMain: true) { nodes { name } }
|
||||
}
|
||||
}
|
||||
'
|
||||
local json_payload
|
||||
json_payload=$(jq -n --arg query "$query" --argjson id "$anime_id" \
|
||||
'{query: $query, variables: {id: $id}}')
|
||||
|
||||
# Fetch and format details for the preview window
|
||||
curl --silent \
|
||||
--header "Content-Type: application/json" \
|
||||
--header "Accept: application/json" \
|
||||
--request POST \
|
||||
--data "$json_payload" \
|
||||
https://graphql.anilist.co | \
|
||||
jq -r '
|
||||
.data.Media |
|
||||
"Title: \(.title.english // .title.romaji)\n" +
|
||||
"Score: \(.meanScore // "N/A") | Episodes: \(.episodes // "N/A")\n" +
|
||||
"Status: \(.status // "N/A") | Format: \(.format // "N/A")\n" +
|
||||
"Season: \(.season // "N/A") \(.seasonYear // "")\n" +
|
||||
"Genres: \(.genres | join(", "))\n" +
|
||||
"Studio: \(.studios.nodes[0].name // "N/A")\n\n" +
|
||||
"\(.description | gsub("<br><br>"; "\n\n") | gsub("<[^>]*>"; "") | gsub("""; "\""))"
|
||||
'
|
||||
}
|
||||
"""
|
||||
Reference in New Issue
Block a user