mirror of
https://github.com/haiwen/seahub.git
synced 2025-05-10 17:05:06 +00:00
add pdf thumbnail (#6157)
Co-authored-by: 孙永强 <11704063+s-yongqiang@user.noreply.gitee.com>
This commit is contained in:
parent
0b84b22df9
commit
ca83ef90dc
frontend/src
requirements.txtseahub
test-requirements.txt@ -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 ;
|
||||
|
@ -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 ;
|
||||
|
@ -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) {
|
||||
|
@ -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 || [];
|
||||
|
@ -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-*
|
||||
|
@ -26,3 +26,4 @@ Markdown==3.4.*
|
||||
bleach==5.0.*
|
||||
python-ldap==3.4.*
|
||||
pypinyin==0.50.*
|
||||
PyMuPDF==1.24.*
|
||||
|
@ -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.
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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 %},
|
||||
|
@ -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 %}
|
||||
|
@ -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 %},
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
})
|
||||
|
||||
|
||||
|
@ -7,3 +7,4 @@ splinter
|
||||
pytest==7.4.4
|
||||
pytest-django
|
||||
selenium
|
||||
PyMuPDF==1.24.3
|
Loading…
Reference in New Issue
Block a user