download discord avatar automatically

This commit is contained in:
Evert Prants 2017-09-09 14:15:11 +03:00
parent 8a231dfd73
commit f54f6fb1b0
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
6 changed files with 96 additions and 28 deletions

13
package-lock.json generated
View File

@ -455,7 +455,8 @@
"dev": true
},
"bluebird": {
"version": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
"integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw="
},
"bn.js": {
@ -1146,7 +1147,7 @@
"resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.14.5.tgz",
"integrity": "sha1-WiUEe8dvcwcmZ8jLUsmJiI9JTGM=",
"requires": {
"bluebird": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz"
"bluebird": "3.5.0"
}
},
"constantinople": {
@ -1640,7 +1641,7 @@
"resolved": "https://registry.npmjs.org/email-templates/-/email-templates-2.7.1.tgz",
"integrity": "sha512-WJ0csXaBK3gV90dwBco5d3liu/XSH1jPEn3qfLDES/AsxOoMv4IRqp/MsQduKBexJZ81577OUbrdgnzvK2Kk9Q==",
"requires": {
"bluebird": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
"bluebird": "3.5.0",
"consolidate": "0.14.5",
"debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
"glob": "6.0.4",
@ -3169,7 +3170,7 @@
"integrity": "sha1-CN1JT2u2SSiTTuydrDR4ehTKX6Q=",
"requires": {
"babel-runtime": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz",
"bluebird": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
"bluebird": "3.5.0",
"chalk": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"commander": "https://registry.npmjs.org/commander/-/commander-2.10.0.tgz",
"debug": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
@ -3661,7 +3662,7 @@
"resolved": "https://registry.npmjs.org/oauth-libre/-/oauth-libre-0.9.17.tgz",
"integrity": "sha1-5Jg39iFj4QVj49BRNd82DcYYpxI=",
"requires": {
"bluebird": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
"bluebird": "3.5.0",
"body-parser": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
"express": "https://registry.npmjs.org/express/-/express-4.15.3.tgz",
"express-session": "https://registry.npmjs.org/express-session/-/express-session-1.15.3.tgz",
@ -3708,7 +3709,7 @@
"integrity": "sha1-CCNKazCoudpFAKWz9ynN63JphY4=",
"requires": {
"ajv": "https://registry.npmjs.org/ajv/-/ajv-5.2.0.tgz",
"bluebird": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
"bluebird": "3.5.0",
"lodash": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz"
}
},

View File

@ -35,6 +35,7 @@
"babel-core": "^6.25.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
"bcryptjs": "^2.4.3",
"bluebird": "^3.5.0",
"body-parser": "^1.17.2",
"connect-redis": "^3.3.0",
"connect-session-knex": "^1.3.4",

View File

@ -1,8 +1,10 @@
import config from './load-config'
import path from 'path'
import fs from 'fs'
import util from 'util'
import Promise from 'bluebird'
const fs = Promise.promisifyAll(require('fs'))
let lfs
function pz (z) {
@ -49,6 +51,19 @@ console.error = function () {
stampAndWrite.call(this, realConsoleError, ' err', message)
}
async function initializeLogger () {
let logPath = path.resolve(config.logger.file)
try {
await fs.accessAsync(logPath, fs.W_OK)
lfs = fs.createWriteStream(logPath, {flags: 'a'})
} catch (e) {
lfs = null
console.error('Failed to initiate log file write stream')
console.error(e.stack)
}
}
module.exports = function () {
this.logProcess = (pid, msg) => {
if (msg.indexOf('warn') === 0) {
@ -64,12 +79,5 @@ module.exports = function () {
// Create log file write stream
if (!config.logger || !config.logger.write) return
try {
lfs = fs.createWriteStream(path.resolve(config.logger.file), {flags: 'a'})
} catch (e) {
lfs = null
console.error('Failed to initiate log file write stream')
console.error(e.stack)
}
initializeLogger()
}

View File

@ -7,6 +7,8 @@ import oauth from 'oauth-libre'
import path from 'path'
import url from 'url'
const imgdir = path.join(__dirname, '../../', 'usercontent', 'images')
let twitterApp
let discordApp
@ -59,7 +61,6 @@ const API = {
},
saveAvatar: async (avatarUrl) => {
if (!avatarUrl) return null
let imgdir = path.join(__dirname, '../../', 'usercontent', 'images')
let imageName = 'download-' + UAPI.Hash(12)
let uridata = url.parse(avatarUrl)
let pathdata = path.parse(uridata.path)
@ -385,12 +386,23 @@ const API = {
let bans = await API.Common.getBan(null, ipAddress)
if (bans.length) return { banned: bans, ip: true }
// Determine profile picture
// Download profile picture
let profilepic = null
let aviSnowflake = ddata.avatar
if (aviSnowflake) {
try {
let avpt = await API.Common.saveAvatar('https://cdn.discordapp.com/avatars/' + ddata.id + '/' + aviSnowflake + '.png')
if (avpt && avpt.fileName) {
profilepic = avpt.fileName
}
} catch (e) {
profilepic = null
}
}
// Create a new user
let udataLimited = {
username: 'D' + ddata.discriminator,
username: ddata.username.replace(/\W+/gi, '_'),
display_name: ddata.username,
email: ddata.email || '',
avatar_file: profilepic,
@ -400,6 +412,11 @@ const API = {
created_at: new Date()
}
// Check if the username is already taken
if (await UAPI.User.get(udataLimited.username) != null) {
udataLimited.username = udataLimited.username + UAPI.Hash(4)
}
// Check if the email Discord gave us is already registered, if so,
// associate an external node with the user bearing the email
if (udataLimited.email && udataLimited.email !== '') {

View File

@ -1,12 +1,12 @@
import gm from 'gm'
import fs from 'fs'
import path from 'path'
import crypto from 'crypto'
import Promise from 'bluebird'
const fsBlue = Promise.promisifyAll(fs)
const fs = Promise.promisifyAll(require('fs'))
const uploads = path.join(__dirname, '../../', 'usercontent')
const images = path.join(uploads, 'images')
const maxFileSize = 1000000
const imageTypes = {
'image/png': '.png',
@ -14,6 +14,20 @@ const imageTypes = {
'image/jpeg': '.jpeg'
}
function decodeBase64Image (dataString) {
let matches = dataString.match(/^data:([A-Za-z-+/]+);base64,(.+)$/)
let response = {}
if (matches.length !== 3) {
return null
}
response.type = matches[1]
response.data = Buffer.from(matches[2], 'base64')
return response
}
function saneFields (fields) {
let out = {}
@ -28,12 +42,35 @@ function saneFields (fields) {
}
async function bailOut (file, error) {
await fsBlue.unlinkAsync(file)
await fs.unlinkAsync(file)
return { error: error }
}
async function imageBase64 (baseObj) {
if (!baseObj) return null
let imgData = decodeBase64Image(baseObj)
if (!imgData) return null
if (!imageTypes[imgData.type]) return null
let imageName = 'base64-' + crypto.randomBytes(12).toString('hex')
let ext = imageTypes[imgData.type] || '.png'
imageName += ext
let fpath = path.join(images, imageName)
try {
fs.writeFileSync(fpath, imgData.data)
} catch (e) {
console.error(e)
return null
}
return {file: fpath}
}
async function uploadImage (identifier, fields, files) {
let directory = path.join(uploads, 'images')
if (!files.image) return {error: 'No image file'}
let file = files.image[0]
@ -89,13 +126,13 @@ async function uploadImage (identifier, fields, files) {
await new Promise(function (resolve, reject) {
gm(file)
.crop(fields.width, fields.height, fields.x, fields.y)
.write(path.join(directory, fileName), (err) => {
.write(path.join(images, fileName), (err) => {
if (err) return reject(err)
resolve(fileName)
})
})
await fsBlue.unlinkAsync(file)
await fs.unlinkAsync(file)
} catch (e) {
console.error(e)
return bailOut(file, 'An error occured while cropping.')
@ -105,5 +142,7 @@ async function uploadImage (identifier, fields, files) {
}
module.exports = {
uploadImage: uploadImage
uploadImage: uploadImage,
imageBase64: imageBase64,
types: imageTypes
}

View File

@ -7,7 +7,9 @@ import crypto from 'crypto'
import notp from 'notp'
import base32 from 'thirty-two'
import emailer from './emailer'
import fs from 'fs'
import Promise from 'bluebird'
const fs = Promise.promisifyAll(require('fs'))
const emailRe = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
@ -191,7 +193,7 @@ const API = {
if (user.avatar_file != null) {
let file = path.join(uploadsDir, user.avatar_file)
if (fs.existsSync(file)) {
fs.unlinkSync(file)
await fs.unlinkAsync(file)
}
}
@ -205,7 +207,7 @@ const API = {
let file = path.join(uploadsDir, user.avatar_file)
if (fs.existsSync(file)) {
fs.unlinkSync(file)
await fs.unlinkAsync(file)
}
return API.User.update(user, {avatar_file: null})