Files
comun/utile/citeste_email.ps1

104 lines
4.0 KiB
PowerShell

# Citeste emailurile din mbox-urile Thunderbird Portable (fara conectorul Gmail).
# citeste_email.ps1 [-Cauta <text>] [-Cont <nume>] [-Ultimele <n>] -> lista mesaje
# citeste_email.ps1 -Nr <linie> [-Linii <n>] -> corpul unui mesaj
param(
[string]$Cauta = '',
[string]$Cont = '',
[int]$Ultimele = 20,
[int]$Nr = 0,
[int]$Linii = 200,
[string]$Radacina = 'D:\UTIL\portable\PortableApps\ThunderbirdPortable\Data\profile\ImapMail'
)
$ErrorActionPreference = 'Stop'
function Get-Mboxuri {
param([string]$Cont)
$c = if ($Cont) { $Cont } else { '*' }
Get-ChildItem $Radacina -Directory -Filter $c |
ForEach-Object { Join-Path $_.FullName 'INBOX' } |
Where-Object { Test-Path $_ } |
Where-Object { (Get-Item $_).LastWriteTime -gt (Get-Date).AddYears(-2) }
}
function Deschide-Fisier {
param([string]$Cale)
# Thunderbird tine fisierul deschis -> FileShare ReadWrite obligatoriu
$fs = New-Object IO.FileStream($Cale, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::ReadWrite)
New-Object IO.StreamReader($fs, [Text.Encoding]::GetEncoding(28591))
}
function Decodeaza-Subiect {
param([string]$S)
$rx = [regex]'=\?([^?]+)\?([BbQq])\?([^?]*)\?='
$rx.Replace($S, {
param($m)
$enc = [Text.Encoding]::GetEncoding($m.Groups[1].Value)
$txt = $m.Groups[3].Value
if ($m.Groups[2].Value -match '[Bb]') {
$enc.GetString([Convert]::FromBase64String($txt))
} else {
$b = New-Object Collections.Generic.List[byte]
for ($i = 0; $i -lt $txt.Length; $i++) {
if ($txt[$i] -eq '=') { $b.Add([Convert]::ToByte($txt.Substring($i + 1, 2), 16)); $i += 2 }
elseif ($txt[$i] -eq '_') { $b.Add(32) }
else { $b.Add([byte][char]$txt[$i]) }
}
$enc.GetString($b.ToArray())
}
})
}
# ---- corpul unui mesaj: de la linia data pana la urmatorul separator mbox ----
if ($Nr -gt 0) {
foreach ($f in Get-Mboxuri -Cont $Cont) {
$r = Deschide-Fisier $f
try {
$i = 0; $scris = 0; $pornit = $false
while ($null -ne ($l = $r.ReadLine())) {
$i++
if ($i -lt $Nr) { continue }
# linia ceruta trebuie sa fie inceput de mesaj, altfel e alt cont
if ($i -eq $Nr -and $l -notmatch '^From - \w\w\w \w\w\w ') { break }
if ($pornit -and $l -match '^From - \w\w\w \w\w\w ') { break }
$pornit = $true
$l
if (++$scris -ge $Linii) { "... (taiat la $Linii linii, mareste cu -Linii)"; break }
}
if ($pornit) { return }
} finally { $r.Dispose() }
}
Write-Warning "Linia $Nr nu exista in mbox-urile cautate."
return
}
# ---- lista de mesaje ----
$mesaje = @()
foreach ($f in Get-Mboxuri -Cont $Cont) {
$cont = Split-Path (Split-Path $f -Parent) -Leaf
$r = Deschide-Fisier $f
try {
$i = 0; $inAntet = $false; $m = $null
while ($null -ne ($l = $r.ReadLine())) {
$i++
if ($l -match '^From - \w\w\w \w\w\w ') {
if ($m) { $mesaje += $m }
$m = [pscustomobject]@{ Cont = $cont; Linie = $i; Data = ''; De_la = ''; Subiect = '' }
$inAntet = $true
continue
}
if (-not $inAntet -or -not $m) { continue }
if ($l -eq '') { $inAntet = $false; continue }
if ($l -like 'Date: *' -and -not $m.Data) { $m.Data = $l.Substring(6).Trim() }
elseif ($l -like 'From: *' -and -not $m.De_la) { $m.De_la = $l.Substring(6).Trim() }
elseif ($l -like 'Subject: *' -and -not $m.Subiect) { $m.Subiect = Decodeaza-Subiect $l.Substring(9).Trim() }
}
if ($m) { $mesaje += $m }
} finally { $r.Dispose() }
}
if ($Cauta) {
$mesaje = $mesaje | Where-Object { $_.Subiect -like "*$Cauta*" -or $_.De_la -like "*$Cauta*" }
}
$mesaje | Select-Object -Last $Ultimele | Format-Table -AutoSize -Wrap