Skip to content

Commit

Permalink
add chat handling (#52)
Browse files Browse the repository at this point in the history
* add chat handling

* fix import and type

* whoops

* fix lint
  • Loading branch information
RyanHirsch authored Aug 31, 2024
1 parent aa6d432 commit bf770d5
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 184 deletions.
162 changes: 162 additions & 0 deletions src/parser/phase/__test__/phase-7.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/* eslint-disable sonarjs/no-duplicate-string */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import * as helpers from "../../__test__/helpers";
import { spliceFeed, spliceFirstItem } from "../../__test__/helpers";

const phase = 7;

describe("phase 7", () => {
let feed;
beforeAll(async () => {
feed = await helpers.loadSimple();
});

describe("chat", () => {
const supportedName = "chat";

function spliceInLiveItem(thisFeed: string, chatBlock: string, item = 0): string {
if (item > 2) {
throw new Error("Only three items eligible, zero based index");
}
return helpers.spliceFeed(
thisFeed,
`
<podcast:liveItem status="LIVE" start="2021-09-26T07:30:00.000-0600"
end="2021-09-26T08:30:00.000-0600">
<title>Podcasting 2.0 Live Stream</title>
<guid>e32b4890-983b-4ce5-8b46-f2d6bc1d8819</guid>
<enclosure url="https://example.com/pc20/livestream?format=.mp3" type="audio/mpeg" length="312" />
<podcast:contentLink href="https://example.com/html/livestream">Listen Live!</podcast:contentLink>
${item === 0 ? chatBlock : ""}
</podcast:liveItem>
<podcast:liveItem status="pending" start="2021-09-27T07:30:00.000-0600"
end="2021-09-27T08:30:00.000-0600">
<title>Podcasting 2.0 Live Stream</title>
<guid>e32b4890-983b-4ce5-8b46-f2d6bc1d8819</guid>
<enclosure url="https://example.com/pc20/livestream?format=.mp3" type="audio/mpeg" length="312" />
<podcast:contentLink href="https://example.com/html/livestream">Listen Live!</podcast:contentLink>
${item === 1 ? chatBlock : ""}
</podcast:liveItem>
<podcast:liveItem status="ENded" start="2021-09-28T07:30:00.000-0600"
end="2021-09-28T08:30:00.000-0600">
<title>Podcasting 2.0 Live Stream</title>
<guid>e32b4890-983b-4ce5-8b46-f2d6bc1d8819</guid>
<enclosure url="https://example.com/pc20/livestream?format=.mp3" type="audio/mpeg" length="312" />
<podcast:contentLink href="https://example.com/html/livestream">Listen Live!</podcast:contentLink>
${item === 2 ? chatBlock : ""}
</podcast:liveItem>
`
);
}
// parent is liveItem - https://github.com/Podcastindex-org/podcast-namespace/discussions/502
it("extracts IRC", () => {
const chatBlock = `<podcast:chat
server="irc.zeronode.net"
protocol="irc"
accountId="@jsmith"
space="#myawesomepodcast"
/>`;
const result = helpers.parseValidFeed(spliceInLiveItem(feed, chatBlock));

expect(result.podcastLiveItems).toHaveLength(3);
const [firstLIT] = result.podcastLiveItems ?? [];

expect(firstLIT.chat).toHaveProperty("server", "irc.zeronode.net");
expect(firstLIT.chat).toHaveProperty("protocol", "irc");
expect(firstLIT.chat).toHaveProperty("accountId", "@jsmith");
expect(firstLIT.chat).toHaveProperty("space", "#myawesomepodcast");
});

it("extracts XMPP", () => {
const chatBlock = `<podcast:chat
server="jabber.example.com"
protocol="XMPP"
accountId="[email protected]"
space="[email protected]"
/>`;
const result = helpers.parseValidFeed(spliceInLiveItem(feed, chatBlock));

expect(result.podcastLiveItems).toHaveLength(3);
const [firstLIT] = result.podcastLiveItems ?? [];

expect(firstLIT.chat).toHaveProperty("server", "jabber.example.com");
expect(firstLIT.chat).toHaveProperty("protocol", "xmpp");
expect(firstLIT.chat).toHaveProperty("accountId", "[email protected]");
expect(firstLIT.chat).toHaveProperty("space", "[email protected]");
});

it("extracts nostril", () => {
const chatBlock = `<podcast:chat
server="relay.example.com"
protocol="NoSTr"
accountId="npub1pvdw7mm7k20t9dn9gful8n5xua5yv8rmgd9wul88qq5dxj80lpxqd39r3u"
space="#myawesomepodcast_episode129"
/>`;

const result = helpers.parseValidFeed(spliceInLiveItem(feed, chatBlock, 2));

expect(result.podcastLiveItems).toHaveLength(3);
const [, , thirdLIT] = result.podcastLiveItems ?? [];

expect(thirdLIT.chat).toHaveProperty("server", "relay.example.com");
expect(thirdLIT.chat).toHaveProperty("protocol", "nostr");
expect(thirdLIT.chat).toHaveProperty(
"accountId",
"npub1pvdw7mm7k20t9dn9gful8n5xua5yv8rmgd9wul88qq5dxj80lpxqd39r3u"
);
expect(thirdLIT.chat).toHaveProperty("space", "#myawesomepodcast_episode129");
});

it("extracts matrix", () => {
const chatBlock = `<podcast:chat
server="jupiterbroadcasting.com"
protocol="matrix"
accountId="@chrislas:jupiterbroadcasting.com"
space="#general:jupiterbroadcasting.com"
/>`;
const result = helpers.parseValidFeed(spliceInLiveItem(feed, chatBlock));

expect(result.podcastLiveItems).toHaveLength(3);
const [firstLIT] = result.podcastLiveItems ?? [];

expect(firstLIT.chat).toHaveProperty("server", "jupiterbroadcasting.com");
expect(firstLIT.chat).toHaveProperty("protocol", "matrix");
expect(firstLIT.chat).toHaveProperty("accountId", "@chrislas:jupiterbroadcasting.com");
expect(firstLIT.chat).toHaveProperty("space", "#general:jupiterbroadcasting.com");
});

it("extracts IRC for item level", () => {
const chatBlock = `<podcast:chat
server="irc.zeronode.net"
protocol="irc"
accountId="@jsmith"
space="#myawesomepodcast"
/>`;
const result = helpers.parseValidFeed(spliceFirstItem(feed, chatBlock));

const [firstItem] = result.items ?? [];

expect(firstItem.chat).toHaveProperty("server", "irc.zeronode.net");
expect(firstItem.chat).toHaveProperty("protocol", "irc");
expect(firstItem.chat).toHaveProperty("accountId", "@jsmith");
expect(firstItem.chat).toHaveProperty("space", "#myawesomepodcast");
});

it("extracts XMPP from the feed", () => {
const chatBlock = `<podcast:chat
server="jabber.example.com"
protocol="XMPP"
accountId="[email protected]"
space="[email protected]"
/>`;
const result = helpers.parseValidFeed(spliceFeed(feed, chatBlock));

expect(result.chat).toHaveProperty("server", "jabber.example.com");
expect(result.chat).toHaveProperty("protocol", "xmpp");
expect(result.chat).toHaveProperty("accountId", "[email protected]");
expect(result.chat).toHaveProperty("space", "[email protected]");
expect(helpers.getPhaseSupport(result, phase)).toContain(supportedName);
});
});
});
118 changes: 0 additions & 118 deletions src/parser/phase/__test__/phase-pending.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,124 +469,6 @@ describe("phase pending", () => {
});
});

