104 lines
4.0 KiB
PowerShell
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
|