abhinavk99 / jikanpy

Python wrapper for the Jikan API
MIT License
217 stars 29 forks source link

[Idea] Random manga/anime suggestion function #96

Closed ghost closed 3 years ago

ghost commented 3 years ago

Hello guys. I have an idea about making some random manga/anime suggest bot. This is my concept. I'm currently improve it, but using random number is kinda risky. Because some time it give me 404 . Can you point me where can i improve , or prevent both 404 siuation?

import random
from jikanpy import Jikan
jikan = Jikan()
# getting random id_number
id_Number = random.randint(1, 10000)
print("Random number = ",id_Number)

try:
    search = jikan.anime(id_Number)
    print("anime")

except:
      print("Becasue 404, i give you another anime")
    id_Number_changed = random.randint(1, 10000)
    search_changed = jikan.anime(id_Number_changed)
    print(search_changed)
purarue commented 3 years ago

Theres a cache of anime IDs I maintain here

In [11]: import random, requests, jikanpy

In [12]: cache = requests.get("https://raw.githubusercontent.com/seanbreckenridge/mal-id-cache/master/cache/anime_cache.json").json()["sfw"]

In [13]: resp = jikanpy.Jikan().anime(random.choice(cache))

In [14]: print(resp["title"], resp["url"])
Mijikamon https://myanimelist.net/anime/25045/Mijikamon

You should still probably handle 404s, since theres a small chance old IDs might still be there, but should be much more accurate than picking randomly

ghost commented 3 years ago

Hey. Thanks for your mal_cache. It working perfectly. Just one thing, does mal_cache will be update automatic?

purarue commented 3 years ago

Uh, you can check the commits here it updates itself every few hours

You'd still have to redownload that file periodically, random code from discord I wrote a while back, which keeps track of when it was last requested for a discord bot;

import datetime, json
data = None
last_requested_at = None
async def update_data():
    global data
    global last_requested_at
    # request if hasnt been requested or its been 6 hours
    if last_requested_at is None or datetime.datetime.now() - last_requested_at > datetime.timedelta(hours=6):
        async with aiohttp.ClientSession() as session:
            async with session.get("https://raw.githubusercontent.com/seanbreckenridge/mal-id-cache/master/cache/anime_cache.json") as s:
                if s.status == 200:
                    text = await s.text()
                    data = json.loads(text)["sfw"]
                    last_updated_at = datetime.datetime.now()

@commands.command()
async def randani(self, ctx):
    await update_data()  # updated the global if its out of date
    id_ = random.choice(data)
    async with session.get(f'https://api.jikan.moe/v3/anime/{id_}') as y:
         if y.status == 200:
....
ghost commented 3 years ago

Oh nooo not async. I'm no experience with async.

purarue commented 3 years ago

Doesnt have to be async, its just an example showing how one would cache the results -- just uses the global data and last_requested_at, and then checks if its expired

if last_requested_at is None or datetime.datetime.now() - last_requested_at > datetime.timedelta(hours=6):

(every 6 hours), and then re-requests the information

Wasnt sure what you meant by 'update automatic'

ghost commented 3 years ago

I'm just confused a bit in this section

@commands.command()
async def randani(self, ctx):
    await update_data()  # updated the global if its out of date
    id_ = random.choice(data)
    async with session.get(f'https://api.jikan.moe/v3/anime/{id_}') as y:
         if y.status == 200:

I know that concept of your work that json will be updated every 6 hours or if no update at the moment. But somehow i'm still confusing above. Why you using session.get(f'https://api.jikan.moe/v3/anime/{id_}') after you request.get(https://raw.githubusercontent.com/seanbreckenridge/mal-id-cache/master/cache/anime_cache.json) already?

abhinavk99 commented 3 years ago

request.get(https://raw.githubusercontent.com/seanbreckenridge/mal-id-cache/master/cache/anime_cache.json) is for storing the cache of anime id's

session.get(f'https://api.jikan.moe/v3/anime/{id_}') is for making the request to the Jikan API using an id found in the cache

purarue commented 3 years ago

request.get(https://raw.githubusercontent.com/seanbreckenridge/mal-id-cache/master/cache/anime_cache.json) grabs the list of IDs from https://github.com/seanbreckenridge/mal-id-cache

The session.get(f'https://api.jikan.moe/v3/anime/{id_}') is to request the anime info from something like https://api.jikan.moe/v3/anime/1

You could use jikanpy there instead, like jikanpy.Jikan().anime(id_)

purarue commented 3 years ago

welp, no user is typing... on github

ghost commented 3 years ago

I start to understand now :). Sorry for make you "confused" . The question "automatically update" i mean, is i want to make my own anime_cache.json. But is will update everytime MAL update new anime/Manga ID . That my goal . Sorry for miss information :(

purarue commented 3 years ago

Easiest way to do that would be to either download the file from here periodically, or have a script like

#!/usr/bin/env bash

# get the current directory
THIS_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"

# change current directory to this one
cd "$THIS_DIR"

# clone the repo if it doesnt exist
if [[ ! -e mal-id-cache ]]; then
  git clone 'https://github.com/seanbreckenridge/mal-id-cache'
fi

cd 'mal-id-cache'

# infinite loop to keep this updated
while true; do
  git pull
  sleep 30m
done

keep a local clone of it updated.

anime_cache.json is created by this repo but you dont have to run that to use it, just use the JSON file - it gets updated whenever MAL adds new Ids

ghost commented 3 years ago

Thanks. I will close this report bug. Thanks for your patience