describe("chat", () => {
function spliceInLiveItem(thisFeed: string, chatBlock: string, item = 0): string {
if (item > 2) {
throw new Error("Only three items eligible, zero based index");
}
return helpers.spliceFeed(
thisFeed,
`
<podcast:liveItem status="LIVE" start="2021-09-26T07:30:00.000-0600"
end="2021-09-26T08:30:00.000-0600">
<title>Podcasting 2.0 Live Stream</title>
<guid>e32b4890-983b-4ce5-8b46-f2d6bc1d8819</guid>
<enclosure url="https://example.com/pc20/livestream?format=.mp3" type="audio/mpeg" length="312" />
<podcast:contentLink href="https://example.com/html/livestream">Listen Live!</podcast:contentLink>
${item === 0 ? chatBlock : ""}
</podcast:liveItem>
<podcast:liveItem status="pending" start="2021-09-27T07:30:00.000-0600"
end="2021-09-27T08:30:00.000-0600">
<title>Podcasting 2.0 Live Stream</title>
<guid>e32b4890-983b-4ce5-8b46-f2d6bc1d8819</guid>
<enclosure url="https://example.com/pc20/livestream?format=.mp3" type="audio/mpeg" length="312" />
<podcast:contentLink href="https://example.com/html/livestream">Listen Live!</podcast:contentLink>
${item === 1 ? chatBlock : ""}
</podcast:liveItem>
<podcast:liveItem status="ENded" start="2021-09-28T07:30:00.000-0600"
end="2021-09-28T08:30:00.000-0600">
<title>Podcasting 2.0 Live Stream</title>
<guid>e32b4890-983b-4ce5-8b46-f2d6bc1d8819</guid>
<enclosure url="https://example.com/pc20/livestream?format=.mp3" type="audio/mpeg" length="312" />
<podcast:contentLink href="https://example.com/html/livestream">Listen Live!</podcast:contentLink>
${item === 2 ? chatBlock : ""}
</podcast:liveItem>
`
);
}
// parent is liveItem - https://github.com/Podcastindex-org/podcast-namespace/discussions/502
it("extracts IRC", () => {
const chatBlock = `<podcast:chat
server="irc.zeronode.net"
protocol="irc"
accountId="@jsmith"
space="#myawesomepodcast"
embedUrl="https://map.example.org/chat/iframe.html"
/>`;
const result = helpers.parseValidFeed(spliceInLiveItem(feed, chatBlock));

expect(result.podcastLiveItems).toHaveLength(3);
const [firstLIT] = result.podcastLiveItems ?? [];

expect(firstLIT.chat).toHaveProperty("server", "irc.zeronode.net");
expect(firstLIT.chat).toHaveProperty("protocol", "irc");
expect(firstLIT.chat).toHaveProperty("accountId", "@jsmith");
expect(firstLIT.chat).toHaveProperty("space", "#myawesomepodcast");
expect(firstLIT.chat).toHaveProperty("embedUrl", "https://map.example.org/chat/iframe.html");
});

it("extracts XMPP", () => {
const chatBlock = `<podcast:chat
server="jabber.example.com"
protocol="XMPP"
accountId="[email protected]"
space="[email protected]"
/>`;
const result = helpers.parseValidFeed(spliceInLiveItem(feed, chatBlock));

expect(result.podcastLiveItems).toHaveLength(3);
const [firstLIT] = result.podcastLiveItems ?? [];

expect(firstLIT.chat).toHaveProperty("server", "jabber.example.com");
expect(firstLIT.chat).toHaveProperty("protocol", "xmpp");
expect(firstLIT.chat).toHaveProperty("accountId", "[email protected]");
expect(firstLIT.chat).toHaveProperty("space", "[email protected]");
expect(firstLIT.chat).not.toHaveProperty("embedUrl");
});

it("extracts nostril", () => {
const chatBlock = `<podcast:chat
server="relay.example.com"
protocol="NoSTr"
accountId="npub1pvdw7mm7k20t9dn9gful8n5xua5yv8rmgd9wul88qq5dxj80lpxqd39r3u"
space="#myawesomepodcast_episode129"
/>`;

const result = helpers.parseValidFeed(spliceInLiveItem(feed, chatBlock, 2));

expect(result.podcastLiveItems).toHaveLength(3);
const [, , thirdLIT] = result.podcastLiveItems ?? [];

expect(thirdLIT.chat).toHaveProperty("server", "relay.example.com");
expect(thirdLIT.chat).toHaveProperty("protocol", "nostr");
expect(thirdLIT.chat).toHaveProperty(
"accountId",
"npub1pvdw7mm7k20t9dn9gful8n5xua5yv8rmgd9wul88qq5dxj80lpxqd39r3u"
);
expect(thirdLIT.chat).toHaveProperty("space", "#myawesomepodcast_episode129");
expect(thirdLIT.chat).not.toHaveProperty("embedUrl");
});

it("extracts matrix", () => {
const chatBlock = `<podcast:chat
server="jupiterbroadcasting.com"
protocol="matrix"
accountId="@chrislas:jupiterbroadcasting.com"
space="#general:jupiterbroadcasting.com"
/>`;
const result = helpers.parseValidFeed(spliceInLiveItem(feed, chatBlock));

expect(result.podcastLiveItems).toHaveLength(3);
const [firstLIT] = result.podcastLiveItems ?? [];

expect(firstLIT.chat).toHaveProperty("server", "jupiterbroadcasting.com");
expect(firstLIT.chat).toHaveProperty("protocol", "matrix");
expect(firstLIT.chat).toHaveProperty("accountId", "@chrislas:jupiterbroadcasting.com");
expect(firstLIT.chat).toHaveProperty("space", "#general:jupiterbroadcasting.com");
expect(firstLIT.chat).not.toHaveProperty("embedUrl");
});
});

