This commit is contained in:
parent
9156b45c30
commit
f54c8ba9c7
|
@ -1,2 +1,3 @@
|
|||
node_modules
|
||||
config.local.yml
|
||||
tmp
|
||||
|
|
17
Dockerfile
17
Dockerfile
|
@ -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"]
|
10
README.md
10
README.md
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 = ?
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue