fix recovered deleted items still shown in trash

This commit is contained in:
Hongbo Wu 2023-09-22 11:09:57 +08:00
parent 7bf3f1bbf4
commit 3b8b48bc21
10 changed files with 68 additions and 74 deletions

View file

@ -5,13 +5,13 @@
/* eslint-disable @typescript-eslint/no-floating-promises */
import { Readability } from '@omnivore/readability'
import graphqlFields from 'graphql-fields'
import { DeepPartial } from 'typeorm'
import { Not } from 'typeorm'
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'
import { LibraryItem, LibraryItemState } from '../../entity/library_item'
import { env } from '../../env'
import {
ArticleError,
ArticleErrorCode,
ArticleSavingRequestStatus,
ArticleSuccess,
BulkActionError,
BulkActionErrorCode,
@ -58,6 +58,7 @@ import {
addLabelsToLibraryItem,
findLabelsByIds,
findOrCreateLabels,
saveLabelsInLibraryItem,
} from '../../services/labels'
import {
createLibraryItem,
@ -287,6 +288,7 @@ export const createArticleResolver = authorized<
uploadFileHash,
canonicalUrl,
uploadFileId,
state,
})
log.info('New article saving', {
@ -311,13 +313,6 @@ export const createArticleResolver = authorized<
await makeStorageFilePublic(uploadFileData.id, uploadFileData.fileName)
}
// save page's state and labels
libraryItemToSave.archivedAt =
state === ArticleSavingRequestStatus.Archived ? new Date() : null
if (inputLabels) {
libraryItemToSave.labels = await findOrCreateLabels(inputLabels, uid)
}
let libraryItemToReturn: LibraryItem
const existingLibraryItem = await findLibraryItemByUrl(
@ -326,15 +321,15 @@ export const createArticleResolver = authorized<
)
articleSavingRequestId = existingLibraryItem?.id || articleSavingRequestId
if (articleSavingRequestId) {
// update existing page's state from processing to succeeded
// update existing item's state from processing to succeeded
libraryItemToReturn = await updateLibraryItem(
articleSavingRequestId,
libraryItemToSave,
libraryItemToSave as QueryDeepPartialEntity<LibraryItem>,
uid,
pubsub
)
} else {
// create new page in database
// create new item in database
libraryItemToReturn = await createLibraryItem(
libraryItemToSave,
uid,
@ -342,6 +337,12 @@ export const createArticleResolver = authorized<
)
}
// save labels in item
if (inputLabels) {
const labels = await findOrCreateLabels(inputLabels, user.id)
await saveLabelsInLibraryItem(labels, libraryItemToReturn.id, user.id)
}
log.info(
'item created in database',
libraryItemToReturn.id,
@ -524,7 +525,7 @@ export const setBookmarkArticleResolver = authorized<
SetBookmarkArticleError,
MutationSetBookmarkArticleArgs
>(async (_, { input: { articleID } }, { uid, log, pubsub }) => {
// delete the page and its metadata
// delete the item and its metadata
const deletedLibraryItem = await updateLibraryItem(
articleID,
{
@ -545,7 +546,7 @@ export const setBookmarkArticleResolver = authorized<
})
log.info('Article unbookmarked', {
page: Object.assign({}, deletedLibraryItem, {
item: Object.assign({}, deletedLibraryItem, {
readableContent: undefined,
originalContent: undefined,
}),
@ -601,7 +602,7 @@ export const saveArticleReadingProgressResolver = authorized<
: undefined
// If setting to zero we accept the update, otherwise we require it
// be greater than the current reading progress.
const updatedPart: DeepPartial<LibraryItem> = {
const updatedPart: QueryDeepPartialEntity<LibraryItem> = {
readingProgressBottomPercent:
readingProgressPercent === 0
? 0
@ -834,7 +835,7 @@ export const setFavoriteArticleResolver = authorized<
}
const labels = await findOrCreateLabels([label], uid)
// adds Favorites label to page
// adds Favorites label to item
await addLabelsToLibraryItem(labels, id, uid)
return {

View file

@ -125,15 +125,13 @@ export const uploadFileRequestResolver = authorized<
let createdItemId: string | undefined = undefined
if (input.createPageEntry) {
// If we have a file:// URL, don't try to match it
// and create a copy of the page, just create a
// and create a copy of the item, just create a
// new item.
const item = await findLibraryItemByUrl(input.url, uid)
if (item) {
await updateLibraryItem(
item.id,
{
savedAt: new Date(),
archivedAt: null,
state: LibraryItemState.Processing,
},
uid

View file

@ -16,7 +16,7 @@ import {
createLibraryItem,
findLibraryItemById,
findLibraryItemByUrl,
updateLibraryItem,
restoreLibraryItem,
} from '../services/library_item'
import { addRecommendation } from '../services/recommendation'
import { getTokenByRequest } from '../utils/auth'
@ -105,18 +105,8 @@ export function pageRouter() {
const item = await findLibraryItemByUrl(url, claims.uid)
if (item) {
logger.info('updating page')
await updateLibraryItem(
item.id,
{
savedAt: new Date(),
archivedAt: null,
state: LibraryItemState.Succeeded,
},
claims.uid
)
await restoreLibraryItem(item.id, claims.uid)
} else {
logger.info('creating page')
await createLibraryItem(
{
originalUrl: signedUrl,

View file

@ -2,6 +2,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import express from 'express'
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'
import { LibraryItem, LibraryItemState } from '../../entity/library_item'
import { readPushSubscription } from '../../pubsub'
import { authTrx } from '../../repository'
@ -81,7 +82,9 @@ export function contentServiceRouter() {
return
}
const itemToUpdate: Partial<LibraryItem> = { originalContent: msg.content }
const itemToUpdate: QueryDeepPartialEntity<LibraryItem> = {
originalContent: msg.content,
}
if (msg.title) itemToUpdate.title = msg.title
if (msg.author) itemToUpdate.author = msg.author
if (msg.description) itemToUpdate.description = msg.description

View file

@ -113,7 +113,7 @@ export const createPageSaveRequest = async ({
if (!libraryItem) {
logger.info('libraryItem does not exist', { url })
// create processing page
// create processing item
libraryItem = await createLibraryItem(
{
id: articleSavingRequestId,
@ -145,7 +145,7 @@ export const createPageSaveRequest = async ({
// get priority by checking rate limit if not specified
priority = priority || (await getPriorityByRateLimit(userId))
// enqueue task to parse page
// enqueue task to parse item
await enqueueParseRequest({
url,
userId,

View file

@ -342,7 +342,7 @@ export const findLibraryItemByUrl = async (
)
}
export const refreshLibraryItem = async (
export const restoreLibraryItem = async (
id: string,
userId: string,
pubsub = createPubSubClient()
@ -353,6 +353,7 @@ export const refreshLibraryItem = async (
state: LibraryItemState.Succeeded,
savedAt: new Date(),
archivedAt: null,
deletedAt: null,
},
userId,
pubsub
@ -361,17 +362,30 @@ export const refreshLibraryItem = async (
export const updateLibraryItem = async (
id: string,
libraryItem: DeepPartial<LibraryItem>,
libraryItem: QueryDeepPartialEntity<LibraryItem>,
userId: string,
pubsub = createPubSubClient()
): Promise<LibraryItem> => {
const updatedLibraryItem = await authTrx(
async (tx) => {
const itemRepo = tx.withRepository(libraryItemRepository)
await itemRepo.update(
id,
libraryItem as QueryDeepPartialEntity<LibraryItem>
)
// reset deletedAt and archivedAt
switch (libraryItem.state) {
case LibraryItemState.Archived:
libraryItem.archivedAt = new Date()
break
case LibraryItemState.Deleted:
libraryItem.deletedAt = new Date()
break
case LibraryItemState.Processing:
case LibraryItemState.Succeeded:
libraryItem.archivedAt = null
libraryItem.deletedAt = null
break
}
await itemRepo.update(id, libraryItem)
return itemRepo.findOneByOrFail({ id })
},
@ -379,7 +393,7 @@ export const updateLibraryItem = async (
userId
)
await pubsub.entityUpdated<DeepPartial<LibraryItem>>(
await pubsub.entityUpdated<QueryDeepPartialEntity<LibraryItem>>(
EntityType.PAGE,
{ ...libraryItem, id },
userId

View file

@ -20,7 +20,7 @@ import { findOrCreateLabels, saveLabelsInLibraryItem } from './labels'
import {
createLibraryItem,
findLibraryItemByUrl,
updateLibraryItem,
restoreLibraryItem,
} from './library_item'
import { updateReceivedEmail } from './received_emails'
import { saveSubscription } from './subscriptions'
@ -72,12 +72,8 @@ export const saveEmail = async (
input.userId
)
if (existingLibraryItem) {
const updatedLibraryItem = await updateLibraryItem(
const updatedLibraryItem = await restoreLibraryItem(
existingLibraryItem.id,
{
archivedAt: null,
state: LibraryItemState.Succeeded,
},
input.userId
)
logger.info('updated page from email', updatedLibraryItem)

View file

@ -1,14 +1,9 @@
import { LibraryItemState } from '../entity/library_item'
import { User } from '../entity/user'
import { homePageURL } from '../env'
import {
ArticleSavingRequestStatus,
SaveErrorCode,
SaveFileInput,
SaveResult,
} from '../generated/graphql'
import { SaveErrorCode, SaveFileInput, SaveResult } from '../generated/graphql'
import { getStorageFileDetails } from '../utils/uploads'
import { findOrCreateLabels } from './labels'
import { findOrCreateLabels, saveLabelsInLibraryItem } from './labels'
import { updateLibraryItem } from './library_item'
import { findUploadFileById, setFileUploadComplete } from './upload_file'
@ -34,24 +29,20 @@ export const saveFile = async (
}
if (input.state || input.labels) {
// save state
const archivedAt =
input.state === ArticleSavingRequestStatus.Archived ? new Date() : null
// add labels to page
const labels = input.labels
? await findOrCreateLabels(input.labels, user.id)
: undefined
await updateLibraryItem(
input.clientRequestId,
{
archivedAt,
labels,
state: input.state
? (input.state as unknown as LibraryItemState)
: LibraryItemState.Succeeded,
},
user.id
)
// add labels to item
if (input.labels) {
const labels = await findOrCreateLabels(input.labels, user.id)
await saveLabelsInLibraryItem(labels, input.clientRequestId, user.id)
}
}
return {

View file

@ -1,5 +1,6 @@
import { Readability } from '@omnivore/readability'
import { DeepPartial } from 'typeorm'
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity'
import { LibraryItem, LibraryItemState } from '../entity/library_item'
import { User } from '../entity/user'
import { homePageURL } from '../env'
@ -85,7 +86,7 @@ export const savePage = async (
itemType: parseResult.pageType,
originalHtml: parseResult.domContent,
canonicalUrl: parseResult.canonicalUrl,
saveTime: input.savedAt ? new Date(input.savedAt) : undefined,
saveTime: input.savedAt ? new Date(input.savedAt) : new Date(),
publishedAt: input.publishedAt ? new Date(input.publishedAt) : undefined,
state: input.state || undefined,
rssFeedUrl: input.rssFeedUrl,
@ -109,11 +110,7 @@ export const savePage = async (
}
}
} else {
// save state
itemToSave.archivedAt =
input.state === ArticleSavingRequestStatus.Archived ? new Date() : null
// check if the page already exists
// check if the item already exists
const existingLibraryItem = await authTrx((t) =>
t.getRepository(LibraryItem).findOneBy({
user: { id: user.id },
@ -121,7 +118,7 @@ export const savePage = async (
})
)
if (existingLibraryItem) {
// we don't want to update an rss feed page if rss-feeder is tring to re-save it
// we don't want to update an rss feed item if rss-feeder is tring to re-save it
if (existingLibraryItem.subscription === input.rssFeedUrl) {
return {
clientRequestId,
@ -131,14 +128,18 @@ export const savePage = async (
clientRequestId = existingLibraryItem.id
slug = existingLibraryItem.slug
await updateLibraryItem(clientRequestId, itemToSave, user.id)
await updateLibraryItem(
clientRequestId,
itemToSave as QueryDeepPartialEntity<LibraryItem>,
user.id
)
} else {
// do not publish a pubsub event if the page is imported
// do not publish a pubsub event if the item is imported
const newItem = await createLibraryItem(itemToSave, user.id)
clientRequestId = newItem.id
}
// add labels to page
// save labels in item
if (input.labels) {
const labels = await findOrCreateLabels(input.labels, user.id)
await saveLabelsInLibraryItem(labels, clientRequestId, user.id)

View file

@ -271,7 +271,7 @@ export const libraryItemToSearchItem = (item: LibraryItem): SearchItem => ({
export const isParsingTimeout = (libraryItem: LibraryItem): boolean => {
return (
// page processed more than 30 seconds ago
// item processed more than 30 seconds ago
libraryItem.state === LibraryItemState.Processing &&
libraryItem.savedAt.getTime() < new Date().getTime() - 1000 * 30
)