diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 32f45dc..9af48f0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,18 +7,18 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.14 + rev: v0.16.5 hooks: - id: ruff args: [--fix, --show-fixes] - id: ruff-format - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.37.2 + rev: 0.38.0 hooks: - id: check-github-workflows - id: check-github-actions - repo: https://github.com/rbubley/mirrors-prettier # Update mirror as official mirror is deprecated - rev: v3.8.3 + rev: v3.9.6 hooks: - id: prettier args: [--write] # edit files in-place diff --git a/scripts/collate.py b/scripts/collate.py index d95fb45..fee901c 100644 --- a/scripts/collate.py +++ b/scripts/collate.py @@ -3,8 +3,9 @@ This script is placed here for future reference in case another collation is needed. """ +from dataclasses import asdict, dataclass, field + import pandas as pd -from dataclasses import dataclass, asdict, field import yaml # Obtaining the data diff --git a/scripts/discord_integration.py b/scripts/discord_integration.py index 8cf7dfa..e94fb1f 100644 --- a/scripts/discord_integration.py +++ b/scripts/discord_integration.py @@ -1,8 +1,9 @@ -from loguru import logger import argparse -import requests from copy import deepcopy +import requests +from loguru import logger + # Discord char limits https://www.pythondiscord.com/pages/guides/python-guides/discord-embed-limits/ CHAR_LIMITS = { "embed_title": 256, diff --git a/scripts/get_og_previews.py b/scripts/get_og_previews.py index 59cdb22..84ca45e 100644 --- a/scripts/get_og_previews.py +++ b/scripts/get_og_previews.py @@ -3,11 +3,11 @@ from pathlib import Path from urllib.request import Request, urlopen +import httpx +import validators import yaml from bs4 import BeautifulSoup from loguru import logger -import validators -import httpx from PIL import Image, UnidentifiedImageError RESOURCES_FILE = Path("data") / "resources.yml" diff --git a/scripts/onboarding.py b/scripts/onboarding.py index 8318d9b..e8021c4 100644 --- a/scripts/onboarding.py +++ b/scripts/onboarding.py @@ -9,16 +9,15 @@ changes you need to before running. """ -import requests -import yaml -from loguru import logger import re -from urllib.parse import urlparse -from typing import List from datetime import datetime -import pytz from pathlib import Path +from urllib.parse import urlparse +import pytz +import requests +import yaml +from loguru import logger RESOURCE_ISSUE_PATTERN = r"""###\sResource\stitle\s* (?P.+?)\s* @@ -52,7 +51,7 @@ def __str__(self): return f"Issue {self.issue_number}: {self.issue_title} by {self.author} - {self.issue_url}" def __repr__(self): - return f"<GithubIssue issue_number={self.issue_number}, issue_title={repr(self.issue_title)}, author={repr(self.author)}, issue_url={repr(self.issue_url)}>" + return f"<GithubIssue issue_number={self.issue_number}, issue_title={self.issue_title!r}, author={self.author!r}, issue_url={self.issue_url!r}>" class InvalidResourceIssueBody(Exception): @@ -70,7 +69,7 @@ def __init__(self, api_response): self.__class__ = GithubIssue def __repr__(self): - return f"<ResourceIssue issue_number={self.issue_number}, issue_title={repr(self.issue_title)}, author={repr(self.author)}, issue_url={repr(self.issue_url)}>" + return f"<ResourceIssue issue_number={self.issue_number}, issue_title={self.issue_title!r}, author={self.author!r}, issue_url={self.issue_url!r}>" def get_resource_dict(self): """Returns dict for resource according to data/resources.yml schema.""" @@ -98,10 +97,9 @@ def parse_body(self, issue_body): raise InvalidResourceIssueBody("Resource description must be one line.") else: raise InvalidResourceIssueBody("Regex parsing of issue body failed.") - return -def resource_is_duplicated(issues: List[ResourceIssue]): +def resource_is_duplicated(issues: list[ResourceIssue]): """ Checks if the resource already exists in the database. @@ -158,7 +156,7 @@ def get_tl_domain(url): return tl_domain -def get_pr_message(issues: List[ResourceIssue]): +def get_pr_message(issues: list[ResourceIssue]): """ Auto generates the message for the pull request. """ @@ -181,7 +179,7 @@ def get_pr_message(issues: List[ResourceIssue]): return message -def get_all_contributors_message(issues: List[ResourceIssue]): +def get_all_contributors_message(issues: list[ResourceIssue]): # Sorted list of unique authors message = "@all-contributors\n" diff --git a/scripts/resource_converter.py b/scripts/resource_converter.py index c8e0985..c6f2ce2 100644 --- a/scripts/resource_converter.py +++ b/scripts/resource_converter.py @@ -2,13 +2,14 @@ A small utility CLI app to convert Climate Town Knowledge Hub resources between YAML and CSV. """ -import yaml -import pandas as pd -from pathlib import Path +import argparse import json -import jsonschema from copy import deepcopy -import argparse +from pathlib import Path + +import jsonschema +import pandas as pd +import yaml CURRENT_FOLDER = Path(__file__).parent.absolute() ENCODING = "utf-8" @@ -66,7 +67,6 @@ def to_yaml(self, path): yaml.dump( self._data, f, sort_keys=True, width=float("inf"), allow_unicode=True ) - return def __dict__(self): return deepcopy(self._data) diff --git a/scripts/youtube.py b/scripts/youtube.py index 15e65ba..1c6b29c 100644 --- a/scripts/youtube.py +++ b/scripts/youtube.py @@ -3,21 +3,20 @@ """ import argparse -import os -import yaml +import asyncio +import dataclasses +import datetime as dt import json +import os +from dataclasses import dataclass from pathlib import Path -from typing import List -import datetime as dt -import aiohttp -import asyncio -from loguru import logger -from tqdm import tqdm +import aiohttp +import yaml from dotenv import load_dotenv from googleapiclient.discovery import build -from dataclasses import dataclass -import dataclasses +from loguru import logger +from tqdm import tqdm YOUTUBE_CHANNEL_IDS = Path("data") / "youtube_channel_ids.yml" VIDEO_DATA = Path("data") / "video_data.json" @@ -64,15 +63,14 @@ def default(self, o): async def is_youtube_short(video_id: str) -> bool: url = f"https://www.youtube.com/shorts/{video_id}" - async with aiohttp.ClientSession() as session: - async with session.head(url) as response: - is_short = True if response.status == 200 else False - logger.info(f"Checking if {video_id} is a short: {is_short}") - return is_short + async with aiohttp.ClientSession() as session, session.head(url) as response: + is_short = True if response.status == 200 else False + logger.info(f"Checking if {video_id} is a short: {is_short}") + return is_short -async def get_videos_from_channels(channel_ids: List[str], youtube: build): - videos: List[YoutubeVideo] = [] +async def get_videos_from_channels(channel_ids: list[str], youtube: build): + videos: list[YoutubeVideo] = [] pbar = tqdm(channel_ids, desc="Getting videos from channels") for channel_id in channel_ids: @@ -123,11 +121,11 @@ def get_videos_from_channel(channel_id: str, service: build): return response -def save_channel_data(channel_ids: List[str], youtube: build): +def save_channel_data(channel_ids: list[str], youtube: build): """ Uses YouTube API to find the channels, and record data in a JSON file. """ - channels: List[YoutubeChannel] = [] + channels: list[YoutubeChannel] = [] pbar = tqdm(channel_ids, desc="Getting videos from channels") for channel_id in pbar: request = youtube.channels().list(part="snippet,statistics", id=channel_id) @@ -156,10 +154,9 @@ def save_channel_data(channel_ids: List[str], youtube: build): json.dump(channels, f, indent=4, cls=EnhancedJSONEncoder) logger.success(f"Saved video data to {VIDEO_DATA}") - return -async def save_video_data(channel_ids: List[str], youtube: build): +async def save_video_data(channel_ids: list[str], youtube: build): """ Uses the API to find the videos from the channels, and records the data in a JSON file. """ @@ -177,7 +174,6 @@ async def save_video_data(channel_ids: List[str], youtube: build): json.dump(videos, f, indent=4, cls=EnhancedJSONEncoder) logger.success(f"Saved video data to {VIDEO_DATA}") - return async def main(): @@ -214,8 +210,6 @@ async def main(): await save_video_data(channel_ids, youtube) save_channel_data(channel_ids, youtube) - return - if __name__ == "__main__": asyncio.run(main())