mirror of
https://github.com/Noettore/fattureCCSR.git
synced 2025-10-15 11:46:39 +02:00
First alpha version
Signed-off-by: Ettore Dreucci <ettore.dreucci@gmail.com>
This commit is contained in:
27
.gitignore
vendored
Normal file
27
.gitignore
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# ---> Go
|
||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
||||||
|
|
||||||
|
# ---> VisualStudioCode
|
||||||
|
.settings
|
||||||
|
*.code-workspace
|
||||||
|
.vscode
|
208
fattureSanRossore.go
Normal file
208
fattureSanRossore.go
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/extrame/xls"
|
||||||
|
"github.com/pdfcpu/pdfcpu/pkg/api"
|
||||||
|
"github.com/sqweek/dialog"
|
||||||
|
"mvdan.cc/xurls/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var tmp string = os.TempDir()
|
||||||
|
|
||||||
|
func getInvoiceIDs(fileName string) []string {
|
||||||
|
xlFile, err := xls.Open(fileName, "utf-8")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Impossibile aprire il file xls: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sheet := xlFile.GetSheet(0)
|
||||||
|
if sheet == nil {
|
||||||
|
log.Fatalf("Impossibile aprire il foglio nell'xls: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var invoiceIDs []string
|
||||||
|
|
||||||
|
for i := 4; i <= int(sheet.MaxRow); i++ {
|
||||||
|
row := sheet.Row(i)
|
||||||
|
if row.Col(8) != "" {
|
||||||
|
id := strings.ReplaceAll(row.Col(8), "/", "-")
|
||||||
|
invoiceIDs = append(invoiceIDs, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invoiceIDs
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertXLStoFODS(fileName string) string {
|
||||||
|
var sofficePath string = "libreoffice"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
sofficePath = filepath.FromSlash("C:/Program Files/LibreOffice/program/soffice.exe")
|
||||||
|
}
|
||||||
|
cmd := exec.Command(sofficePath, "--convert-to", "fods", "--outdir", tmp, fileName)
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Impossibile convertire l'XLS in FODS: %v\n", err)
|
||||||
|
}
|
||||||
|
return (tmp + "/" + strings.TrimSuffix(filepath.Base(fileName), filepath.Ext(fileName)) + ".fods")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInvoiceURLs(fileName string) []string {
|
||||||
|
fods := convertXLStoFODS(fileName)
|
||||||
|
f, err := os.Open(fods)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Impossibile aprire il FODS convertito: %v\n", err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
err = f.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Impossibile chiudere il file %v: %v\n", fods, err)
|
||||||
|
}
|
||||||
|
err = os.Remove(fods)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Impossibile eliminare il file temporaneo %v: %v\n", fods, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
var invoiceURLs []string
|
||||||
|
s := bufio.NewScanner(f)
|
||||||
|
for s.Scan() {
|
||||||
|
line := s.Text()
|
||||||
|
if strings.Contains(line, "http://report.casadicurasanrossore.it:9146/files/get?type=invoice&id=") {
|
||||||
|
url := xurls.Strict().FindString(line)
|
||||||
|
url = strings.ReplaceAll(url, "&", "&")
|
||||||
|
invoiceURLs = append(invoiceURLs, url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := s.Err(); err != nil {
|
||||||
|
log.Fatalf("Impossibile leggere dal file %v: %v\n", fods, err)
|
||||||
|
}
|
||||||
|
return invoiceURLs
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkFile(fileName string) string {
|
||||||
|
_, err := os.Stat(fileName)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Errore nell'apertura del file %v: %v\n", fileName, err)
|
||||||
|
}
|
||||||
|
absPath, err := filepath.Abs(fileName)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Impossibile recuperare il percorso assoluto del file %v: %v\n", fileName, err)
|
||||||
|
}
|
||||||
|
return absPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func downloadFile(fileName string, url string) error {
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
out, err := os.Create(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(out, resp.Body)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func downloadInvoices(ids []string, urls []string) []string {
|
||||||
|
if len(ids) != len(urls) {
|
||||||
|
log.Fatalf("Il numero di fatture da scaricare non corrisponde al numero di URL individuati nel file")
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := filepath.FromSlash(tmp + "/pdfInvoices" + "_" + time.Now().Format("20060102"))
|
||||||
|
err := os.Mkdir(dir, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Impossibile creare la directory temporanea di salvataggio %v: %v\n", dir, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadCount := 0
|
||||||
|
var downloadedFiles []string
|
||||||
|
for i := 0; i < len(ids); i++ {
|
||||||
|
out := filepath.FromSlash(dir + "/" + ids[i] + ".pdf")
|
||||||
|
|
||||||
|
fmt.Printf("Scaricamento di %v\n", ids[i])
|
||||||
|
err = downloadFile(out, urls[i])
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Impossibile scaricare il file %v: %v\n", urls[i], err)
|
||||||
|
} else {
|
||||||
|
downloadCount++
|
||||||
|
downloadedFiles = append(downloadedFiles, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Printf("Scaricate %d/%d fatture\n", downloadCount, len(ids))
|
||||||
|
return downloadedFiles
|
||||||
|
}
|
||||||
|
|
||||||
|
func mergeInvoices(files []string) string {
|
||||||
|
out, err := dialog.File().Filter("PDF files", "pdf").Title("Scegli dove salvare le fatture unite").Save()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Impossibile recuperare il file selezionato: %v\n", err)
|
||||||
|
}
|
||||||
|
if filepath.Ext(out) == "" {
|
||||||
|
out += ".pdf"
|
||||||
|
}
|
||||||
|
err = api.MergeFile(files, out, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Impossibile unire i pdf: %v\nFatture singole non rimosse\n", err)
|
||||||
|
}
|
||||||
|
dir := filepath.Dir(files[0])
|
||||||
|
for _, file := range files {
|
||||||
|
err = os.Remove(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Impossibile eliminare la fattura singola %v: %v\n", file, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = os.Remove(dir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Impossibile eliminare la directory temporanea %v: %v\n", dir, err)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func openPDF(fileName string) {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
cmd := exec.Command("cmd", "/C start "+fileName)
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Impossibile aprire il pdf con le fatture unite: %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO for Linux
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var fileName string
|
||||||
|
|
||||||
|
args := os.Args
|
||||||
|
if len(args) < 2 {
|
||||||
|
var err error
|
||||||
|
fileName, err = dialog.File().Filter("XLS files", "xls").Load()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Impossibile recuperare il file selezionato: %v\n", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fileName = args[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath := checkFile(fileName)
|
||||||
|
IDs := getInvoiceIDs(filePath)
|
||||||
|
URLs := getInvoiceURLs(filePath)
|
||||||
|
dlFiles := downloadInvoices(IDs, URLs)
|
||||||
|
pdf := mergeInvoices(dlFiles)
|
||||||
|
openPDF(pdf)
|
||||||
|
|
||||||
|
}
|
12
go.mod
Normal file
12
go.mod
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module github.com/Noettore/ccsrReportDownloader
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/extrame/ole2 v0.0.0-20160812065207-d69429661ad7 // indirect
|
||||||
|
github.com/extrame/xls v0.0.1
|
||||||
|
github.com/gotk3/gotk3 v0.4.0 // indirect
|
||||||
|
github.com/pdfcpu/pdfcpu v0.3.2
|
||||||
|
github.com/sqweek/dialog v0.0.0-20200304031853-0dcd55bfe06a
|
||||||
|
mvdan.cc/xurls/v2 v2.2.0
|
||||||
|
)
|
45
go.sum
Normal file
45
go.sum
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
|
||||||
|
github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
|
||||||
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k=
|
||||||
|
github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf h1:FPsprx82rdrX2jiKyS17BH6IrTmUBYqZa/CXT4uvb+I=
|
||||||
|
github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf/go.mod h1:peYoMncQljjNS6tZwI9WVyQB3qZS6u79/N3mBOcnd3I=
|
||||||
|
github.com/extrame/ole2 v0.0.0-20160812065207-d69429661ad7 h1:n+nk0bNe2+gVbRI8WRbLFVwwcBQ0rr5p+gzkKb6ol8c=
|
||||||
|
github.com/extrame/ole2 v0.0.0-20160812065207-d69429661ad7/go.mod h1:GPpMrAfHdb8IdQ1/R2uIRBsNfnPnwsYE9YYI5WyY1zw=
|
||||||
|
github.com/extrame/xls v0.0.1 h1:jI7L/o3z73TyyENPopsLS/Jlekm3nF1a/kF5hKBvy/k=
|
||||||
|
github.com/extrame/xls v0.0.1/go.mod h1:iACcgahst7BboCpIMSpnFs4SKyU9ZjsvZBfNbUxZOJI=
|
||||||
|
github.com/frankban/quicktest v1.5.0/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
|
||||||
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/gotk3/gotk3 v0.4.0 h1:TIuhyQitGeRTxOQIV3AJlYtEWWJpC74JHwAIsxlH8MU=
|
||||||
|
github.com/gotk3/gotk3 v0.4.0/go.mod h1:Eew3QBwAOBTrfFFDmsDE5wZWbcagBL1NUslj1GhRveo=
|
||||||
|
github.com/hhrutter/lzw v0.0.0-20190827003112-58b82c5a41cc/go.mod h1:yJBvOcu1wLQ9q9XZmfiPfur+3dQJuIhYQsMGLYcItZk=
|
||||||
|
github.com/hhrutter/lzw v0.0.0-20190829144645-6f07a24e8650 h1:1yY/RQWNSBjJe2GDCIYoLmpWVidrooriUr4QS/zaATQ=
|
||||||
|
github.com/hhrutter/lzw v0.0.0-20190829144645-6f07a24e8650/go.mod h1:yJBvOcu1wLQ9q9XZmfiPfur+3dQJuIhYQsMGLYcItZk=
|
||||||
|
github.com/hhrutter/tiff v0.0.0-20190829141212-736cae8d0bc7 h1:o1wMw7uTNyA58IlEdDpxIrtFHTgnvYzA8sCQz8luv94=
|
||||||
|
github.com/hhrutter/tiff v0.0.0-20190829141212-736cae8d0bc7/go.mod h1:WkUxfS2JUu3qPo6tRld7ISb8HiC0gVSU91kooBMDVok=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/mattn/go-gtk v0.0.0-20180216084204-5a311a1830ab/go.mod h1:PwzwfeB5syFHXORC3MtPylVcjIoTDT/9cvkKpEndGVI=
|
||||||
|
github.com/mattn/go-pointer v0.0.0-20171114154726-1d30dc4b6f28/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
||||||
|
github.com/pdfcpu/pdfcpu v0.3.2 h1:oHnvW3KUed/jVLnNcN5FyJsmInXAyyfoZ4yG3mxJdk8=
|
||||||
|
github.com/pdfcpu/pdfcpu v0.3.2/go.mod h1:/ULj8B76ZnB4445B0yuSASQqlN0kEO+khtEnmPdEoXU=
|
||||||
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||||
|
github.com/skelterjohn/go.wde v0.0.0-20180104102407-a0324cbf3ffe/go.mod h1:zXxNsJHeUYIqpg890APBNEn9GoCbA4Cdnvuv3mx4fBk=
|
||||||
|
github.com/sqweek/dialog v0.0.0-20200304031853-0dcd55bfe06a h1:BHv3lo0aZg2IPfeBfgYFjq48DoKehP+JC9dtACUEmT4=
|
||||||
|
github.com/sqweek/dialog v0.0.0-20200304031853-0dcd55bfe06a/go.mod h1:QSrNdZLZB8VoFPGlZ2vDuA2oNaVdhld3g0PZLc7soX8=
|
||||||
|
github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
|
||||||
|
github.com/tealeg/xlsx/v2 v2.0.1 h1:RP+VEscpPFjH2FnpKh1p9HVLAk1htqb9Urcxi2AU1ns=
|
||||||
|
github.com/tealeg/xlsx/v2 v2.0.1/go.mod h1:l9GvhCCjdaIGkAyZcFedDALcYcXUOei55f6umRMOz9c=
|
||||||
|
golang.org/x/image v0.0.0-20190823064033-3a9bac650e44/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52 h1:2fktqPPvDiVEEVT/vSTeoUPXfmRxRaGy6GU8jypvEn0=
|
||||||
|
golang.org/x/image v0.0.0-20191214001246-9130b4cfad52/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
mvdan.cc/xurls v1.1.0 h1:kj0j2lonKseISJCiq1Tfk+iTv65dDGCl0rTbanXJGGc=
|
||||||
|
mvdan.cc/xurls/v2 v2.2.0 h1:NSZPykBXJFCetGZykLAxaL6SIpvbVy/UFEniIfHAa8A=
|
||||||
|
mvdan.cc/xurls/v2 v2.2.0/go.mod h1:EV1RMtya9D6G5DMYPGD8zTQzaHet6Jh8gFlRgGRJeO8=
|
Reference in New Issue
Block a user