feat: add availability check
This commit is contained in:
93
src/app.py
93
src/app.py
@@ -35,12 +35,13 @@ komga = KOMGAPI(
|
|||||||
username=settings.komga.user,
|
username=settings.komga.user,
|
||||||
password=settings.komga.password,
|
password=settings.komga.password,
|
||||||
)
|
)
|
||||||
|
cat = Nyaa()
|
||||||
# komga_series = komga.seriesList()
|
# komga_series = komga.seriesList()
|
||||||
|
|
||||||
|
|
||||||
@limit(limit=1, every=2)
|
@limit(limit=1, every=2)
|
||||||
async def fetch_data(
|
async def fetch_data(
|
||||||
inputdata: Dict[str, Any], check_downloads: bool = False
|
inputdata: Dict[str, Any], check_downloads: int = 0
|
||||||
) -> List[Dict[str, Any]]:
|
) -> List[Dict[str, Any]]:
|
||||||
log.error(f"fetch_data called with data: {inputdata}")
|
log.error(f"fetch_data called with data: {inputdata}")
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
@@ -92,36 +93,41 @@ async def fetch_data(
|
|||||||
args={"id": manga.id},
|
args={"id": manga.id},
|
||||||
)
|
)
|
||||||
komga_request = bool(requested)
|
komga_request = bool(requested)
|
||||||
results.append(
|
|
||||||
{
|
result_data: dict[str, Any] = {
|
||||||
"id": manga.id,
|
"id": manga.id,
|
||||||
"title": manga.title.english
|
"title": manga.title.english
|
||||||
if manga.title.english
|
if manga.title.english
|
||||||
else manga.title.romaji,
|
else manga.title.romaji,
|
||||||
"image": manga.coverImage.get("large")
|
"image": manga.coverImage.get("large")
|
||||||
if manga.coverImage
|
if manga.coverImage
|
||||||
else "https://demofree.sirv.com/nope-not-here.jpg",
|
else "https://demofree.sirv.com/nope-not-here.jpg",
|
||||||
"status": manga.status,
|
"status": manga.status,
|
||||||
"type": manga.format,
|
"type": manga.format,
|
||||||
"genres": manga.genres or [],
|
"genres": manga.genres or [],
|
||||||
"tags": [tag.name for tag in (manga.tags or [])],
|
"tags": [tag.name for tag in (manga.tags or [])],
|
||||||
"description": manga.description.replace("<br>", "\n")
|
"description": manga.description.replace("<br>", "\n")
|
||||||
if manga.description
|
if manga.description
|
||||||
else "No description available",
|
else "No description available",
|
||||||
"isAdult": manga.isAdult,
|
"isAdult": manga.isAdult,
|
||||||
"in_komga": in_komga,
|
"in_komga": in_komga,
|
||||||
"requested": komga_request,
|
"requested": komga_request,
|
||||||
"siteUrl": manga.siteUrl,
|
"siteUrl": manga.siteUrl,
|
||||||
}
|
}
|
||||||
)
|
|
||||||
if check_downloads:
|
results.append(result_data)
|
||||||
for result in results:
|
# async check for available downloads
|
||||||
downloads = Nyaa().search(result.get("title"), 3, 1)
|
|
||||||
else:
|
|
||||||
downloads = []
|
|
||||||
result["download"] = len(downloads) if downloads else 0
|
|
||||||
|
|
||||||
log.debug(f"Fetched {len(results)} results for query: {inputdata['query']}")
|
log.debug(f"Fetched {len(results)} results for query: {inputdata['query']}")
|
||||||
|
if check_downloads == 1:
|
||||||
|
for manga in results:
|
||||||
|
log.debug(f"Checking downloads for manga: {manga['title']}")
|
||||||
|
search_query = manga["title"]
|
||||||
|
search_results = cat.search(search_query, 3, 1)
|
||||||
|
manga["downloads"] = (
|
||||||
|
len(search_results) if isinstance(search_results, list) else 0
|
||||||
|
)
|
||||||
|
log.debug(f"Downloads for {manga['title']}: {manga['downloads']}")
|
||||||
log.error(f"Results: {results}")
|
log.error(f"Results: {results}")
|
||||||
return results
|
return results
|
||||||
except ValueError as ve:
|
except ValueError as ve:
|
||||||
@@ -247,7 +253,10 @@ async def get_tags():
|
|||||||
async def search():
|
async def search():
|
||||||
data = await request.get_json()
|
data = await request.get_json()
|
||||||
print(data)
|
print(data)
|
||||||
results = await fetch_data(data)
|
# in data replace bool value for check_downloads with 1 or 0
|
||||||
|
if "check_downloads" in data:
|
||||||
|
data["check_downloads"] = 1 if data["check_downloads"] is True else 0
|
||||||
|
results = await fetch_data(data, check_downloads=data.get("check_downloads", 0))
|
||||||
if not results:
|
if not results:
|
||||||
return jsonify({"error": "No results found"}), 404
|
return jsonify({"error": "No results found"}), 404
|
||||||
return jsonify(results)
|
return jsonify(results)
|
||||||
@@ -358,9 +367,23 @@ async def delete_request():
|
|||||||
return jsonify({"status": "failed"}), 400
|
return jsonify({"status": "failed"}), 400
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
log.info("Starting Komga Manga Grabber API")
|
import sys
|
||||||
# use hypercorn to run the app
|
|
||||||
import uvicorn
|
|
||||||
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=5001)
|
log.info("Starting Komga Manga Grabber API")
|
||||||
# run in test mode
|
if len(sys.argv) > 1:
|
||||||
|
if sys.argv[1] == "test":
|
||||||
|
log.info("Running in test mode")
|
||||||
|
# run in test mode
|
||||||
|
app.run(debug=True, host="0.0.0.0", port=5001)
|
||||||
|
elif sys.argv[1] == "prod":
|
||||||
|
log.info("Running in production mode")
|
||||||
|
# run in production mode
|
||||||
|
log.info("Starting Komga Manga Grabber API")
|
||||||
|
# use hypercorn to run the app
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=5001)
|
||||||
|
# run in test mode
|
||||||
|
else:
|
||||||
|
log.info("No arguments provided, running in default mode")
|
||||||
|
app.run(debug=True, host="0.0.0.0", port=5000)
|
||||||
|
|||||||
@@ -52,6 +52,10 @@
|
|||||||
<input type="checkbox" id="toggleNovels" checked />
|
<input type="checkbox" id="toggleNovels" checked />
|
||||||
Show Novels
|
Show Novels
|
||||||
</label>
|
</label>
|
||||||
|
<label style="margin-left: 1em;">
|
||||||
|
<input type="checkbox" id="checkAvailability" />
|
||||||
|
Check Availability
|
||||||
|
</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -271,13 +275,14 @@
|
|||||||
const selectedGenres = document.getElementById("genreInput").value.split(',').map(v => v.trim()).filter(v => v);
|
const selectedGenres = document.getElementById("genreInput").value.split(',').map(v => v.trim()).filter(v => v);
|
||||||
const selectedTags = document.getElementById("tagInput").value.split(',').map(v => v.trim()).filter(v => v);
|
const selectedTags = document.getElementById("tagInput").value.split(',').map(v => v.trim()).filter(v => v);
|
||||||
const selectedType = document.getElementById("typeSelect").value;
|
const selectedType = document.getElementById("typeSelect").value;
|
||||||
|
const checkDownloads = document.getElementById("checkAvailability").checked; // Get the checkbox value
|
||||||
|
|
||||||
const query = {
|
const query = {
|
||||||
query: searchTerm,
|
query: searchTerm,
|
||||||
genres: selectedGenres,
|
genres: selectedGenres,
|
||||||
tags: selectedTags,
|
tags: selectedTags,
|
||||||
type: selectedType // Include the selected type in the query
|
type: selectedType,
|
||||||
|
check_downloads: checkDownloads // Pass the checkbox value
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadingElement = document.getElementById("loading");
|
const loadingElement = document.getElementById("loading");
|
||||||
@@ -324,6 +329,24 @@
|
|||||||
imageContainer.appendChild(badge);
|
imageContainer.appendChild(badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add download badge if applicable
|
||||||
|
if (result.downloads && document.getElementById("checkAvailability").checked) {
|
||||||
|
const downloadBadge = document.createElement('div');
|
||||||
|
downloadBadge.className = 'download-badge';
|
||||||
|
downloadBadge.textContent = `${result.downloads} Downloads`;
|
||||||
|
downloadBadge.style.position = 'absolute';
|
||||||
|
downloadBadge.style.top = '8px';
|
||||||
|
downloadBadge.style.right = '8px';
|
||||||
|
downloadBadge.style.backgroundColor = 'rgba(0, 0, 255, 0.8)';
|
||||||
|
downloadBadge.style.color = 'white';
|
||||||
|
downloadBadge.style.padding = '4px 8px';
|
||||||
|
downloadBadge.style.fontSize = '12px';
|
||||||
|
downloadBadge.style.fontWeight = 'bold';
|
||||||
|
downloadBadge.style.borderRadius = '4px';
|
||||||
|
downloadBadge.style.zIndex = '1';
|
||||||
|
imageContainer.appendChild(downloadBadge);
|
||||||
|
}
|
||||||
|
|
||||||
const title = document.createElement('p');
|
const title = document.createElement('p');
|
||||||
title.textContent = result.title || 'Untitled';
|
title.textContent = result.title || 'Untitled';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user