Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
b016d58d84
|
|||
|
6232e91925
|
|||
| 7ce4fbd756 | |||
| bb62acfc7f |
38
AGENTS.md
38
AGENTS.md
@@ -3,7 +3,6 @@
|
|||||||
## Build/Lint/Test Commands
|
## Build/Lint/Test Commands
|
||||||
|
|
||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install dependencies with Poetry
|
# Install dependencies with Poetry
|
||||||
poetry install
|
poetry install
|
||||||
@@ -13,7 +12,6 @@ pre-commit install
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Linting and Formatting
|
### Linting and Formatting
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run all pre-commit checks (linting, formatting, type checking)
|
# Run all pre-commit checks (linting, formatting, type checking)
|
||||||
pre-commit run --all-files
|
pre-commit run --all-files
|
||||||
@@ -26,52 +24,70 @@ yamllint . # YAML linting
|
|||||||
markdownlint . # Markdown linting
|
markdownlint . # Markdown linting
|
||||||
```
|
```
|
||||||
|
|
||||||
### Testing
|
### Running Tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Run tests (no specific test framework configured)
|
# No formal test framework configured
|
||||||
# Project uses manual testing with example PDF files in repository
|
# Project uses manual testing with example PDF files in repository
|
||||||
|
# To test individual functions, run the CLI commands directly:
|
||||||
|
# myice schedule --days 7
|
||||||
|
# myice mobile-login
|
||||||
|
# myice search --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running the Web API
|
||||||
|
```bash
|
||||||
|
# Or with poetry
|
||||||
|
poetry run fastapi run myice/webapi.py --host 127.0.0.1
|
||||||
```
|
```
|
||||||
|
|
||||||
## Code Style Guidelines
|
## Code Style Guidelines
|
||||||
|
|
||||||
### Imports
|
### Imports
|
||||||
|
|
||||||
- Standard library imports first, then third-party, then local imports
|
- Standard library imports first, then third-party, then local imports
|
||||||
- Use explicit imports rather than wildcard imports
|
- Use explicit imports rather than wildcard imports
|
||||||
- Group imports logically with blank lines between groups
|
- Group imports logically with blank lines between groups
|
||||||
|
|
||||||
### Formatting
|
### Formatting
|
||||||
|
|
||||||
- Use ruff-format for automatic formatting
|
- Use ruff-format for automatic formatting
|
||||||
- Follow PEP 8 style guide
|
- Follow PEP 8 style guide
|
||||||
- Maximum line length: 88 characters (default ruff setting)
|
- Maximum line length: 88 characters (default ruff setting)
|
||||||
- Use 4 spaces for indentation
|
- Use 4 spaces for indentation
|
||||||
|
|
||||||
### Types
|
### Types
|
||||||
|
|
||||||
- Use type hints for function parameters and return values
|
- Use type hints for function parameters and return values
|
||||||
- Prefer built-in types (str, int, list, dict) over typing aliases when possible
|
- Prefer built-in types (str, int, list, dict) over typing aliases when possible
|
||||||
- Use typing.Annotated for Typer command options
|
- Use typing.Annotated for Typer command options
|
||||||
|
|
||||||
### Naming Conventions
|
### Naming Conventions
|
||||||
|
|
||||||
- Variables and functions: snake_case
|
- Variables and functions: snake_case
|
||||||
- Classes: PascalCase
|
- Classes: PascalCase
|
||||||
- Constants: UPPER_SNAKE_CASE
|
- Constants: UPPER_SNAKE_CASE
|
||||||
- Private members: prefixed with underscore (_private)
|
- Private members: prefixed with underscore (_private)
|
||||||
|
|
||||||
### Error Handling
|
### Error Handling
|
||||||
|
|
||||||
- Use try/except blocks for expected exceptions
|
- Use try/except blocks for expected exceptions
|
||||||
- Raise appropriate HTTPException for API errors
|
- Raise appropriate HTTPException for API errors
|
||||||
- Include descriptive error messages
|
- Include descriptive error messages
|
||||||
- Use sys.exit(1) for command-line tool errors
|
- Use sys.exit(1) for command-line tool errors
|
||||||
|
|
||||||
### Frameworks and Libraries
|
### Frameworks and Libraries
|
||||||
|
|
||||||
- Typer for CLI interface
|
- Typer for CLI interface
|
||||||
- FastAPI for web API
|
- FastAPI for web API
|
||||||
- requests for HTTP requests
|
- requests for HTTP requests
|
||||||
- PyPDF2 for PDF processing
|
- PyPDF2 for PDF processing
|
||||||
- Use rich for enhanced console output
|
- Use rich for enhanced console output
|
||||||
|
- Custom rl_ai_tools package for AI functionalities
|
||||||
|
|
||||||
|
### Git Commit Messages
|
||||||
|
- Use conventional commits format
|
||||||
|
- Never mention Claude in commit messages
|
||||||
|
- Be descriptive but concise
|
||||||
|
- Use present tense ("add feature" not "added feature")
|
||||||
|
|
||||||
|
### Additional Rules
|
||||||
|
- Always use ddg-mcp to perform Web Search functionality
|
||||||
|
- Follow the existing code patterns in myice/myice.py and myice/webapi.py
|
||||||
|
- Maintain backward compatibility when modifying existing APIs
|
||||||
|
- Document new features in README.md
|
||||||
|
- Always run ruff format and ruff check after editing a python file
|
||||||
|
- use conventional commit messages
|
||||||
90
index.html
90
index.html
@@ -32,16 +32,28 @@
|
|||||||
<div class="container mt-2" id="mainContent" style="display: none;">
|
<div class="container mt-2" id="mainContent" style="display: none;">
|
||||||
|
|
||||||
<div id="eventFilters" style="display: none;">
|
<div id="eventFilters" style="display: none;">
|
||||||
<div class="mb-3">
|
<div class="mb-3 row">
|
||||||
<label for="account" class="form-label">Compte</label>
|
<div class="col-md-3">
|
||||||
<select id="account" class="form-select">
|
<label for="account" class="form-label">Compte</label>
|
||||||
<option value="default">Défaut</option>
|
<select id="account" class="form-select">
|
||||||
</select>
|
<option value="default">Défaut</option>
|
||||||
<label for="agegroup" class="form-label">Âge</label>
|
</select>
|
||||||
<select id="agegroup" class="form-select">
|
</div>
|
||||||
<option value="">Tous</option>
|
<div class="col-md-3">
|
||||||
</select>
|
<label for="agegroup" class="form-label">Âge</label>
|
||||||
<button id="fetchEvents" class="btn btn-primary" style="margin-top: 1.2rem;">Charger</button>
|
<select id="agegroup" class="form-select">
|
||||||
|
<option value="">Tous</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label for="subgroup" class="form-label">Sous-groupe</label>
|
||||||
|
<select id="subgroup" class="form-select">
|
||||||
|
<option value="">Tous</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3 d-flex align-items-end">
|
||||||
|
<button id="fetchEvents" class="btn btn-primary">Charger</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -77,6 +89,7 @@
|
|||||||
const eventFilters = document.getElementById("eventFilters");
|
const eventFilters = document.getElementById("eventFilters");
|
||||||
const accountSelect = document.getElementById("account");
|
const accountSelect = document.getElementById("account");
|
||||||
const agegroupSelect = document.getElementById("agegroup");
|
const agegroupSelect = document.getElementById("agegroup");
|
||||||
|
const subgroupSelect = document.getElementById("subgroup");
|
||||||
const eventList = document.getElementById("eventList");
|
const eventList = document.getElementById("eventList");
|
||||||
const fetchButton = document.getElementById("fetchEvents");
|
const fetchButton = document.getElementById("fetchEvents");
|
||||||
const eventDetailsContent = document.getElementById("eventDetailsContent");
|
const eventDetailsContent = document.getElementById("eventDetailsContent");
|
||||||
@@ -335,6 +348,12 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
agegroupSelect.addEventListener("change", () => {
|
agegroupSelect.addEventListener("change", () => {
|
||||||
|
// Update subgroup options based on selected agegroup
|
||||||
|
updateSubgroupOptions(agegroupSelect.value, lastFetchedEvents);
|
||||||
|
displayEvents(lastFetchedEvents);
|
||||||
|
});
|
||||||
|
|
||||||
|
subgroupSelect.addEventListener("change", () => {
|
||||||
displayEvents(lastFetchedEvents);
|
displayEvents(lastFetchedEvents);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -413,12 +432,61 @@
|
|||||||
option.textContent = group;
|
option.textContent = group;
|
||||||
agegroupSelect.appendChild(option);
|
agegroupSelect.appendChild(option);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Reset subgroup selector
|
||||||
|
subgroupSelect.innerHTML = '<option value="">Tous</option>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSubgroupOptions(selectedAgegroup, events) {
|
||||||
|
// Reset subgroup options
|
||||||
|
subgroupSelect.innerHTML = '<option value="">Tous</option>';
|
||||||
|
|
||||||
|
if (selectedAgegroup === "") {
|
||||||
|
// If no agegroup is selected, disable subgroup selector
|
||||||
|
subgroupSelect.disabled = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable subgroup selector
|
||||||
|
subgroupSelect.disabled = false;
|
||||||
|
|
||||||
|
// Extract subgroups from events matching the selected agegroup
|
||||||
|
let subgroups = new Set();
|
||||||
|
events
|
||||||
|
.filter(event => event.agegroup === selectedAgegroup)
|
||||||
|
.forEach(event => {
|
||||||
|
// Extract subgroup from event.name or event.title
|
||||||
|
// This assumes the subgroup is part of the name field
|
||||||
|
if (event.name && event.name !== selectedAgegroup) {
|
||||||
|
subgroups.add(event.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add subgroups to the selector
|
||||||
|
Array.from(subgroups).sort().forEach(subgroup => {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = subgroup;
|
||||||
|
option.textContent = subgroup;
|
||||||
|
subgroupSelect.appendChild(option);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayEvents(events) {
|
function displayEvents(events) {
|
||||||
eventList.innerHTML = "";
|
eventList.innerHTML = "";
|
||||||
let selectedAgegroup = agegroupSelect.value;
|
let selectedAgegroup = agegroupSelect.value;
|
||||||
let filteredEvents = events.filter(event => event.event === "Jeu" && (selectedAgegroup === "" || event.agegroup === selectedAgegroup));
|
let selectedSubgroup = subgroupSelect.value;
|
||||||
|
let filteredEvents = events.filter(event => {
|
||||||
|
// Filter by event type
|
||||||
|
if (event.event !== "Jeu") return false;
|
||||||
|
|
||||||
|
// Filter by agegroup
|
||||||
|
if (selectedAgegroup !== "" && event.agegroup !== selectedAgegroup) return false;
|
||||||
|
|
||||||
|
// Filter by subgroup
|
||||||
|
if (selectedSubgroup !== "" && event.name !== selectedSubgroup) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
if (filteredEvents.length === 0) {
|
if (filteredEvents.length === 0) {
|
||||||
eventList.innerHTML = "<p class='text-muted'>Aucun événement 'Jeu' trouvé.</p>";
|
eventList.innerHTML = "<p class='text-muted'>Aucun événement 'Jeu' trouvé.</p>";
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "myice"
|
name = "myice"
|
||||||
version = "v0.5.5"
|
version = "v0.5.7"
|
||||||
description = "myice parsing"
|
description = "myice parsing"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "Rene Luria", "email" = "<rene@luria.ch>"},
|
{ name = "Rene Luria", "email" = "<rene@luria.ch>"},
|
||||||
|
|||||||
Reference in New Issue
Block a user