Showing 4 changed files with 273 additions and 0 deletions
+156
imapfilter/.imapfilter/config.lua
... ...
@@ -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
+10
imapfilter/authorized.lua.example
... ...
@@ -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
+}
+12
imapfilter/contact@paris12.pcf.fr.lua
... ...
@@ -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
+}
+95
imapfilter/printscript.model
... ...
@@ -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__"