... | ... |
@@ -0,0 +1,156 @@ |
1 |
+--------------- |
|
2 |
+-- Options -- |
|
3 |
+--------------- |
|
4 |
+ |
|
5 |
+options.timeout = 120 |
|
6 |
+options.subscribe = true |
|
7 |
+options.cache = true |
|
8 |
+options.close = false |
|
9 |
+options.expunge = true |
|
10 |
+options.recover = 'all' |
|
11 |
+options.info = false |
|
12 |
+options.keepalive = 15 |
|
13 |
+ |
|
14 |
+dofile(os.getenv('HOME') .. '/' .. os.getenv('IMAPACCOUNT') .. '.lua') |
|
15 |
+dofile(os.getenv('HOME') .. '/' .. os.getenv('IMAPACCOUNT') .. '.credentials.lua') |
|
16 |
+ |
|
17 |
+if account1.connect() == nil then return 2 end |
|
18 |
+ |
|
19 |
+delete_oldest = function (a) |
|
20 |
+ local r = Set {} |
|
21 |
+ for _, k in pairs(a.age_table) do |
|
22 |
+ r = a.account[k.folder]:is_older(k.age) * a.account[k.folder]:is_unflagged() |
|
23 |
+ if #r > 0 then |
|
24 |
+ r:delete_messages() |
|
25 |
+ end |
|
26 |
+ end |
|
27 |
+end |
|
28 |
+ |
|
29 |
+-- SYSTÈME D'IMPRESSION |
|
30 |
+authorized_mails = function () |
|
31 |
+ authorized = {} |
|
32 |
+ dofile(os.getenv('HOME') .. '/authorized.lua') |
|
33 |
+ local s = "" |
|
34 |
+ for mail, _ in pairs(authorized) do |
|
35 |
+ s = s .. "|" .. mail |
|
36 |
+ end |
|
37 |
+ return "(" .. string.sub(s, 2) .. ")" |
|
38 |
+end |
|
39 |
+ |
|
40 |
+set_info = function (subject, from, pdf) |
|
41 |
+ local info = { |
|
42 |
+ ["colormodel"] = "Gray" , ["colormodel_hr"] = "niveaux de gris" , |
|
43 |
+ ["sides"] = "two-sided-long-edge", ["sides_hr"] = "rect-verso bord long", |
|
44 |
+ ["papersize"] = "a4" , ["papersize_hr"] = "A4" , |
|
45 |
+ ["inputslot"] = "PF730A" , ["inputslot_hr"] = "1" , |
|
46 |
+ ["qty"] = string.gsub(subject, "^.*impression%s+(%d+).*$", "%1") , |
|
47 |
+ ["pdf"] = pdf , |
|
48 |
+ ["prenom"] = authorized[from].prenom , |
|
49 |
+ ["phone"] = authorized[from].phone , |
|
50 |
+ ["from"] = from , |
|
51 |
+ ["mode"] = "" , |
|
52 |
+ } |
|
53 |
+ local options = { |
|
54 |
+ ["court"] = function () info.sides = "two-sided-short-edge"; info.sides_hr = "recto-verso bord court" end, |
|
55 |
+ ["long"] = function () info.sides = "two-sided-long-edge"; info.sides_hr = "recto-verso bord long" end, |
|
56 |
+ ["recto"] = function () info.sides = "recto"; info.sides_hr = "recto" end, |
|
57 |
+ ["couleur"] = function () info.colormodel = "CYMB"; info.colormodel_hr = "couleur" end, |
|
58 |
+ ["gris"] = function () info.colormodel = "Gray"; info.colormodel_hr = "niveaux de gris" end, |
|
59 |
+ ["bac1"] = function () info.inputslot = "PF730A"; info.inputslot_hr = "1" end, |
|
60 |
+ ["bac2"] = function () info.inputslot = "PF730B"; info.inputslot_hr = "2" end, |
|
61 |
+ ["a4"] = function () info.papersize = "a4"; info.papersize_hr = "A4" end, |
|
62 |
+ ["a3"] = function () info.papersize = "a3"; info.papersize_hr = "A3" end, |
|
63 |
+ ["massicot"]= function () info.mode = "massicot" end, |
|
64 |
+ ["livret"] = function () info.mode = "livret" end, |
|
65 |
+ } |
|
66 |
+ if (tonumber(info.qty) > 250) then |
|
67 |
+ info.qty = 250 |
|
68 |
+ end |
|
69 |
+ for option in string.gmatch(subject, "[^%s]+") do |
|
70 |
+ if options[option] then |
|
71 |
+ options[option]() |
|
72 |
+ end |
|
73 |
+ end |
|
74 |
+ if (info.mode == "massicot") then |
|
75 |
+ info.papersize = "a4" |
|
76 |
+ info.papersize_hr = "A4" |
|
77 |
+ info.sides = "two-sided-short-edge" |
|
78 |
+ info.sides_hr = "recto-verso bord court" |
|
79 |
+ end |
|
80 |
+ if (info.mode == "livret") then |
|
81 |
+ info.sides = "two-sided-short-edge" |
|
82 |
+ info.sides_hr = "recto-verso bord court" |
|
83 |
+ end |
|
84 |
+ if (info.papersize == "a3") then |
|
85 |
+ info.inputslot = "PF730D" |
|
86 |
+ info.inputslot_hr = "4" |
|
87 |
+ end |
|
88 |
+ return info |
|
89 |
+end |
|
90 |
+ |
|
91 |
+generate_script = function (info, spool) |
|
92 |
+ local script = '"' .. spool .. info.pdf .. '.print"' |
|
93 |
+ local sedcmd = "" |
|
94 |
+ for key, value in pairs(info) do |
|
95 |
+ sedcmd = sedcmd .. "s/__" .. key .. "__/" .. string.gsub(value, "/", "\\/") .. "/g;" |
|
96 |
+ end |
|
97 |
+ os.execute("sed '" .. sedcmd:sub(1, -2) .. "' " |
|
98 |
+ .. os.getenv("HOME") .. "/printscript.model > " .. script) |
|
99 |
+end |
|
100 |
+ |
|
101 |
+inform_user = function (info) |
|
102 |
+ local print_time, wakeup_time = 9, 9 |
|
103 |
+ for _, wakeup_time in ipairs({9, 11, 16, 18, 21}) do |
|
104 |
+ if (tonumber(os.date('%H')) < tonumber(wakeup_time)) then |
|
105 |
+ print_time = wakeup_time |
|
106 |
+ break |
|
107 |
+ end |
|
108 |
+ end |
|
109 |
+ mode = info.mode ~= "" and ", en mode " .. info.mode or "" |
|
110 |
+ os.execute("/usr/local/bin/smsapi 'sms pour " .. info.phone |
|
111 |
+ .. ":impression de " .. string.gsub(info.pdf, "'", "\\'") |
|
112 |
+ .. " prévue pour " .. print_time .. "h (" |
|
113 |
+ .. info.qty .. "," |
|
114 |
+ .. info.papersize_hr .. "," |
|
115 |
+ .. info.sides_hr .. "," |
|
116 |
+ .. info.inputslot_hr .. "," |
|
117 |
+ .. info.colormodel_hr |
|
118 |
+ .. mode |
|
119 |
+ .. ")'") |
|
120 |
+end |
|
121 |
+ |
|
122 |
+set_prints = function (a) |
|
123 |
+ local recent = a.inbox:is_unseen() |
|
124 |
+ local results = Set {} |
|
125 |
+ results = recent:match_from(authorized_mails()) |
|
126 |
+ * recent:match_subject("(?i)^impression\\s+\\d") |
|
127 |
+ for _, mesg in ipairs(results) do |
|
128 |
+ mbox, uid = table.unpack(mesg) |
|
129 |
+ structure = mbox[uid]:fetch_structure() |
|
130 |
+ for partid, partinf in pairs(structure) do |
|
131 |
+ if (partinf.type == "application/pdf") then |
|
132 |
+ local spool = "/media/nextcloud_db/impression/" |
|
133 |
+ local info = set_info( |
|
134 |
+ string.lower(mbox[uid]:fetch_field("subject")), |
|
135 |
+ string.gsub(mbox[uid]:fetch_field("from"), "^.*<(.+@.+)>.*$", "%1"), |
|
136 |
+ partinf.name) |
|
137 |
+ pipe_to("base64 -id > \"" .. spool .. info.pdf .. "\"", mbox[uid]:fetch_part(partid)) |
|
138 |
+ generate_script(info, spool) |
|
139 |
+ done = table.pack(mbox, uid) |
|
140 |
+ inform_user(info) |
|
141 |
+ end |
|
142 |
+ end |
|
143 |
+ end |
|
144 |
+ results:mark_seen() |
|
145 |
+end |
|
146 |
+ |
|
147 |
+date = os.date('%j') |
|
148 |
+while true do |
|
149 |
+ set_prints(account1) |
|
150 |
+ local date_ = os.date('%j') |
|
151 |
+ if date ~= date_ then |
|
152 |
+ delete_oldest(account1) |
|
153 |
+ date = date_ |
|
154 |
+ end |
|
155 |
+ account1.inbox:enter_idle() |
|
156 |
+end |
... | ... |
@@ -0,0 +1,10 @@ |
1 |
+authorized = { |
|
2 |
+ ["foo@bar.com"] = { |
|
3 |
+ ["prenom"] = "Foo", |
|
4 |
+ ["phone"] = "0123456789" |
|
5 |
+ }, |
|
6 |
+ ["bar@bar.com"] = { |
|
7 |
+ ["prenom"] = "Bar", |
|
8 |
+ ["phone"] = "0234567891" |
|
9 |
+ }, |
|
10 |
+} |
... | ... |
@@ -0,0 +1,12 @@ |
1 |
+account1 = { |
|
2 |
+ connect = function () |
|
3 |
+ account1.account = IMAP(account1.credentials) |
|
4 |
+ account1.inbox = account1.account['INBOX'] |
|
5 |
+ return account1.account |
|
6 |
+ end, |
|
7 |
+ age_table = { |
|
8 |
+ { folder = 'INBOX', age = 30 }, |
|
9 |
+ { folder = 'Deleted Items', age = 10 }, |
|
10 |
+ { folder = 'Sent', age = 15 }, |
|
11 |
+ }, |
|
12 |
+} |
... | ... |
@@ -0,0 +1,95 @@ |
1 |
+#!/bin/bash |
|
2 |
+ |
|
3 |
+spool='/misc/nextcloud_db/impression' |
|
4 |
+test -r "$spool/__pdf__" || exit |
|
5 |
+ |
|
6 |
+size=$(pdfinfo "$spool/__pdf__" | awk '/^Page size:/{ |
|
7 |
+ a = $3 |
|
8 |
+ b = $5 |
|
9 |
+ if (a >= 419 && a <= 421 && b >= 594 && b <= 596 ) print "a5" |
|
10 |
+ if (a >= 594 && a <= 596 && b >= 419 && b <= 421 ) print "a5" |
|
11 |
+ if (a >= 594 && a <= 596 && b >= 841 && b <= 843 ) print "a4" |
|
12 |
+ if (a >= 841 && a <= 843 && b >= 594 && b <= 596 ) print "a4" |
|
13 |
+ if (a >= 841 && a <= 843 && b >= 1189 && b <= 1191) print "a3" |
|
14 |
+ if (a >= 1189 && a <= 1191 && b >= 841 && b <= 843 ) print "a3" |
|
15 |
+}') |
|
16 |
+test -n "$size" || exit |
|
17 |
+mode=__mode__ |
|
18 |
+pages=$(pdfinfo "$spool/__pdf__" | awk '/Pages:/{print $2}') |
|
19 |
+ |
|
20 |
+case ${mode:-normal} in |
|
21 |
+ massicot) |
|
22 |
+ output=$(mktemp --dry-run /dev/shm/XXXXXXXX.pdf) |
|
23 |
+ if test "${size,,}" != "a4"; then |
|
24 |
+ gs -o $output -sDEVICE=pdfwrite -sPAPERSIZE=a5 -dFIXEDMEDIA -dPDFFitPage -dCompatibilityLevel=1.6 "$spool/__pdf__" |
|
25 |
+ else |
|
26 |
+ cp "$spool/__pdf__" $output |
|
27 |
+ fi |
|
28 |
+ recto=$(mktemp -d /dev/shm/XXXXXXXX) |
|
29 |
+ verso=$(mktemp -d /dev/shm/XXXXXXXX) |
|
30 |
+ pdfjam --paper a4paper --nup 2x1 --landscape --outfile $recto "$output" 1 "$output" 1 |
|
31 |
+ if test $pages -eq 2; then |
|
32 |
+ pdfjam --paper a4paper --nup 2x1 --landscape --outfile $verso "$output" 2 "$output" 2 |
|
33 |
+ pdftk A=$(find $recto -name "*pdf") B=$(find $verso -name "*pdf") cat A B output "$output" |
|
34 |
+ elif test $pages -eq 1; then |
|
35 |
+ output=$(find $recto -name "*pdf") |
|
36 |
+ fi |
|
37 |
+ rm -fr $recto $verso $output |
|
38 |
+ ;; |
|
39 |
+ livret) |
|
40 |
+ if test $pages -ne 4; then |
|
41 |
+ rm "$spool/__pdf__" |
|
42 |
+ /home/sebastien/scripts/smsapi "sms pour __phone__:le document __pdf__ ne contient pas strictement 4 pages nécessaire pour le mode livret, impression annulée" |
|
43 |
+ exit |
|
44 |
+ fi |
|
45 |
+ output=$(mktemp --dry-run /dev/shm/XXXXXXXX.pdf) |
|
46 |
+ recto=$(mktemp --dry-run /dev/shm/XXXXXXXX) |
|
47 |
+ verso=$(mktemp --dry-run /dev/shm/XXXXXXXX) |
|
48 |
+ if test $size = "a3"; then |
|
49 |
+ size="a4" |
|
50 |
+ gs -o $output -sDEVICE=pdfwrite -sPAPERSIZE=$size -dFIXEDMEDIA -dPDFFitPage -dCompatibilityLevel=1.6 "$spool/__pdf__" |
|
51 |
+ else |
|
52 |
+ cp "$spool/__pdf__" $output |
|
53 |
+ fi |
|
54 |
+ |
|
55 |
+ booksize="a$((${size//[^45]}-1))" |
|
56 |
+ pdfjam --paper ${booksize}paper --nup 2x1 --landscape --outfile $recto "$output" 1 "$output" 4 |
|
57 |
+ pdfjam --paper ${booksize}paper --nup 2x1 --landscape --outfile $verso "$output" 2 "$output" 3 |
|
58 |
+ pdftk A=$(find $recto -name "*pdf") B=$(find $verso -name "*pdf") cat A B output "$spool/__pdf__" |
|
59 |
+ rm -f $recto $verso $output |
|
60 |
+ ;; |
|
61 |
+ normal) |
|
62 |
+ if test "${size,,}" != "__papersize__"; then |
|
63 |
+ output=$(mktemp --dry-run /dev/shm/XXXXXXXX) |
|
64 |
+ gs -o $output -sDEVICE=pdfwrite -sPAPERSIZE=__papersize__ -dFIXEDMEDIA -dPDFFitPage -dCompatibilityLevel=1.6 "$spool/__pdf__" |
|
65 |
+ mv $output "$spool/__pdf__" |
|
66 |
+ fi |
|
67 |
+ ;; |
|
68 |
+esac |
|
69 |
+ |
|
70 |
+sync |
|
71 |
+ |
|
72 |
+lp -o InputSlot=__inputslot__ -o sides=__sides__ -o ColorModel=__colormodel__ -n __qty__ "$spool/__pdf__" |
|
73 |
+ |
|
74 |
+msmtp __from__ << EOM |
|
75 |
+Subject: confirmation impression de __pdf__ |
|
76 |
+ |
|
77 |
+Salut __prenom__, |
|
78 |
+ |
|
79 |
+L'impression de __pdf__ en __qty__ exemplaires, __papersize_hr__ __sides_hr__ __colormodel_hr__ est lancée sur le bac __inputslot_hr__${mode:+, en mode ${mode}}. Merci de venir la récupérer au plus vite. |
|
80 |
+ |
|
81 |
+Attention, ça ne veut pas dire que l'impression va se dérouler sans accroc: |
|
82 |
+- pas assez de papier dans le bac |
|
83 |
+- plus de toner |
|
84 |
+- bac de récupération de toner plein |
|
85 |
+- une impression précédente pas encore récupérée et la limite de 250 feuilles imprimées est dépassée |
|
86 |
+- bourrage papier |
|
87 |
+- ... |
|
88 |
+ |
|
89 |
+État actuel de l'imprimante |
|
90 |
+$(/usr/local/bin/printer) |
|
91 |
+EOM |
|
92 |
+ |
|
93 |
+/home/sebastien/scripts/smsapi "sms pour __phone__:impression __pdf__ (__qty__, __papersize_hr__, __colormodel_hr__, __sides_hr__, bac __inputslot_hr__${mode:+, en mode ${mode}}) lancée" |
|
94 |
+ |
|
95 |
+rm -f "$spool/__pdf__" |