peertube-plugin-transposer-connector
Version:
Transposer connector is a PeerTube language tool plugin to transcribe and translate with Whisper
276 lines (234 loc) • 8.11 kB
JavaScript
const { v4: uuidv4 } = require("uuid");
class LanguageMetadataDAO {
constructor(peertubeHelpers) {
this.peertubeHelpers = peertubeHelpers;
this.initializeDatabase();
}
async initializeDatabase() {
const createTableQuery = `
CREATE TABLE IF NOT EXISTS fairkom_language_metadata (
id VARCHAR(36) PRIMARY KEY,
fk_video_id INTEGER REFERENCES video(id) ON DELETE CASCADE,
language TEXT,
attribute TEXT,
value TEXT,
type TEXT,
created_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
modified_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`;
try {
const result = await this.peertubeHelpers.database.query(
createTableQuery
);
console.log("fairkom_language_metadata table created successfully");
} catch (error) {
console.error("Error creating fairkom_language_metadata table:", error);
}
}
// Helper function to escape SQL strings
escapeSQL(value) {
if (value === null || value === undefined) {
return "NULL";
}
if (typeof value === "number" || typeof value === "boolean") {
return value.toString();
}
// For strings, replace single quotes with two single quotes (SQL standard)
return value.toString().replace(/'/g, "''");
}
async formatResult(result) {
if (!result || result.length === 0) {
return {};
}
const groupedAttributes = {};
result.forEach((item) => {
const { attribute, language, value } = item;
if (!groupedAttributes[attribute]) {
groupedAttributes[attribute] = {};
}
groupedAttributes[attribute][language] = value;
});
return groupedAttributes;
}
async addLanguagedMetadata(fkVideoId, metadata) {
console.log("LanguageMetadataDAO: addLanguagedMetadata");
console.log(metadata);
if (!metadata) {
throw new Error("Metadata is missing.");
}
try {
const deleteQuery = `
DELETE FROM fairkom_language_metadata
WHERE fk_video_id = '${this.escapeSQL(fkVideoId)}'
`;
await this.peertubeHelpers.database.query(deleteQuery);
const insertQueries = [];
for (const language in metadata) {
const attributes = metadata[language];
for (const attribute in attributes) {
const value = attributes[attribute];
if (value !== null && value !== undefined) {
var metadataId = uuidv4();
var type = attribute == "tags" ? "array" : "string";
insertQueries.push([
metadataId,
fkVideoId,
language,
attribute,
value,
type,
]);
}
}
}
if (insertQueries.length === 0) {
throw new Error("No valid metadata found to insert.");
}
const query = `
INSERT INTO fairkom_language_metadata (id, fk_video_id, language, attribute, value, type)
VALUES
${insertQueries
.map((queryValues) => {
// Properly escape special characters, especially single quotes
const escapedValues = queryValues.map((value) =>
this.escapeSQL(value)
);
return `('${escapedValues.join("','")}')`;
})
.join(",")}
`;
console.log("language Metadata Query", query);
const result = await this.peertubeHelpers.database.query(query);
console.log(`Metadata added successfully`, result);
return true;
} catch (error) {
console.error("Error adding metadata:", error);
throw error;
}
}
async formatResult(result) {
if (!result || result.length === 0) {
return {};
}
const groupedByLanguage = {};
result.forEach((item) => {
const { attribute, language, value } = item;
if (!groupedByLanguage[language]) {
groupedByLanguage[language] = {};
}
groupedByLanguage[language][attribute] = value;
});
return groupedByLanguage;
}
async updateLanguageMetadata(fkVideoId, language, attribute, value) {
const escapedValue = this.escapeSQL(value);
const escapedFkVideoId = this.escapeSQL(fkVideoId);
const escapedLanguage = this.escapeSQL(language);
const escapedAttribute = this.escapeSQL(attribute);
const updateQuery = `
UPDATE fairkom_language_metadata
SET value = '${escapedValue}',
modified_date = CURRENT_TIMESTAMP
WHERE fk_video_id = '${escapedFkVideoId}'
AND language = '${escapedLanguage}'
AND attribute = '${escapedAttribute}'
`;
try {
const result = await this.peertubeHelpers.database.query(updateQuery);
console.log(`Updated fairkom_language_metadata:`, result);
return result.rowCount; // Use rowCount for PostgreSQL
} catch (error) {
console.error("Error updating fairkom_language_metadata:", error);
throw error;
}
}
async findLanguageMetadata(fkVideoId, language, attribute) {
const escapedFkVideoId = this.escapeSQL(fkVideoId);
const escapedLanguage = this.escapeSQL(language);
const escapedAttribute = this.escapeSQL(attribute);
const findQuery = `
SELECT * FROM fairkom_language_metadata
WHERE fk_video_id = ${escapedFkVideoId}
AND language = '${escapedLanguage}'
AND attribute = '${escapedAttribute}';
`;
try {
const result = await this.peertubeHelpers.database.query(findQuery);
console.log("Found fairkom_language_metadata:", result[0]);
return result[0];
} catch (error) {
console.error("Error finding fairkom_language_metadata:", error);
throw error;
}
}
async findLanguageMetadataById(fkVideoId) {
console.log("findLanguageMetadataById 1");
console.log(fkVideoId);
const escapedFkVideoId = this.escapeSQL(fkVideoId);
const findlanguageQuery = `
SELECT attribute, "language", MAX(value) AS value
FROM fairkom_language_metadata
WHERE fk_video_id = '${escapedFkVideoId}'
GROUP BY attribute, "language"
ORDER BY attribute;
`;
try {
const result = await this.peertubeHelpers.database.query(
findlanguageQuery
);
console.log("Found fairkom_language_metadata:", result);
const formatedResult = await this.formatResult(result[0]);
return formatedResult;
} catch (error) {
console.error("Error finding fairkom_language_metadata:", error);
throw error;
}
}
async findLanguageMetadataByIdAndLanguages(fkVideoId, languages) {
const escapedFkVideoId = this.escapeSQL(fkVideoId);
let languageFilter = "";
if (languages && languages.length > 0) {
const escapedLanguages = languages.map((lang) => this.escapeSQL(lang));
languageFilter = `AND "language" IN ('${escapedLanguages.join("','")}')`;
}
const findlanguageQuery = `
SELECT attribute, "language", MAX(value) AS value
FROM fairkom_language_metadata
WHERE fk_video_id = '${escapedFkVideoId}' ${languageFilter}
GROUP BY attribute, "language"
ORDER BY attribute;
`;
try {
const result = await this.peertubeHelpers.database.query(
findlanguageQuery
);
console.log("Found fairkom_language_metadata:", result[0]);
return result[0];
} catch (error) {
console.error("Error finding fairkom_language_metadata:", error);
throw error;
}
}
async findLanguageMetadataByUuid(fkVideoUuid) {
const escapedFkVideoUuid = this.escapeSQL(fkVideoUuid);
const findlanguageQuery = `
SELECT * FROM fairkom_language_metadata
WHERE video_uuid = '${escapedFkVideoUuid}'
ORDER BY created_date DESC;
`;
try {
const result = await this.peertubeHelpers.database.query(
findlanguageQuery
);
console.log("Found fairkom_language_metadata:", result[0]);
return result[0];
} catch (error) {
console.error("Error finding fairkom_language_metadata:", error);
throw error;
}
}
}
module.exports = {
LanguageMetadataDAO,
};