refs #4550 Solved bugs
gitea/printnatura/pipeline/head This commit looks good Details

This commit is contained in:
Guillermo Bonet 2022-12-15 15:04:36 +01:00
parent 9156b45c30
commit f54c8ba9c7
6 changed files with 66 additions and 54 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules
config.local.yml
tmp

View File

@ -14,6 +14,16 @@ RUN curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash - \
&& apt install -y nodejs \
&& rm -rf /var/lib/apt/lists/*
# Cups
RUN useradd admin && usermod -g lpadmin admin
COPY ctzcls-cups_1.1.0-0_amd64.deb /tmp/
RUN chmod a+x /tmp/ctzcls-cups_1.1.0-0_amd64.deb \
&& dpkg -i /tmp/ctzcls-cups_1.1.0-0_amd64.deb
# Printnatura
WORKDIR /printnatura
COPY \
@ -22,9 +32,6 @@ COPY \
./
RUN npm install
COPY cupsd.conf /etc/cups/
RUN useradd admin && usermod -g lpadmin admin
COPY \
main.js \
print-server.js \
@ -33,9 +40,5 @@ COPY \
./
COPY sql sql
COPY ctzcls-cups_1.1.0-0_amd64.deb /tmp/
RUN chmod a+x /tmp/ctzcls-cups_1.1.0-0_amd64.deb \
&& dpkg -i /tmp/ctzcls-cups_1.1.0-0_amd64.deb
ENTRYPOINT ["/printnatura/entrypoint.sh"]
CMD ["node", "main.js"]

View File

@ -8,12 +8,13 @@ This project is used to print pdf, it acts as a print server.
## Installaton
Clone the repository
```
$ git clone https://gitea.verdnatura.es/verdnatura/printnatura.git
> git clone https://gitea.verdnatura.es/verdnatura/printnatura.git
```
Build
```
$ docker build -t printnatura .
> $CUPS_PASSWORD = 1234
> docker build --build-arg CUPS_PASSWORD -t printnatura .
```
Create file named "config.local.yml" and put your private configuration:
@ -35,12 +36,13 @@ refreshRate: 1000
Exec
```
$ docker run --name printnatura -it --rm -v $PWD/config.local.yml:/printnatura/config.local.yml:ro -p 80:631 printnatura
> docker run --name printnatura -it --rm -v $PWD/config.local.yml:/printnatura/config.local.yml:ro -v $PWD/cupsd.conf:/etc/cups/cupsd.conf:ro -p 80:631 printnatura
```
Bash
```
$ docker exec -i -t printnatura bash
> docker exec -i -t printnatura bash
```
Has a graphical web interface (cupsd.conf)

View File

@ -7,6 +7,7 @@ const axios = require('axios');
const yml = require('require-yml');
const selectQuery = fs.readFileSync(`sql/selectQueued.sql`).toString();
const jobDataQuery = fs.readFileSync(`sql/jobData.sql`).toString();
const jobArgsQuery = fs.readFileSync(`sql/jobArgs.sql`).toString();
const updateQuery = fs.readFileSync(`sql/updateState.sql`).toString();
const appDir = path.dirname(require.main.filename);
@ -92,7 +93,6 @@ class PrintServer {
}
jobId = printJob.id;
this.method = printJob.method;
await conn.query(updateQuery, ['printing', null, jobId]);
await conn.commit();
@ -102,22 +102,27 @@ class PrintServer {
}
try {
// Job data
const [[jobData]] = await conn.query(jobDataQuery, jobId);
const args = {};
const res = await conn.query(jobArgsQuery, jobId);
for (const row of res[0])
const [res] = await conn.query(jobArgsQuery, jobId);
for (const row of res)
args[row.name] = row.value;
try {
// Path params
const usedParams = new Set();
let methodPath = this.method.replace(/{\w+}/g, function(match) {
const key = match.substr(1, match.length - 2);
const value = args[key];
usedParams.add(key);
return value !== undefined ? value : match;
});
// Path params
const usedParams = new Set();
const methodPath = jobData.method.replace(/{\w+}/g, function(match) {
const key = match.substr(1, match.length - 2);
const value = args[key];
usedParams.add(key);
return value !== undefined ? value : match;
});
let pdfData;
for (let attempts = 0; !pdfData && attempts <= 1; attempts++) {
// URL params
let params = {
const params = {
access_token: this.token,
userFk: printJob.userFk
};
@ -128,34 +133,34 @@ class PrintServer {
const urlParams = new URLSearchParams(params);
// Request
const response = await axios({
method: 'get',
url: `${conf.salix.url}/api/${methodPath}?${urlParams.toString()}`,
responseType: 'arraybuffer',
headers: {
'Accept': 'application/pdf'
}
});
this.pdfData = response.data
}
catch (err) {
switch(err.response.statusText) {
case 'Unauthorized':
try {
await this.getToken();
} catch(err) {
throw new Error(`Could not get token: ${err.message}`);
try {
const response = await axios({
method: 'get',
url: `${conf.salix.url}/api/${methodPath}?${urlParams.toString()}`,
responseType: 'arraybuffer',
headers: {
'Accept': 'application/pdf'
}
break;
});
pdfData = response.data;
}
catch (err) {
if (err.response?.statusText === 'Unauthorized') {
await this.getToken();
} else
throw err;
}
}
const printer = printJob.printer;
// Save PDF to disk
const printer = jobData.printer;
const tmpPath = path.join(appDir, 'tmp')
if (!fs.existsSync(tmpPath))
fs.mkdirSync(tmpPath)
const tmpFilePath = path.join(tmpPath, `${Math.random().toString(36).substring(7)}.pdf`);
await fs.writeFile(tmpFilePath, this.pdfData, 'binary');
await fs.writeFile(tmpFilePath, pdfData, 'binary');
// Print PDF
try {
await pExec(`lp -d "${printer}" "${tmpFilePath}"`);
} catch(err) {
@ -166,7 +171,7 @@ class PrintServer {
await conn.query(updateQuery, ['printed', null, jobId]);
if (conf.debug)
console.debug(`(${colors.yellow(jobId)}) Document has been printed`, `[${args.collectionFk}, ${printJob.report}, ${printer}]`.green);
console.debug(`(${colors.yellow(jobId)}) Document has been printed`, `[${args.collectionFk}, ${jobData.report}, ${printer}]`.green);
await fs.unlink(tmpFilePath);
} catch (err) {

7
sql/jobData.sql Normal file
View File

@ -0,0 +1,7 @@
SELECT r.name report,
p.name printer,
r.method
FROM printQueue pq
JOIN report r ON r.id = pq.reportFk
JOIN printer p ON p.id = pq.printerFk
WHERE pq.id = ?

View File

@ -1,15 +1,9 @@
SELECT pq.id,
r.name report,
p.name printer,
pqa.name arg,
pqa.value,
r.method,
pq.workerFk userFk
FROM printQueue pq
JOIN report r ON r.id = pq.reportFk
JOIN printQueueArgs pqa ON pqa.printQueueFk = pq.id
LEFT JOIN printer p ON p.id = pq.printerFk
WHERE pq.statusCode = 'queued'
AND NOT r.method IS NULL
AND r.method IS NOT NULL
ORDER BY pq.priorityFk ASC
LIMIT 1
LIMIT 1
FOR UPDATE