Delphi-PRAXiS
Seite 1 von 2  1 2   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   email-downloader as as service (https://www.delphipraxis.net/192647-email-downloader-service.html)

erich.wanker 8. Mai 2017 13:05

email-downloader as as service
 
Hallo,

Da ich Performance-Probleme bei einer Webapplication habe, die eMails downloadet und in eine Firebird SQL Datenbank schreibt - suche ich nun eine Möglichkeit das ganze als eigenen Dienst zu realisieren...


Gibt es da zufällig schon irgendeinen Demo-Sourcecode - wo der Download via Pop (Intervall alle x Minuten -inkl. abspeichern der Mail als HTML UND Eintrag in Datenbank - abspeichern der Attachement) realisiert wurde?

Vielen Dank für Hinweise

Erich

Bernhard Geyer 8. Mai 2017 15:24

AW: email-downloader as as service
 
Erzähl doch mal mehr wo genau bei dir die Performanceprobleme auftreten.
Ich glaube es ist sinnvoller diese zu beheben als diese durch das "verstecken" in einem Diest nur scheinbar zu lösen.

erich.wanker 9. Mai 2017 10:25

AW: email-downloader as as service
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

vielen Dank für deine Nachfrage: Hab jetzt - das was ich in der Webapp hatte - in einen Service gepackt ..

ABER: Ob das, was ich da so zusammengeschustert hab auch wirklich stabil läuft ist ne andere Frage ????


Code:
program mailservice;

uses
  Vcl.SvcMgr,
  Unit1 in 'Unit1.pas' {MountainWebMailer: TService};

{$R *.RES}

begin
  if not Application.DelayInitialize or Application.Installing then
    Application.Initialize;
  Application.CreateForm(TMountainWebMailer, MountainWebMailer);
  Application.Run;
end.

Code:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs,
  ZAbstractConnection, ZConnection, Data.DB, ZAbstractRODataset,ComCtrls,
  ZAbstractDataset, ZDataset, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack,
  IdSSL, IdSSLOpenSSL, IdMessage, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdExplicitTLSClientServerBase,IdAttachment, IdMessageClient, IdPOP3,IniFiles,
  Vcl.ExtCtrls,IdText,Registry;


type
  TMountainWebMailer = class(TService)
    pop: TIdPOP3;
    msg: TIdMessage;
    IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL;
    MAILDATENBANK: TZQuery;
    DMAILDATENBANK: TDataSource;
    MAILKONTEN: TZQuery;
    DMAILKONTEN: TDataSource;
    Z_NUMMER: TZQuery;
    ZConnection1: TZConnection;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
      ini: TIniFile;
      filename:String;
  public
    function GetServiceController: TServiceController; override;
    { Public-Deklarationen }
  end;

var
  MountainWebMailer: TMountainWebMailer;

implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  MountainWebMailer.Controller(CtrlCode);
end;

function TMountainWebMailer.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;




procedure TMountainWebMailer.Timer1Timer(Sender: TObject);
var MailCount,Mailgroesse,intIndex :Integer;
    itm:TListItem;
    i:integer;
    s,extensio:string;
    neue_nummer:String;

    ininame:String;
    lokaler_pfad,
    hostname,
    datenpfad,
    installationspfad,
    domain_name :String;
begin

 with TEventLogger.Create('Mailservice') do
  begin
    try
      LogMessage('ServiceStart...', EVENTLOG_INFORMATION_TYPE);
    finally
      Free;
    end;
  end;



  ininame := extractfilepath(ParamStr(0)) + 'server.ini';
  filename := extractfilepath(ParamStr(0));



  ini := TIniFile.Create(ininame);
  try
    lokaler_pfad     := ini.ReadString('DATABASE','Pfad',extractfilepath(ParamStr(0))+'files\database\DATABASE.FDB');
    hostname         := ini.ReadString('DATABASE','Host','localhost');
    datenpfad        := ini.ReadString('FILES',  'Pfad',extractfilepath(ParamStr(0)));
    installationspfad := ini.ReadString('PFAD',   'Pfad','');
    domain_name      := ini.ReadString('DATABASE','Domain','');
  finally
    ini.Free;
  end;





 with TEventLogger.Create('Mailservice') do
  begin
    try
      ZConnection1.Disconnect;
      ZConnection1.HostName:=hostname;
      ZConnection1.Port:=3050;
      ZConnection1.Database:=lokaler_pfad;
      ZConnection1.User:='SYSDBA';
      ZConnection1.Password:='masterkey';
      ZConnection1.Connect;


      LogMessage('Connection.Connect ...', EVENTLOG_INFORMATION_TYPE);
      LogMessage('Connection.Database ...' + lokaler_pfad, EVENTLOG_INFORMATION_TYPE);
    finally
      Free;
    end;
  end;







 with TEventLogger.Create('Mailservice') do
  begin
    try
      LogMessage('Loop starts ...', EVENTLOG_INFORMATION_TYPE);
    finally
      Free;
    end;
  end;




 with TEventLogger.Create('Mailservice') do
  begin
    try

      MAILKONTEN.SQL.Clear;
      MAILKONTEN.SQL.Append('SELECT * FROM MAILKONTEN');
      MAILKONTEN.Open;

      LogMessage('MAILKONTEN Open...', EVENTLOG_INFORMATION_TYPE);
    finally
      Free;
    end;
  end;





while not MAILKONTEN.Eof do
begin

      POP.Disconnect;
      POP.Host := MAILKONTEN.FieldByName('POP3').AsString;
      POP.Port := strtoint(MAILKONTEN.FieldByName('PORT_POP3').AsString);
      POP.Username := MAILKONTEN.FieldByName('BENUTZERNAME').AsString;
      POP.Password := MAILKONTEN.FieldByName('KENNWORT').AsString;
      POP.Connect;




      MailCount := POP.CheckMessages;

      LogMessage('MAILKONTO "'+POP.Username+'" hat '+inttostr(MailCount)+' Mails', EVENTLOG_INFORMATION_TYPE);
      if MailCount > 0 then
      begin

          for intIndex := 1 to MailCount do
          begin
            msg.Clear;
            pop.Retrieve(intIndex, Msg);


            MAILDATENBANK.SQL.Clear;
            MAILDATENBANK.SQL.Append('SELECT MESSAGID FROM MAILDATENBANK WHERE MESSAGID = '+#39+msg.MsgId+#39+'');
            MAILDATENBANK.Open;



            // Die Mail habe ich noch nicht !!!!!!!!!
            if MAILDATENBANK.RecordCount = 0 then
            begin

            Z_NUMMER.SQL.Clear;
            Z_NUMMER.SQL.add('SELECT GEN_ID( POOL, 1 ) AS IDR FROM RDB$DATABASE');
            Z_NUMMER.open;
            neue_nummer:=inttostr(Z_NUMMER.FieldByName('IDR').AsInteger);


            MAILDATENBANK.SQL.Clear;
            MAILDATENBANK.SQL.Append('SELECT * FROM MAILDATENBANK WHERE INR = -1');
            MAILDATENBANK.Open;

            MAILKONTEN.SQL.Clear;
            MAILKONTEN.SQL.Append('SELECT * FROM MAILKONTEN WHERE INR = -1');
            MAILKONTEN.Open;


            MAILDATENBANK.Append;
            //MAILDATENBANK.FieldByName('USER').AsInteger:=strtoint(main.MainForm.benutzernummer);
            MAILDATENBANK.FieldByName('INR').AsString:=neue_nummer;

            MAILDATENBANK.FieldByName('VON').AsString:=Msg.From.Text;
            MAILDATENBANK.FieldByName('ANTWORTADRESSE').AsString:=msg.from.Address;
            MAILDATENBANK.FieldByName('BETREFF').AsString:=Msg.Subject;
            MAILDATENBANK.FieldByName('DATUM').AsDateTime:=Msg.Date;
            MAILDATENBANK.FieldByName('MIMETYPE').AsString:=msg.AttachmentEncoding;
            MAILDATENBANK.FieldByName('CONTENTTYPE').AsString:=msg.ContentType;
            MAILDATENBANK.FieldByName('MESSAGID').AsString:=msg.MsgId;
            MAILDATENBANK.FieldByName('KONTONAME').AsString:=MAILKONTEN.FieldByName('KONTONAME').AsString;
            MAILDATENBANK.FieldByName('KONTONUMMER').AsString:=MAILKONTEN.FieldByName('INR').AsString;

            if Msg.MessageParts.Count = 0 then MAILDATENBANK.FieldByName('ANHANG').AsString:='';
            if Msg.MessageParts.Count > 0 then MAILDATENBANK.FieldByName('ANHANG').AsString:='Anhang';
            MAILDATENBANK.FieldByName('GELESEN').AsInteger:=0;
            MAILDATENBANK.FieldByName('PR').AsInteger:=0;
            MAILDATENBANK.FieldByName('ZUORDNUNG').AsString:='';

            MAILDATENBANK.Post;



                //Anhang
                for i := 0 to Msg.MessageParts.Count-1 do begin
                  if Msg.MessageParts.Items[i] is tIdAttachment then
                      begin
                        s := (Msg.MessageParts.Items[i] as tIdAttachment).Filename;

                        // Extension ändern
                       extensio:= ExtractFileExt(s) ;

                       (Msg.MessageParts.Items[i] as tIdAttachment).savetofile(filename +'files\Mails\Anhang_' + neue_nummer +extensio);
                      end;
                end;




                // HTML Mail
                if msg.MessageParts.Count > 0 then
                begin

                for i := 0 to Msg.MessageParts.Count-1 do begin
                    if Msg.MessageParts.Items[i] is TIdText then
                     begin
                      //Logger.AddLogStrings(TIdText(Msg.MessageParts.Items[i]).Body);
                      TIdText(Msg.MessageParts.Items[i]).Body.SaveToFile(filename +'files\Mails\html_' + neue_nummer + '.html');
                     end;
                end;
                end;


                // Text Mail
                if msg.ContentType = 'text/html' then
                begin

                  //Logger.AddLogStrings(msg.body);
                  Msg.Body.SaveToFile(filename +'files\Mails\html_' + neue_nummer + '.html');
                end;


                // Text Mail
                if msg.ContentType = 'text/plain' then
                begin

                  //Logger.AddLogStrings(msg.body);
                  Msg.Body.SaveToFile(filename +'files\Mails\text_' + neue_nummer + '.txt');
                end;


            end; // Die Mail habe ich noch nicht


            ///////
            //Kopie am Server belassen: also NICHT löschen
            //pop.Delete(intIndex);  // Löscht die aktuelle Mail !!!!
            end;

            end;

      // POP.Disconnect;



MAILKONTEN.Next;
end;






 with TEventLogger.Create('Mailservice') do
  begin
    try
      LogMessage('ServiceStop...', EVENTLOG_INFORMATION_TYPE);
    finally
      Free;
    end;
  end;
    ZConnection1.Disconnect;


end; // procedure

end.

Hobbycoder 9. Mai 2017 10:36

AW: email-downloader as as service
 
Man kann auch PAS-Dateien anhängen.
Macht Thread's bei langem Code lesbarer und lohnt sich, wenn eh ganze Units gepostet werden.

Union 9. Mai 2017 15:14

AW: email-downloader as as service
 
Bzgl. der Performance: Du loggst doch. WO genau treten denn die Performanceprobleme auf? Du solltest Dich zunächst mal auf die Queries konzentieren:
* Parametrisieren statt zusammensetzen
* Konstante Queries nicht jedes mal neu erzeugen sondern stehen lassen und dann jeweils öffnen / schliessen
* Active anstelle von Open / Close verwenden, das ist (minimal) weniger Stack und Laufzeit

himitsu 9. Mai 2017 15:34

AW: email-downloader as as service
 
Zitat:

Zitat von Union (Beitrag 1370756)
* Active anstelle von Open / Close verwenden, das ist (minimal) weniger Stack und Laufzeit

Kommt drauf an, im PgDAC und vermutlich auch anderen DB-Komponenten macht Open/Close/Active das Selbe, bzw. es ruft sich geggenseitig auf.

TEventLogger.Create Free Create Free Create Free Create Free ...

Und wenn es in der Schleife knallt, dann wird kein Disconnect gemacht.

erich.wanker 12. Mai 2017 09:29

AW: email-downloader as as service
 
Hallo und vielen Dank für eure Hinweise...

Hab jetzt Try Except verbessert .. und Logger deaktiviert :-)


Jetzt hätte ich eine weitere Frage:

In manchen Mails sind bilder als CID integriert ...

Wie schaffe ich es, die Mails als HTML abzuspeichern - die Links der CID href="cid:xxxx ... ) im Quelltext zu verändern .. und die CID´s als Datei irgendwo lokal hinterlegen?

Vielen Dank

Erich

Union 12. Mai 2017 13:45

AW: email-downloader as as service
 
Damit die Maildaten wirklich protabel sind, bette die Bilder base64-encoded in die Mail ein (referenziert via data:image/jpeg;base64). Externe images dafür einzulesen können aber Deinen Service zum Absturz bringen oder zu Timeouts führen und stellen ein Sicherheitsrisiko dar.

erich.wanker 12. Mai 2017 14:46

AW: email-downloader as as service
 
Hallo Union :-)

danke für deinen Tipp - leider werden die Mails ja nicht von mir erstellt sondern werden von allen möglichen Absendern erzeugt ...

Ich will sie darstellen - was schon gut klappt.
Das Abspeichern der Anhänge funktioniert auch.

Nur die Bilder, die als cid eingebettet sind bereiten mir Kopfzerbrechen ;-)


Vielen Dank
erich

nahpets 12. Mai 2017 15:29

AW: email-downloader as as service
 
Zitat:

Zitat von erich.wanker (Beitrag 1371126)
Nur die Bilder, die als cid eingebettet sind bereiten mir Kopfzerbrechen ;-)

Und Union meint, dass Du genau diese (referenziert via data:image/jpeg;base64) in die Mails Bilder base64-encoded einbetten solltest.

D. H.: Du musst die entsprechenden Mails (automatisiert) bearbeiten und dann die bearbeitete Version speichern.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:59 Uhr.
Seite 1 von 2  1 2   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz