Reduced album title max length from 280 to 70.
Existing albums with longer titles will have their titles truncated in
their public pages, but the original titles will still remain in db.

"Load images for preview" will now properly display its saved value.

Increased max parallel uploads to 10.

"yarn develop" will now also restart safe if some Nunjuck templates are
edited (_globals.njk, _layout.njk, and album.njk).

Better meta tags generation.

Bumped v1 version string.
This commit is contained in:
Bobby Wibowo 2019-09-19 08:27:19 +07:00
parent e6d4d96693
commit ea37e0b7d3
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
17 changed files with 74 additions and 58 deletions

View File

@ -12,7 +12,7 @@ const db = require('knex')(config.database)
const self = { const self = {
// Don't forget to update max length of text inputs in // Don't forget to update max length of text inputs in
// home.js & dashboard.js when changing these values // home.js & dashboard.js when changing these values
titleMaxLength: 280, titleMaxLength: 70,
descMaxLength: 4000, descMaxLength: 4000,
onHold: new Set() onHold: new Set()
@ -21,7 +21,7 @@ const self = {
const homeDomain = config.homeDomain || config.domain const homeDomain = config.homeDomain || config.domain
const zipMaxTotalSize = parseInt(config.cloudflare.zipMaxTotalSize) const zipMaxTotalSize = parseInt(config.cloudflare.zipMaxTotalSize)
const zipMaxTotalSizeBytes = config.cloudflare.zipMaxTotalSize * 1000000 const zipMaxTotalSizeBytes = zipMaxTotalSize * 1e6
const zipOptions = config.uploads.jsZipOptions const zipOptions = config.uploads.jsZipOptions
// Force 'type' option to 'nodebuffer' // Force 'type' option to 'nodebuffer'
@ -32,8 +32,10 @@ if (zipOptions.streamFiles === undefined)
zipOptions.streamFiles = true zipOptions.streamFiles = true
if (zipOptions.compression === undefined) if (zipOptions.compression === undefined)
zipOptions.compression = 'DEFLATE' zipOptions.compression = 'DEFLATE'
if (zipOptions.compressionOptions === undefined || zipOptions.compressionOptions.level === undefined) if (zipOptions.compressionOptions === undefined)
zipOptions.compressionOptions = { level: 1 } zipOptions.compressionOptions = {}
if (zipOptions.compressionOptions.level === undefined)
zipOptions.compressionOptions.level = 1
self.zipEmitters = new Map() self.zipEmitters = new Map()

View File

@ -76,7 +76,7 @@ const executeMulter = multer({
delete req.body[key] delete req.body[key]
} }
if (req.body.chunkindex && !chunkedUploads) if (req.body.chunkindex !== undefined && !chunkedUploads)
return cb('Chunked uploads are disabled at the moment.') return cb('Chunked uploads are disabled at the moment.')
else else
return cb(null, true) return cb(null, true)
@ -111,8 +111,7 @@ const executeMulter = multer({
return cb(null, name) return cb(null, name)
} }
}) })
}).array('files[]', { }).array('files[]')
})
self.isExtensionFiltered = extname => { self.isExtensionFiltered = extname => {
// If empty extension needs to be filtered // If empty extension needs to be filtered
@ -340,7 +339,7 @@ self.actuallyUploadUrls = async (req, res, user, albumid, age) => {
}) })
} }
// If not errors found, clear cache of downloaded files // If no errors found, clear cache of downloaded files
downloaded.length = 0 downloaded.length = 0
if (utils.clamd.scanner) { if (utils.clamd.scanner) {
@ -467,6 +466,7 @@ self.actuallyFinishChunks = async (req, res, user) => {
if (chunksData[file.uuid] !== undefined) if (chunksData[file.uuid] !== undefined)
// Continue even when encountering errors // Continue even when encountering errors
await self.cleanUpChunks(file.uuid).catch(logger.error) await self.cleanUpChunks(file.uuid).catch(logger.error)
// Re-throw error
throw error throw error
} }
} }
@ -492,8 +492,7 @@ self.combineChunks = async (destination, uuid) => {
writeStream.end() writeStream.end()
// Re-throw error // Re-throw error
if (errorObj) if (errorObj) throw errorObj
throw errorObj
} }
self.cleanUpChunks = async (uuid) => { self.cleanUpChunks = async (uuid) => {
@ -700,8 +699,7 @@ self.list = async (req, res) => {
const user = await utils.authorize(req, res) const user = await utils.authorize(req, res)
if (!user) return if (!user) return
// Headers is string-only, this seem to be the safest and lightest const all = Boolean(req.headers.all)
const all = req.headers.all === '1'
const filters = req.headers.filters const filters = req.headers.filters
const ismoderator = perms.is(user, 'moderator') const ismoderator = perms.is(user, 'moderator')
if ((all || filters) && !ismoderator) if ((all || filters) && !ismoderator)

View File

@ -281,7 +281,7 @@ self.generateThumbs = async (name, extname, force) => {
return false return false
} }
} catch (error) { } catch (error) {
// Suppress error logging for errors these patterns // Suppress error logging for errors matching these patterns
const errorString = error.toString() const errorString = error.toString()
const suppress = [ const suppress = [
/Input file contains unsupported image format/, /Input file contains unsupported image format/,
@ -683,7 +683,7 @@ self.stats = async (req, res, next) => {
} }
if (os.platform !== 'linux') { if (os.platform !== 'linux') {
// If not Linux platform, rely on DB for total size // If not Linux platform, rely on DB for total size
const uploads = await db.table('files') const uploads = await db.table('files')
.select('size') .select('size')
stats.uploads.total = uploads.length stats.uploads.total = uploads.length

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/js/home.js vendored

File diff suppressed because one or more lines are too long

2
dist/js/home.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -119,7 +119,10 @@ gulp.task('nodemon', done => {
'config.js', 'config.js',
'controllers/', 'controllers/',
'database/', 'database/',
'routes/' 'routes/',
'views/_globals.njk',
'views/_layout.njk',
'views/album.njk'
], ],
ext: 'js', ext: 'js',
done done

View File

@ -86,7 +86,7 @@ const page = {
isTriggerLoading: null, isTriggerLoading: null,
fadingIn: null, fadingIn: null,
albumTitleMaxLength: 280, albumTitleMaxLength: 70,
albumDescMaxLength: 4000 albumDescMaxLength: 4000
} }

View File

@ -48,7 +48,7 @@ const page = {
imageExts: ['.webp', '.jpg', '.jpeg', '.bmp', '.gif', '.png', '.tiff', '.tif', '.svg'], imageExts: ['.webp', '.jpg', '.jpeg', '.bmp', '.gif', '.png', '.tiff', '.tif', '.svg'],
videoExts: ['.webm', '.mp4', '.wmv', '.avi', '.mov', '.mkv'], videoExts: ['.webm', '.mp4', '.wmv', '.avi', '.mov', '.mkv'],
albumTitleMaxLength: 280, albumTitleMaxLength: 70,
albumDescMaxLength: 4000 albumDescMaxLength: 4000
} }
@ -594,7 +594,7 @@ page.prepareUploadConfig = () => {
const numConfig = { const numConfig = {
chunkSize: { min: 1, max: 95 }, chunkSize: { min: 1, max: 95 },
parallelUploads: { min: 1, max: 8 } parallelUploads: { min: 1, max: 10 }
} }
document.querySelector('#chunkSizeDiv .help').innerHTML = document.querySelector('#chunkSizeDiv .help').innerHTML =
@ -684,6 +684,7 @@ page.prepareUploadConfig = () => {
} }
page.previewImages = localStorage[lsKeys.previewImages] !== '0' page.previewImages = localStorage[lsKeys.previewImages] !== '0'
if (!page.previewImages) document.querySelector('#previewImages').value = '0'
document.querySelector('#saveConfig').addEventListener('click', () => { document.querySelector('#saveConfig').addEventListener('click', () => {
if (!form.checkValidity()) if (!form.checkValidity())

View File

@ -15,7 +15,7 @@
v3: CSS and JS files (libs such as bulma, lazyload, etc). v3: CSS and JS files (libs such as bulma, lazyload, etc).
v4: Renders in /public/render/* directories (to be used by render.js). v4: Renders in /public/render/* directories (to be used by render.js).
#} #}
{% set v1 = "iDzQ0dov5j" %} {% set v1 = "yUGjkyDjqU" %}
{% set v2 = "hiboQUzAzp" %} {% set v2 = "hiboQUzAzp" %}
{% set v3 = "iDzQ0dov5j" %} {% set v3 = "iDzQ0dov5j" %}
{% set v4 = "S3TAWpPeFS" %} {% set v4 = "S3TAWpPeFS" %}

View File

@ -1,7 +1,17 @@
{% import '_globals.njk' as globals %} {%- import '_globals.njk' as globals -%}
{# Set root domain here to inherit values from config file #} {# Set root domain here to inherit values from config file #}
{% set root = config.homeDomain or config.domain %} {%- set root = config.homeDomain or config.domain -%}
{%- set title -%}
{%- if metaTitle -%}
{{ metaTitle + ' | ' + globals.name }}
{%- else -%}
{{ globals.name + ' ' + globals.motto }}
{%- endif %}
{%- endset -%}
{%- set url = root + (metaUrl or '') -%}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
@ -12,11 +22,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
{% if title -%} <title>{{ title }}</title>
<title>{{ title + ' | ' + globals.name }}</title>
{%- else -%}
<title>{{ globals.name + ' ' + globals.motto }}</title>
{%- endif %}
{% block stylesheets %} {% block stylesheets %}
<!-- Stylesheets --> <!-- Stylesheets -->
@ -26,10 +32,13 @@
{% block opengraph %} {% block opengraph %}
<!-- Open Graph tags --> <!-- Open Graph tags -->
<meta property="og:url" content="{{ root }}" /> <meta property="og:url" content="{{ url }}" />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:title" content="{{ globals.name }} {{ globals.motto }}" /> <meta property="og:title" content="{{ title }}" />
<meta property="og:description" content="{{ globals.description }}" /> <meta property="og:description" content="{{ metaDesc or globals.description }}" />
{%- if metaImage %}
<meta property="og:image" content="{{ metaImage }}" />
{%- endif %}
<meta property="og:image" content="{{ root }}/icons/600px.png?v={{ globals.v2 }}" /> <meta property="og:image" content="{{ root }}/icons/600px.png?v={{ globals.v2 }}" />
<meta property="og:image:width" content="600" /> <meta property="og:image:width" content="600" />
<meta property="og:image:height" content="600" /> <meta property="og:image:height" content="600" />
@ -40,9 +49,13 @@
<!-- Twitter Card tags --> <!-- Twitter Card tags -->
<meta name="twitter:card" content="summary"> <meta name="twitter:card" content="summary">
<meta name="twitter:title" content="{{ globals.name }} {{ globals.motto }}"> <meta name="twitter:title" content="{{ title }}">
<meta name="twitter:description" content="{{ globals.description }}"> <meta name="twitter:description" content="{{ metaDesc or globals.description }}">
{%- if metaImage %}
<meta name="twitter:image" content="{{ metaImage }}">
{% else %}
<meta name="twitter:image" content="{{ root }}/icons/600px.png?v={{ globals.v2 }}"> <meta name="twitter:image" content="{{ root }}/icons/600px.png?v={{ globals.v2 }}">
{%- endif %}
{% endblock %} {% endblock %}
<!-- Icons, configs, etcetera --> <!-- Icons, configs, etcetera -->

View File

@ -1,7 +1,14 @@
{% set title = album.name %} {% set metaTitle %}
{% extends "_layout.njk" %} {{- album.name | truncate(60, true, '…') + ' ' + files.length + ' file' + ('s' if files.length !== 1) -}}
{% endset %}
{% set metaDesc = album.description | truncate(200, true, '…') %}
{% set metaUrl = '/' + album.url %}
{% set fileRoot = config.domain %} {% set fileRoot = config.domain %}
{% set metaImage = fileRoot + '/' + album.thumb %}
{% extends "_layout.njk" %}
{% set generateZips = config.uploads.generateZips %} {% set generateZips = config.uploads.generateZips %}
{% set usingCdn = config.cloudflare and config.cloudflare.purgeCache %} {% set usingCdn = config.cloudflare and config.cloudflare.purgeCache %}
@ -22,22 +29,6 @@
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block opengraph %}
<!-- Open Graph tags -->
<meta property="og:type" content="website" />
<meta property="og:title" content="{{ album.name | safe }} &#8211; {{ files.length }} files" />
<meta property="og:url" content="{{ root }}/{{ album.url }}" />
<meta property="og:description" content="{{ album.description }}" />
<meta property="og:image" content="{{ fileRoot }}/{{ album.thumb }}" />
<meta property="og:locale" content="en_US" />
<!-- Twitter Card tags -->
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="{{ album.name | safe }} &#8211; {{ files.length }} files">
<meta name="twitter:description" content="{{ album.description }}">
<meta name="twitter:image" content="{{ fileRoot }}/{{ album.thumb }}">
{% endblock %}
{% block content %} {% block content %}
{{ super() }} {{ super() }}
<section class="section"> <section class="section">
@ -46,7 +37,7 @@
<div class="level-left"> <div class="level-left">
<div class="level-item"> <div class="level-item">
<h1 id="title" class="title"> <h1 id="title" class="title">
{{ album.name | safe }} {{ album.name | truncate(70, true, '…') }}
</h1> </h1>
</div> </div>
<div class="level-item"> <div class="level-item">

View File

@ -1,4 +1,6 @@
{% set title = "Auth" %} {% set metaTitle = "Auth" %}
{% set metaUrl = '/auth' %}
{% extends "_layout.njk" %} {% extends "_layout.njk" %}
{% block stylesheets %} {% block stylesheets %}

View File

@ -1,4 +1,6 @@
{% set title = "Dashboard" %} {% set metaTitle = "Dashboard" %}
{% set metaUrl = '/dashboard' %}
{% extends "_layout.njk" %} {% extends "_layout.njk" %}
{% block stylesheets %} {% block stylesheets %}

View File

@ -1,4 +1,6 @@
{% set title = "FAQ" %} {% set metaTitle = "FAQ" %}
{% set metaUrl = '/faq' %}
{% extends "_layout.njk" %} {% extends "_layout.njk" %}
{% set noJsMaxSizeInt = config.cloudflare.noJsMaxSize | int %} {% set noJsMaxSizeInt = config.cloudflare.noJsMaxSize | int %}

View File

@ -1,4 +1,6 @@
{% set title = "No-JS uploader" %} {% set metaTitle = "No-JS uploader" %}
{% set metaUrl = '/nojs' %}
{% extends "_layout.njk" %} {% extends "_layout.njk" %}
{% set private = config.private %} {% set private = config.private %}