1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-05-10 17:05:06 +00:00

add pdf thumbnail ()

Co-authored-by: 孙永强 <11704063+s-yongqiang@user.noreply.gitee.com>
This commit is contained in:
awu0403 2024-06-04 16:06:57 +08:00 committed by GitHub
parent 0b84b22df9
commit ca83ef90dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 83 additions and 11 deletions

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import cookie from 'react-cookies';
import moment from 'moment';
import { navigate } from '@gatsbyjs/reach-router';
import { gettext, siteRoot, username, enableVideoThumbnail } from '../../utils/constants';
import { gettext, siteRoot, username, enableVideoThumbnail, enablePDFThumbnail } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import collabServer from '../../utils/collab-server';
@ -538,7 +538,7 @@ class LibContentView extends React.Component {
getThumbnails = (repoID, path, direntList) => {
let items = direntList.filter((item) => {
return (Utils.imageCheck(item.name) || (enableVideoThumbnail && Utils.videoCheck(item.name))) && !item.encoded_thumbnail_src;
return (Utils.imageCheck(item.name) || (enableVideoThumbnail && Utils.videoCheck(item.name)) || (enablePDFThumbnail && Utils.pdfCheck(item.name))) && !item.encoded_thumbnail_src;
});
if (items.length == 0) {
return ;

View File

@ -5,7 +5,7 @@ import { Link, navigate } from '@gatsbyjs/reach-router';
import moment from 'moment';
import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils';
import { gettext, siteRoot, enableVideoThumbnail } from '../../utils/constants';
import { gettext, siteRoot, enableVideoThumbnail, enablePDFThumbnail } from '../../utils/constants';
import EmptyTip from '../../components/empty-tip';
import Loading from '../../components/loading';
import toaster from '../../components/toast';
@ -79,7 +79,10 @@ class TableBody extends Component {
getThumbnails() {
let items = this.state.items.filter((item) => {
return (Utils.imageCheck(item.obj_name) || (enableVideoThumbnail && Utils.videoCheck(item.obj_name))) && !item.repo_encrypted && !item.encoded_thumbnail_src && !item.deleted;
return (Utils.imageCheck(item.obj_name) ||
(enableVideoThumbnail && Utils.videoCheck(item.obj_name)) ||
(enablePDFThumbnail && Utils.pdfCheck(item.obj_name))) &&
!item.repo_encrypted && !item.encoded_thumbnail_src && !item.deleted;
});
if (items.length == 0) {
return ;

View File

@ -30,7 +30,7 @@ let {
repoID, relativePath,
mode, thumbnailSize, zipped,
trafficOverLimit, canDownload,
noQuota, canUpload, enableVideoThumbnail
noQuota, canUpload, enableVideoThumbnail, enablePDFThumbnail
} = window.shared.pageOptions;
const showDownloadIcon = !trafficOverLimit && canDownload;
@ -111,7 +111,8 @@ class SharedDirView extends React.Component {
let items = this.state.items.filter((item) => {
return !item.is_dir &&
(Utils.imageCheck(item.file_name) ||
(enableVideoThumbnail && Utils.videoCheck(item.file_name))) &&
(enableVideoThumbnail && Utils.videoCheck(item.file_name)) ||
(enablePDFThumbnail && Utils.pdfCheck(item.file_name))) &&
!item.encoded_thumbnail_src;
});
if (items.length == 0) {

View File

@ -91,6 +91,7 @@ export const curNoteID = window.app.pageOptions.curNoteID;
export const enableTC = window.app.pageOptions.enableTC;
export const enableVideoThumbnail = window.app.pageOptions.enableVideoThumbnail;
export const enablePDFThumbnail = window.app.pageOptions.enablePDFThumbnail;
export const enableOnlyoffice = window.app.pageOptions.enableOnlyoffice || false;
export const onlyofficeConverterExtensions = window.app.pageOptions.onlyofficeConverterExtensions || [];

View File

@ -124,6 +124,19 @@ export const Utils = {
}
},
pdfCheck: function(filename) {
if (filename.lastIndexOf('.') == -1) {
return false;
}
var file_ext = filename.substr(filename.lastIndexOf('.') + 1).toLowerCase();
var image_exts = ['pdf'];
if (image_exts.indexOf(file_ext) != -1) {
return true;
} else {
return false;
}
},
getShareLinkPermissionList: function(itemType, permission, path, canEdit) {
// itemType: library, dir, file
// permission: rw, r, admin, cloud-edit, preview, custom-*

View File

@ -26,3 +26,4 @@ Markdown==3.4.*
bleach==5.0.*
python-ldap==3.4.*
pypinyin==0.50.*
PyMuPDF==1.24.*

View File

@ -23,7 +23,7 @@ from seahub.utils import check_filename_with_rename, is_valid_dirent_name, \
normalize_dir_path, is_pro_version, FILEEXT_TYPE_MAP, get_file_type_and_ext
from seahub.utils.timeutils import timestamp_to_isoformat_timestr
from seahub.utils.file_tags import get_files_tags_in_dir
from seahub.utils.file_types import IMAGE, VIDEO, XMIND, SEADOC
from seahub.utils.file_types import IMAGE, VIDEO, XMIND, SEADOC, PDF
from seahub.base.models import UserStarredFiles
from seahub.base.templatetags.seahub_tags import email2nickname, \
email2contact_email
@ -175,7 +175,7 @@ def get_dir_file_info_list(username, request_type, repo_obj, parent_dir,
fileExt = os.path.splitext(file_name)[1][1:].lower()
file_type = FILEEXT_TYPE_MAP.get(fileExt)
if file_type in (IMAGE, XMIND) or \
if file_type in (IMAGE, XMIND, PDF) or \
(file_type == VIDEO and ENABLE_VIDEO_THUMBNAIL):
# if thumbnail has already been created, return its src.

View File

@ -747,6 +747,9 @@ THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT = 256
ENABLE_VIDEO_THUMBNAIL = False
THUMBNAIL_VIDEO_FRAME_TIME = 5 # use the frame at 5 second as thumbnail
# pdf thumbnails
ENABLE_PDF_THUMBNAIL = True
# template for create new office file
OFFICE_TEMPLATE_ROOT = os.path.join(MEDIA_ROOT, 'office-template')

View File

@ -141,6 +141,7 @@
enableTC: {% if enable_terms_and_conditions %} true {% else %} false {% endif %},
enableSSOToThirdpartWebsite: {% if enable_sso_to_thirdpart_website %} true {% else %} false {% endif %},
enableVideoThumbnail: {% if enable_video_thumbnail %} true {% else %} false {% endif %},
enablePDFThumbnail: {% if enable_pdf_thumbnail %} true {% else %} false {% endif %},
showLogoutIcon: {% if show_logout_icon %} true {% else %} false {% endif %},
additionalShareDialogNote: {% if additional_share_dialog_note %} {{ additional_share_dialog_note|safe }} {% else %} null {% endif %},
additionalAppBottomLinks: {% if additional_app_bottom_links %} {{ additional_app_bottom_links|safe }} {% else %} null {% endif %},

View File

@ -24,6 +24,10 @@ thumbnailSizeForOriginal: {{ thumbnail_size_for_original }},
enableVideoThumbnail: {% if enable_video_thumbnail %} true {% else %} false {% endif %},
{% endif %}
{% if filetype == 'PDF' %}
enablePDFThumbnail: {% if enable_pdf_thumbnail %} true {% else %} false {% endif %},
{% endif %}
{% if filetype == 'XMind' %}
xmindImageSrc: '{{ xmind_image_src|escapejs }}',
{% endif %}

View File

@ -38,6 +38,7 @@
mode: '{{ mode }}',
thumbnailSize: {{ thumbnail_size }},
enableVideoThumbnail: {% if enable_video_thumbnail %}true{% else %}false{% endif %},
enablePDFThumbnail: {% if enable_pdf_thumbnail %}true{% else %}false{% endif %},
trafficOverLimit: {% if traffic_over_limit %}true{% else %}false{% endif %},
canDownload: {% if permissions.can_download %}true{% else %}false{% endif %},
noQuota: {% if no_quota %}true{% else %}false{% endif %},

View File

@ -8,6 +8,7 @@ import logging
import subprocess
from io import BytesIO
import zipfile
from fitz import open as fitz_open
try: # Py2 and Py3 compatibility
from urllib.request import urlretrieve
except:
@ -18,7 +19,7 @@ from seaserv import get_file_id_by_path, get_repo, get_file_size, \
seafile_api
from seahub.utils import gen_inner_file_get_url, get_file_type_and_ext
from seahub.utils.file_types import VIDEO, XMIND
from seahub.utils.file_types import VIDEO, XMIND, PDF
from seahub.settings import THUMBNAIL_IMAGE_SIZE_LIMIT, \
THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT,\
ENABLE_VIDEO_THUMBNAIL, THUMBNAIL_VIDEO_FRAME_TIME
@ -117,7 +118,10 @@ def generate_thumbnail(request, repo_id, size, path):
thumbnail_file, file_size)
else:
return (False, 400)
if filetype == PDF:
# pdf thumbnails
return create_pdf_thumbnails(repo, file_id, path, size,
thumbnail_file, file_size)
if filetype == XMIND:
return extract_xmind_image(repo_id, path, size)
@ -181,6 +185,41 @@ def create_psd_thumbnails(repo, file_id, path, size, thumbnail_file, file_size):
os.unlink(tmp_img_path)
return (False, 500)
def create_pdf_thumbnails(repo, file_id, path, size, thumbnail_file, file_size):
t1 = timeit.default_timer()
token = seafile_api.get_fileserver_access_token(repo.id,
file_id, 'view', '', use_onetime=False)
if not token:
return (False, 500)
inner_path = gen_inner_file_get_url(token, os.path.basename(path))
tmp_path = str(os.path.join(tempfile.gettempdir(), '%s.png' % file_id[:8]))
pdf_file = urllib.request.urlopen(inner_path)
pdf_stream = BytesIO(pdf_file.read())
try:
pdf_doc = fitz_open(stream=pdf_stream)
pdf_stream.close()
page = pdf_doc[0]
pix = page.get_pixmap()
pix.save(tmp_path)
pdf_doc.close()
except Exception as e:
logger.error(e)
return (False, 500)
t2 = timeit.default_timer()
logger.debug('Create PDF thumbnail of [%s](size: %s) takes: %s' % (path, file_size, (t2 - t1)))
try:
ret = _create_thumbnail_common(tmp_path, thumbnail_file, size)
os.unlink(tmp_path)
return ret
except Exception as e:
logger.error(e)
os.unlink(tmp_path)
return (False, 500)
def create_video_thumbnails(repo, file_id, path, size, thumbnail_file, file_size):
t1 = timeit.default_timer()

View File

@ -1089,6 +1089,7 @@ def react_fake_view(request, **kwargs):
'ocm_remote_servers': OCM_REMOTE_SERVERS,
'enable_share_to_department': settings.ENABLE_SHARE_TO_DEPARTMENT,
'enable_video_thumbnail': settings.ENABLE_VIDEO_THUMBNAIL,
'enable_pdf_thumbnail': settings.ENABLE_PDF_THUMBNAIL,
'group_import_members_extra_msg': GROUP_IMPORT_MEMBERS_EXTRA_MSG,
'request_from_onlyoffice_desktop_editor': ONLYOFFICE_DESKTOP_EDITOR_HTTP_USER_AGENT in request.headers.get('user-agent', ''),
'enable_sso_to_thirdpart_website': settings.ENABLE_SSO_TO_THIRDPART_WEBSITE,

View File

@ -765,6 +765,8 @@ def view_lib_file(request, repo_id, path):
send_file_access_msg(request, repo, path, 'web')
if filetype == VIDEO:
return_dict['enable_video_thumbnail'] = settings.ENABLE_VIDEO_THUMBNAIL
if filetype == PDF:
return_dict['enable_pdf_thumbnail'] = settings.ENABLE_PDF_THUMBNAIL
return render(request, template, return_dict)
elif filetype == XMIND:

View File

@ -31,7 +31,7 @@ from seahub.settings import ENABLE_UPLOAD_FOLDER, \
THUMBNAIL_ROOT, THUMBNAIL_DEFAULT_SIZE, THUMBNAIL_SIZE_FOR_GRID, \
MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD, SHARE_LINK_EXPIRE_DAYS_MIN, \
SHARE_LINK_EXPIRE_DAYS_MAX, SEAFILE_COLLAB_SERVER, \
ENABLE_SHARE_LINK_REPORT_ABUSE
ENABLE_SHARE_LINK_REPORT_ABUSE, ENABLE_PDF_THUMBNAIL
from seahub.utils.file_types import IMAGE, VIDEO, XMIND
from seahub.thumbnail.utils import get_share_link_thumbnail_src
from seahub.group.utils import is_group_admin
@ -363,6 +363,7 @@ def view_shared_dir(request, fileshare):
'desc_for_ogp': desc_for_ogp,
'enable_share_link_report_abuse': ENABLE_SHARE_LINK_REPORT_ABUSE,
'enable_video_thumbnail': ENABLE_VIDEO_THUMBNAIL,
'enable_pdf_thumbnail': ENABLE_PDF_THUMBNAIL,
})

View File

@ -7,3 +7,4 @@ splinter
pytest==7.4.4
pytest-django
selenium
PyMuPDF==1.24.3