Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 8 additions & 14 deletions .github/models/trafic.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,12 @@
"title": "Trafic configuration schema",
"description": "Schema describing the structure of a trafic.json file used by the project.",
"type": "object",
"required": ["companyId", "companyLogo", "lines"],
"required": ["companyLogo", "lines"],
"additionalProperties": false,
"properties": {
"companyId": {
"oneOf": [
{
"type": "string",
"description": "Unique identifier for the company (e.g. 'fr-idf')."
},
{
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"description": "Array of unique identifiers for the company."
}
]
"type": "string",
"description": "Unique identifier for the company (e.g. 'fr-idf'). Required for single company configurations. Omit when multiple companies share the same configuration (each line must then have its own companyId)."
},
"companyLogo": {
"type": "string",
Expand Down Expand Up @@ -74,7 +64,11 @@
]
},
"lineLogoDark": { "type": ["string","null"], "format": "uri", "description": "Optional dark-mode logo URL.", "default": null },
"isDisabled": { "type": "boolean", "description": "Optional flag to mark a line as disabled." }
"isDisabled": { "type": "boolean", "description": "Optional flag to mark a line as disabled." },
"companyId": {
"type": "string",
"description": "Optional: specify which company this line belongs to. If root companyId is omitted (multiple companies case), this field becomes required for each line. Must be a string."
}
},
"additionalProperties": false
}
Expand Down
46 changes: 30 additions & 16 deletions .github/scripts/check_gtfs_route_trafic.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,45 @@ def gather_trafic_json(root_dir):
continue

def process_company(company):
aid = company.get('companyId')
if not aid:
return
root_aid = company.get('companyId')

# Collect line IDs for this company
line_ids = set()
# Determine if we have a root companyId (single company case)
has_root_company = root_aid is not None and isinstance(root_aid, str) and root_aid.strip()
root_company_id = root_aid.strip() if has_root_company else None

# Process each line
for group in company.get('lines', []) or []:
for item in group:
if not isinstance(item, dict):
continue

# Get lineId
lid = item.get('lineId')
if lid is None:
continue
lid_s = str(lid).strip()
if lid_s:
line_ids.add(lid_s)

# Handle companyId as either a string or a list of strings
if isinstance(aid, str):
if aid.strip() and line_ids:
agencies[aid.strip()].update(line_ids)
elif isinstance(aid, list):
for cid in aid:
if isinstance(cid, str) and cid.strip() and line_ids:
agencies[cid.strip()].update(line_ids)
if not lid_s:
continue

# Get line-specific companyId
line_aid = item.get('companyId')

if has_root_company:
# Single company case: use line's companyId if present, otherwise use root
if line_aid is not None and isinstance(line_aid, str):
cid = line_aid.strip()
if cid:
agencies[cid].add(lid_s)
else:
agencies[root_company_id].add(lid_s)
else:
# Multiple companies case: line MUST have its own companyId
if line_aid is None or not isinstance(line_aid, str):
print(f'Warning: Line {lid_s} has no companyId and no root companyId found. Skipping.')
continue
cid = line_aid.strip()
if cid:
agencies[cid].add(lid_s)

if isinstance(data, list):
for company in data:
Expand Down
Loading