Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pick out useful commits from last year's hotfixes #219

Merged
merged 6 commits into from
Feb 1, 2024
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
4 changes: 2 additions & 2 deletions src/Conference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -855,8 +855,8 @@ export class Conference {
const until = Date.now() + inNextMinutes * 60000;

const upcomingTalks: ITalk[] = [];
for (const t of Object.values(this.talks)) {
const talk = await t.getDefinition();
// Use this.backend.talks because we care about physical talks here too.
for (const talk of this.backend.talks.values()) {
const talkEventTime = lambda(talk);
// If null is returned then the talk does not have this event, so don't return it as upcoming.
if (talkEventTime === null) continue;
Expand Down
17 changes: 12 additions & 5 deletions src/Scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@ export class Scheduler {
} else {
await this.client.sendHtmlText(confAud.roomId, `<h3>The talk will end shortly</h3>`);
}
} else if (task.type === ScheduledTaskType.TalkStart1H && confTalk !== undefined) {
} else if (task.type === ScheduledTaskType.TalkStart1H) {
if (confTalk === undefined) return;
// This stage is skipped entirely for physical auditoriums' talks, because it only serves to nag
// TODO Do we need to ensure that coordinators have checked in?

Expand Down Expand Up @@ -445,11 +446,15 @@ export class Scheduler {
await this.client.sendHtmlText(confTalk.roomId, `<h3>Your talk ends in about 5 minutes</h3><p>The next talk will start automatically after yours.</p>`);
}
await this.client.sendHtmlText(confAud.roomId, `<h3>This talk ends in about 5 minutes</h3>` + (task.talk.qa_startTime !== null ? `<p>Ask questions here for the speakers!</p>`: ''));
} else if (task.type === ScheduledTaskType.TalkLivestreamEnd1M && confTalk !== undefined) {
} else if (task.type === ScheduledTaskType.TalkLivestreamEnd1M) {
if (confTalk === undefined) return;
await this.client.sendHtmlText(confTalk.roomId, `<h3>Your talk ends in about 1 minute!</h3><p>The next talk will start automatically after yours. Wrap it up!</p>`);
} else if (task.type === ScheduledTaskType.TalkEnd1M) {
// It's a bit spammy for a physical talk.
if (confTalk === undefined) return;
await this.client.sendHtmlText(confAud.roomId, `<h3>This talk ends in about 1 minute!</h3>`);
} else if (task.type === ScheduledTaskType.TalkCheckin45M && confTalk !== undefined) {
} else if (task.type === ScheduledTaskType.TalkCheckin45M) {
if (confTalk === undefined) return;
// TODO This is skipped entirely for physical talks, but do we want to ensure coordinators are checked-in?

if (!task.talk.prerecorded) return;
Expand Down Expand Up @@ -486,7 +491,8 @@ export class Scheduler {
const resolved = (await resolveIdentifiers(this.client, userIds)).filter(p => p.mxid).map(p => p.mxid!);
await this.checkins.expectCheckinFrom(resolved);
}
} else if (task.type === ScheduledTaskType.TalkCheckin30M && confTalk !== undefined) {
} else if (task.type === ScheduledTaskType.TalkCheckin30M) {
if (confTalk === undefined) return;
// TODO This is skipped entirely for physical talks, but do we want to ensure coordinators are checked-in?

if (!task.talk.prerecorded) return;
Expand Down Expand Up @@ -523,7 +529,8 @@ export class Scheduler {
const resolved = (await resolveIdentifiers(this.client, userIds)).filter(p => p.mxid).map(p => p.mxid!);
await this.checkins.expectCheckinFrom(resolved);
} // else no complaints
} else if (task.type === ScheduledTaskType.TalkCheckin15M && confTalk !== undefined) {
} else if (task.type === ScheduledTaskType.TalkCheckin15M) {
if (confTalk === undefined) return;
// TODO This is skipped entirely for physical talks, but do we want to ensure coordinators are checked-in?

if (!task.talk.prerecorded) return;
Expand Down
7 changes: 4 additions & 3 deletions src/commands/InviteCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,13 @@ export class InviteCommand implements ICommand {
} else if (args[0] && args[0] === "coordinators-support") {
let people: IPerson[] = [];
for (const aud of this.conference.storedAuditoriums) {
if (!(await aud.getId()).startsWith("D.")) {
// This hack was not wanted in 2023 or 2024.
// if (!(await aud.getId()).startsWith("D.")) {
// HACK: Only invite coordinators for D.* auditoriums.
// TODO: Make invitations for support rooms more configurable.
// https://github.com/matrix-org/this.conference-bot/issues/76
continue;
}
// continue;
// }

const inviteTargets = await this.conference.getInviteTargetsForAuditorium(aud, true);
people.push(...inviteTargets.filter(i => i.role === Role.Coordinator));
Expand Down
15 changes: 10 additions & 5 deletions src/commands/actions/people.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { LogService, MatrixClient } from "matrix-bot-sdk";
import { LogLevel, LogService, MatrixClient } from "matrix-bot-sdk";
import { ResolvedPersonIdentifier, resolveIdentifiers } from "../../invites";
import { Auditorium } from "../../models/Auditorium";
import { Conference } from "../../Conference";
import { asyncFilter } from "../../utils";
import { InterestRoom } from "../../models/InterestRoom";
import { ConferenceMatrixClient } from "../../ConferenceMatrixClient";
import { logMessage } from "../../LogProxy";

export interface IAction {
(client: MatrixClient, roomId: string, people: ResolvedPersonIdentifier[]): Promise<void>;
Expand Down Expand Up @@ -60,9 +61,12 @@ export async function doAuditoriumResolveAction(
? await conference.getInviteTargetsForAuditorium(realAud)
: await conference.getModeratorsForAuditorium(realAud);
const resolvedAudPeople = audPeople.map(p => allPossiblePeople.find(b => p.id === b.person.id));
if (resolvedAudPeople.some(p => !p)) throw new Error(`Failed to resolve all targets for auditorium ${audId}`);
if (resolvedAudPeople.some(p => !p)) {
logMessage(LogLevel.WARN, "people", `Failed to resolve all targets for auditorium ${audId}. Inviting others anyway.`, client);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what the difference between logMessage and LogService (i.e. LogService.warn) which I see being used a lot but if it works, it works :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logMessage sends a message to the room, LogService.xxx is for the program's logs

I think

}

await action(client, realAud.roomId, resolvedAudPeople as ResolvedPersonIdentifier[]);
const resolvedAudPeopleOnly = resolvedAudPeople.filter(p => !!p);
await action(client, realAud.roomId, resolvedAudPeopleOnly as ResolvedPersonIdentifier[]);

if (!skipTalks) {
const talks = await asyncFilter(
Expand All @@ -80,10 +84,11 @@ export async function doAuditoriumResolveAction(
const unresolveable = talkPeople.filter(
p => allPossiblePeople.find(b => p.id === b.person.id) === undefined
)
throw new Error(`Failed to resolve all targets for talk ${await talk.getId()}: ` + JSON.stringify(unresolveable));
logMessage(LogLevel.WARN, "people", `Failed to resolve all targets for talk ${await talk.getId()}: ` + JSON.stringify(unresolveable), client);
}

await action(client, talk.roomId, resolvedTalkPeople as ResolvedPersonIdentifier[]);
const resolvedTalkPeopleOnly = resolvedTalkPeople.filter(p => !!p);
await action(client, talk.roomId, resolvedTalkPeopleOnly as ResolvedPersonIdentifier[]);
}
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@ export function renderAuditoriumWidget(req: Request, res: Response, conference:
return res.sendStatus(404);
}

//let sid = audId.toLowerCase().replace(/[^a-z0-9]/g, '');

// HACK for FOSDEM 2023 and FOSDEM 2024: transform auditorium IDs to the livestream ID
// 1. 'K1.105A (Words)' -> 'k1.105a'
// 2. 'k1.105a' -> 'k1105a'
let sid = audId.toLowerCase().replace(/\s+\(.+\)$/, '').replace(/[^a-z0-9]/g, '');

const streamUrl = template(auditoriumUrl, {
id: audId.toLowerCase(),
sId: audId.toLowerCase().replace(/[^a-z0-9]/g, ''),
sId: sid
});

return res.render('auditorium.liquid', {
Expand Down
Loading