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""
+ return f""
class InvalidResourceIssueBody(Exception):
@@ -70,7 +69,7 @@ def __init__(self, api_response):
self.__class__ = GithubIssue
def __repr__(self):
- return f""
+ return f""
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())