diff --git a/.gitignore b/.gitignore index 1e78d59..a4b35c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ __pycache__ .idea .vscode -README.md.dev \ No newline at end of file +README.md.dev +venv/ \ No newline at end of file diff --git a/README.md b/README.md index 5a6a3bb..11a18ba 100644 --- a/README.md +++ b/README.md @@ -22,56 +22,61 @@ Simply add this to your README.md ``` -and setup the workflow like this: +and setup the workflow file at `.github/workflows/anilist.yml` like this: ```yml name: AniList readme workflow on: - schedule: - # Runs every hour - - cron: "0 * * * *" - workflow_dispatch: + schedule: + # Runs every hour + - cron: "0 * * * *" + workflow_dispatch: # for manual debuging jobs: - update-readme-with-anilist: - name: Update this repo's README with latest AniList activites - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: AniList readme workflow - uses: pxseu/anilist-readme@v1.4.2 - with: - user_id: YOUR_USER_ID + update-readme-with-anilist: + name: Update this repo's README with latest AniList activites + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: AniList readme workflow + uses: pxseu/anilist-readme@senpai # latest version + with: + user_id: YOUR_USER_ID # or + user_name: YOUR_USER_NAME ``` ## Settings -| Option | Description | Default | Required | -| ----------------- | --------------------------------------------------- | -------------------------------------- | -------- | -| `user_id` | Your AniList user id | "" | `True` | -| `gh_token` | Authorized github token | ${{ github.token }} | `False` | -| `readme_path` | Path to the readme file to edit | "./README.md" | `False` | -| `max_post_count` | A number from 1 to 50 limiting the ammount of posts | "5" | `False` | -| `commit_message` | A message to use when commiting | "Update AniList activity in README.md" | `False` | -| `commit_username` | The username for the commiter | "GitHub Action" | `False` | -| `commit_email` | The email for the commiter | "action@github.com" | `False` | -| `timezone` | Timezone of the list content (e.g. Europe/Berlin) | "UTC" | `False` | -| `date_format` | Date format of the list content (e.g. {D}/{M or MW}/{Y} {h}:{m}) | "{h}:{m} {D} {MW} {Y}" | `False` | - -> Note: I recommend you leave the default `commit_username` and `commit_email` \ +| Option | Description | Default | Required | +| -------------------- | ---------------------------------------------------------------- | -------------------------------------- | -------- | +| `user_id` | Your AniList user id | "" | `True` | +| `user_name` | Your AniList username | "" | `True` | +| `max_post_count` | A number from 1 to 50 limiting the ammount of posts | "5" | `False` | +| `preferred_language` | The language of the list content (e.g. Romaji, English, Native) | "english" | `False` | +| `timezone` | Timezone of the list content (e.g. Europe/Berlin) | "UTC" | `False` | +| `date_format` | Date format of the list content (e.g. {D}/{M or MW}/{Y} {h}:{m}) | "{h}:{m} {D} {MW} {Y}" | `False` | +| `readme_path` | Path to the readme file to edit | "./README.md" | `False` | +| `gh_token` | Authorized github token | ${{ github.token }} | `False` | +| `commit_message` | A message to use when commiting | "Update AniList activity in README.md" | `False` | +| `commit_username` | The username for the commiter | "GitHub Action" | `False` | +| `commit_email` | The email for the commiter | "action@github.com" | `False` | + +> Note: Eiter `user_id` or `user_name` is required! \ +> I recommend you leave the default `commit_username` and `commit_email` \ > For `date_format` months: {M} will result in a number (e.g '3') & {MW} will result in a string (e.g 'March') \ > If you're unsure what's your User ID on AniList follow the quide below -## How to get my user id +## How to get my user ID +If you change your username frequently or you're unsure what your user id is, you can use the AniList API to get it. Head on over to https://anilist.co/graphiql and input the query below and replace `YOUR_USERNAME` with your username. ```gql query { - User(name: "YOUR_USERNAME") { - id - name - } + User(name: "YOUR_USERNAME") { + id + name + } } ``` diff --git a/__main__.py b/__main__.py index 38e3f54..b6444bb 100644 --- a/__main__.py +++ b/__main__.py @@ -1,5 +1,5 @@ from anilist_readme.actions_utils import actions_input, add_secret -from anilist_readme.config import ANILIST_QUERY +from anilist_readme.config import LIST_QUERY, USERNAME_QUERY from anilist_readme.git import git_add_commit_push from anilist_readme.graphql import grapql from anilist_readme.list_activity import ListActivity, validate_language @@ -20,8 +20,10 @@ def main( ): language = validate_language(preferred_language) + user_id = user_id or grapql(USERNAME_QUERY, {"name": user_name})["data"]["User"]["id"] + response = grapql( - ANILIST_QUERY, {"id": int(user_id), "post_count": int(max_post_count)} + LIST_QUERY, {"id": int(user_id), "post_count": int(max_post_count)} ) parsed = [ ListActivity(activity, timezone, language, date_format) @@ -37,7 +39,11 @@ def main( if __name__ == "__main__": readme_path = actions_input("README_PATH", optional=True) or find_readme() - user_id = actions_input("USER_ID", optional=False) or "0" + user_id = actions_input("USER_ID", optional=True) + user_name = actions_input("USER_NAME", optional=True) + + if not user_id and not user_name: + raise ValueError("USER_ID or USER_NAME must be provided") max_post_count = actions_input("MAX_POST_COUNT", optional=True) or "5" commit_message = ( diff --git a/action.yml b/action.yml index 250c0d9..e0981d7 100644 --- a/action.yml +++ b/action.yml @@ -5,8 +5,10 @@ description: "Puts your newest activity from AniList into your readme" inputs: user_id: description: "Your anilist user id" - default: "" - required: true + required: false + user_name: + description: "Your anilist username" + required: false gh_token: description: "GitHub access token with Repo scope" @@ -66,6 +68,7 @@ runs: shell: bash env: INPUT_USER_ID: ${{ inputs.user_id }} + INPUT_USER_NAME: ${{ inputs.user_name }} INPUT_PREFERRED_LANGUAGE: ${{ inputs.preferred_language }} INPUT_MAX_POST_COUNT: ${{ inputs.max_post_count }} INPUT_README_PATH: ${{ inputs.readme_path }} diff --git a/anilist_readme/config.py b/anilist_readme/config.py index 5c2137d..7a40313 100644 --- a/anilist_readme/config.py +++ b/anilist_readme/config.py @@ -1,5 +1,5 @@ ANILIST_ENDPOINT = "https://graphql.anilist.co" -ANILIST_QUERY = """query ($id: Int, $post_count: Int) { +LIST_QUERY = """query ($id: Int, $post_count: Int) { Page(page: 1, perPage: $post_count) { activities(userId: $id, sort: ID_DESC, type: MEDIA_LIST) { ... on ListActivity { @@ -19,6 +19,11 @@ } } }""" +USERNAME_QUERY = """query ($name: String) { + User(name: $name) { + id + } +}""" EMOJI_DICT = {"MANGA_LIST": "📖", "ANIME_LIST": "📺"} diff --git a/anilist_readme/list_activity.py b/anilist_readme/list_activity.py index 22b1513..a81cc89 100644 --- a/anilist_readme/list_activity.py +++ b/anilist_readme/list_activity.py @@ -1,6 +1,5 @@ from datetime import datetime, tzinfo from enum import auto, Enum -from typing import Optional from dateutil import tz from .config import EMOJI_DICT @@ -17,8 +16,8 @@ def validate_language(lang: str) -> Language: Check if the language is valid. """ languages = [x.name for x in Language] - if lang in languages: - return Language[lang] + if lang.lower() in languages: + return Language[lang.lower()] raise ValueError( f"'{lang}'' is not a valid language. Must be: '{', '.join(languages)}'" ) @@ -44,6 +43,7 @@ def __init__( preferred_lang.name if preferred_lang else "english" ] or activity_data["media"]["title"]["romaji"] + or activity_data["media"]["title"]["native"] ) self.url: str = activity_data["media"]["siteUrl"] diff --git a/anilist_readme/readme_actions.py b/anilist_readme/readme_actions.py index e76de13..f94a6f7 100644 --- a/anilist_readme/readme_actions.py +++ b/anilist_readme/readme_actions.py @@ -11,7 +11,7 @@ def find_readme(): Find the readme file in the given current directory. """ logger.info("Searching for the readme file...") - readme_path = None + readme_path = None for root, _, files in walk(".", topdown=True): for file in files: @@ -34,7 +34,7 @@ def open_readme(readme: str) -> "list[str]": """ logger.info(f"Opening readme in '{readme}'") - with open(readme, "r") as file: + with open(readme, "r", encoding="utf-8") as file: opened = file.read() return opened.splitlines() @@ -55,7 +55,7 @@ def update_readme( top_part = "\n".join(readme_content[: start_index + 1]) bottom_part = "\n".join(readme_content[end_index:]) - with open(readme_path, "w") as file: + with open(readme_path, "w", encoding="utf-8") as file: new_content = ( top_part + "\n\n" diff --git a/test.ps1 b/test.ps1 new file mode 100644 index 0000000..8d6bc3f --- /dev/null +++ b/test.ps1 @@ -0,0 +1,16 @@ + + +Write-Output "[TEST_SCRIPT]: Starting the project" +Write-Output "" + +venv/Scripts/python.exe -m unittest + +$env:DEV = $true +$env:INPUT_USER_ID = "889921" +$env:INPUT_GH_TOKEN = "test" +$env:INPUT_PREFERRED_LANGUAGE = "english" +$env:INPUT_TIMEZONE = "UTC" +venv/Scripts/python.exe . + +Write-Output "" +Write-Output "[TEST_SCRIPT]: Done" diff --git a/tests/test_custom_date_format.py b/tests/test_custom_date_format.py index 1662772..5b450b5 100644 --- a/tests/test_custom_date_format.py +++ b/tests/test_custom_date_format.py @@ -1,6 +1,6 @@ import unittest from dateutil import tz -from datetime import datetime, tzinfo +from datetime import datetime from anilist_readme.list_activity import custom_datetime_format @@ -19,7 +19,7 @@ def test_custom_datetime_format_with_tz(self): ) def test_custom_datetime_format_without_tz(self): - date = datetime.utcfromtimestamp(1667059380) + date = datetime.fromtimestamp(1667059380, tz.gettz("UTC")) self.assertEqual( custom_datetime_format(date, "{h}:{m} {D} {MW} {Y}"),