Make clients opt into creating a page when uploading a file

This commit is contained in:
Jackson Harper 2022-05-26 13:35:30 -07:00
parent c3096e5dfe
commit cb98a9cf86
7 changed files with 62 additions and 27 deletions

View file

@ -1992,7 +1992,9 @@ export enum UploadFileRequestErrorCode {
}
export type UploadFileRequestInput = {
clientRequestId?: InputMaybe<Scalars['String']>;
contentType: Scalars['String'];
createPageEntry?: InputMaybe<Scalars['Boolean']>;
url: Scalars['String'];
};

View file

@ -1535,7 +1535,9 @@ enum UploadFileRequestErrorCode {
}
input UploadFileRequestInput {
clientRequestId: String
contentType: String!
createPageEntry: Boolean
url: String!
}

View file

@ -51,6 +51,7 @@ import {
stringToHash,
userDataToUser,
validatedDate,
titleForFilePath,
} from '../../utils/helpers'
import {
ParsedContentPuppeteer,
@ -166,6 +167,7 @@ export const createArticleResolver = authorized<
.join('.')
).replace(/_/gi, ' ')
let title: string | undefined
let parsedContent: Readability.ParseResult | null = null
let canonicalUrl
let userArticleUrl: string | null = null
@ -219,6 +221,7 @@ export const createArticleResolver = authorized<
userArticleUrl = uploadFileDetails.fileUrl
canonicalUrl = uploadFile.url
pageType = PageType.File
title = titleForFilePath(uploadFile.url)
} else if (
source !== 'puppeteer-parse' &&
FORCE_PUPPETEER_URLS.some((regex) => regex.test(url))
@ -252,6 +255,7 @@ export const createArticleResolver = authorized<
content: parsedContent?.content || '',
description: parsedContent?.excerpt || '',
title:
title ||
parsedContent?.title ||
preparedDocument?.pageInfo.title ||
croppedPathname,
@ -333,7 +337,6 @@ export const createArticleResolver = authorized<
} else {
// update existing page's state from processing to succeeded
articleToSave.archivedAt = archive ? saveTime : undefined
articleToSave.url = uploadFileUrlOverride || articleToSave.url
const updated = await updatePage(pageId, articleToSave, {
...ctx,
uid,

View file

@ -16,7 +16,7 @@ import path from 'path'
import normalizeUrl from 'normalize-url'
import { analytics } from '../../utils/analytics'
import { env } from '../../env'
import { createPage } from '../../elastic/pages'
import { createPage, getPageByParam, updatePage } from '../../elastic/pages'
import { PageType } from '../../elastic/types'
import { generateSlug } from '../../utils/helpers'
@ -82,28 +82,40 @@ export const uploadFileRequestResolver: ResolverFn<
input.contentType
)
const pageId = await createPage(
{
id: '',
url: input.url,
if (input.createPageEntry) {
let page = await getPageByParam({
userId: claims.uid,
title: title,
hash: uploadFilePathName,
content: '',
pageType: PageType.File,
uploadFileId: uploadFileData.id,
slug: generateSlug(uploadFilePathName),
createdAt: new Date(),
savedAt: new Date(),
readingProgressPercent: 0,
readingProgressAnchorIndex: 0,
state: ArticleSavingRequestStatus.Processing,
},
ctx
)
if (!pageId) {
return { errorCodes: [UploadFileRequestErrorCode.FailedCreate] }
url: input.url,
})
if (page) {
await updatePage(page.id, {
savedAt: new Date(),
archivedAt: null,
}, ctx)
} else {
const pageId = await createPage(
{
url: input.url,
id: input.clientRequestId || '',
userId: claims.uid,
title: title,
hash: uploadFilePathName,
content: '',
pageType: PageType.File,
uploadFileId: uploadFileData.id,
slug: generateSlug(uploadFilePathName),
createdAt: new Date(),
savedAt: new Date(),
readingProgressPercent: 0,
readingProgressAnchorIndex: 0,
state: ArticleSavingRequestStatus.Processing,
},
ctx
)
if (!pageId) {
return { errorCodes: [UploadFileRequestErrorCode.FailedCreate] }
}
}
}
return { id: uploadFileData.id, uploadSignedUrl }

View file

@ -416,7 +416,10 @@ const schema = gql`
input UploadFileRequestInput {
url: String!
contentType: String!
createPageEntry: Boolean
clientRequestId: String
}
enum UploadFileRequestErrorCode {
UNAUTHORIZED
BAD_INPUT

View file

@ -18,6 +18,8 @@ import { Merge } from '../util'
import { CreateArticlesSuccessPartial } from '../resolvers'
import { ArticleSavingRequestStatus, Page } from '../elastic/types'
import { updatePage } from '../elastic/pages'
import path from 'path'
import normalizeUrl from 'normalize-url'
interface InputObject {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -230,3 +232,13 @@ export const validatedDate = (
return undefined
}
}
export const titleForFilePath = (url: string): string => {
try {
const title = decodeURI(path.basename(new URL(url).pathname, '.pdf'))
return title
} catch (e) {
console.log(e)
}
return url
}

View file

@ -94,7 +94,7 @@ const uploadToSignedUrl = async ({ id, uploadSignedUrl }, contentType, contentOb
})
};
const getUploadIdAndSignedUrl = async (userId, url) => {
const getUploadIdAndSignedUrl = async (userId, url, articleSavingRequestId) => {
const auth = await signToken({ uid: userId }, process.env.JWT_SECRET);
const data = JSON.stringify({
query: `mutation UploadFileRequest($input: UploadFileRequestInput!) {
@ -112,6 +112,7 @@ const getUploadIdAndSignedUrl = async (userId, url) => {
input: {
url,
contentType: 'application/pdf',
clientRequestId: articleSavingRequestId,
}
}
});
@ -126,10 +127,10 @@ const getUploadIdAndSignedUrl = async (userId, url) => {
return response.data.data.uploadFileRequest;
};
const uploadPdf = async (url, userId) => {
const uploadPdf = async (url, userId, articleSavingRequestId) => {
validateUrlString(url);
const uploadResult = await getUploadIdAndSignedUrl(userId, url);
const uploadResult = await getUploadIdAndSignedUrl(userId, url, articleSavingRequestId);
await uploadToSignedUrl(uploadResult, 'application/pdf', url);
return uploadResult.id;
};
@ -282,7 +283,7 @@ async function fetchContent(req, res) {
try {
if (contentType === 'application/pdf') {
const uploadedFileId = await uploadPdf(finalUrl, userId);
const uploadedFileId = await uploadPdf(finalUrl, userId, articleSavingRequestId);
const l = await saveUploadedPdf(userId, finalUrl, uploadedFileId, articleSavingRequestId);
} else {
if (!content || !title) {