Skip to content

Instantly share code, notes, and snippets.

@indyone
Last active February 4, 2022 07:47
Show Gist options
  • Save indyone/beff40da977e15f5f72e360d83c83793 to your computer and use it in GitHub Desktop.
Save indyone/beff40da977e15f5f72e360d83c83793 to your computer and use it in GitHub Desktop.
EduPass Generator for Lame Fathers (and Mothers)
{
"TaxisnetUsername": "xxxxxxxx",
"TaxisnetPassword": "xxxxxxxx",
"TelegramBotToken": "xxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"TelegramChatId": "-xxxxxxxxx",
"Students": [
{
"SchoolCounty": "ΑΤΤΙΚΗΣ",
"SchoolRegion": "ΚΕΝΤΡΙΚΟΥ ΤΟΜΕΑ ΑΘΗΝΩΝ",
"SchoolMunicipality": "xxxxxxxxx",
"SchoolCategory": "Δημοτικά Σχολεία",
"SchoolType": "Ενιαίου Τύπου Ολοήμερο Δημοτικό Σχολείο",
"SchoolName": "ΣΧΟΛΕΙΟ/xxxxxxx",
"StudentFirstName": "xxxxxxxxxxxxx",
"StudentLastName": "xxxxxxxxxxxxxxxxxxx",
"StudentBirthDate": "yyyy-MM-dd",
"StudentAmkaNumber": "xxxxxxxxxxx"
},
{
"SchoolCounty": "ΑΤΤΙΚΗΣ",
"SchoolRegion": "ΚΕΝΤΡΙΚΟΥ ΤΟΜΕΑ ΑΘΗΝΩΝ",
"SchoolMunicipality": "xxxxxxxxx",
"SchoolCategory": "Νηπιαγωγεία",
"SchoolType": "Ενιαίου Τύπου Ολοήμερο Νηπιαγωγείο",
"SchoolName": "ΣΧΟΛΕΙΟ/xxxxxxx",
"StudentFirstName": "xxxxx",
"StudentLastName": "xxxxxxxxxxxxxxxxxxx",
"StudentBirthDate": "yyyy-MM-dd",
"StudentAmkaNumber": "xxxxxxxxxxx"
}
]
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>10</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Playwright" Version="1.16.1" />
<PackageReference Include="Telegram.Bot" Version="17.0.0" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
using Microsoft.Playwright;
using Newtonsoft.Json;
using Telegram.Bot;
using Telegram.Bot.Types.InputFiles;
var eduPassOptions = JsonConvert.DeserializeObject<EduPassOptions>(File.ReadAllText("appsettings.json"));
var telegramBot = new EduPassTelegramBot(eduPassOptions);
var taxisnetClient = new EduPassTaxisnetClient(eduPassOptions);
foreach (var student in eduPassOptions.Students)
{
await telegramBot.SendProcessingStartedAsync(student);
var output = await taxisnetClient.RunAsync(student);
using (var screenshotStream = new MemoryStream(output.ScreenshotBytes))
{
await telegramBot.SendScreenshotAsync(student, screenshotStream, "png");
}
using (var pdfStream = new MemoryStream(output.PdfBytes))
{
await telegramBot.SendScreenshotAsync(student, pdfStream, "pdf");
}
}
// The program ends here
public class EduPassOptions
{
public string TaxisnetUsername = string.Empty;
public string TaxisnetPassword = string.Empty;
public string TelegramBotToken = string.Empty;
public string TelegramChatId = string.Empty;
public DateTime RunningDate = DateTime.Now;
public Student[] Students = new Student[0];
public class Student
{
public string SchoolCounty = String.Empty;
public string SchoolRegion = String.Empty;
public string SchoolMunicipality = String.Empty;
public string SchoolCategory = string.Empty;
public string SchoolType = string.Empty;
public string SchoolName = string.Empty;
public string StudentFirstName = string.Empty;
public string StudentLastName = string.Empty;
public DateTime StudentBirthDate;
public string StudentAmkaNumber = string.Empty;
}
}
public class EduPassTelegramBot
{
private readonly ITelegramBotClient? _botClient;
private readonly string _chatId;
private readonly DateTime _runningDate;
public EduPassTelegramBot(EduPassOptions options)
{
if (!string.IsNullOrEmpty(options.TelegramBotToken))
{
_botClient = new TelegramBotClient(options.TelegramBotToken);
}
_chatId = options.TelegramChatId;
_runningDate = options.RunningDate;
}
public Task SendProcessingStartedAsync(EduPassOptions.Student student)
{
if (_botClient == null) return Task.CompletedTask;
return _botClient.SendTextMessageAsync(_chatId,
$"Ξεκινησε η διαδικασία παραγωγής της δήλωσης EduPass για τον/την μαθητή/τρια " +
$"{student.StudentFirstName} {student.StudentLastName} στις {_runningDate:ddd, dd MMM yyyy}.");
}
public Task SendScreenshotAsync(EduPassOptions.Student student, Stream stream, string extension)
{
if (_botClient == null) return Task.CompletedTask;
var onlineFile = new InputOnlineFile(stream, $"{student.StudentFirstName} {student.StudentLastName} - {_runningDate:yyyyMMdd}.{extension}");
return _botClient.SendDocumentAsync(_chatId, onlineFile);
}
}
public class EduPassTaxisnetClient
{
private readonly string _username;
private readonly string _password;
private readonly DateTime _runningDate;
public EduPassTaxisnetClient(EduPassOptions options)
{
_username = options.TaxisnetUsername;
_password = options.TaxisnetPassword;
_runningDate = options.RunningDate;
}
public async Task<(byte[] ScreenshotBytes, byte[] PdfBytes)> RunAsync(EduPassOptions.Student student)
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = true });
var page = await browser.NewPageAsync(new BrowserNewPageOptions { ViewportSize = new ViewportSize { Width = 1280, Height = 1200 } });
await page.GotoAsync("https://edupass.gov.gr/start/");
await page.ClickAsync("input[value='schools']");
await page.ClickAsync("button[type='submit']");
await page.WaitForNavigationAsync();
await page.ClickAsync("input[value='studentCard']");
await page.ClickAsync("button[type='submit']");
await page.WaitForNavigationAsync();
await page.ClickAsync("a[label='Σύνδεση']");
await page.WaitForNavigationAsync();
await page.ClickAsync("button[type='button']:has-text('Taxisnet')");
// Αυθεντικοποίηση Χρήστη
await page.FillAsync("input[name='j_username']", _username);
await page.FillAsync("input[name='j_password']", _password);
await page.ClickAsync("button#btn-login-submit", new PageClickOptions { Force = true, NoWaitAfter = true });
try
{
await page.ClickAsync("button#btn-submit", new PageClickOptions { Force = true, NoWaitAfter = true, Timeout = 3000 });
}
catch
{
// Expected to timeout if not exist
}
await page.ClickAsync("button[label='Συνέχεια']");
await page.ClickAsync("button[type='button']:has-text('Αποδοχή')", new PageClickOptions { Force = true, NoWaitAfter = true });
// Δήλωση EDUPASS - Σχολική Κάρτα
// Συμπληρώστε τα στοιχεία του σχολείου στο οποίο φοιτά ο μαθητής
await page.ClickAsync("div[customlabel='Περιφέρεια']");
await page.ClickAsync($"li[data-value='{student.SchoolCounty}']");
await page.ClickAsync("div[customlabel='Περιφερειακή Ενότητα']");
await page.ClickAsync($"li[data-value='{student.SchoolRegion}']");
await page.ClickAsync("div[customlabel='Δήμος']");
await page.ClickAsync($"li[data-value='{student.SchoolMunicipality}']");
await page.ClickAsync("div[customlabel='Κατηγορία']");
await page.ClickAsync($"li[data-value='{student.SchoolCategory}']");
await page.ClickAsync("div[customlabel='Τύπος']");
await page.ClickAsync($"li[data-value='{student.SchoolType}']");
await page.ClickAsync("div[customlabel='Σχολείο']");
await page.ClickAsync($"li[data-value='{student.SchoolName}']");
// Συμπληρώστε τα στοιχεία του μαθητή
await page.FillAsync("input[name='input_firstname']", student.StudentFirstName);
await page.FillAsync("input[name='input_lastname']", student.StudentLastName);
await page.FillAsync("input[name='input_dob-day']", $"{student.StudentBirthDate:dd}");
await page.FillAsync("input[name='input_dob-month']", $"{student.StudentBirthDate:MM}");
await page.FillAsync("input[name='input_dob-year']", $"{student.StudentBirthDate:yyyy}");
await page.FillAsync("input[name='input_amka']", student.StudentAmkaNumber);
await page.ClickAsync("div#mui-component-select-can_use_amka");
await page.ClickAsync("li[data-value='ΝΑΙ']");
// Συμπληρώστε τα στοιχεία self-test
await page.FillAsync("input[name='self_test_date-day']", $"{_runningDate:dd}");
await page.FillAsync("input[name='self_test_date-month']", $"{_runningDate:MM}");
await page.FillAsync("input[name='self_test_date-year']", $"{_runningDate:yyyy}");
await page.ClickAsync("div#mui-component-select-self_test_result");
await page.ClickAsync("li[data-value='ΑΡΝΗΤΙΚΟ']");
await page.ClickAsync("button[label='Υποβολή']");
// Η δήλωση υποβλήθηκε
await page.WaitForNavigationAsync();
// Prepare outputs
var screenshotBytes = await page.ScreenshotAsync(new PageScreenshotOptions() { FullPage = true });
await page.EmulateMediaAsync(new PageEmulateMediaOptions() { Media = Media.Print });
var path = $"{student.StudentFirstName} {student.StudentLastName} - {_runningDate:yyyyMMdd}.pdf";
var pdfBytes = await page.PdfAsync(new PagePdfOptions { Path = path, Format = "A4" });
return (screenshotBytes, pdfBytes);
}
}
@indyone
Copy link
Author

indyone commented Feb 4, 2022

Update program to sent the screenshot and the PDF to telegram bot. Also fixed clicking this "Can use AMKA" selection box that was added recently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment