The whole workflow: define a database target for logging, build a logger that writes to it, publish a few events for it to record, write the settings out through the converter, then configure and send an email.
using GenerallyPositive;
using static GenerallyPositive
GPALDatabase database = (GPALDatabase)GPAL
IGPALGrid<string> grid = GPAL
GPAL
// the logger writes what GPAL publishes, so it is built and then handed to GPAL
IGPALLogger gPALLogger = GPAL
GPAL
// every published event is an entry from here on
GPAL
GPAL
// a grid or a class is a file, which is what the converter is for
GPAL
GPAL
IGPALMail gPALMail = GPAL
gPALMail
GPAL.Database describes a SQL connection and, optionally, an insert statement for new rows. WithCreateAs gives the parameterized SQL, and WithNVarCharParameter declares the type of each parameter the SQL names. This same GPALDatabase object can be reused anywhere GPAL needs database access - here, as a logging destination.
GPALDatabase database = (GPALDatabase)GPAL
WithDatabase points the logger at the database object instead of a file, and ToGPALObject() finalizes it into an IGPALLogger. GPAL.WithPublishToLogger hands it to GPAL, and from then on every published event is written to the configured log destination; nothing calls the logger directly. WithLogEventTypes picks which event types it writes, and WithDelimiter sets the character written between the fields on a line.
// the logger is told where entries go, then handed to GPAL so published events reach it
IGPALLogger gPALLogger = GPAL
GPAL
// nothing calls the logger directly
// which is what makes GPAL's own events and the workflow's own land in the same place
GPAL
GPAL
// which types the logger writes, when all of them is more than you want
GPAL
Converting GPAL.GPALSettings to a grid and saving it, as the next section does, 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. A logger does not take a grid, so the converter writes the grid out to a file, and the NOTICE that follows records in the log that it happened.
IGPALGrid<string> grid = GPAL
// a grid is not a log entry
// that it happened
GPAL
GPAL
GPAL
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
gPALMail
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();