Compare commits
4 Commits
831b3fe38f
..
v0.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 6ad0587246 | |||
| 7a19f9acb7 | |||
| 6c502f94f1 | |||
| e102cfa9c8 |
@@ -1,24 +1,5 @@
|
|||||||
# myice
|
# myice
|
||||||
|
|
||||||
## intro
|
|
||||||
|
|
||||||
Avec tout ça on va aller chercher sur MyIce les planning des gamins et générer
|
|
||||||
les pdf qu'on veut
|
|
||||||
|
|
||||||
## install
|
|
||||||
|
|
||||||
with [uv](https://docs.astral.sh/uv/getting-started/installation/):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
uv tool install --extra-index-url https://gitea.parano.ch/api/packages/herel/pypi/simple/ myice
|
|
||||||
```
|
|
||||||
|
|
||||||
with [pipx](https://pipx.pypa.io/stable/installation/):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
pipx install --extra-index-url https://gitea.parano.ch/api/packages/herel/pypi/simple/ myice
|
|
||||||
```
|
|
||||||
|
|
||||||
## récupérer le schedule
|
## récupérer le schedule
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -29,7 +10,7 @@ myice schedule -o schedule.json
|
|||||||
|
|
||||||
### listing
|
### listing
|
||||||
|
|
||||||
Pour récupérer les event des U13 Elite par example:
|
Pour récupérer les event des U13 Elite par exemple:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
❯ myice search "U13 (Elite)"
|
❯ myice search "U13 (Elite)"
|
||||||
@@ -76,13 +57,3 @@ et pour la convoc d'un entraînement:
|
|||||||
Opening file practice_561855.pdf
|
Opening file practice_561855.pdf
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### AI
|
|
||||||
|
|
||||||
```text
|
|
||||||
❯ myice ai
|
|
||||||
> prochain match u13 top ?
|
|
||||||
< Le prochain match de l'équipe U13 Top se déroulera le dimanche 10 novembre 2024 contre HC Ajoie à la Raffeisen Arena de Porrentruy. Le match débutera à 14h00 et se terminera à 16h15.
|
|
||||||
> et les u13 a ?
|
|
||||||
< Le prochain match de l'équipe U13 A se déroulera le samedi 9 novembre 2024 contre HC Vallorbe à P. du Frézillon, 1337 Vallorbe VD. Le match débutera à 13h00 et se terminera à 15h00. Le prochain match à domicile de l'équipe U13 A se déroulera le dimanche 10 novembre 2024 contre CP Meyrin à Les Vernets, Glace extérieure, 1227 Les Acacias GE. Le match débutera à 13h00 et se terminera à 15h00.
|
|
||||||
```
|
|
||||||
|
|||||||
+14
-83
@@ -12,8 +12,6 @@ import sys
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
from typing import List, Tuple
|
|
||||||
from rl_ai_tools import utils # type: ignore
|
|
||||||
import requests
|
import requests
|
||||||
import typer
|
import typer
|
||||||
|
|
||||||
@@ -33,11 +31,6 @@ class AgeGroup(str, Enum):
|
|||||||
u15a = "U15 (A)"
|
u15a = "U15 (A)"
|
||||||
|
|
||||||
|
|
||||||
class EventType(str, Enum):
|
|
||||||
game = "game"
|
|
||||||
practice = "practice"
|
|
||||||
|
|
||||||
|
|
||||||
def load_cookies(file: str = "cookies.txt") -> requests.cookies.RequestsCookieJar:
|
def load_cookies(file: str = "cookies.txt") -> requests.cookies.RequestsCookieJar:
|
||||||
cookie_jar_file = Path(file)
|
cookie_jar_file = Path(file)
|
||||||
cj_dict = {}
|
cj_dict = {}
|
||||||
@@ -47,9 +40,8 @@ def load_cookies(file: str = "cookies.txt") -> requests.cookies.RequestsCookieJa
|
|||||||
return requests.cookies.cookiejar_from_dict(cj_dict)
|
return requests.cookies.cookiejar_from_dict(cj_dict)
|
||||||
|
|
||||||
|
|
||||||
def save_cookies(file: str = "cookies.txt"):
|
def save_cookies():
|
||||||
cookie_jar_file = Path(file)
|
with open("cookies.txt", "w") as f:
|
||||||
with cookie_jar_file.open("w") as f:
|
|
||||||
f.write(json.dumps(requests.utils.dict_from_cookiejar(session.cookies)))
|
f.write(json.dumps(requests.utils.dict_from_cookiejar(session.cookies)))
|
||||||
|
|
||||||
|
|
||||||
@@ -69,12 +61,10 @@ def get_login(local_file: str = "myice.ini") -> tuple[str, str, int]:
|
|||||||
password = default_config.get("password")
|
password = default_config.get("password")
|
||||||
userid = default_config.getint("userid")
|
userid = default_config.getint("userid")
|
||||||
if not username or not password:
|
if not username or not password:
|
||||||
print(
|
print("Error: please configure username/password in ini file")
|
||||||
"Error: please configure username/password in ini file", file=sys.stderr
|
|
||||||
)
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
print("Error: please configure username/password in ini file", file=sys.stderr)
|
print("Error: please configure username/password in ini file")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return username, password, userid
|
return username, password, userid
|
||||||
|
|
||||||
@@ -128,12 +118,12 @@ def wrapper_session(func):
|
|||||||
session.cookies = load_cookies()
|
session.cookies = load_cookies()
|
||||||
session.cookies.clear_expired_cookies()
|
session.cookies.clear_expired_cookies()
|
||||||
if not session.cookies.get("mih_v3_cookname"):
|
if not session.cookies.get("mih_v3_cookname"):
|
||||||
print("login...", file=sys.stderr)
|
print("login...")
|
||||||
do_login()
|
do_login()
|
||||||
save_cookies()
|
save_cookies()
|
||||||
_, _, userid = get_login()
|
_, _, userid = get_login()
|
||||||
if not userid:
|
if not userid:
|
||||||
print("get userid...", file=sys.stderr)
|
print("get userid...")
|
||||||
userid = get_userid()
|
userid = get_userid()
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
@@ -146,7 +136,7 @@ def get_schedule() -> str:
|
|||||||
global userid
|
global userid
|
||||||
assert session and userid
|
assert session and userid
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
date_start = now
|
date_start = now + datetime.timedelta(days=1)
|
||||||
date_end = date_start + datetime.timedelta(days=7)
|
date_end = date_start + datetime.timedelta(days=7)
|
||||||
r = session.post(
|
r = session.post(
|
||||||
"https://app.myice.hockey/inc/processclubplanning.php",
|
"https://app.myice.hockey/inc/processclubplanning.php",
|
||||||
@@ -217,10 +207,11 @@ def schedule(
|
|||||||
with outfile.open("w") as f:
|
with outfile.open("w") as f:
|
||||||
f.write(schedule)
|
f.write(schedule)
|
||||||
else:
|
else:
|
||||||
|
print("Schedule:", file=sys.stderr)
|
||||||
print(schedule)
|
print(schedule)
|
||||||
|
|
||||||
|
|
||||||
def os_open(file: str) -> None:
|
def open(file: str) -> None:
|
||||||
if os.uname().sysname == "Linux":
|
if os.uname().sysname == "Linux":
|
||||||
os.system(f"xdg-open {file}")
|
os.system(f"xdg-open {file}")
|
||||||
else:
|
else:
|
||||||
@@ -237,7 +228,7 @@ def get_game_pdf(
|
|||||||
"""
|
"""
|
||||||
output_filename = f"game_{game_id}.pdf"
|
output_filename = f"game_{game_id}.pdf"
|
||||||
game_pdf(game_id, Path(output_filename))
|
game_pdf(game_id, Path(output_filename))
|
||||||
os_open(output_filename)
|
open(output_filename)
|
||||||
|
|
||||||
|
|
||||||
@app.command("practice")
|
@app.command("practice")
|
||||||
@@ -249,16 +240,12 @@ def get_practice_pdf(
|
|||||||
"""
|
"""
|
||||||
output_filename = f"practice_{game_id}.pdf"
|
output_filename = f"practice_{game_id}.pdf"
|
||||||
practice_pdf(game_id, Path(output_filename))
|
practice_pdf(game_id, Path(output_filename))
|
||||||
os_open(output_filename)
|
open(output_filename)
|
||||||
|
|
||||||
|
|
||||||
@app.command("search")
|
@app.command("search")
|
||||||
def parse_schedule(
|
def parse_schedule(
|
||||||
age_group: Annotated[AgeGroup | None, typer.Option(...)] = None,
|
age_group: Annotated[AgeGroup, typer.Argument(...)],
|
||||||
event_type_filter: Annotated[
|
|
||||||
EventType | None,
|
|
||||||
typer.Option("--type", help="Only display events of this type"),
|
|
||||||
] = None,
|
|
||||||
schedule_file: Annotated[
|
schedule_file: Annotated[
|
||||||
Path, typer.Option(help="schedule json file to parse")
|
Path, typer.Option(help="schedule json file to parse")
|
||||||
] = Path("schedule.json"),
|
] = Path("schedule.json"),
|
||||||
@@ -268,22 +255,9 @@ def parse_schedule(
|
|||||||
"""
|
"""
|
||||||
with schedule_file.open("r") as f:
|
with schedule_file.open("r") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
# age_group filter
|
for event in [x for x in data if x["agegroup"] == age_group]:
|
||||||
if age_group:
|
# print(json.dumps(event, indent=2))
|
||||||
events = [x for x in data if x["agegroup"] == age_group]
|
|
||||||
else:
|
|
||||||
events = [x for x in data if x["agegroup"] in AgeGroup]
|
|
||||||
# event_type filter
|
|
||||||
if event_type_filter:
|
|
||||||
if event_type_filter.value == EventType.game:
|
|
||||||
events = [x for x in events if "event" in x and x["event"] == "Jeu"]
|
|
||||||
else:
|
|
||||||
events = [x for x in events if "event" not in x or x["event"] == "Jeu"]
|
|
||||||
for event in events:
|
|
||||||
if age_group:
|
|
||||||
raw_title = event["title"].removeprefix(age_group + "\n")
|
raw_title = event["title"].removeprefix(age_group + "\n")
|
||||||
else:
|
|
||||||
raw_title = event["title"]
|
|
||||||
title = " ".join(raw_title.split("\n"))
|
title = " ".join(raw_title.split("\n"))
|
||||||
start = datetime.datetime.fromisoformat(event["start"])
|
start = datetime.datetime.fromisoformat(event["start"])
|
||||||
start_fmt = start.strftime("%H:%M")
|
start_fmt = start.strftime("%H:%M")
|
||||||
@@ -299,48 +273,5 @@ def parse_schedule(
|
|||||||
print(f"{event_type}: {title}\n")
|
print(f"{event_type}: {title}\n")
|
||||||
|
|
||||||
|
|
||||||
@app.command("ai")
|
|
||||||
def check_with_ai(
|
|
||||||
schedule_file: Annotated[
|
|
||||||
Path, typer.Option(help="schedule json file to parse")
|
|
||||||
] = Path("schedule.json"),
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Search through the schedule with natural language using Infomaniak LLM API
|
|
||||||
"""
|
|
||||||
if not utils.init():
|
|
||||||
sys.exit(1)
|
|
||||||
with schedule_file.open("r") as f:
|
|
||||||
schedule_data = json.load(f)
|
|
||||||
schedule_data = [x for x in schedule_data if x["agegroup"] in AgeGroup]
|
|
||||||
for event in schedule_data:
|
|
||||||
event["team"] = event["agegroup"].replace("(", "").replace(")", "")
|
|
||||||
del event["agegroup"]
|
|
||||||
when = datetime.datetime.now().strftime("%d-%m-%Y et il est %H:%M")
|
|
||||||
system = "\n".join(
|
|
||||||
[
|
|
||||||
"Tu es une IA connaissant bien les données suivantes, qui décrivent les match et entraînements d'équipes de hockey sur glace.",
|
|
||||||
f"aujourd'hui, nous sommes le {when}"
|
|
||||||
"attention: ce qu'il y a entre parenthèse après la catégorie est une catégorie à part entière, example, u13 a = U13 (A) et ça correspond aux agegroup",
|
|
||||||
"assure-toi de ne pas confondre les catégories d'age dans tes réponses. ne donne pas une réponse pour la mauvaise équipe",
|
|
||||||
"ne confond pas top, elite, a, prép",
|
|
||||||
"```json",
|
|
||||||
json.dumps(schedule_data),
|
|
||||||
"```",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
history: List[Tuple[str, str]] = []
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
question = input("> ")
|
|
||||||
except EOFError:
|
|
||||||
break
|
|
||||||
answer = utils.llm_inference(
|
|
||||||
question, history, system=system, model="mixtral8x22b"
|
|
||||||
)
|
|
||||||
print("<", answer)
|
|
||||||
history.append((question, answer))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app()
|
app()
|
||||||
|
|||||||
Generated
+4
-24
@@ -874,13 +874,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rich"
|
name = "rich"
|
||||||
version = "13.9.4"
|
version = "13.9.3"
|
||||||
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8.0"
|
python-versions = ">=3.8.0"
|
||||||
files = [
|
files = [
|
||||||
{file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"},
|
{file = "rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283"},
|
||||||
{file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"},
|
{file = "rich-13.9.3.tar.gz", hash = "sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -890,26 +890,6 @@ pygments = ">=2.13.0,<3.0.0"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rl-ai-tools"
|
|
||||||
version = "1.10.1"
|
|
||||||
description = "Tools using AI"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.11,<4.0"
|
|
||||||
files = [
|
|
||||||
{file = "rl_ai_tools-1.10.1-py3-none-any.whl", hash = "sha256:72f3e939c7688d1696ec1744a1e64ba1ce61737e30dab0ebe2f1722761b5683e"},
|
|
||||||
{file = "rl_ai_tools-1.10.1.tar.gz", hash = "sha256:53f64a4b677d022d64b6cc99cf925d1b7172a3a56589f29053b2083103899f20"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
requests = ">=2.32.3,<3.0.0"
|
|
||||||
typer = ">=0.12.5,<0.13.0"
|
|
||||||
|
|
||||||
[package.source]
|
|
||||||
type = "legacy"
|
|
||||||
url = "https://pypi.purple.infomaniak.ch"
|
|
||||||
reference = "infomaniak"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shellingham"
|
name = "shellingham"
|
||||||
version = "1.5.4"
|
version = "1.5.4"
|
||||||
@@ -1045,4 +1025,4 @@ files = [
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.12"
|
python-versions = "^3.12"
|
||||||
content-hash = "c8b74100d5c4f5889db217b5fb249f55248d1955787fd76dbda5ded8b73875b3"
|
content-hash = "e11a9960c50f8b210bd0942533a30915eb56bed47cf5f67ac33f405cb1ef5859"
|
||||||
|
|||||||
+2
-9
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "myice"
|
name = "myice"
|
||||||
version = "v0.2.5"
|
version = "0.1.0"
|
||||||
description = "myice parsing"
|
description = "myice parsing"
|
||||||
authors = ["Rene Luria <rene@luria.ch>"]
|
authors = ["Rene Luria <rene@luria.ch>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@@ -9,19 +9,12 @@ readme = "README.md"
|
|||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.12"
|
python = "^3.12"
|
||||||
requests = "^2.32.3"
|
requests = "^2.32.3"
|
||||||
typer = "^0.12.5"
|
typer = {extras = ["all"], version = "^0.12.5"}
|
||||||
rl-ai-tools = {version = "^1.9.0", source = "infomaniak"}
|
|
||||||
|
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
ipykernel = "^6.29.5"
|
ipykernel = "^6.29.5"
|
||||||
|
|
||||||
|
|
||||||
[[tool.poetry.source]]
|
|
||||||
name = "infomaniak"
|
|
||||||
url = "https://pypi.purple.infomaniak.ch"
|
|
||||||
priority = "supplemental"
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|||||||
Reference in New Issue
Block a user