Koozali.org: home of the SME Server
Contribs.org Forums => General Discussion => Topic started by: holck on January 17, 2017, 08:29:40 PM
-
I found a simple and (in my view) elegant way to make users able to print pdf-files - even if they are not on the LAN, even from cell phones and other devices without installing printer drivers etc. It is based on this: https://www.linux.com/comment/6798 (https://www.linux.com/comment/6798). Users simply attach their pdf-files to an email, and send this email to a specific address.
First, create a user to receive the emails with attached pdf-files. The user name should be simple to remember, but hard to guess for strangers. Here I'll call the user "printpdf" for convience. Switch to the new user's home directory and create the file .fetchmailrc with this content:
poll yourserver.org
proto POP3
user printpdf
pass printpdfpassword
Here, yourserver.org and printpdfpassword should of course be replaced with your local settings.
Also create a file, autoprint.sh, with this content:
#!/bin/bash
SUPPORTED_FILETYPES=".pdf"
LP_OPTIONS="-d Yourprintername -o media=A4,tray1 -o fit-to-page -o position=top -o scaling=100"
FILENAME=$(date +%H%M%S).txt
/usr/bin/fetchmail -s --bsmtp ~/mailtemp/$FILENAME
if [ "$?" = "0" ]; then
/usr/bin/uudeview +e $SUPPORTED_FILETYPES -p ~/printable -i ~/mailtemp/$FILENAME
rm ~/mailtemp/$FILENAME
for f in ~/printable/*
do
lp $LP_OPTIONS "$f"
rm "$f"
done
fi
Please replace "Yourprintername" with the name of your local printer to use. Also, you may want to change LP_OPTIONS according to your hardware and needs.
Then you need to create the relevant folders and make sure the ownerships are ok:
$ mkdir mailtemp
$ mkdir printable
$ chown -R printpdf mailtemp printable .fetchmailrc
$ chmod 600 .fetchmailrc
$ chmod 700 autoprint.sh
You will also need to install the uudeview package. I did it like this:
$ cd /tmp
$ wget ftp://ftp.pbone.net/mirror/pkgs.repoforge.org/uudeview/uudeview-0.5.20-2.el6.rf.x86_64.rpm
$ yum localinstall uudeview-0.5.20-2.el6.rf.x86_64.rpm
Finally, you should put an entry in the crontab to make the script run as user printpdf every 5 minutes or so. Create the file /etc/e-smith/templates-custom/etc/crontab/autoprint with this content:
*/5 * * * * printpdf /home/e-smith/files/users/printpdf/autoprint.sh
And do
/sbin/e-smith/expand-template /etc/crontab
Obviously this solution can be improved in many ways. But for me and some of my users, it's really convenient. E.g. when you on your phone receive an email with an attached pdf. You simply forward the email to printpdf@yourserver.org, and after a few minutes, the pdf is printed.
What do you think?
/Jesper H
-
If it works it is a very elegant solution. Worth a contrib... :wink:
Congrats!
-
nice
you might want to add some protection to avoid external sending to this account as it could make your printer run unnecessary.
indeed worth a contrib!
-
First thing is to make a Wiki page :-)
I could probably code something basic up - the only trick bit I guess is autocreating a user (or checking if the user already exists during install)
Easy enough to add a config entry to allow you to modify the printer name and some options
I don't mind bashing out something basic to get it started if someone else is prepared to test and modify stuff ?
B. Rgds
John
-
I've never made a contrib, but will be happy to contribute :-)
As Jean-Philippe says, some additional protection maybe needed. This could be added by e.g. requiring a special password to appear in the Subject-field. But for users, it is much simpler if all they need to remember is the email-address to send to.
I haven't done substantial testing here, but it seems to work very well. It is really convenient to be able from your phone to just forward an email and have the attached pdf's printed.
/Jesper H
-
Is it possible to ONLY accept email on that printpdf account from emails originating from the same domain... ?
-
I've never made a contrib, but will be happy to contribute :-)
As Jean-Philippe says, some additional protection maybe needed. This could be added by e.g. requiring a special password to appear in the Subject-field. But for users, it is much simpler if all they need to remember is the email-address to send to.
I haven't done substantial testing here, but it seems to work very well. It is really convenient to be able from your phone to just forward an email and have the attached pdf's printed.
/Jesper H
Let me see if I can flesh out some templates and a basic rpm. I'll sling it in my git account so you can hack it about. Good opportunity to see how to build a contrib
If we get something workable Jean Phillippe will import it to contribs :-)
Give me a few days as I rammed. Suggest you write this up on a wiki page and we can add developments there.
B. Rgds
John
-
Is it possible to ONLY accept email on that printpdf account from emails originating from the same domain... ?
I'm sure, but don't know how myself.
Any ideas ? Only mail sent by an authenticated user on this IP?
B. Rgds
John
-
Is it possible to ONLY accept email on that printpdf account from emails originating from the same domain... ?
Yes it would be possible - but that would still be open to spoofing. You would want to accept the messages only from authenticated SMTP connections.
-
Yes it would be possible - but that would still be open to spoofing. You would want to accept the messages only from authenticated SMTP connections.
Thanks Charlie
-
I may be naïve, but I doubt that the risk of somebody from outside the organisation to be misusing this kind of facility is quite small. There is no economical incentive. The only benefit for an outside mis-user will be to cause irritation.
-
Put me down as a tester...
-
Put me down as a tester...
It's coming....
-
I may be naïve, but I doubt that the risk of somebody from outside the organisation to be misusing this kind of facility is quite small. There is no economical incentive. The only benefit for an outside mis-user will be to cause irritation.
No, but we always err on the side of caution..... :-) If I get the basic thing thrown together I'll look at it
-
https://wiki.contribs.org/Print_PDF
https://github.com/reetp/smeserver-print-pdf
I have just basically fleshed out the templates but it needs a lot of work. Ignore createlinks - that is just an example one to remind myself of how some things go when we come to build the RPM. Basic spec file is in place. It might not be the prettiest or tightest code but I have tried to make it easy to follow for anyone wanting to learn how to do this stuff.
Seems that to expand user templates we need an action so I stole the qmail-update-user one (thanks Stefano)
So we can do /etc/e-smith/events/actions/printpdf-update to regenerate fragments. I'll add that in properly with some createlinks etc later.
We need to think about user creation (see notes.txt)
Basic default keys
printpdf=service
Media=A4,tray1
Password=NoPasswordSet
PrinterName=none
status=enabled
I have added checks to make sure things like POP3 is enabled before it tries to create templates but some logic is broken on that someplace..... to be fixed.
Currently to test.......
You can copy the templates out of git, or clone it to your server and copy the etc directory across.
chmod 0554 /etc/e-smith/events/actions/printpdf-update
Signal-event post-upgrade & reboot
Check we have some keys as above
Add a user 'printpdf' manually for now
/etc/e-smith/events/actions/printpdf-update
See if you have .fetchmailrc and action.sh in the printpdf user directory. Mod some keys and see what happens.
That at least gets the basic templates done.
I'll try and do a bit more tomorrow. Merge requests welcome :-)
B. Rgds
John
-
I may be naïve, but I doubt that the risk of somebody from outside the organisation to be misusing this kind of facility is quite small. There is no economical incentive. The only benefit for an outside mis-user will be to cause irritation.
well think about your old fax machine that receive hundred of unsolicited advertisements...
Also, all the spams you can gather everyday through emails... imagine this arrive on your pdf printing address with pdf attached ...
as pointed Charlie we just have to put a verification on from where it was sent. we do something similar with the alias everyone
-
Updated in git.
copy printpdf-update to the actions directory
chmod 0774 /etc/e-smith/events/actions/printpdf-update
Then
/etc/e-smith/events/actions/printpdf-update
This now seems to work and generate the relevant files and permissions and is locked to the pdfprint user.
Just need to figure my logical 'ands' in the templates now :-)
B. Rgds
John
-
Load more bits done. Would help if I was a proper coder!
git pull
cp the /etc dir over
chmod 0554 /etc/e-smith/events/actions/printpdf-update (will be fixed in rpm spec file)
signal-event post-upgrade & reboot
[root@test printpdf]# config show printpdf
printpdf=service
Media=A4,tray1
Password=NoPasswordSet
PrinterName=none
status=enabled
Add a user 'printpdf' manually for now
mkdir -p /home/e-smith/files/users/printpdf/mailtemp
mkdir -p /home/e-smith/files/users/printpdf/printable
chown -R printpdf:printpdf /home/e-smith/files/users/printpdf
Add a printer
config set printpdf Password printpdfUserPass
config set printpdf PrinterName MyPrinter
/etc/e-smith/events/actions/printpdf-update
If the status of printpdf or pop3 are disabled or the printer is none or nothing the templated files will show an error. I need to add a check that the printer name matches that in the AccountsDB.
Could do with a way of allowing extra print options. Perhaps add some keys (option1 option2 etc ? Easier to parse them I guess) to the printer in the accounts DB so if you change printer it reads the setup from the printer rather than printpdf ?
Most of this will work out of the box once I build a rpm.
Need to figure the user autocreation next.
B. Rgds
John
-
FYI there are some intriguing solutions following my post here:
https://lists.contribs.org/pipermail/devinfo/2017-January/013855.html
I will have a look at some options ASAP. Been a bit busy hacking my libreswan to add certificate support :-)
-
Very interesting. I will try to make a Perl-script to handle the emails and attachments, as suggested by Charlie.
Thanks to everyone contributing :-)
-
Very interesting. I will try to make a Perl-script to handle the emails and attachments, as suggested by Charlie.
Thanks to everyone contributing :-)
Jesper,
if you get something based on this then I will add it to the code I already have. Or if you use git you can do a PR and we can merge it all up :-)
I think it is a neat idea and I am happy to build an RPM if we get the basic code thrashed out.
Let me know - but note I am away for a long weekend tomorrow. No computers. Lots of wine :-)
B. Rgds
John
-
Here is a new way to do it, following the suggestion of Charlie.
Create /var/qmail/alias/.qmail-printdf with this content
| /var/qmail/bin/printpdf.pl
The file owner should be root.qmail, attributes 644
Create /var/qmail/bin/printpdf.pl with this content
#!/usr/bin/perl -w
use MIME::Parser;
use MIME::WordDecoder;
use strict;
my ($parser, $password, $subject, $from, $entity, $num_parts, $part, $line, %settings, $tmpdir);
# Mime-type to print:
my %type_ok = (
'application/pdf' => 1,
'application/octet-stream' => 1
);
open (LOG, ">>", "/tmp/printpdf.log");
print LOG "Received new email at ".localtime()."\n";
# Get settings from configuration-file
my $config_file = "/etc/printpdf.conf";
if (-e $config_file) {
open (CONF, "<", $config_file);
while ($line = <CONF>) {
chomp $line;
$line =~ s/#.*//;
$line =~ s/^\s+//;
$line =~ s/\s+$//;
next unless (length($line));
my ($var, $value) = split (/\s*=\s*/, $line, 2);
$settings{$var} = $value;
}
}
# Use default settings if not provided in configuration-file
$settings{"tmpdir"} ||= "/tmp/printpdf";
$tmpdir = $settings{"tmpdir"};
$settings{"lp-options"} ||= "-o media=A4,tray1 -o fit-to-page -o position=top -o scaling=100";
unless (-e $tmpdir) {
print LOG "Creating new tmpdir: $tmpdir\n";
system("mkdir -p $tmpdir")
}
# Create parser
$parser = MIME::Parser->new();
$parser -> output_dir($tmpdir);
# Parse input
$entity = $parser -> parse(\*STDIN) or die "Parse failed\n";
$num_parts = $entity -> parts;
# Handle mime parts
if ($num_parts > 0) {
$from = unmime $entity -> head -> get('from');
$subject = unmime $entity -> head -> get('subject');
print LOG "Message from:\n$from\nSubject:\n$subject\n$num_parts mime parts\n";
# Password ok?
if (exists($settings{"password"}) && index($subject, $settings{"password"}) < 0) {
print LOG "Password not found in subject-field\n"
} else {
for (my $i = 0; $i < $num_parts; $i++) {
$part = $entity -> parts($i);
if (exists ($type_ok{lc $part -> mime_type})) {
my $bh = $part -> bodyhandle;
print LOG "Printing ", $bh -> path, " ...\n";
system("lp " . $settings{"lp-options"} . ' "' . $bh->path . '"'.);
}
}
}
}
$parser->filer->purge;
print LOG "Done!\n";
Finally, create a configuration-file /etc/printpdf.conf, e.g.
password = secret
lp-options = -d MC560 -o media=A4,tray1 -o fit-to-page -o position=top -o scaling=100
The configuration-file can easily be templated. If a password is given, this password must also be part of the subject-line in the email-message.
If there is no user named "printpdf", only email from authenticated users will be allowed.
The program writes a log-file in /tmp/printpdf .
ReetP, please take a look at it when you are sober again :-)
-
ReetP, please take a look at it when you are sober again :-)
Will do.....
Still testing here :-)
https://flic.kr/p/RBUptH
-
Here is a new way to do it, following the suggestion of Charlie.
The configuration-file can easily be templated. If a password is given, this password must also be part of the subject-line in the email-message.
Yes that's easy
If there is no user named "printpdf", only email from authenticated users will be allowed.
Better to have no user then ? Allows authenticated users only.
However, where do you then send the email to and how does qmail pick it up as a printpdf only job? Seems that this looks at every single mail ?
The program writes a log-file in /tmp/printpdf .
Probably better in /var/log/printpdf.log ?
ReetP, please take a look at it when you are sober again :-)
That's always a rare event ;-)
-
Better to have no user then ? Allows authenticated users only.
Yes. You only need a "printpdf"-user, if you want un-authenticated users to be able to print also.
However, where do you then send the email to and how does qmail pick it up as a printpdf only job? Seems that this looks at every single mail ?
You send the email to printpdf@yourdomain.com . For qmail, printpdf is an alias.
Probably better in /var/log/printpdf.log ?
Yes, I guess so. I haven't tested this.
That's always a rare event ;-)
I'll wait ...
-
Just curious, any progress on this pls?
-
Just curious, any progress on this pls?
I have been working on some code with Jesper.
Will post something more soon.
B. Rgds
John
-
Finally.....
I have updated some stuff, updated it to git, built a RPM and modified the wiki, though the wiki page needs more work
Please give us some feedback
B. Rgds
John
-
Finally.....
I have updated some stuff, updated it to git, built a RPM and modified the wiki, though the wiki page needs more work
Please give us some feedback
B. Rgds
John
and the rpm is called?
-
and the rpm is called?
smeserver-qmail-printpdf :-)
-
:lol:
-
smeserver-qmail-printpdf v0.1-6 in my repo
It generates the /etc/printpdf.conf template correctly if the Printer and Pass are set to something other than None and status is enabled. Not tested beyond that
Bugs on git at the minute whilst in pre pre pre Alpha
-
I was having another look at this.
Another method, and one that would not require passwords being thrown around, is to try and use procmail and a script to process the PDF.
I have been messing about with this at work but get stuck on passing the body of the mail message to the script. I can get the script to run from .procmailrc but just can't see the body which is mean to be on STDIN. Allegedly.
Something like this seems to copy the mail to the 'Printed' directory and echo a bit to a tmp file but no idea how top access the actual mail body:
# ---- user rules ------------------
:0
* ^Subject.*Order
{
:0cWhi
|~/echotest.sh
:0
$MAILDIR/.Printed/
}
I'm pretty sure if I can get the mail body then the scripts we have already got will process the mail.
Any suggestions appreciated.