Giter Site home page Giter Site logo

erkghlerngm44 / aniffinity Goto Github PK

View Code? Open in Web Editor NEW
10.0 2.0 1.0 243 KB

Calculate affinity between AniList, Kitsu and MyAnimeList users

Home Page: https://aniffinity.readthedocs.io

License: MIT License

Python 100.00%
affinity correlation affinity-calculations anilist kitsu myanimelist mal

aniffinity's Introduction

ftb1 ftb2 ftb3

aniffinity

pypi travis rtd

"An-knee-fin-knee-tea".

Calculate affinity between anime list users.

What is this?

Calculate affinity between a user and another user on anime list services. Refer to the docs for more info.

Install

pip install aniffinity

Dependencies

  • json-api-doc
  • requests

Example Usage

from aniffinity import Aniffinity

af = Aniffinity("Xinil", base_service="MyAnimeList")

affinity, shared = af.calculate_affinity("Josh", service="AniList")

print(affinity)
# 32.15230953451651
print(shared)
# 31

Available Services

For more info, read the docs.

Documentation

Documentation at https://aniffinity.readthedocs.io

Licensed under MIT. See LICENSE for more info.

Cat Gif

aniffinity's People

Contributors

erkghlerngm44 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

purplepinapples

aniffinity's Issues

Kitsu support

Re erkghlerngm44/malaffinity#1

It's possible ๐Ÿ˜ฎ

Though I'm having to end up trudging through 68,000+ lines of JSON and pairing:

  • Kitsu IDs to scores
  • Kitsu IDs to mapping ids
  • Kitsu IDs to MAL IDs
  • MAL IDs to scores

in order to get it to work, so it's not going to be fast...

Ah well, once the endpoint is written, adding it in shouldn't be an issue.

Exception messages should resolve user before being raised

Current example:

"Shared rated anime count between xxx and https://myanimelist.net/profile/yyy is less than eleven"

Exception messages that state a users' username (that isn't the "base user") should have the username resolved, with that being returned instead of whatever the user specified (in this case, a URL was specified). The users in the messages should ideally contain the "username" and "service", following something along the lines of: SERVICE:username.

Ideal example:

"Shared rated anime count between ANILIST:xxx and MYANIMELIST:yyy is less than eleven"

Large MyAnimeList lists cause RateLimitExceededError

I modified the code from here:

import time
import aniffinity

time.sleep(2)

success = False

for i in range(5):
    print(i)
    try:
        af = aniffinity.Aniffinity("purplepinapples", base_service="MyAnimeList")
        affinity, shared = af.calculate_affinity("lanblade", service="MyAnimeList")
        print(affinity, shared)
    # Rate limit exceeded. Halt your script and try again
    except aniffinity.exceptions.RateLimitExceededError:
        time.sleep(10)
        continue

    # Any other aniffinity exception.
    # Affinity can't be calculated for some reason.
    # ``AniffinityException`` is the base exception class for
    # all aniffinity exceptions
    except aniffinity.exceptions.AniffinityException:
        break

    # Exceptions not covered by aniffinity. Not sure what
    # you could do here. Feel free to handle however you like
    except Exception as e:
        print("Exception: `{}`".format(e))
        break

    # Success!
    else:
        success = True
        break

The code above fails with a RateLimitExceededError.

Even increasing the time.sleep to over a minute does nothing, since in order to process purplepinapples or lanblade (which I chose because of their length), it takes around 50 load.json requests, meaning its bound to exceed the API limit sometime in this loop.

I have a crude fix on my fork, for which the code above succeeds.

Perhaps accepting an argument in aniffinity.Affinity and aniffinity.calculate_affinity like wait_time that waits between paginated requests?

Allow resolving of username & service as `SERVICE:username`

When #13 goes ahead, it makes sense to allow the username/service to be specified in the above form.

Example:

>>> aniffinity.Aniffinity("ANILIST:erkghlerngm44")
# Aniffinity(base_user="erkghlerngm44", base_service="ANILIST", ...)

Might work by doing a check for a : (or maybe a regex /(?P<service>\w+):(?P<user>[a-z0-9_-]+)/i), splitting into respective values, and recursively passing back into .resolver.resolve_user.

Documentation changes

Things that may need changing in docs:

  • Add in (future) SERVICE:username (#15) support to "Passing Arguments to the Class and its Methods" in Walkthrough page.
  • Move the "For older changes, read the changelog at erkghlerngm44/malaffinity" bit from the Changelog page to the actual changelog in the repo.
  • Figure out why the first six pages in the RTFD PDF output are full of whitespace.
  • Add in note about importing exceptions, into exception handling page.
  • Change code snippet in exception handling page, to denote that the entire snippet should be run for each user (include something like for user in users: and then indent everything else.
  • Move the "Passing Arguments to the Class and its Methods" section to the bottom of the Walkthrough page.
  • Maybe add in .models.User and .models.Affinity to API page.
  • Have all the contribution stuff onto one page instead of spread out in the "Getting Started" and "Package Info" sections.
  • Update the example link in the exception handling page. The current one points to erkghlerngm44/r-anime-soulmate-finder v4.2.0, which uses MALAffinity.
  • Add in more cute gifs.

Make `DEFAULT_SERVICE` supported behaviour

So the package can be restricted to use one service only, so the service won't have to be specified on every request.

Currently it defaults to ANILIST while showing a warning, if no service is specified.

Maybe some examples:

import aniffinity
aniffinity.endpoints.DEFAULT_SERVICE = "MYANIMELIST"
aniffinity.Aniffinity("erkghlerngm44")
...

or possibly specified in the Aniffinity class?

import aniffinity
af = aniffinity.Aniffinity("erkghlerngm44", base_service="ANILIST", ...something)

Or possibly something else?

Test suite needs a complete rewrite

The current test suite is designed to work with MALAffinity.

May be worth deleting the suite for now, and re-adding it when the new one is up and running.

Round affinity values by default to 10dp, instead of no rounding

10dp should be more than enough for most cases, with 2dp probably being the limit between "useful" and "unnecessary padding".

Values beyond 10dp are arguably "unnecessary padding", and have the greatest chance of introducing some form of floating-point error.

This can, of course, be overridden by the user by specifying False for round.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.