Merge branch 'linkwarden:main' into fixes
This commit is contained in:
commit
fa051c0d4d
|
@ -86,17 +86,18 @@ export default async function archiveHandler(link: LinksAndCollectionAndOwner) {
|
||||||
image:
|
image:
|
||||||
user.archiveAsScreenshot && !link.image?.startsWith("archive")
|
user.archiveAsScreenshot && !link.image?.startsWith("archive")
|
||||||
? "pending"
|
? "pending"
|
||||||
: "unavailable",
|
: undefined,
|
||||||
pdf:
|
pdf:
|
||||||
user.archiveAsPDF && !link.pdf?.startsWith("archive")
|
user.archiveAsPDF && !link.pdf?.startsWith("archive")
|
||||||
? "pending"
|
? "pending"
|
||||||
: "unavailable",
|
: undefined,
|
||||||
|
monolith:
|
||||||
|
user.archiveAsMonolith && !link.monolith?.startsWith("archive")
|
||||||
|
? "pending"
|
||||||
|
: undefined,
|
||||||
readable: !link.readable?.startsWith("archive")
|
readable: !link.readable?.startsWith("archive")
|
||||||
? "pending"
|
? "pending"
|
||||||
: undefined,
|
: undefined,
|
||||||
monolith: !link.monolith?.startsWith("archive")
|
|
||||||
? "pending"
|
|
||||||
: undefined,
|
|
||||||
preview: !link.readable?.startsWith("archive")
|
preview: !link.readable?.startsWith("archive")
|
||||||
? "pending"
|
? "pending"
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "linkwarden",
|
"name": "linkwarden",
|
||||||
"version": "v2.6.0",
|
"version": "v2.6.2",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"repository": "https://github.com/linkwarden/linkwarden.git",
|
"repository": "https://github.com/linkwarden/linkwarden.git",
|
||||||
"author": "Daniel31X13 <daniel31x13@gmail.com>",
|
"author": "Daniel31X13 <daniel31x13@gmail.com>",
|
||||||
|
|
|
@ -79,10 +79,7 @@ const STRIPE_SECRET_KEY = process.env.STRIPE_SECRET_KEY;
|
||||||
|
|
||||||
const providers: Provider[] = [];
|
const providers: Provider[] = [];
|
||||||
|
|
||||||
if (
|
if (process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED !== "false") {
|
||||||
process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED === "true" ||
|
|
||||||
process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED === undefined
|
|
||||||
) {
|
|
||||||
// undefined is for backwards compatibility
|
// undefined is for backwards compatibility
|
||||||
providers.push(
|
providers.push(
|
||||||
CredentialsProvider({
|
CredentialsProvider({
|
||||||
|
|
|
@ -414,8 +414,7 @@ export function getLogins() {
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
credentialsEnabled:
|
credentialsEnabled:
|
||||||
process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED === "true" ||
|
process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED !== "false"
|
||||||
process.env.NEXT_PUBLIC_CREDENTIALS_ENABLED === undefined
|
|
||||||
? "true"
|
? "true"
|
||||||
: "false",
|
: "false",
|
||||||
emailEnabled:
|
emailEnabled:
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
// [Optional, but recommended]
|
|
||||||
|
|
||||||
// We decided that the "name" field should be the auto-generated field instead of the "description" field, so we need to
|
|
||||||
// move the data from the "description" field to the "name" field for links that have an empty name.
|
|
||||||
|
|
||||||
// This script is meant to be run only once.
|
|
||||||
|
|
||||||
// Run the script with `node scripts/migration/descriptionToName.js`
|
|
||||||
|
|
||||||
const { PrismaClient } = require("@prisma/client");
|
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
console.log("Starting...");
|
|
||||||
|
|
||||||
const count = await prisma.link.count({
|
|
||||||
where: {
|
|
||||||
name: "",
|
|
||||||
description: {
|
|
||||||
not: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`Applying the changes to ${count} ${
|
|
||||||
count == 1 ? "link" : "links"
|
|
||||||
} in 10 seconds...`
|
|
||||||
);
|
|
||||||
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 10000));
|
|
||||||
|
|
||||||
console.log("Applying the changes...");
|
|
||||||
|
|
||||||
const links = await prisma.link.findMany({
|
|
||||||
where: {
|
|
||||||
name: "",
|
|
||||||
description: {
|
|
||||||
not: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
description: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const link of links) {
|
|
||||||
await prisma.link.update({
|
|
||||||
where: {
|
|
||||||
id: link.id,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
name: link.description,
|
|
||||||
description: "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Done!");
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
.catch((e) => {
|
|
||||||
throw e;
|
|
||||||
})
|
|
||||||
.finally(async () => {
|
|
||||||
await prisma.$disconnect();
|
|
||||||
});
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
// Run the script with `node scripts/migration/v2.6.1/index.js`
|
||||||
|
// Docker users can run the script with `docker exec -it CONTAINER_ID /bin/bash -c 'node scripts/migration/v2.6.1/index.js'`
|
||||||
|
|
||||||
|
// There are two parts to this script:
|
||||||
|
|
||||||
|
// Firstly we decided that the "name" field should be the auto-generated field instead of the "description" field, so we need to
|
||||||
|
// move the data from the "description" field to the "name" field for links that have an empty name.
|
||||||
|
|
||||||
|
// Secondly it looks for every link and checks if the pdf/screenshot exist in the filesystem.
|
||||||
|
// If they do, it updates the link with the path in the db.
|
||||||
|
// If they don't, it passes.
|
||||||
|
|
||||||
|
const { S3 } = require("@aws-sdk/client-s3");
|
||||||
|
const { PrismaClient } = require("@prisma/client");
|
||||||
|
const { existsSync } = require("fs");
|
||||||
|
const util = require("util");
|
||||||
|
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
const STORAGE_FOLDER = process.env.STORAGE_FOLDER || "data";
|
||||||
|
|
||||||
|
const s3Client =
|
||||||
|
process.env.SPACES_ENDPOINT &&
|
||||||
|
process.env.SPACES_REGION &&
|
||||||
|
process.env.SPACES_KEY &&
|
||||||
|
process.env.SPACES_SECRET
|
||||||
|
? new S3({
|
||||||
|
forcePathStyle: false,
|
||||||
|
endpoint: process.env.SPACES_ENDPOINT,
|
||||||
|
region: process.env.SPACES_REGION,
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: process.env.SPACES_KEY,
|
||||||
|
secretAccessKey: process.env.SPACES_SECRET,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
async function checkFileExistence(path) {
|
||||||
|
if (s3Client) {
|
||||||
|
// One millisecond delay to avoid rate limiting
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1));
|
||||||
|
|
||||||
|
const bucketParams = {
|
||||||
|
Bucket: process.env.SPACES_BUCKET_NAME,
|
||||||
|
Key: path,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const headObjectAsync = util.promisify(
|
||||||
|
s3Client.headObject.bind(s3Client)
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await headObjectAsync(bucketParams);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Error:", err);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
if (existsSync(STORAGE_FOLDER + "/" + path)) {
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
console.log("Starting... Please do not interrupt the process.");
|
||||||
|
|
||||||
|
const linksWithoutName = await prisma.link.findMany({
|
||||||
|
where: {
|
||||||
|
name: "",
|
||||||
|
description: {
|
||||||
|
not: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
description: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const link of linksWithoutName) {
|
||||||
|
await prisma.link.update({
|
||||||
|
where: {
|
||||||
|
id: link.id,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
name: link.description,
|
||||||
|
description: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const links = await prisma.link.findMany({
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
collectionId: true,
|
||||||
|
image: true,
|
||||||
|
pdf: true,
|
||||||
|
readable: true,
|
||||||
|
monolith: true,
|
||||||
|
},
|
||||||
|
orderBy: { id: "asc" },
|
||||||
|
});
|
||||||
|
|
||||||
|
// PDFs
|
||||||
|
for (let link of links) {
|
||||||
|
const path = `archives/${link.collectionId}/${link.id}.pdf`;
|
||||||
|
|
||||||
|
const res = await checkFileExistence(path);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
await prisma.link.update({
|
||||||
|
where: { id: link.id },
|
||||||
|
data: { pdf: path },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Indexing the PDF for link:", link.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Screenshots (PNGs)
|
||||||
|
for (let link of links) {
|
||||||
|
const path = `archives/${link.collectionId}/${link.id}.png`;
|
||||||
|
|
||||||
|
const res = await checkFileExistence(path);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
await prisma.link.update({
|
||||||
|
where: { id: link.id },
|
||||||
|
data: { image: path },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Indexing the PNG for link:", link.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Screenshots (JPEGs)
|
||||||
|
for (let link of links) {
|
||||||
|
const path = `archives/${link.collectionId}/${link.id}.jpeg`;
|
||||||
|
|
||||||
|
const res = await checkFileExistence(path);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
await prisma.link.update({
|
||||||
|
where: { id: link.id },
|
||||||
|
data: { image: path },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Indexing the JPEG for link:", link.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
await prisma.$disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
Ŝarĝante…
Reference in New Issue