Auto purge uploads from old deleted posts

Discourse already automatically removes orphan unreferenced uploads. Why not expand this functionality and erase uploads from deleted posts? Only staff members are able to see deleted posts and that is very useful. But is it really necessary to keep all the files indefinitely? As administrator I really don`t care about 2 years old deleted pictures. Some of which may even be right out against site guidelines.

It would be nice if Discourse would automatically delete these kind old files and place some kind of text block in the place of deleted file. So that it would be evident that file deletion has taken place.

For example all year old uploads which are referenced only in deleted posts would be automatically deleted.

8개의 좋아요

저도 이 기능이 정말 필요할 것 같습니다.

해당 기능이 어느 정도 구현되어 있는 것으로 보입니다:

제가 설정으로 사용하는 항목:
clean orphan uploads grace period hours: 1
purge deleted uploads grace period days: 1

다만, 삭제된 업로드에는 게시글이 삭제될 때 그 안에 포함된 이미지의 경우가 포함되지 않습니다. 게시글을 삭제하기 전에 이미지/업로드를 게시글에서 먼저 편집하여 제거해야 한다고 생각합니다.

특정 이미지가 포함된 유일한 게시글이 삭제된 경우에도 이미지가 삭제되지 않는다는 것을 확인할 수 있습니다. 2023년에 삭제된 게시글에서 사용되었던 이미지가 여전히 데이터베이스와 S3에 존재하며, 해당 이미지는 다른 어떤 게시글에서도 사용되지 않고 있습니다. 이전 사례들에서도 삭제된 적이 없습니다.

즉, 관리자가 규칙에 위배되는 업로드된 이미지가 포함된 게시글을 삭제하는 경우, 실제로 이를 삭제하려면 먼저 해당 주제/게시글에서 이미지를 편집하여 제거해야 합니다(그리고 다른 게시글에 존재하지 않기를 바랍니다). 그렇지 않으면 S3에 무기한 존재하게 됩니다. 적어도 제 이해 범위 내에서 그렇습니다.

아래와 같은 기능이 있으면 정말 좋겠습니다:

  • purge deleted uploads grace period days - 삭제된 게시글 안에 포함된 이미지의 경우를 이 설정에 포함시키거나, 해당 경우를 위한 별도의 설정을 추가해 주세요.

  • purge deleted uploads grace period days - ‘일(day)’ 대신 ‘시간(hour)’ 단위를 사용하세요. 저작권 제거 요청은 일반적으로 24~48시간 이내에 매우 신속한 조치가 필요합니다. 1일은 이 경우 너무 느립니다. 삭제 후 CDN 캐시도 수동으로 정리해야 하므로 시간적 여유는 더 빠듯해집니다.

  • 대시보드에서 이미지를 삭제/정리할 수 있는 기능. 단, 삭제된 게시글 내부의 이미지도 ‘삭제된 업로드 정리’ 대상에 포함된다면 이 기능의 필요성은 줄어들겠지만, 이미지가 아바타나 프로필 배너 등으로 사용되는 경우 등 여전히 필요한 사례가 있으며, 관리자 입장에서 더 효율적입니다. Feature suggestion: Image removal/purge via web dashboard

  • 이미지 URL을 검색할 수 있도록 해 주세요. 이는 관리자가 특정 이미지가 포함된 모든 주제/게시글을 찾아 해당 게시글도 삭제할 수 있게 해 주며, SSH를 사용하지 않아도 됩니다.

  • 특정 해시값이 업로드되는 것을 금지하는 기능이 있으면 좋겠습니다.

이렇게 되면 SSH 접근 권한이나 기술적 전문 지식이 없는 사람도 이러한 프로세스를 처리할 수 있게 되어 좋습니다. 특히 이러한 요청은 신속하게 처리되어야 하기 때문입니다. 이러한 상황이 발생할 때마다 24시간/365일 기술 인력이 대기해야 하는 것은 비용 면에서 부담이 큽니다. 휴일, 주말, 누군가 아프거나 하는 경우를 포함하여 언제든 즉시 대응할 준비가 되어 있어야 합니다. 언제 발생할지 예측할 수 없으므로, 항상 신속하게 대응할 준비가 되어 있어야 합니다. 이는 UGC(사용자 생성 콘텐츠)의 불가피한 특성입니다.

2개의 좋아요

왜 이 문제가 더 널리 논의되지 않는지 궁금합니다. 정말 큰 문제입니다.

다음 SQL 쿼리로 생성된 CSV 파일을 사용하는 PHP 스크립트를 작성했습니다. 이 쿼리는 모든 업로드와 해당 참조를 나열합니다:
(업로드가 많다면 limit 값을 늘리세요)

SELECT 
    uploads.original_filename,
    ROUND(uploads.filesize / 1000000.0, 2) AS size_in_mb,
    uploads.extension,
    uploads.created_at,
    uploads.url,
    upload_references.upload_id,
    upload_references.target_id,
    upload_references.target_type,
    upload_references.created_at,
    upload_references.updated_at
FROM upload_references
JOIN uploads ON uploads.id = upload_references.upload_id
ORDER BY upload_references.target_type
LIMIT 90000

이 스크립트는 초안으로만 남아 있는 업로드를 필터링합니다. (제가 여기에서 설명했듯이, 이는 데이터베이스에 잘못 남아 있는 것입니다.) 스크립트는 모든 파일 이름을 공백으로 구분된 문자열로 출력합니다. 스크립트를 수정하여 전체 경로도 출력할 수 있습니다(basename() 함수를 제거하면 됩니다).

그 다음 discourse SSH 서버에 로그인하여 모든 파일에 대해 rm 명령을 실행하세요.

  • 이 방법의 한 가지 단점은 활성 초안에 남아 있는 모든 이미지도 함께 삭제된다는 것입니다(하지만 n일 이상 지난 초안 삭제 설정을 낮추면 이를 제한할 수 있습니다).
  • 두 번째 단점은 잘못된 데이터베이스 항목이 여전히 남아 있다는 것입니다. 이에 대해서는 개발팀에 수정을 요청해야 합니다.

잘못된 항목이 삭제되면 문제가 제대로 해결되어야 합니다.

<?php
 
if (($open = fopen("test.csv", "r")) !== false) {
    while (($data = fgetcsv($open, 100000, ",")) !== false) {
        $array[] = $data;
    }
 
    fclose($open);
}
$final = array();
$i=0;
foreach ($array as $item){
	if($item[7]=="Draft"){
			foreach ($array as $item_inside){
				if(($item_inside[4]==$item[4]) && ($item_inside[7]!="Draft")) $i++; //초안이 아닌 항목이 있는지 확인
				}
			if($i==0)array_push($final, $item[4]); //초안만 있었던 경우 배열에 추가
			$i=0;
		}
	}
$final_unique= array_unique($final);
//print_r($final_unique);

foreach($final_unique as $single){
	echo basename($single)." ";
	}
?>

쿼리 결과를 담은 test.csv 파일은 스크립트와 같은 디렉터리에 있어야 합니다.
문제가 있으면 저에게 질문해 주세요!

3개의 좋아요

많은 사람들이 업로드된 파일이 자동으로 정리되지 않는다는 사실을 인지하지 못하고 있기 때문일 것 같습니다.

더 자세히 읽고 싶으신 분들을 위해 관련 스레드를 하나 더 공유합니다:

2개의 좋아요

이렇게 오랜 시간이 지난 만큼 이미 수정되었기를 바랐습니다. 고아 데이터가 여전히 서버에 남아 있는지 다시 확인해 봐야 할 것 같습니다. 어쨌든 그 스크립트는 정말 유용합니다.

3개의 좋아요

안녕하세요! 지난 주에 이 문제가 어느 정도 수정된 것 같습니다…

이제 삭제된 게시글의 업로드 마크다운을 제거하는 자동화(Remove upload markup in deleted posts가 자동화 이름입니다)를 사용할 수 있게 되었습니다. 예를 들어:

 Hey it is a regular post with a link to [Discourse](https://www.discourse.org) 
 and an image: ![logo.png|100x200](upload://gj6GJHlc1Sa5YXuGz549oXBbcFv.png)
 and a file: [small.pdf|attachment](upload://3bWzVVoRhUXxi7tiPenInoebHyX.pdf) (130 Bytes)

이 게시글에서 자동화가 실행되면, 수정된 버전은 다음과 같습니다:

 Hey it is a regular post with a link to [Discourse](https://www.discourse.org) 
 and an image:
 and a file: 

그리고 이제 이 업로드들은 orphans(고아 파일) 상태가 되므로, cleanup uploads job에 의해 정리됩니다.


또한, 자가 호스팅(self-hosted) 환경이라면 s3_stale_while_revalidate와 s3_max_age 설정을 통해 캐시 제어 지시문(cache control directives)을 업데이트할 수 있습니다.

3개의 좋아요

정말 훌륭합니다! 아주 좋은 해결책이네요. :slight_smile:

업로드가 삭제되었지만 해당 업로드를 참조하는 게시글은 여전히 활성화된 상태인 역방향 시나리오에서도, 게시글의 마크다운 업로드 참조를 제거하는 동일한 전략을 적용하는 것이 의미 있을지 궁금합니다.

다음과 같이 업로드를 삭제하는 경우:

Upload.find(123).destroy

업로드 123이 다음 용도로 사용된 경우:

  • 프로필 커스텀 아바타
  • 프로필 배경
  • 카드 배경

모든 참조가 제거되는 것 같습니다. 이는 다음에서 비롯되는 것으로 보입니다:

before_destroy (배경/카드 배너 업로드 참조 제거)

https://github.com/discourse/discourse/blob/6759ad71cac395697b2978eb34fcfbf1162d30d1/app/models/upload.rb#L53

after_destroy (아바타 업로드 참조 제거)

https://github.com/discourse/discourse/blob/6759ad71cac395697b2978eb34fcfbf1162d30d1/app/models/upload.rb#L60

업로드 ID와 연관된 게시글 ID를 사용하여 업로드가 삭제될 때 마크다운 업로드 제거를 큐에 넣을 수 있다면, 업로드가 수동으로 삭제될 때 삭제되지 않은 게시글 내의 무효화된 업로드 참조를 방지할 수 있을 것 같습니다.

예를 들어, 한 게시글에 업로드가 두 개 있지만 그중 하나만 삭제된 경우처럼, 삭제되지 않은 업로드 ID에 대한 마크다운 업로드를 유지하는 것이 이상적입니다.

예를 들어, https://meta.discourse.org/t/legal-compliance-plugin/356331 또는 rails CLI를 통해 여러 게시글(예: 인용 게시글)에서 참조되는 업로드를 삭제하는 경우입니다.

1개의 좋아요