Skip to content

Commit

Permalink
Add caleg report
Browse files Browse the repository at this point in the history
  • Loading branch information
ronnygunawan committed Feb 17, 2024
1 parent a31117c commit 89f2b76
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 0 deletions.
1 change: 1 addition & 0 deletions BotNet.CommandHandlers/SQL/SQLCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ await _telegramBotClient.SendTextMessageAsync(
text: $$"""
<code>Table '{{table}}' not found. Available tables are:
- pileg_dpr_dapil
- pileg_dpr_<kodedapil>
- pileg_dpr_provinsi
- pilpres
- vps
Expand Down
131 changes: 131 additions & 0 deletions BotNet.Services/Pemilu2024/PilegDPRDapilDataSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using BotNet.Services.SQL;
using BotNet.Services.Sqlite;

namespace BotNet.Services.Pemilu2024 {
public sealed class PilegDPRDapilDataSource(
ScopedDatabase scopedDatabase,
SirekapClient sirekapClient
) : IScopedDataSource {
private const string PKB = "1";
private const string GERINDRA = "2";
private const string PDIP = "3";
private const string GOLKAR = "4";
private const string NASDEM = "5";
private const string PARTAI_BURUH = "6";
private const string GELORA = "7";
private const string PKS = "8";
private const string PKN = "9";
private const string HANURA = "10";
private const string GARUDA = "11";
private const string PAN = "12";
private const string PBB = "13";
private const string DEMOKRAT = "14";
private const string PSI = "15";
private const string PERINDO = "16";
private const string PPP = "17";
private const string PNA = "18";
private const string GABTHAT = "19";
private const string PDA = "20";
private const string PARTAI_ACEH = "21";
private const string PAS_ACEH = "22";
private const string PARTAI_SIRA = "23";
private const string PARTAI_UMMAT = "24";
private readonly ScopedDatabase _scopedDatabase = scopedDatabase;
private readonly SirekapClient _sirekapClient = sirekapClient;

public string? KodeDapil { get; set; }

public async Task LoadTableAsync(CancellationToken cancellationToken) {
if (KodeDapil is null) throw new InvalidProgramException("KodeDapil is not set");

_scopedDatabase.ExecuteNonQuery($$"""
CREATE TABLE pileg_dpr_{{KodeDapil}} (
partai VARCHAR(50),
kode_caleg VARCHAR(10),
nomor_urut INTEGER,
nama VARCHAR(100),
jenis_kelamin VARCHAR(1),
tempat_tinggal VARCHAR(100),
jumlah_suara INTEGER
)
""");

IDictionary<string, IDictionary<string, Caleg>> calegByKodeByKodePartai = await _sirekapClient.GetCalegByKodeByKodePartaiAsync(KodeDapil, cancellationToken);
ReportCalegDPR report = await _sirekapClient.GetReportCalegDPRAsync(KodeDapil, cancellationToken);

foreach ((string kodePartai, IDictionary<string, int> votesByKodeCaleg) in report.VotesByKodeCalegByKodePartai.OrderBy(pair => pair.Key)) {
string partai = kodePartai switch {
PKB => "PKB",
GERINDRA => "Gerindra",
PDIP => "PDIP",
GOLKAR => "Golkar",
NASDEM => "Nasdem",
PARTAI_BURUH => "Partai Buruh",
GELORA => "Gelora",
PKS => "PKS",
PKN => "PKN",
HANURA => "Hanura",
GARUDA => "Garuda",
PAN => "PAN",
PBB => "PBB",
DEMOKRAT => "Demokrat",
PSI => "PSI",
PERINDO => "Perindo",
PPP => "PPP",
PNA => "Partai Nanggroe Aceh",
GABTHAT => "Partai Generasi Atjeh Beusaboh Tha'at Dan Taqwa",
PDA => "Partai Darul Aceh",
PARTAI_ACEH => "Partai Aceh",
PAS_ACEH => "Partai Adil Sejahtera Aceh",
PARTAI_SIRA => "Partai SIRA",
PARTAI_UMMAT => "Partai Ummat",
_ => throw new InvalidProgramException("Unknown partai")
};

foreach ((string kodeCaleg, int votes) in votesByKodeCaleg!.OrderBy(pair => pair.Key)) {
if (!int.TryParse(kodeCaleg, out _)) continue;
Caleg caleg = calegByKodeByKodePartai[kodePartai][kodeCaleg];
_scopedDatabase.ExecuteNonQuery($$"""
INSERT INTO pileg_dpr_{{KodeDapil}} (partai, kode_caleg, nomor_urut, nama, jenis_kelamin, tempat_tinggal, jumlah_suara)
VALUES (@partai, @kode_caleg, @nomor_urut, @nama, @jenis_kelamin, @tempat_tinggal, @jumlah_suara)
""",
[
( "@partai", partai ),
( "@kode_caleg", kodeCaleg ),
( "@nomor_urut", caleg.NomorUrut ),
( "@nama", caleg.Nama ),
( "@jenis_kelamin", caleg.JenisKelamin ),
( "@tempat_tinggal", caleg.TempatTinggal ),
( "@jumlah_suara", votes )
]
);
}

_scopedDatabase.ExecuteNonQuery($$"""
INSERT INTO pileg_dpr_{{KodeDapil}} (partai, kode_caleg, nomor_urut, nama, jenis_kelamin, tempat_tinggal, jumlah_suara)
VALUES (@partai, null, null, 'Jumlah Suara Total', null, null, @jumlah_suara)
""",
[
( "@partai", partai ),
( "@jumlah_suara", votesByKodeCaleg["jml_suara_total"] )
]
);

_scopedDatabase.ExecuteNonQuery($$"""
INSERT INTO pileg_dpr_{{KodeDapil}} (partai, kode_caleg, nomor_urut, nama, jenis_kelamin, tempat_tinggal, jumlah_suara)
VALUES (@partai, null, null, 'Jumlah Suara Partai', null, null, @jumlah_suara)
""",
[
( "@partai", partai ),
( "@jumlah_suara", votesByKodeCaleg["jml_suara_partai"] )
]
);
}
}
}
}
94 changes: 94 additions & 0 deletions BotNet.Services/Pemilu2024/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,103 @@ namespace BotNet.Services.Pemilu2024 {
public static class ServiceCollectionExtensions {
public static IServiceCollection AddPemilu2024(this IServiceCollection services) {
services.AddTransient<SirekapClient>();
services.AddTransient<PilegDPRDapilDataSource>();
services.AddKeyedTransient<IScopedDataSource, PilpresDataSource>("pilpres");
services.AddKeyedTransient<IScopedDataSource, PilegDPRPerProvinsiDataSource>("pileg_dpr_provinsi");
services.AddKeyedTransient<IScopedDataSource, PilegDPRPerDapilDataSource>("pileg_dpr_dapil");
services.AddPilegDPRDapilDataSource("1101");
services.AddPilegDPRDapilDataSource("1102");
services.AddPilegDPRDapilDataSource("5101");
services.AddPilegDPRDapilDataSource("3601");
services.AddPilegDPRDapilDataSource("3602");
services.AddPilegDPRDapilDataSource("3603");
services.AddPilegDPRDapilDataSource("1701");
services.AddPilegDPRDapilDataSource("3401");
services.AddPilegDPRDapilDataSource("3101");
services.AddPilegDPRDapilDataSource("3102");
services.AddPilegDPRDapilDataSource("3103");
services.AddPilegDPRDapilDataSource("7501");
services.AddPilegDPRDapilDataSource("1501");
services.AddPilegDPRDapilDataSource("3201");
services.AddPilegDPRDapilDataSource("3202");
services.AddPilegDPRDapilDataSource("3203");
services.AddPilegDPRDapilDataSource("3204");
services.AddPilegDPRDapilDataSource("3209");
services.AddPilegDPRDapilDataSource("3205");
services.AddPilegDPRDapilDataSource("3206");
services.AddPilegDPRDapilDataSource("3207");
services.AddPilegDPRDapilDataSource("3208");
services.AddPilegDPRDapilDataSource("3210");
services.AddPilegDPRDapilDataSource("3211");
services.AddPilegDPRDapilDataSource("3301");
services.AddPilegDPRDapilDataSource("3302");
services.AddPilegDPRDapilDataSource("3303");
services.AddPilegDPRDapilDataSource("3304");
services.AddPilegDPRDapilDataSource("3309");
services.AddPilegDPRDapilDataSource("3305");
services.AddPilegDPRDapilDataSource("3306");
services.AddPilegDPRDapilDataSource("3307");
services.AddPilegDPRDapilDataSource("3308");
services.AddPilegDPRDapilDataSource("3310");
services.AddPilegDPRDapilDataSource("3501");
services.AddPilegDPRDapilDataSource("3502");
services.AddPilegDPRDapilDataSource("3503");
services.AddPilegDPRDapilDataSource("3504");
services.AddPilegDPRDapilDataSource("3509");
services.AddPilegDPRDapilDataSource("3505");
services.AddPilegDPRDapilDataSource("3506");
services.AddPilegDPRDapilDataSource("3507");
services.AddPilegDPRDapilDataSource("3508");
services.AddPilegDPRDapilDataSource("3510");
services.AddPilegDPRDapilDataSource("3511");
services.AddPilegDPRDapilDataSource("6101");
services.AddPilegDPRDapilDataSource("6102");
services.AddPilegDPRDapilDataSource("6301");
services.AddPilegDPRDapilDataSource("6302");
services.AddPilegDPRDapilDataSource("6201");
services.AddPilegDPRDapilDataSource("6401");
services.AddPilegDPRDapilDataSource("6501");
services.AddPilegDPRDapilDataSource("1901");
services.AddPilegDPRDapilDataSource("2101");
services.AddPilegDPRDapilDataSource("1801");
services.AddPilegDPRDapilDataSource("1802");
services.AddPilegDPRDapilDataSource("8101");
services.AddPilegDPRDapilDataSource("8201");
services.AddPilegDPRDapilDataSource("5201");
services.AddPilegDPRDapilDataSource("5202");
services.AddPilegDPRDapilDataSource("5301");
services.AddPilegDPRDapilDataSource("5302");
services.AddPilegDPRDapilDataSource("9101");
services.AddPilegDPRDapilDataSource("9201");
services.AddPilegDPRDapilDataSource("9601");
services.AddPilegDPRDapilDataSource("9501");
services.AddPilegDPRDapilDataSource("9301");
services.AddPilegDPRDapilDataSource("9401");
services.AddPilegDPRDapilDataSource("1401");
services.AddPilegDPRDapilDataSource("1402");
services.AddPilegDPRDapilDataSource("7601");
services.AddPilegDPRDapilDataSource("7301");
services.AddPilegDPRDapilDataSource("7302");
services.AddPilegDPRDapilDataSource("7303");
services.AddPilegDPRDapilDataSource("7201");
services.AddPilegDPRDapilDataSource("7401");
services.AddPilegDPRDapilDataSource("7101");
services.AddPilegDPRDapilDataSource("1301");
services.AddPilegDPRDapilDataSource("1302");
services.AddPilegDPRDapilDataSource("1601");
services.AddPilegDPRDapilDataSource("1602");
services.AddPilegDPRDapilDataSource("1201");
services.AddPilegDPRDapilDataSource("1202");
services.AddPilegDPRDapilDataSource("1203");
return services;
}

private static IServiceCollection AddPilegDPRDapilDataSource(this IServiceCollection services, string kodeDapil) {
services.AddKeyedTransient<IScopedDataSource, PilegDPRDapilDataSource>($"pileg_dpr_{kodeDapil}", (serviceProvider, key) => {
PilegDPRDapilDataSource service = serviceProvider.GetRequiredService<PilegDPRDapilDataSource>();
service.KodeDapil = kodeDapil;
return service;
});
return services;
}
}
Expand Down
14 changes: 14 additions & 0 deletions BotNet.Services/Pemilu2024/SirekapClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ public async Task<IDictionary<string, Paslon>> GetPaslonByKodeAsync(Cancellation
) ?? throw new JsonException("Unexpected response");
}

public async Task<IDictionary<string, IDictionary<string, Caleg>>> GetCalegByKodeByKodePartaiAsync(string kodeDapil, CancellationToken cancellationToken) {
return await _httpClient.GetFromJsonAsync<IDictionary<string, IDictionary<string, Caleg>>>(
requestUri: $"https://sirekap-obj-data.kpu.go.id/pemilu/caleg/partai/{kodeDapil}.json",
cancellationToken: cancellationToken
) ?? throw new JsonException("Unexpected response");
}

public async Task<IDictionary<string, Partai>> GetPartaiByKodeAsync(CancellationToken cancellationToken) {
return await _httpClient.GetFromJsonAsync<IDictionary<string, Partai>>(
requestUri: "https://sirekap-obj-data.kpu.go.id/pemilu/partai.json",
Expand Down Expand Up @@ -77,5 +84,12 @@ public async Task<ReportPilegDPRByDapil> GetReportPilegDPRByDapilAsync(Cancellat
cancellationToken: cancellationToken
) ?? throw new JsonException("Unexpected response");
}

public async Task<ReportCalegDPR> GetReportCalegDPRAsync(string kodeDapil, CancellationToken cancellationToken) {
return await _httpClient.GetFromJsonAsync<ReportCalegDPR>(
requestUri: $"https://sirekap-obj-data.kpu.go.id/pemilu/hhcd/pdpr/{kodeDapil}.json",
cancellationToken: cancellationToken
) ?? throw new JsonException("Unexpected response");
}
}
}
20 changes: 20 additions & 0 deletions BotNet.Services/Pemilu2024/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ public sealed record Wilayah(
int Tingkat
);

public sealed record Caleg(
string Nama,
int NomorUrut,
string JenisKelamin,
string TempatTinggal
);

public sealed record ReportPilpres(
[property: JsonPropertyName("ts")] string Timestamp,
string Psu,
Expand Down Expand Up @@ -146,4 +153,17 @@ public sealed record Progress(
int Progres
);
}

public sealed record ReportCalegDPR(
[property: JsonPropertyName("ts")] string Timestamp,
string Mode,
IDictionary<string, decimal> Chart,
[property: JsonPropertyName("table")] IDictionary<string, IDictionary<string, int>> VotesByKodeCalegByKodePartai,
ReportCalegDPR.Progress Progres
) {
public sealed record Progress(
int Total,
int Progres
);
}
}

0 comments on commit 89f2b76

Please sign in to comment.