

mvanrijnen
Members-
Content Count
482 -
Joined
-
Last visited
-
Days Won
1
mvanrijnen last won the day on October 26 2023
mvanrijnen had the most liked content!
Community Reputation
126 ExcellentRecent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
Regression - Delphi 12 - Unable to debug dynamically loaded packages
mvanrijnen replied to @AT's topic in Delphi IDE and APIs
??? The summit is held in Purmerend (a place near Amsterdam), but it's called Delphi Summit Amsterdam, don't know where you were thinking of, but if it was ment as a joke, it's not a funny joke? -
Regression - Delphi 12 - Unable to debug dynamically loaded packages
mvanrijnen replied to @AT's topic in Delphi IDE and APIs
Most funny thing is that nobody can confirm this is fixed. Kind of confirmation of what a laugh the Delphi IDE is become .......................... Time to make a list of critical question for the next Summit in Purmerend (Amsterdam for the commercial guys&girls). -
Regression - Delphi 12 - Unable to debug dynamically loaded packages
mvanrijnen replied to @AT's topic in Delphi IDE and APIs
Does someone ( @Marco Cantu) knows if this is solved in 12.3.x? We are sure gonna leave the whole RadServer concept because of the lack of support/maintenance. (probably going the MARS way) Who releases a software development product which can debug? (curious the way this went to production/release, Boss! We can not debug the radserver modules, oh, "nobody cares, just ship it,") -
You (as far as i know), need always to create (request for) a new FDConnection with each request, each request runs as it's own thread. At what "ServerConnectionPool data module" you are referring to ? (can not see somehting like this in the template folder? I have examples of how to use the FDConnection in a normal request/resource if you need that. uses MARS.Core.RequestAndResponse.Interfaces, MARS.Data.FireDAC, ..... TMyResource = class strict private protected // connection can be left away, when referring to MAIN_DB in the .ini [Context, Connection('MyDB', False)] FD: TMARSFireDAC; [Context] FRequest : IMARSRequest; public [Produces(TMediaType.APPLICATION_JSON)] function GetInfo([QueryParam('par1')] const APar1: string; const [QueryParam('par2')] APar2 : integer) : TMyInfo; end; function TMyResource.GetInfo(const APar1: string; const APar2: integer): TMyInfo; var fqry : TFDQuery; begin if not FD.Connection.NewQuery(fqry) then raise Exception.Create('Error bij aanmaken van query'); try fqry.sql.text := 'select * from ...........'; fqry.Open(); while not fqry.Eof do begin fqry.Next; ..... end; finally fqry.Free; end; end;
-
Regression - Delphi 12 - Unable to debug dynamically loaded packages
mvanrijnen replied to @AT's topic in Delphi IDE and APIs
So, here we are more than a year later, any news on this issue? -
open mail online with office 365 graph api
mvanrijnen replied to mazluta's topic in RTL and Delphi Object Pascal
Also the method of inline sending the attachments is limited to a size ( i believe 3MB), my code (i'm in a hurry, so just a dump), you can get the idea how to from this. const CNST_RESOURCE_CREATEUPLOADSESSION = 'users/{sendasemailaddress}/messages/{messageid}/attachments/createUploadSession'; CNST_RESOURCE_CREATEDRAFTMESSAGE = 'users/{sendasemailaddress}/mailFolders/drafts/messages'; CNST_RESOURCE_SENDCREATEDRAFT = 'users/{sendasemailaddress}/messages/{messageid}/send'; function THSMSGraphAPI.FetchUploadURL(const AUploadSize: integer; const AFileName, AMessageID, AContentID, AContentType : string; const AIsInline : Boolean): string; var fuploadRequest : TRESTRequest; fuploadResponse : TMSGraphUploadSessionResponse; attreq : TMSGraphUploadSessionRequest; begin Result := ''; fuploadRequest := TRESTRequest.Create(nil); try fuploadRequest.Client := FRestClient; fuploadRequest.Method := TRESTRequestMethod.rmPOST; fuploadRequest.Resource := CNST_RESOURCE_CREATEUPLOADSESSION.Replace('{sendasemailaddress}', AccountEmailAddress, [rfReplaceAll, rfIgnoreCase]).Replace('{messageid}', AMessageID, [rfReplaceAll, rfIgnoreCase]); attreq.AttachmentItem.attachmentType := 'file'; attreq.AttachmentItem.name := ExtractFileName(AFileName); attreq.AttachmentItem.size := AUploadSize; attreq.AttachmentItem.isInline := (AIsInline) or (not AContentID.IsEmpty); attreq.AttachmentItem.contentID := AContentID; attreq.AttachmentItem.contentType := AContentType; fuploadRequest.AddBody(attreq.AsJSON, TRESTContentType.ctAPPLICATION_JSON); fuploadRequest.Execute(); if not LogInvalidResponse(fuploadRequest.Response, True, 'THSMSGraphAPI.FetchUploadURL') then begin fuploadResponse := TMSGraphUploadSessionResponse.FromJSON(fuploadRequest.Response.Content); Result := fuploadResponse.uploadUrl; end; finally fuploadRequest.Free; end; end; procedure THSMSGraphAPI.AddLargeAttachments(const AEmailMessageAttachments : TMvREMailAttachments; const AMessageID : string); function CreateSourceStream(const AAttachment : TMvREMailAttachment) : TStream; begin Result := nil; if AAttachment.IsFile then Result := TFileStream.Create(AAttachment.FileName, fmOpenRead or fmShareDenyWrite) else Result := TStringStream.Create(AAttachment.PayLoad); end; procedure UploadParts(const AUploadUrl : string; const ASourceStream : TStream; const AContentType : string); var memStream : TMemoryStream; fuploadPartRequest : TRESTRequest; hdr : string; size, done, todo : integer; begin fuploadPartRequest := TRESTRequest.Create(nil); memStream := TMemoryStream.Create; try fuploadPartRequest.URLAlreadyEncoded := True; fuploadPartRequest.Client := FUplClient; fuploadPartRequest.Method := TRESTRequestMethod.rmPUT; FUplClient.BaseURL := AUploadUrl; size := ASourceStream.Size; done := 0; todo := 0; ASourceStream.Position := 0; while (done<size) do begin todo := Min(CNST_MAXATTSIZE, size-done); memStream.Clear; ASourceStream.Position := done; memStream.CopyFrom(ASourceStream, todo); memStream.Position := 0; hdr := 'bytes ' + (done).ToString + '-' + (done+todo-1).ToString + '/' + size.ToString; fuploadPartRequest.ClearBody; fuploadPartRequest.Params.Clear; fuploadPartRequest.AddParameter('Content-Length', todo.ToString, TRESTRequestParameterKind.pkHTTPHEADER); fuploadPartRequest.AddParameter('Content-Range', hdr, TRESTRequestParameterKind.pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode]); if not AContentType.IsEmpty then fuploadPartRequest.AddParameter('Content-Type', AContentType, TRESTRequestParameterKind.pkHTTPHEADER, [TRESTRequestParameterOption.poDoNotEncode]); fuploadPartRequest.AddBody(memStream, TRESTContentType.ctAPPLICATION_OCTET_STREAM); ExecuteRequest(fuploadPartRequest, 'THSMSGraphAPI.AddLargeAttachments.UploadParts', True); LogInvalidResponse(fuploadPartRequest.Response, True, 'UploadParts'); done := done + todo; end; finally memStream.Free; fuploadPartRequest.Free; end; end; var att : TMvREMailAttachment; url : string; stream : TStream; begin for att in AEmailMessageAttachments do //if att.IsLargeAttachment then begin stream := CreateSourceStream(att); try // url := FetchUploadURL(stream.Size, att.FileName, AMessageID); url := FetchUploadURL(stream.Size, att.FileName, AMessageID, att.ContentID, att.ContentType, att.IsInline); UploadParts(url, stream, att.ContentType); finally stream.Free; end; end; end; function THSMSGraphAPI.SendEmailWithLargeAttachments(const AEmailMessage: TMvREMailMessage; AAPIMessage: TMSGraphSendEmailMessageBody): Boolean; function FetchImmutableID(const AID : string) : string; var req : TRESTRequest; request : TMSGraphTranslateExchangeIdsRequest; responseJSON, requestJSON : string; response : TMSGraphTranslateExchangeIdsResponse; begin Result := ''; req := TRESTRequest.Create(nil); try try req.Client := FRestClient; req.Method := TRESTRequestMethod.rmPOST; req.Resource := 'users/{sendasemailaddress}/translateExchangeIds'.Replace('{sendasemailaddress}', AccountEmailAddress, [rfReplaceAll, rfIgnoreCase]); SetLength(request.inputIds, 1); request.inputIds[0] := AID; request.targetIdType := 'restImmutableEntryId'; request.sourceIdType := 'restId'; TgoBsonSerializer.Serialize( request, requestJSON); req.AddBody(requestJSON, TRESTContentType.ctAPPLICATION_JSON); req.Execute(); responseJSON := req.Response.Content; TgoBsonSerializer.Deserialize(responseJSON, response); if length(response.value)>0 then Result := response.value[0].targetId; except on e: exception do begin Result := ''; raise Exception.CreateFmt('[THSMSGraphAPI.SendEmailWithLargeAttachments.FetchImmutableId]: %s\n%s', [e.ClassName, e.Message]); end; end; finally req.Free; end; end; function FetchMessagesForInternetMessageID(const AInternetMessageID : string) : TArray<string>; var req : TRESTRequest; request : TMSGraphTranslateExchangeIdsRequest; responseJSON, requestJSON : string; response : TMSGraphTranslateExchangeIdsResponse; begin SetLength(Result, 0); req := TRESTRequest.Create(nil); try try req.Client := FRestClient; req.Method := TRESTRequestMethod.rmGET; req.Resource := 'users/{sendasemailaddress}/messages?$filter=internetMessageId eq ''{internetmessageid}''' .Replace('{sendasemailaddress}', AccountEmailAddress, [rfReplaceAll, rfIgnoreCase]) .Replace('{internetmessageid}', TidUri.ParamsEncode(AInternetMessageID), [rfReplaceAll, rfIgnoreCase]); req.Execute(); except on e: exception do begin raise Exception.CreateFmt('[THSMSGraphAPI.SendEmailWithLargeAttachments.FetchMessagesForInternetMessageID]: %s\n%s', [e.ClassName, e.Message]); end; end; finally req.Free; end; end; var req1, req2 : TRESTRequest; draft : TMSGraphDraftResponse; draftremoved, step1done : boolean; removemsgid, immid : string; begin Result := False; immid := ''; removemsgid := ''; step1done := False; draftremoved := False; req1 := TRESTRequest.Create(nil); req2 := TRESTRequest.Create(nil); try try req1.Client := FRestClient; req1.Method := TRESTRequestMethod.rmPOST; req2.Client := FRestClient; req2.Method := TRESTRequestMethod.rmPOST; req1.Resource := CNST_RESOURCE_CREATEDRAFTMESSAGE.Replace('{sendasemailaddress}', AccountEmailAddress, [rfReplaceAll, rfIgnoreCase]); req1.AddBody(AAPIMessage.message.AsJson(), TRESTContentType.ctAPPLICATION_JSON); try req1.Execute(); except on e: exception do begin raise Exception.CreateFmt('[THSMSGraphAPI.SendEmailWithLargeAttachments.Req1]: %s\n%s', [e.ClassName, e.Message]); end; end; if not LogInvalidResponse(req1.Response, True, 'THSMSGraphAPI.SendEmailWithLargeAttachments.1') then begin draft := TMSGraphDraftResponse.FromJSON(req1.Response.Content); removemsgid := draft.id; step1done := IsValidResponse(req1.Response); if not (AEmailMessage.SaveOnSend) then begin immid := FetchImmutableID(draft.id); removemsgid := immid; end; {$ifdef debug} if not immid.IsEmpty then LogExInfo('ImmutableID: %s', [immid], 'THSMSGraphAPI.SendEmailWithLargeAttachments'); {$endif} //raise Exception.Create('TEST Error Message'); try AddLargeAttachments(AEmailMessage.Attachments, draft.id); except on e: exception do begin raise Exception.CreateFmt('[THSMSGraphAPI.SendEmailWithLargeAttachments.AddLargeAttachments]: %s\n%s', [e.ClassName, e.Message]); end; end; end; req2.Resource := CNST_RESOURCE_SENDCREATEDRAFT.Replace('{sendasemailaddress}', AccountEmailAddress, [rfReplaceAll, rfIgnoreCase]).Replace('{messageid}', draft.id, [rfReplaceAll, rfIgnoreCase]); try req2.Execute(); except on e: exception do begin raise Exception.CreateFmt('[THSMSGraphAPI.SendEmailWithLargeAttachments.Req2]: %s\n%s', [e.ClassName, e.Message]); end; end; if not LogInvalidResponse(req2.Response, True, 'SendWithLargeAttachments.2') then begin Result := True; if not (AEmailMessage.SaveOnSend) then begin if not immid.IsEmpty then draftremoved := TryRemoveEmailMessage(immid) else LogExWarn('Could not remove draft sendmessage because empty immutableid', 'THSMSGraphAPI.SendEmailWithLargeAttachments'); end; end; except on e: exception do begin Result := False; if (not draftremoved) and (step1done) and (not removemsgid.IsEmpty) then begin Sleep(1000); draftremoved := TryRemoveEmailMessage(removemsgid); if draftremoved then LogExWarn('Draft message with id: %s removed.', [removemsgid], 'THSMSGraphAPI.SendEmailWithLargeAttachments') else LogExError('Draft message with id: %s was not removed!', [removemsgid], 'THSMSGraphAPI.SendEmailWithLargeAttachments') end; raise; end; end; finally req2.Free; req1.Free; end; end; -
strange way of looking to solve a problem, if you don't bother, than do no ask....
-
From Delphi to Interbase, over localnetwork/internet ? Which database component set your are using (e.g. FireDac) ?
-
i've build a service (called ProtoBridge, not public available), which does just this. But more 😉 It can act as a simple bridge between older machines/services to forward emails to o365/gmail (oauth2) etc etc. It can also serve as a ftp server, and you can configure different virtual ftp folders which direct the incoming file(s) to a specific email adress so you can "bridge" protocols it can act as server for: * simple smtp * ftp * local folders * smb folders and forward to: * simple smtp * smtp (oauth2 etc) * O365 (MS Graph API) * Exchange EWS * ftp * local folder * smb folder It's using INDY for all the protocols (except MS Graph API & EWS), off course is this a service which is not intended to use on a public server. (there is a white & blacklist on IP numbers available)
-
A specific version?
-
Signotaur Code Signing Server - Looking for beta testers
mvanrijnen replied to Vincent Parrett's topic in Delphi Third-Party
Yes. my question was more, (a discussion i had on this forum a few years ago also), do we benefit for preventing false positives using signing (makes it easier turning the mgmt in positive direction, so they don't only see it as a cost) ? (we are going to implement signing anyway). -
Signotaur Code Signing Server - Looking for beta testers
mvanrijnen replied to Vincent Parrett's topic in Delphi Third-Party
So we create only software for internal use, using (at the moment) , do we benefit from code signing ? -
this is not sustainable as a process to get updates to the end users. I just spent 2 days of work updating our buildmachine from11.x to 12.2. Can start over now?
-
In that case, the text is not static 😉
-
Simulate blocking mode to send Email
mvanrijnen replied to Berocoder's topic in Network, Cloud and Web
Not a direct answer, but we (in our custom ERP solution), put the emails in a table (kind of a mailqueue) , and another process (service) polls and/or gets signaled when to scan the table for messages to send. With this we have better control, and are sure that the email is send in the background. We also can control a minimum, maximum datetime to send the message etc etc. (sometimes an email message is irrelevant if it didn't get send after a specific date) So not high prio mails are send like every 5 minutes, high prio directly. Only problem is that interactive emails (send with a client like outlook) are not under the same control. The service itself is highly configurable, with different outgoing servers, accounts etc etc.,