Posted 10 March 2018
Background:
Some time ago I created Bridge Game Reporter (BGR), a wrapper for Ray Spalding’s wonderful Bridge Composer (BC) program, for the Columbus Bridge Center, our local bridge club. Bridge Composer produces really nifty HTML and PDF reports of duplicate bridge games, but using it can become tedious, and non-technically-oriented bridge directors are prone to making mistakes when FTP’ing result files to a website. So, my BGR program automates all that stuff and makes calls into the BC API to make the magic happen. After the inevitable problems and issues, it seemed to be working fine at the CBC, and then Siraj Haji, owner/operator of the Aloha Bridge Club asked me if I would mind sharing the program with him. Siraj had a slightly different setup, and rather than FTP’ing result files to a website, he wanted to email them to just those players who actually played in a particular game, so he and I worked out the strategy for using ACBL player numbers from session reports as a search key into a CSV-formatted email list. After the usual number of mistakes, we got it working. A few days later Siraj mentioned that he also uses Bridge Composer to generate game files for upcoming games, but it was somewhat tedious – could I maybe use my new-found BC superpowers to do something about that? Well, it turns out that the BC guy (Ray Spalding) created a pretty nice API to BC, and provided a WScript/JScript example that did most of what we wanted. After a few days of fumbling around, I figured out most of what was going on behind the curtains, and realized that I could fairly easily add a ‘game generation tool’ to my BGR app to add bulk game generation capabilities. Again after the normal number of mistakes, Siraj reported that this feature seemed to be working – yay!
At some point in this process, after the email feature was added and before the bulk game generation feature, I got another request for the program from another club in the area, so I realized I was going to have to provide an actual installation program and some user documentation. Since I already had this blog site, I decided to use it as the documentation vehicle.
Bridge Game Reporter Features:
- Uses Ray Spalding’s Bridge Composer program, which must be installed and active for the magic to work.
- Automates the process of calling Bridge Composer with the correct set of files for a particular game.
- Optionally automates the process of FTPing Bridge Composer game summary and hand records to a selected website
- Optionally automates the process of emailing results to a user-supplied list of email recipients
- Automates the process of generating multiple games over a range of dates/times using the ‘Game Generation’ tool.
Main Page:
The main page of the Bridge Game Reporter program is shown below, along with a description of each control area.
Game Date: The user selects the desired game date from a drop-down calendar display. This date is used to construct the filename to be searched for. The file name format is in the form [yymmdd][session time].ext, where yy = year, mm = month, dd = day, session time = ‘M’ (Morning), ‘A’ (Afternoon), ‘E’ (Evening), or ‘L’ (Late). All input files associated with a particular game will have this format. For instance, for an afternoon game on March 6, 2018, the filename will be 180306A.ext, where ‘ext’ = BRI (or DUP or PBN) for the deal file, BWS for the Bridgemate results file, TXT for the text summary file, HTML for the report output from Bridge Composer, and LOG for the log file optionally created by BGR.
Game Time: The user selects one of ‘Morning’, ‘Afternoon’, ‘Evening’, or ‘Late’. This selection is used to form the ‘MAEL’ suffix to the filename.
Lock Entry Fields: For a particular club setup, most of the fields dealing with file locations can be set once and then never changed again. To prevent inadvertent changes to these fields, this option, when checked, will make them all read-only.
Game Input Folders: The location for the .BRI, .DUP, or .PBN game files, the .TXT summary file, and the .BWS Bridgemate score files. The .BWS file can be skipped, if necessary.
Game Report Folders: The location for the .HTML and the optional .LOG files. This section also contains the ‘FTP to Website’ checkbox and the the URL for the destination website, if this feature is enabled, and the ‘Email to List’ checkbox and corresponding location for the email list document.
Start, Close buttons and logging area: The ‘Start’ button will remain grayed-out until all required input conditions are met, at which time it will become click-able. Clicking ‘Start’ will cause the program to assemble all the required information and send it to Bridge Composer for processing; then it will optionally transmit the results to either a selected website or to addresses on an email list. The ‘Close’ button will close the program. The logging area displays progress and/or error information. If the ‘Save log to folder’ option is checked, then the log file will be saved to [yymmdd][session].LOG in the selected folder.
Set FTP/Email Creds: FTP and/or email server login information (username & password) is saved in the ‘BGR.TXT’ file, which must be in the C:\BGR\ folder (this folder and a default file are automatically created at installation). The format of the BGR.TXT file is
accesspass
ftpusername
ftppassword
smtp.gmail.com
your_email_username
your_email_password
Clicking the Set FTP/Email Creds button will bring up the following dialog box for editing the contents of BGR.TXT. This dialog is password protected, more to prevent inadvertent changes by untrained personnel than for any serious security.
Reset Folders to Defaults: Clicking this button will overwrite the current folder settings with the last-saved set of default settings. This button (and the corresponding ‘Save Current Settings as Defaults’) are almost never used, as the program automatically saves the last set of user settings whenever the program is closed, and automatically restores them the next time the program is launched.
Emailing Results:
The email feature requires four components:
- The session summary ([date][session].TXT) file produced by ACBLSCOR containing player names and ACBL player numbers *see 10 July 2021 Update for more info on this
- A user-provided file containing email addresses in CSV format (an example is provided)
- A user-customized ‘EmailTemplate.txt’ email template file (an example is provided) containing the body of the email to be sent
- Any HTML/PDF attachments to be sent. All desired attachments must have the same filename as all the game files for the particular session, with a .HTML or .PDF extension, and must be in the same folder.
The email list must be in CSV format, and must be formatted as follows:
Name,ACBL #,Email Address,Opt out
Jody Lastname,R892974,name@ee.net,
Marge,L916928,name@hotmail.com,
Barb,K778289,name@gmail.com,
Daniel Lastname,N184169,name@yahoo.com,yes
Luaine,5169593,name@gmail.com,
A ‘yes’ (case-insensitive) in the ‘Opt out’ field will cause that address to be skipped.
The ‘EmailTemplate.TXT’ file format is:
FROM:
info@alohabridgeclub.com
SUBJECT:
Aloha Bridge Club results for [GAMEDATE] – [SESSION]
BODY:
Aloha,
Thank you for playing. This automated email is intended solely for players in this specific session. Thank you for your support and cooperation.
info@alohabridgeclub.com
614.890.1459
In the above example, the FROM:, SUBJECT:, and BODY: sections are required fields, and must be placed as shown. [GAMEDATE] and [SESSION] are optional fields that will be replaced by the actual game date and the actual session time (‘Morning’, ‘Afternoon’, etc). The resulting email using the above template looks like the following, where ‘[GAMEDATE] – [SESSION]’ was replaced by ‘February 26, 2018 – Evening’
Game Generation Tool:
The game generation tool is intended to automate the process of batch-producing dealer (.PBN or .BRI) files for games over a range of dates and session times. if, for instance, you wished to produce the deal files for all Monday, Wednesday, and Friday afternoon and evening games for the entire month of April you could simply set up the dates and times, and press one button to generate all the game files.
The game generator tool is accessed from the main Bridge Game Reporter page by selecting the ‘Game Generator’ item under the ‘Tools’ menu. The tool dialog is shown below, along with an explanation of each control section.
Start/End Date: The starting and ending dates for game generation (inclusive)
Game Times: Select one or more game time checkboxes to have that session time’s game generated for every applicable date. Checking ‘All’ will enable all times, and unchecking ‘All’ will disable all times.
Game Days: Select one or more game day checkboxes to have games generated for all enabled session times for all those days of the week within the selected date range, inclusive. Checking ‘All’ will enable all days, and unchecking ‘All’ will disable all days.
Selection Summary: This is a read-only running summary of the number of days, times, and total games to be generated. It’s a good idea to check that the ‘Tot Games’ number is what you expect, before starting the generation run.
Destination Folder: The folder to be used as the destination for generated game files. This folder must exist, and must contain the template file ‘handrecord.pbn’ (see below)
Output Format: Bridge Composer can create game files in either .PBN or .BRI format – simply select which one is desired.
Number of boards to generate: Type in the desired number of boards to generate per game. This will typically be 24, 27, or 36, but can be anything. I suggest setting this to 2 or 3 when first getting used to the program.
Generate Games: Starts the generation process. Note that this button won’t be enabled (click-able) until all the prerequisites are met (start/end date, days of week, session times, destination folder, etc). If the button won’t enable, check the log for helpful messages.
handrecord.pbn template file: This is a required file, and it must be present in the folder selected in the ‘Destination Folder’ entry field. This template file is used by Bridge Composer to customize hand record output for your club or organization, as shown below:
The above figure shows a 2-board game generated by Bridge Composer using the default ‘handrecord.pbn’ file. The text in the title area above can be customized for your own club using Bridge Composer’s ‘Format Title Area’ menu as shown below
Once the required customizations have been accomplished, simply save the result back to ‘handrecord.pbn’, and they will show up the next time a game is generated. Note that Bridge Composer supports many other customizations to the ‘handrecord.pbn’ template, but that’s an exercise that is left up to the user ;-).
Installation:
Download and launch BridgeGameReporter.msi to install Bridge Game Reporter on your (Windows only – not MAC) PC. The installation program will do the following:
- Install the BGR application in C:\ProgramFiles(x86)\Bridge Game Reporter
- Create the folder C:\BGR\ and place a default BGR.TXT file there for ftp/email credentials
- Create another BridgeGameReporter folder in your ‘My Documents’ folder to hold the ‘handrecord.pbn’ file required for game generation, and the ‘EmailAddressList_Sample.csv’ and ‘EmailTemplate_Sample.txt’ sample files.
- Place a red heart-shaped ‘BGR’ icon on your desktop
Once the installation completes, launch the program using the desktop icon, and fill in fields as required/desired. Note that if you want to use the game generation tool, you should set the Destination Folder field to the ‘BridgeGameReporter’ folder in your ‘My Documents’ folder.
09 July 2021 Update:
When the Aloha Bridge Club restarted face-to-face bridge recently, Siraj Haji ran across a problem when he tried to use BGR to email results to game participants. He got the following error message from the part of the program that uses the Gmail SMTP server:
1 |
Failed with message: The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.0 Authentication Required. Learn more at |
At first I thought this might be a standard “your username and/or password is incorrect” kind of message, and then later I thought it might be due to Google moving to an SSL based SMTP server during the pandemic. As it turns out, both of these suppositions were wrong. The actual problem was due to Google de-activating the required ‘Less less secure app access‘ setting during the year+ of inactivity on the account. There is actually a note associated with the setting that says “Google will automatically turn this setting OFF if it is not being used”. After turning it back ON again, I was able to successfully send an email using the SMTP server from my debug version of the BGR app (and Siraj confirmed that doing the same thing on his account allowed him to email out the results from his latest game). See the screenshot below:
While I was looking through the BGR code trying to find the problem that was eventually traced down to the above setting, I noticed something that might, or might not, be a bug. The following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
//check for summary (.TXT) file existence try { string TxtFilename = GetFullFilename(tbSummaryFolder.Text, ".TXT"); FileInfo fi = new FileInfo(TxtFilename); if (fi.Exists) { AppendToLog("Found Summary File " + TxtFilename, Color.Black); bSummaryFileExists = true; } else { AppendToLog("Couldn't find Summary file " + TxtFilename, Color.Red); //03/23/16 try to find the correct file - may have been a typo or have extra characters bSummaryFileExists = SearchForMissingFile(TxtFilename, tbSummaryFolder.Text, "TXT"); //search for a suitable file if (bSummaryFileExists) { AppendToLog("Found Summary File " + TxtFilename, Color.Black); } } } catch (Exception ex) { AppendToLog("Error opening Summary (TXT) File: " + ex.Message, Color.Red); } |
calls SearchForMissingFile(TxtFilename, tbSummaryFolder.Text, "TXT") to see if there is a file with the right date and ‘gametime’ configuration, but maybe extra letters. The SearchForMissingFile(TxtFilename, tbSummaryFolder.Text, "TXT") function is shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
private bool SearchForMissingFile(string fullfilename, string folderstr, string extstr) { try { //look for files ending in desired filename. string srchstr = GetGameDateTimeStr(); string filestr = srchstr + "." + extstr; string[] dirs = Directory.GetFiles(folderstr, "*" + srchstr + "*" + extstr); Console.WriteLine("The number of matching files is {0}.", dirs.Length); foreach (string dir in dirs) { string dirstr = Path.GetFileName(dir); dirstr = dirstr.ToUpper(); Console.WriteLine(dir); //ask user if the file in question is 'close enough' if (dirstr.Substring(dirstr.Length - 3, 3) == extstr) { DialogResult res = MessageBox.Show("Couldn't find " + filestr + ", but did find " + dirstr + System.Environment.NewLine + "Use this one instead (it will be renamed to " + filestr + ")?", "Missing File Search", MessageBoxButtons.YesNoCancel); if (res == DialogResult.Yes) { try { //string destPath = TxtFilename; FileInfo info = new FileInfo(dir); info.MoveTo(fullfilename); AppendToLog("File Rename from " + dirstr + " to" + filestr + " Successful", Color.Green); return true; //ok, all done! } catch (Exception e) { Console.WriteLine("File Rename failed: {0}", e.ToString()); AppendToLog("File Rename from " + dirstr + " to" + filestr + " Failed!", Color.Red); return false; //oops } } } } } catch (Exception e) { Console.WriteLine("The process failed: {0}", e.ToString()); } return false; //if we get to here, search failed } |
And there is this code:
1 2 3 |
//extract player numbers from game summary (.TXT) file AppendToLog("Extracting player numbers from game summary (.TXT) file ...\n"); string PlayerNumFilename = GetFullFilename(tbSummaryFolder.Text, "P.TXT"); |
with a strange extra letter (“P”) added to the extension parameter. Here’s the GetFullFilename() function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
private string GetFullFilename(string foldername, string ext) { string namestr = ""; string filestr = ""; string datestr = ""; datestr = GetGameDateTimeStr(); if (datestr.Length > 0) { filestr = datestr + ext; //concatenate folder & filename to form final filename namestr = foldername + "\\" + filestr; } else { AppendToLog("Eror in GetFullFilename()", Color.Red); } return namestr; } |
So, if the program can’t find the normal ‘YYMMDD[M/A/E/L].TXT’ file, it looks for ‘YYMMDD[M/A/E/L]P.TXT’ and offers to use it instead. However, it also renames the file (by removing the extra ‘P’), and I don’t know why I decided to do that, rather than, say, copying the file so that both versions would exist. I asked Siraj about this, but it may be that the reason is lost in antiquity.
10 July 2021 Update:
I got the following email back from Siraj when I asked him about the ‘P’ file:
We use the ACBL numbers to find email addresses in a text file. ACBLScore does not include the ACBL number In their Press + Recap report. We run a Short Press report to get the ACBL numbers. That report that’s the ‘P’ in the file name. Recap sheet does not.
So, the mystery is now solved. Siraj generates the ‘P’ file from the regular ACBLScore ‘recap’ file in order to add in ACBL player numbers, to facilitate extraction of email addresses from the overall email address database. Note that the regular ‘recap’ file is still required, as it contains the Board #/Matchpoints grid for each pair number, and is the file that is sent to BridgeComposer to be incorporated into the HTML document along with the double-dummy analysis for the game boards.
This then brings up more questions – what happens to the original (non ‘P’) ACBLScore recap output file? Why not just replace the ACBLScore (non ‘P’) file with the ‘P’ version but with the original ACBLScore [GAMEDATE][GAMETIME].TXT filename and avoid the whole problem of not finding the original file, searching for and finding the ‘P’ version, and then offering to then rename it to the original ACBLScore filename?
After another conversation with Siraj, I now understand the following:
- The regular ACBLScor summary file ([GAMEDATE][GAMETIME].TXT) file is required for generating the proper HTML file layout from Bridge Composer. The ‘short press’ ([GAMEDATE][GAMETIME]P.TXT) format does not contain all the information needed
- The ‘short press’ ([GAMEDATE][GAMETIME]P.TXT) format is also required (for the ’email’ option) because that is the only output that connects ACBL player numbers with player names for the game, and the player numbers are required to extract email addresses from the email list. Using just player names doesn’t work, because they are not necessarily unique, but player numbers are.
The last piece of the puzzle is the mystery of the dialog box that popped up during my initial testing, as shown below:
This dialog led me on a merry chase, as initially I thought (wrongly, as it turned out) that this offer was somehow a good thing and that the extra ‘P’ was just a typo or something. What I didn’t realize at the time was that not having a ‘regular’ summary file was an abortable condition, and that the ‘P’ file wasn’t just due to a typo – the ‘P’ file is also required when the ‘Email to List’ option is selected. In this case, both files are required, and so I should have selected ‘NO’ here (which would have caused the program to abort).
Apparently this feature was incorporated into the program before I added the email-to-list feature for Siraj, to cover cases where the summary file name had somehow gotten corrupted with an extra space or other character, and the situation could be recovered by finding and renaming the errant file name. This works great, right up until the ‘P’ file got added for Siraj’s email feature.
09 June 2022 Update:
Siraj called me with a problem; as it turns out, Google Gmail turned off its ‘use less secure apps’ option as of 31 May 2022, and the Aloha Bridge Club game results email capability went away – oops!
So, I started digging into the problem, and discovered that the workaround was to use their ‘App Password’ option, which turned out to be pretty simple to do. Here’s the link to their help file entry, and I have supplied some screenshots below to show the process, using my Google account – the process should be identical for Siraj’s account.
Open your Gmail client and click on the ‘Google Account’ button, as shown below:
Click on ‘Manage Your Google Account’
Click on the ‘Security’ menu item on the left:
Scroll down to the ‘Signing in to Google’ section as shown below:
Make sure 2-Step Verification is turned ON. If it was OFF, turn it ON and go through the process of establishing 2-step verification.
Click on ‘App Passwords’ as shown below. You may or may not have any app passwords already – I have a couple of data backup applications that use Google Drive, so I already had app passwords for them.
At this point, Google will require you to provide your account credentials again. This is your normal Google login username and password.
This will bring up the ‘App passwords’ screen. Note that my screen shows that I have already created an app password for ‘Bridge Game Reporter’ – your screen may or may not have any entries in the ‘your app passwords’ list. At the bottom are two drop-down lists – ‘Select app’ and ‘Select device’; both will have to be defined. As shown below, the ‘Windows Computer’ selection has been made for the ‘device’:
For ‘Select app’, choose ‘Other (Custom name)‘ as shown:
The ‘Other’ selection brings up a text entry box where you can type in the app name (‘Bridge Game Reporter’) in our case, as shown below. Note that the ‘Generate’ button is now active:
The next screen shows the app password generated by Google for this device and application. Copy/Paste the password from the yellow box to a temporary location. This password will be used, along with your normal user name (‘paynterf@gmail.com’ in my case) in the ’email creds’ dialog box in the Bridge Game Reporter app. Then click on ‘Done’ to exit the box. You will get a ‘Security Alert’ from Google noting that someone has created an app password. You can safely ignore this.
Launch Bridge Game Reporter, and click on the ‘Email Creds’ button at the bottom of the window and enter the access password. The access password is in the BGR.TXT file located in the C:\BGR folder:
This will bring up the email/ftp credentials dialog. In the ‘Email Credentials’ section, make sure the ‘SMTP Host’ is ‘smtp.gmail.com’ as shown, and the ‘Username’ entry is your normal Google username. Then paste the saved application password into the ‘Password’ box, and click on ‘OK’.
At this point, you should be good to go. When Bridge Game Reporter connects to GMail’s SMTP server at ‘smtp.gmail.com’, it will supply the username and password entered above. At least in my case, this worked seamlessly – your mileage may vary!
Stay tuned,
Frank