describe("liveValue", () => {
function addLiveValueToFeed(thisFeed: string, liveValue: string): string {
return helpers.spliceFeed(
Expand Down
5 changes: 5 additions & 0 deletions src/parser/phase/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import * as phase3 from "./phase-3";
import * as phase4 from "./phase-4";
import * as phase5 from "./phase-5";
import * as phase6 from "./phase-6";
import * as phase7 from "./phase-7";
import * as pending from "./phase-pending";
import { XmlNodeSource } from "./types";

Expand Down Expand Up @@ -88,6 +89,8 @@ const feeds: FeedUpdate[] = [
phase6.remoteItem,
phase6.podroll,

phase7.podcastChat,

pending.id,
pending.social,
pending.podcastRecommendations,
Expand All @@ -113,6 +116,8 @@ const items: ItemUpdate[] = [

phase6.txt,

phase7.podcastChat,

pending.podcastRecommendations,
pending.podcastGateway,
];
Expand Down
5 changes: 3 additions & 2 deletions src/parser/phase/phase-4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import type { EmptyObj, Episode, XmlNode } from "../types";
import * as ItemParser from "../item";

import { addSubTag, getSubTags, useParser } from "./helpers";
import type { PhasePendingChat, PhasePendingLiveUpdates } from "./phase-pending";
import type { PhasePendingLiveUpdates } from "./phase-pending";
import type { Phase7Chat } from "./phase-7";
import { extractRecipients, validRecipient } from "./value-helpers";
import type { Phase6ValueTimeSplit } from "./phase-6";

Expand Down Expand Up @@ -228,7 +229,7 @@ export type Phase4PodcastLiveItemItem = Pick<Episode, "title" | "guid" | "enclos
// phased in properties assumed to be dynamically added via addSubTag

// Pending
chat?: PhasePendingChat | { phase: "4"; url: string };
chat?: Phase7Chat | { phase: "4"; url: string };
/** PENDING AND LIKELY TO CHANGE */
liveUpdates?: PhasePendingLiveUpdates;
};
Expand Down
Loading

0 comments on commit bf770d5

Please sign in to comment.