# Citeste emailurile din mbox-urile Thunderbird Portable (fara conectorul Gmail). # citeste_email.ps1 [-Cauta ] [-Cont ] [-Ultimele ] -> lista mesaje # citeste_email.ps1 -Nr [-Linii ] -> 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