GIL was a production automation tool that I conceived, developed and introduced for my operations team while supporting Vodafone UK within the Atlantic NOC. It monitored enterprise ticket queues, identified the correct technical scope and assigned incidents and tasks to available engineers according to the weekly team plan and operational rules.
This repository is a sanitised, authorised portfolio version of the original project. It preserves the real workflow and source structure; it is not a generic reconstruction. Credentials, employee data, internal URLs, production logs, private assignment-group names and infrastructure-specific files have been removed or replaced with synthetic examples.
Status: historical project. The original operational service was decommissioned with the wider project and is no longer in use.
Incoming Remedy incidents and tasks had to be reviewed, routed and assigned throughout the day. The dispatcher needed to account for more than simple team availability:
- whether the record was an incident or a task;
- priority and parent-request information;
- network vendor and technology;
- configuration-item and site information;
- assignment group and special-project overrides;
- each engineer's role on that day;
- work already assigned during the shift;
- exceptions that required a human vendor decision.
The team plan already existed in Excel, but the manual process consumed time, could interrupt engineers repeatedly and made it harder to maintain a clear distribution history.
The retained code implements the original workflow:
cronJob.pyand the shell scripts keep the dispatcher running during its configured shift window.main.pyopens the Remedy and site-lookup sessions and authenticates via Selenium.weekplan2remedy.pyselects the current ISO-week workbook and reads the engineers and roles available on the current day.dispatch.pyrefreshes the queue, distinguishes incidents from tasks, reads ticket fields and resolves the vendor or assignment group using CI, site lookup, summary patterns, historical mappings and project rules.- The rotation starts from the previous assignments stored in MySQL. Role constraints and specialist cases are applied before the ticket is updated.
assigned_user()changes the Remedy assignment group and assignee, saves the record and verifies the action.- Assignment history and unresolved-vendor cases are persisted for reporting and subsequent runs.
- Higher-priority tickets, unknown-vendor cases, errors, morning summaries and end-of-day distribution tables are sent through the email adapter.
The original code uses a shuffled daily roster to avoid a permanently fixed order, a rotating index for regular assignments and the lowest current count for specific specialist roles.
The production deployment also included a small ingestion and reporting chain around this code. The weekly Excel plan was held in SharePoint so the team could access and update it without requiring access to the GIL server. Whenever the workbook changed, a Power Automate flow emailed the updated file to a mailbox monitored by the server. A server-side process handled that message and placed the workbook in the correct weekly-plan directory for the dispatcher.
Assignment records stored in MySQL were presented through Grafana. The team could review the current distribution and its history, including which records had been assigned, to whom, and how many each engineer received per day. The public repository retains the Excel parser and reporting data model, but not the original SharePoint, Power Automate, mailbox-ingestion or Grafana configuration.
flowchart TB
SP["Shared Excel plan in SharePoint"] --> PA["Power Automate change flow"]
PA --> MB["Mailbox monitored by the GIL server"]
MB --> I["Server-side workbook ingestion"]
I --> X["Current weekly-plan directory"]
X --> W["weekplan2remedy.py"]
W --> D["dispatch.py"]
C["Shift supervisor"] --> M["main.py"]
M --> S["Selenium session"]
S --> R["Remedy ticket queue"]
S --> L["Site and vendor lookup"]
R --> D
L --> D
J["Routing and user JSON"] --> D
D --> R
D --> DB["MySQL history and metrics"]
DB --> G["Grafana operational dashboards"]
D --> E["Priority alerts and summaries"]
See the detailed architecture notes for the main modules and data flow.
An external implementation of equivalent functionality had been estimated at approximately EUR 70,000. That value was the quoted cost of an alternative implementation, not an audited accounting saving.
The project is useful evidence of more than Python development: it required understanding the team's operational process, translating exceptions into rules, integrating systems that did not expose a convenient end-to-end API, introducing the automation into daily work and supporting it in production.
The public version deliberately excludes:
- Remedy, proxy and database credentials;
- real employee names and Remedy identifiers;
- internal URLs, hostnames, IP addresses and filesystem paths;
- production logs and previous execution output;
- real assignment-group and special-project values;
- backups, bytecode and bundled ChromeDriver binaries;
- the original internal email framework.
The repository instead contains:
config.example.iniwith non-working example values;- synthetic routing and user files under
json/; - two synthetic but structurally compatible weekly plans;
- a generic PHP mail adapter;
- a generic MySQL schema covering the tables used by the application.
During sanitisation, SQL statements were parameterised and deprecated Selenium locator calls were migrated to the current API. Those changes improve safety without replacing the original assignment workflow.
The Excel parser can be exercised without Remedy, MySQL or a browser:
python -m unittest discover -s tests -vThe test suite reads the included workbooks for ISO week 33 of 2026 and confirms the original availability rules:
D,DD,l,S-Aand eligibleT/2entries are included;CRQandIAvariants are excluded from automatic assignment;- Huawei/Nokia and Ericsson/ALU use their own team sections.
The files are intentionally synthetic:
The complete workflow cannot be run against a real system without authorised access to a compatible Remedy interface, site-lookup service, database, mail transport and Chrome environment. The selectors also reflect the retired UI used by the original project.
For an isolated lab review:
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
pip install -r requirements.txt
cp config.example.ini config.iniCreate the synthetic schema from examples/schema.sql
and replace only the example values in the ignored config.ini. If an
authenticated proxy is required, install requirements-proxy.txt; the base
installation does not depend on the unmaintained proxy adapter.
├── main.py # Browser startup, login and lifecycle
├── dispatch.py # Queue reading, routing and assignment workflow
├── weekplan2remedy.py # Weekly Excel availability parser
├── aux_func.py # Database, logging, email and Selenium helpers
├── globals.py # Externalised runtime configuration
├── cronJob.py # Shift-window process supervision
├── mail.php # Generic public mail adapter
├── json/ # Synthetic routing, group and user mappings
├── examples/ # Synthetic workbooks and database schema
├── tests/ # Parser and privacy-safe configuration tests
└── scripts/privacy_check.py # Repository privacy guard
python -m unittest discover -s tests -v
python -m compileall -q *.py tests
python scripts/privacy_check.pyGitHub Actions runs the same checks on Python 3.10, 3.12 and 3.13.
Do not place real credentials, employee data, incident data or internal URLs in
this repository. config.ini, logs, workbooks outside the synthetic example
folders and runtime artefacts are ignored by Git. See SECURITY.md.
This repository is provided as a source-available portfolio archive. No open-source licence is granted. Redistribution or operational reuse requires separate permission from the relevant rights holders.