Skip to content

Commit

Permalink
Fixed names and details for metadata fetcher and video downloader.
Browse files Browse the repository at this point in the history
  • Loading branch information
jMyles committed Jan 16, 2025
1 parent 943e605 commit 15bd966
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 90 deletions.
71 changes: 15 additions & 56 deletions __tests__/video_fetch_tests.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import { jest } from '@jest/globals';
import { Collection } from 'discord.js';
import { blueRailroadContractAddress } from '../src/build_logic/constants.js';

const mockFs = {
existsSync: jest.fn(() => false),
writeFileSync: jest.fn(),
mkdirSync: jest.fn()
};

const mockMessage = {
attachments: new Collection([
Expand All @@ -28,11 +21,6 @@ const mockClient = {
};

// Set up all mocks
jest.unstable_mockModule('fs', () => ({
default: mockFs,
__esModule: true
}));

jest.unstable_mockModule('discord.js', () => ({
Client: jest.fn(() => mockClient),
GatewayIntentBits: {
Expand All @@ -41,55 +29,26 @@ jest.unstable_mockModule('discord.js', () => ({
GuildMessages: 3
}
}));
jest.unstable_mockModule('node-fetch', () => ({
default: jest.fn(() => Promise.resolve({
buffer: () => Promise.resolve(Buffer.from('video data'))
}))
}));

// Import the functions we want to test - TODO: Move this to a shared file? Or only do it in one module? It's a pain.
let fetchDiscordVideos, generateVideoFilename;
// Import the functions we want to test
let generateVideoMetadata;
beforeAll(async () => {
const module = await import('../src/build_logic/discord_video_fetcher.js');
fetchDiscordVideos = module.fetchDiscordVideos;
generateVideoFilename = module.generateVideoFilename;
generateVideoMetadata = module.generateVideoMetadata;
});

describe('Discord Video Fetcher', () => {
test('downloads new video if not exists', async () => {
describe('Discord Video Metadata Generator', () => {
test('generates metadata for discord video url', async () => {
const testUrl = 'https://discord.com/channels/server/channel/message';
await fetchDiscordVideos([testUrl]);
expect(mockFs.existsSync).toHaveBeenCalled();
expect(mockFs.writeFileSync).toHaveBeenCalled();
const metadata = await generateVideoMetadata([testUrl]);

expect(metadata).toHaveLength(1);
expect(metadata[0]).toEqual(expect.objectContaining({
originalUrl: testUrl,
discordUrl: expect.any(String),
fileName: expect.stringMatching(/\.mp4$/),
timestamp: expect.any(Number),
contentType: expect.stringMatching(/^video\//)
}));
});
});

describe('Video Filename Generation', () => {
test('generates correct filename format', () => {
const tokenId = '42';
const token = {
id: tokenId,
uri: 'https://discord.com/something/video.mp4'
};

const filename = generateVideoFilename(token, token.uri);
const metadataFromFilename = filename.split('.')[0];
const chainId = metadataFromFilename.split('-')[0];
const contractAddress = metadataFromFilename.split('-')[1];
const tokenIdFromFilename = metadataFromFilename.split('-')[2];
expect(chainId).toBe('10'); // Optimism. OK. But what if it's not?
expect(blueRailroadContractAddress).toContain(contractAddress);
expect(tokenIdFromFilename).toBe(tokenId);
});

test('handles different file extensions', () => {
const token = {
id: '42',
uri: 'https://discord.com/something/video.webm'
};

const filename = generateVideoFilename(token, token.uri);
expect(filename).toMatch(/\.webm$/);
});

});
2 changes: 1 addition & 1 deletion src/build_logic/chain_reading.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export async function appendSetStoneDataToShows(showsChainData, config) {

///////////BACK TO TONY

async function getBlueRailroads(config) {
export async function getBlueRailroads(config) {
console.time("blue-railroads");
const blueRailroadCount = await readContract(config,
{
Expand Down
41 changes: 10 additions & 31 deletions src/build_logic/discord_video_fetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ export async function downloadVideos(metadataList, outputDir) {
}
}

export async function fetchDiscordVideos(messageUrls) {
const { fetchedAssetsDir } = getProjectDirs();
export async function generateVideoMetadata(messageUrls) {
const client = new Client({
intents: [
GatewayIntentBits.MessageContent,
Expand All @@ -55,60 +54,40 @@ export async function fetchDiscordVideos(messageUrls) {

try {
await client.login(process.env.DISCORD_BOT_TOKEN);

const videos = [];
const metadata = [];

for (const url of messageUrls) {
const { channelId, messageId } = parseDiscordUrl(url);
const videoFileName = `${messageId}.mp4`;
const videoPath = path.join(fetchedAssetsDir, videoFileName);

// Check if we already have this video
if (fs.existsSync(videoPath)) {
videos.push({
originalUrl: url,
localPath: videoPath,
fileName: videoFileName
});
continue;
}
let message;
let videoAttachment;

try {
const channel = await client.channels.fetch(channelId);
message = await channel.messages.fetch(messageId);

videoAttachment = message.attachments.find(
attachment => attachment.contentType?.startsWith('video/')
);

} catch (messageError) {
console.warn(`Failed to fetch message from ${url}:`, messageError);
continue;
}
try {
if (videoAttachment) {
await downloadVideo(videoAttachment.url, videoPath);
videos.push({
metadata.push({
originalUrl: url,
localPath: videoPath,
discordUrl: videoAttachment.url,
fileName: videoFileName,
timestamp: message.createdTimestamp
timestamp: message.createdTimestamp,
contentType: videoAttachment.contentType
});
} else {
console.warn(`No video found in message ${url}`);
continue;
}
} catch (messageError) {
console.warn(`Found message, but had problems fetching video from ${url}:`, messageError);
} catch (error) {
console.warn(`Failed to fetch message from ${url}:`, error);
}
}

await client.destroy();
return videos;
return metadata;
} catch (error) {
console.error('Error fetching Discord videos:', error);
console.error('Error fetching Discord video metadata:', error);
throw error;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/build_logic/fetch_video_metadata.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { generateVideoMetadata } from './discord_video_fetcher.js';
import { fetchedAssetsDir } from './constants.js';
import { blueRailroadContractAddress } from 'js/constants.js';
import { blueRailroadContractAddress } from './constants.js';
import { getProjectDirs } from './locations.js';
import { createConfig, http } from '@wagmi/core';
import { mainnet, optimism } from '@wagmi/core/chains';
import fs from 'fs';
Expand All @@ -12,6 +12,7 @@ import { getBlueRailroads } from './chain_reading.js';
dotenv.config();

async function getBlueRailroadMetadata() {
const { fetchedAssetsDir } = getProjectDirs();
const spinner = ora('Reading Blue Railroad contract data').start();

try {
Expand Down

0 comments on commit 15bd966

Please sign in to comment.