163 lines
4.4 KiB
JavaScript
163 lines
4.4 KiB
JavaScript
const QRCode = require('qrcode');
|
|
const axios = require('axios');
|
|
const FormData = require('form-data');
|
|
const winston = require('winston');
|
|
|
|
// Configure logger
|
|
const logger = winston.createLogger({
|
|
level: process.env.NODE_ENV === 'production' ? 'info' : 'debug',
|
|
format: winston.format.combine(
|
|
winston.format.timestamp(),
|
|
winston.format.json()
|
|
),
|
|
transports: [
|
|
new winston.transports.Console({
|
|
format: winston.format.simple()
|
|
})
|
|
]
|
|
});
|
|
|
|
/**
|
|
* Generate QR code as PNG buffer
|
|
* @param {string} text - Text/URL to encode
|
|
* @param {Object} options - QR code options
|
|
* @returns {Promise<Buffer>} PNG buffer
|
|
*/
|
|
async function generateQRCode(text, options = {}) {
|
|
const defaultOptions = {
|
|
type: 'png',
|
|
width: 256,
|
|
margin: 1,
|
|
color: {
|
|
dark: '#000000',
|
|
light: '#FFFFFF'
|
|
},
|
|
errorCorrectionLevel: 'M'
|
|
};
|
|
|
|
const qrOptions = { ...defaultOptions, ...options };
|
|
|
|
try {
|
|
const buffer = await QRCode.toBuffer(text, qrOptions);
|
|
return buffer;
|
|
} catch (error) {
|
|
logger.error('Failed to generate QR code:', error);
|
|
throw new Error('Failed to generate QR code');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Upload QR code to NocoDB storage
|
|
* @param {Buffer} buffer - PNG buffer
|
|
* @param {string} filename - Filename for the upload
|
|
* @param {Object} config - NocoDB configuration
|
|
* @returns {Promise<Object>} Upload response
|
|
*/
|
|
async function uploadQRCodeToNocoDB(buffer, filename, config) {
|
|
const formData = new FormData();
|
|
formData.append('file', buffer, {
|
|
filename: filename,
|
|
contentType: 'image/png'
|
|
});
|
|
|
|
try {
|
|
// Use the base URL without /api/v1 for v2 endpoints
|
|
const baseUrl = config.apiUrl.replace('/api/v1', '');
|
|
const uploadUrl = `${baseUrl}/api/v2/storage/upload`;
|
|
|
|
logger.info(`Uploading QR code to: ${uploadUrl}`);
|
|
|
|
const response = await axios({
|
|
url: uploadUrl,
|
|
method: 'post',
|
|
data: formData,
|
|
headers: {
|
|
...formData.getHeaders(),
|
|
'xc-token': config.apiToken
|
|
},
|
|
params: {
|
|
path: 'qrcodes'
|
|
}
|
|
});
|
|
|
|
logger.info('QR code upload successful:', response.data);
|
|
return response.data;
|
|
} catch (error) {
|
|
logger.error('Failed to upload QR code to NocoDB:', error.response?.data || error.message);
|
|
throw new Error('Failed to upload QR code');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate and upload QR code
|
|
* @param {string} url - URL to encode
|
|
* @param {string} label - Label for the QR code
|
|
* @param {Object} config - NocoDB configuration
|
|
* @returns {Promise<Object>} Upload result
|
|
*/
|
|
async function generateAndUploadQRCode(url, label, config) {
|
|
if (!url) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
// Generate QR code
|
|
const buffer = await generateQRCode(url);
|
|
|
|
// Create filename
|
|
const timestamp = Date.now();
|
|
const safeLabel = label.replace(/[^a-z0-9]/gi, '_').toLowerCase();
|
|
const filename = `qr_${safeLabel}_${timestamp}.png`;
|
|
|
|
// Upload to NocoDB
|
|
const uploadResult = await uploadQRCodeToNocoDB(buffer, filename, config);
|
|
|
|
return uploadResult;
|
|
} catch (error) {
|
|
logger.error('Failed to generate and upload QR code:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete QR code from NocoDB storage
|
|
* @param {string} fileUrl - File URL to delete
|
|
* @param {Object} config - NocoDB configuration
|
|
* @returns {Promise<boolean>} Success status
|
|
*/
|
|
async function deleteQRCodeFromNocoDB(fileUrl, config) {
|
|
if (!fileUrl) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
// Extract file path from URL
|
|
const urlParts = fileUrl.split('/');
|
|
const filePath = urlParts.slice(-2).join('/');
|
|
|
|
await axios({
|
|
url: `${config.apiUrl}/api/v2/storage/upload`,
|
|
method: 'delete',
|
|
headers: {
|
|
'xc-token': config.apiToken
|
|
},
|
|
params: {
|
|
path: filePath
|
|
}
|
|
});
|
|
|
|
return true;
|
|
} catch (error) {
|
|
logger.error('Failed to delete QR code from NocoDB:', error);
|
|
// Don't throw error for deletion failures
|
|
return false;
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
generateQRCode,
|
|
uploadQRCodeToNocoDB,
|
|
generateAndUploadQRCode,
|
|
deleteQRCodeFromNocoDB
|
|
};
|