#!/usr/bin/perl -w
my
$config
= SReview::Config::Common::setup;
my
$dbh
= DBI->
connect
(
$config
->get(
'dbistring'
),
''
,
''
) or
die
'Cannot connect to database!'
;
my
$format
=
$config
->get(
'schedule_format'
);
my
$pclass
=
'SReview::Schedule::'
.
ucfirst
(
$format
);
eval
"require $pclass;"
or
die
"Could not load schedule parser for format $format: $@\n"
;
my
$opts
=
$config
->get(
'schedule_options'
);
my
$parser
=
"$pclass"
->new(
%$opts
);
my
$update_talk
=
$dbh
->prepare(
"UPDATE talks SET room = ?, slug = ?, starttime = ?::timestamptz, endtime = ?::timestamptz, title = ?, subtitle = ?, track = ? WHERE id = ?"
);
my
$search_room
=
$dbh
->prepare(
"SELECT id FROM rooms WHERE name = ?"
);
my
$add_room
=
$dbh
->prepare(
"INSERT INTO rooms(name, altname, outputname) VALUES(?, ?, ?) RETURNING id"
);
my
$update_room
=
$dbh
->prepare(
"UPDATE rooms SET altname = ?, outputname = ? WHERE name = ?"
);
my
$add_track
=
$dbh
->prepare(
"INSERT INTO tracks(name, email, upstreamid) VALUES(?, ?, ?) RETURNING id"
);
my
$update_track
=
$dbh
->prepare(
"UPDATE tracks SET name = ?, email = ? WHERE upstreamid = ?"
);
my
$add_talk
=
$dbh
->prepare(
"INSERT INTO talks(room, slug, starttime, endtime, title, event, upstreamid, subtitle, track, description) VALUES(?, ?, ?::timestamptz, ?::timestamptz, ?, ?, ?, ?, ?, ?) RETURNING id"
);
my
$set_flags
=
$dbh
->prepare(
"UPDATE talks SET flags = COALESCE(flags::jsonb || ?::jsonb, ?::jsonb) WHERE id = ?"
);
my
$search_speaker
=
$dbh
->prepare(
"SELECT id FROM speakers WHERE upstreamid = ? AND event = ?"
);
my
$update_speaker
=
$dbh
->prepare(
"UPDATE speakers SET name = ?, email = ? WHERE upstreamid = ?"
);
my
$add_speaker
=
$dbh
->prepare(
"INSERT INTO speakers(email, name, upstreamid, event) VALUES(?, ?, ?, ?) RETURNING id"
);
my
$clear_speakers
=
$dbh
->prepare(
"DELETE FROM speakers_talks WHERE talk = ?"
);
my
$link_speaker
=
$dbh
->prepare(
"INSERT INTO speakers_talks(speaker, talk) VALUES (?, ?) ON CONFLICT ON CONSTRAINT speakers_talks_pkey DO NOTHING"
);
my
$ignore_talk
=
$dbh
->prepare(
"UPDATE talks SET state='ignored' WHERE id = ? AND state <= 'waiting_for_files'"
);
my
$unignore_talk
=
$dbh
->prepare(
"UPDATE talks SET state='waiting_for_files' WHERE id = ? AND state = 'ignored'"
);
my
$all_talks
=
$dbh
->prepare(
"SELECT id, upstreamid FROM talks WHERE event = ?"
);
my
$all_tracks
=
$dbh
->prepare(
"SELECT id, upstreamid FROM tracks"
);
foreach
my
$event
(@{
$parser
->events}) {
my
$st
=
$dbh
->prepare(
"SELECT id FROM events WHERE name = ?"
);
$st
->execute(
$event
->name) or
die
$!;
if
(
$st
->rows > 1) {
warn
"Multiple events with name \""
.
$event
->name .
"\", proceeding with first found one.\n"
;
}
elsif
(
$st
->rows == 0) {
$st
=
$dbh
->prepare(
"INSERT INTO events(name) VALUES(?) RETURNING id"
);
$st
->execute(
$event
->name) or
die
$!;
}
else
{
$st
=
$dbh
->prepare(
"SELECT id FROM events WHERE name = ?"
);
$st
->execute(
$event
->name) or
die
$!;
}
my
$row
=
$st
->fetchrow_arrayref;
my
$eventid
=
$row
->[0];
my
%known_talks
;
my
%roomid
;
my
%trackid
;
$all_talks
->execute(
$eventid
) or
die
$!;
while
(
$row
=
$all_talks
->fetchrow_arrayref) {
$known_talks
{
$row
->[1]} =
$row
->[0];
}
$all_tracks
->execute or
die
$!;
while
(
$row
=
$all_tracks
->fetchrow_arrayref) {
$trackid
{
$row
->[1]} =
$row
->[0];
}
TALK:
foreach
my
$talk
(@{
$event
->talks}) {
eval
{
next
TALK
if
$talk
->filtered;
$dbh
->begin_work;
my
$room
;
if
(
exists
(
$roomid
{
$talk
->room->name})) {
$room
=
$roomid
{
$talk
->room->name};
}
else
{
$search_room
->execute(
$talk
->room->name) or
die
$!;
if
(
$search_room
->rows > 1) {
warn
"Multiple rooms with name \""
.
$talk
->room->name .
"\", proceeding with first found one.\n"
;
}
elsif
(
$search_room
->rows == 0) {
$add_room
->execute(
$talk
->room->name,
$talk
->room->altname,
$talk
->room->outputname) or
die
$!;
$row
=
$add_room
->fetchrow_arrayref;
}
else
{
$row
=
$search_room
->fetchrow_arrayref;
if
(
defined
(
$talk
->room->altname) ||
defined
(
$talk
->room->outputname)) {
$update_room
->execute(
$talk
->room->altname,
$talk
->room->outputname,
$talk
->room->name);
}
}
$room
=
$row
->[0];
$roomid
{
$talk
->room->name} =
$room
;
}
my
$track
=
$talk
->track;
if
(
defined
(
$track
)) {
if
(
exists
(
$trackid
{
$talk
->track->upstreamid})) {
$track
=
$trackid
{
$talk
->track->upstreamid};
if
(
defined
(
$talk
->track->email)) {
$update_track
->execute(
$talk
->track->name,
$talk
->track->email,
$talk
->track->upstreamid);
}
}
else
{
$add_track
->execute(
$talk
->track->name,
$talk
->track->email,
$talk
->track->upstreamid) or
die
$!;
$row
=
$add_track
->fetchrow_arrayref;
$track
=
$row
->[0];
$trackid
{
$talk
->track->upstreamid} =
$track
;
}
}
my
$talkid
;
if
(
exists
(
$known_talks
{
$talk
->upstreamid})) {
$update_talk
->execute(
$room
,
$talk
->slug, DateTime::Format::Pg->format_timestamptz(
$talk
->starttime), DateTime::Format::Pg->format_timestamptz(
$talk
->endtime),
$talk
->title,
$talk
->subtitle,
$track
,
$known_talks
{
$talk
->upstreamid}) or
die
$!;
$talkid
=
$known_talks
{
$talk
->upstreamid};
$unignore_talk
->execute(
$known_talks
{
$talk
->upstreamid});
delete
$known_talks
{
$talk
->upstreamid};
}
else
{
$add_talk
->execute(
$room
,
$talk
->slug, DateTime::Format::Pg->format_timestamptz(
$talk
->starttime), DateTime::Format::Pg->format_timestamptz(
$talk
->endtime),
$talk
->title,
$eventid
,
$talk
->upstreamid,
$talk
->subtitle,
$track
,
$talk
->description) or
die
$!;
$row
=
$add_talk
->fetchrow_arrayref;
$talkid
=
$row
->[0];
}
if
(
defined
(
$talk
->flags)) {
my
$flags
= { %{
$talk
->flags} };
foreach
my
$flag
(
keys
%$flags
) {
if
(
$flags
->{
$flag
}) {
$flags
->{
$flag
} =
$JSON::true
;
}
else
{
$flags
->{
$flag
} =
$JSON::false
;
}
}
$flags
= encode_json(
$flags
);
$set_flags
->execute(
$flags
,
$flags
,
$talkid
);
}
$clear_speakers
->execute(
$talkid
) or
die
$!;
foreach
my
$speaker
(@{
$talk
->speakers}) {
$search_speaker
->execute(
$speaker
->upstreamid,
$eventid
) or
die
$!;
if
(
$search_speaker
->rows > 1) {
warn
"Multiple speakers with upstream ID \""
.
$speaker
->upstreamid .
"\", proceeding with first found one.\n"
;
}
elsif
(
$search_speaker
->rows == 0) {
$add_speaker
->execute(
$speaker
->email,
$speaker
->name,
$speaker
->upstreamid,
$eventid
) or
die
$!;
$row
=
$add_speaker
->fetchrow_arrayref;
}
else
{
$row
=
$search_speaker
->fetchrow_arrayref;
if
(
defined
(
$speaker
->email)) {
$update_speaker
->execute(
$speaker
->name,
$speaker
->email,
$speaker
->upstreamid);
}
}
my
$speakerid
=
$row
->[0];
$link_speaker
->execute(
$speakerid
,
$talkid
) or
die
$!;
}
$dbh
->commit;
};
if
($@) {
say
"Rolling back update of a talk due to schedule parser error: $@"
;
$dbh
->rollback;
}
}
foreach
my
$talkid
(
values
%known_talks
) {
$ignore_talk
->execute(
$talkid
);
}
}
$dbh
->commit;