Compare commits
2 Commits
25fefef893
...
e772bcf6d5
Author | SHA1 | Date | |
---|---|---|---|
e772bcf6d5 | |||
dceb67b0aa |
46
README.md
46
README.md
|
@ -20,7 +20,12 @@ This is a HP ePrint clone that has similar functions to normal HP ePrint but its
|
||||||
|
|
||||||
3. Build the binary:
|
3. Build the binary:
|
||||||
```
|
```
|
||||||
go build -o web-hp-eprint
|
go build -o eprintclone
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Execture the binary:
|
||||||
|
```
|
||||||
|
./eprintclone
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
@ -31,6 +36,45 @@ In the .env file this is the only thing you can set
|
||||||
PORT=8080
|
PORT=8080
|
||||||
LOG=log # enables file logging (aka copies file to user home directory under the folder imagelog so make a folder first in the home root if you wish to enable it), to disable it replace it with nolog
|
LOG=log # enables file logging (aka copies file to user home directory under the folder imagelog so make a folder first in the home root if you wish to enable it), to disable it replace it with nolog
|
||||||
```
|
```
|
||||||
|
## Autostart with systemd or OpenRC
|
||||||
|
|
||||||
|
You can autostart the web server using systemd or OpenRC (init scripts are in the init-scripts folder)
|
||||||
|
To use it, edit the script accordingly (edit username on what user it is going to run and the path to the binary on where it will run from)
|
||||||
|
|
||||||
|
## for systemd edit the following lines:
|
||||||
|
|
||||||
|
```
|
||||||
|
; Don't forget to change the value here!
|
||||||
|
; There is no reason to run this program as root, just use your username
|
||||||
|
User=examplename # change this to your username
|
||||||
|
|
||||||
|
WorkingDirectory=/path/to/binary # change this to the path where the binary resides
|
||||||
|
```
|
||||||
|
### and to add it as a service:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo cp /path/to/cloned/repo/init-scripts/eprint-clone-web.service /etc/systemd/system
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable eprint-clone-web.service
|
||||||
|
sudo systemctl start eprint-clone-web.service
|
||||||
|
```
|
||||||
|
|
||||||
|
## for OpenRC edit the following lines:
|
||||||
|
|
||||||
|
```
|
||||||
|
command="bash -c cd ~/web-hp-eprint-clone && ./eprintclone" # if you have put the eprintclone binary somewhere else change this line
|
||||||
|
# Don't forget to change the value here!
|
||||||
|
# There is no reason to run this program as root, just use your username
|
||||||
|
command_user="userexample" # change this to your usernames
|
||||||
|
```
|
||||||
|
|
||||||
|
### and to add it as a service:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo cp /path/to/cloned/repo/init-scripts/eprint-clone-web /etc/init.d/eprint-clone-web
|
||||||
|
sudo rc-update add eprint-clone-web
|
||||||
|
sudo rc-service eprint-clone-web start
|
||||||
|
```
|
||||||
|
|
||||||
### For this to even work
|
### For this to even work
|
||||||
You need a linux distro which has the modern equifelent of the lpr program. To check if you have the newer version, type `man lpr` and look at the program description, if it says `lpr - print files` (present on recent Ubuntu versions and rolling release distros like Arch Linux) then you are good to go otherwaise if it says `lpr - off line print` (present on Debian and older Ubuntu versions) then this won't work as the commands for the older version are different and this targets the newer version of the program.
|
You need a linux distro which has the modern equifelent of the lpr program. To check if you have the newer version, type `man lpr` and look at the program description, if it says `lpr - print files` (present on recent Ubuntu versions and rolling release distros like Arch Linux) then you are good to go otherwaise if it says `lpr - off line print` (present on Debian and older Ubuntu versions) then this won't work as the commands for the older version are different and this targets the newer version of the program.
|
||||||
|
|
33
eprintcloned
33
eprintcloned
|
@ -1,8 +1,29 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# Check for specified arguments
|
||||||
|
if [ $# -lt 3 ]
|
||||||
|
then
|
||||||
|
echo "Not enough arguments - exiting"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
printer=examplename # replace this with your actual printer name before putting it into /usr/bin
|
printer=examplename # replace this with your actual printer name before putting it into /usr/bin
|
||||||
imagelogmsg="Server hoster decided to enable file logging, if you don't wish your file to be logged, ask the server owner to delete your sent file or if you are the server hoster set LOG=nolog in .env file" # add a custom logging of files message
|
imagelogmsg="Server hoster decided to enable file logging, if you don't wish your file to be logged, ask the server owner to delete your sent file or if you are the server hoster set LOG=nolog in .env file" # add a custom logging of files message
|
||||||
|
|
||||||
|
# check if quality is specified, it it isn't then set the default quality
|
||||||
|
if [ $# -gt 4 ]; then
|
||||||
|
quality=$3
|
||||||
|
else
|
||||||
|
quality=4
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check if page range is specified, it it isn't then ignore setting a page range
|
||||||
|
if [ $# -gt 4 ]; then
|
||||||
|
pagerange=$4
|
||||||
|
else
|
||||||
|
pagerange=""
|
||||||
|
fi
|
||||||
|
|
||||||
# Loop through each file passed as an argument
|
# Loop through each file passed as an argument
|
||||||
for file in "$1"; do
|
for file in "$1"; do
|
||||||
# Get the MIME type of the file
|
# Get the MIME type of the file
|
||||||
|
@ -12,22 +33,22 @@ for file in "$1"; do
|
||||||
if [[ "$mime_type" == image/* || "$mime_type" == application/pdf ]]; then
|
if [[ "$mime_type" == image/* || "$mime_type" == application/pdf ]]; then
|
||||||
if [[ $2 == log ]]; then
|
if [[ $2 == log ]]; then
|
||||||
echo $imagelogmsg
|
echo $imagelogmsg
|
||||||
cp $1 $HOME/imagelog
|
cp "$1" $HOME/imagelog/
|
||||||
echo "Printing image/document"
|
echo "Printing image/document"
|
||||||
lpr -o portrait -o media=A4 -o fit-to-page $1 -P $printer # if you are using a different printer that requires different commands to print, change this part of the code.
|
lpr -r -o portrait -o media=A4 -o fit-to-page -o print-quality=$quality $pagerange "$1" -P $printer # if you are using a different printer that requires different commands to print, change this part of the code.
|
||||||
else
|
else
|
||||||
echo "Printing image/document"
|
echo "Printing image/document"
|
||||||
lpr -o portrait -o media=A4 -o fit-to-page $1 -P $printer # if you are using a different printer that requires different commands to print, change this part of the code.
|
lpr -r -o portrait -o media=A4 -o fit-to-page -o print-quality=$quality $pagerange "$1" -P $printer # if you are using a different printer that requires different commands to print, change this part of the code.
|
||||||
fi
|
fi
|
||||||
elif [[ "$mime_type" == text/* ]]; then
|
elif [[ "$mime_type" == text/* ]]; then
|
||||||
if [[ $2 == log ]]; then
|
if [[ $2 == log ]]; then
|
||||||
echo $imagelogmsg
|
echo $imagelogmsg
|
||||||
cp $1 $HOME/imagelog
|
cp "$1" $HOME/imagelog/
|
||||||
echo "Printing text"
|
echo "Printing text"
|
||||||
lpr -o portrait -o media=A4 -o fit-to-page $1 -P $printer # if you are using a different printer that requires different commands to print, change this part of the code.
|
lpr -o portrait -o media=A4 -o fit-to-page -o print-quality=$quality $pagerange "$1" -P $printer # if you are using a different printer that requires different commands to print, change this part of the code.
|
||||||
else
|
else
|
||||||
echo "Printing text"
|
echo "Printing text"
|
||||||
lpr -o portrait -o media=A4 -o fit-to-page $1 -P $printer # if you are using a different printer that requires different commands to print, change this part of the code.
|
lpr -r -o portrait -o media=A4 -o fit-to-page -o print-quality=$quality $pagerange "$1" -P $printer # if you are using a different printer that requires different commands to print, change this part of the code.
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "Error: Invalid file type or, ePrint clone only accepts the following MIME types: text/*, image/*, application/pdf"
|
echo "Error: Invalid file type or, ePrint clone only accepts the following MIME types: text/*, image/*, application/pdf"
|
||||||
|
|
15
init-scripts/eprint-clone-web
Normal file
15
init-scripts/eprint-clone-web
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
|
name=eprint-clone-web
|
||||||
|
description="HP ePrint clone (on the web)"
|
||||||
|
|
||||||
|
command="bash -c cd ~/web-hp-eprint-clone && ./eprintclone" # if you have put the eprintclone binary somewhere else change this line
|
||||||
|
# Don't forget to change the value here!
|
||||||
|
# There is no reason to run this program as root, just use your username
|
||||||
|
command_user="userexample" # change this to your username
|
||||||
|
|
||||||
|
pidfile="/run/${RC_SVCNAME}.pid"
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
need net
|
||||||
|
}
|
29
init-scripts/eprint-clone-web.service
Executable file
29
init-scripts/eprint-clone-web.service
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
[Unit]
|
||||||
|
Description=HP ePrint clone (on the web)
|
||||||
|
Requires=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
|
||||||
|
; Don't forget to change the value here!
|
||||||
|
; There is no reason to run this program as root, just use your username
|
||||||
|
User=examplename # change this to your username
|
||||||
|
|
||||||
|
WorkingDirectory=/path/to/binary # change this to the path where the binary resides
|
||||||
|
|
||||||
|
ExecStart=./eprintclone
|
||||||
|
|
||||||
|
; Always restart the script
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
; cf. https://www.darkcoding.net/software/the-joy-of-systemd/
|
||||||
|
; /usr, /boot and /etc are read-only
|
||||||
|
ProtectSystem=full
|
||||||
|
; /tmp is isolated from all other processes
|
||||||
|
PrivateTmp=false
|
||||||
|
; Don't allow process to raise privileges (e.g. disable suid)
|
||||||
|
NoNewPrivileges=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
31
main.go
31
main.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
)
|
)
|
||||||
|
@ -73,11 +74,31 @@ func handleUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
targetmail := r.FormValue("targetmail")
|
// Regular expression to check if input contains only numbers and hyphens so that user canot execute arbitary code
|
||||||
if targetmail == "" {
|
printconfig := r.FormValue("printconfig")
|
||||||
fmt.Printf("Warning: User did not specify a mail on sent request")
|
if printconfig == "" {
|
||||||
|
fmt.Printf("Warning: User did not specify page range on sent request\n")
|
||||||
|
} else {
|
||||||
|
re := regexp.MustCompile(`^[0-9]+(-[0-9]+)*$`)
|
||||||
|
if !re.MatchString(printconfig) {
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"error": "Invalid page range"})
|
||||||
|
fmt.Printf("debug: printconfig is: %s\n", printconfig)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Regular expression to check if input contains only numbers so that user canot execute arbitary code
|
||||||
|
printres := r.FormValue("res")
|
||||||
|
if printres == "" {
|
||||||
|
fmt.Printf("Warning: User did not specify quality on sent request, assuming normal quality\n")
|
||||||
|
printres = "4"
|
||||||
|
} else {
|
||||||
|
re := regexp.MustCompile(`^[1-5]+$`)
|
||||||
|
if !re.MatchString(printres) {
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"error": "Invalid quality range"})
|
||||||
|
fmt.Printf("debug: res is: %s\n", printres)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tempFileName := filepath.Join(os.TempDir(), handler.Filename)
|
tempFileName := filepath.Join(os.TempDir(), handler.Filename)
|
||||||
tempFile, err := os.Create(tempFileName)
|
tempFile, err := os.Create(tempFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -96,7 +117,7 @@ func handleUpload(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
printingcmdPath := filepath.Join("/", "usr", "bin", "eprintcloned")
|
printingcmdPath := filepath.Join("/", "usr", "bin", "eprintcloned")
|
||||||
filelog := os.Getenv("LOG")
|
filelog := os.Getenv("LOG")
|
||||||
cmd := exec.Command(printingcmdPath, tempFile.Name(), filelog, targetmail)
|
cmd := exec.Command(printingcmdPath, tempFile.Name(), filelog, printres, printconfig)
|
||||||
|
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -4,7 +4,7 @@ const commandOutput = document.getElementById('commandOutput');
|
||||||
|
|
||||||
uploadForm.addEventListener('submit', async (e) => {
|
uploadForm.addEventListener('submit', async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
uploadStatus.textContent = 'Uploading and printing...';
|
uploadStatus.textContent = 'Uploading...';
|
||||||
commandOutput.textContent = '';
|
commandOutput.textContent = '';
|
||||||
|
|
||||||
const formData = new FormData(uploadForm);
|
const formData = new FormData(uploadForm);
|
||||||
|
|
|
@ -21,12 +21,21 @@
|
||||||
<input type="file" accept=".jpg, .jpeg, .png, .gif, .txt, .pdf" name="file" required />
|
<input type="file" accept=".jpg, .jpeg, .png, .gif, .txt, .pdf" name="file" required />
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="targetmail"
|
name="printconfig"
|
||||||
placeholder="Confirmation e-mail after printing finishes [Optional]"
|
placeholder="Specify which pages to print (only supported on PDF documents) [Optional]"
|
||||||
style="width: 210px;"
|
style="width: 450px;"
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<button type="submit" class="button">Upload</button>
|
<form id="quality">
|
||||||
|
<label for="res">Quality:</label>
|
||||||
|
<select id="res" name="res">
|
||||||
|
<option value="1">1 (Draft)</option>
|
||||||
|
<option value="2">2 (Draft)</option>
|
||||||
|
<option value="3">3 (Draft)</option>
|
||||||
|
<option value="4" selected>4 (Normal)</option>
|
||||||
|
<option value="5">5 (Best)</option>
|
||||||
|
</select>
|
||||||
|
<button type="submit" style="width: 750px;" class="button">Upload</button>
|
||||||
</form>
|
</form>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user