GPAL.Logger can write log entries to a SQL database instead of a file, accepting plain strings, settings objects, and whole grids. GPAL.Mail sends email through a configured SMTP server with To, CC, and BCC recipients. Together they show how GPAL subsystems share the same fluent factory pattern across very different jobs.
The whole workflow: define a database target for logging, build a logger that writes to it, log a few different kinds of data, then configure and send an email.
using GenerallyPositive;
using static GenerallyPositive.Enums;
GPALDatabase database = (GPALDatabase)GPAL.Database
.WithServerName(@"MYSERVERSQLEXPRESS")
.WithDatabaseName("GPAL")
.WithDatabaseType(DatabaseType.SQLServer)
.WithCreateAs("Insert Into TestInput (SearchTerm) Values (@SearchTerm)")
.WithNVarCharColumn("SearchTerm");
IGPALGrid<string> grid = GPAL.Grid.ToGPALObject();
GPAL.WithPublishToDebug().WithAutoUpdateWebDriver();
IGPALLogger gPALLogger = GPAL.Logger.WithDatabase(database).ToGPALObject();
gPALLogger.Log(GPAL.GPALSettings);
gPALLogger.Log("Log This");
gPALLogger.WithDelimiter(',').Log("AND, THIS");
GPAL.Converter.WithInput(GPAL.GPALSettings).SaveTo(ref grid);
gPALLogger.Log(grid);
IGPALMail gPALMail = GPAL.Mail
.WithSMTPServerName("smtp.example.com")
.WithSMTPPortNum(587)
.WithFromEmailAddress("reports@example.com")
.WithCcEmailAddress("cc@example.com").WithName("CC")
.WithBccEmailAddress("bcc@example.com").WithName("BCC")
.WithToEmailAddress("recipient@example.com").WithName("Recipient")
.WithSubject("Run Complete").ToGPALObject();
gPALMail.Send();
GPAL.Database describes a SQL connection and, optionally, an insert statement for new rows. WithCreateAs gives the parameterized SQL, and WithNVarCharColumn declares the column type for each parameter. This same GPALDatabase object can be reused anywhere GPAL needs database access - here, as a logging destination.
GPALDatabase database = (GPALDatabase)GPAL.Database
.WithServerName(@"MYSERVERSQLEXPRESS")
.WithDatabaseName("GPAL")
.WithDatabaseType(DatabaseType.SQLServer)
.WithCreateAs("Insert Into TestInput (SearchTerm) Values (@SearchTerm)")
.WithNVarCharColumn("SearchTerm");
WithDatabase points the logger at the database object instead of a file, and ToGPALObject() finalizes it into an IGPALLogger. From there, Log accepts plain strings, the live GPAL.GPALSettings object, or an IGPALGrid - GPAL serializes whatever you hand it into the configured log destination. WithDelimiter changes how multi-part log entries are joined.
IGPALLogger gPALLogger = GPAL.Logger.WithDatabase(database).ToGPALObject();
gPALLogger.Log(GPAL.GPALSettings);
gPALLogger.Log("Log This");
gPALLogger.WithDelimiter(',').Log("AND, THIS");
Logging GPAL.GPALSettings captures the full configuration GPAL was running with at that moment - handy for reproducing an issue later, since you know exactly what driver locations, automation engines, and flags were in effect.
GPAL.Converter.WithInput().SaveTo() turns a settings object (or any supported source) into an IGPALGrid by reference. Once it is a grid, the same logger that accepted a string or a settings object can log it as tabular data.
IGPALGrid<string> grid = GPAL.Grid.ToGPALObject();
GPAL.Converter.WithInput(GPAL.GPALSettings).SaveTo(ref grid);
gPALLogger.Log(grid);
GPAL.Mail is configured the same way as every other subsystem: With* methods set the SMTP server, port, sender, and recipients, then ToGPALObject() returns an IGPALMail ready to send. WithName attaches a display name to whichever address was most recently set with WithCcEmailAddress, WithBccEmailAddress, or WithToEmailAddress.
IGPALMail gPALMail = GPAL.Mail
.WithSMTPServerName("smtp.example.com")
.WithSMTPPortNum(587)
.WithFromEmailAddress("reports@example.com")
.WithCcEmailAddress("cc@example.com").WithName("CC")
.WithBccEmailAddress("bcc@example.com").WithName("BCC")
.WithToEmailAddress("recipient@example.com").WithName("Recipient")
.WithSubject("Run Complete").ToGPALObject();
gPALMail.Send();
Each WithName call attaches a display name to whichever WithToEmailAddress, WithCcEmailAddress, or WithBccEmailAddress call came immediately before it. Order matters - if you set multiple recipients, call WithName right after each one.
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();