topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Thursday October 10, 2024, 8:36 pm
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: Kyrathasoft Christian Prayer Minder (a NANY 2012 entry)  (Read 15164 times)

kyrathaba

  • N.A.N.Y. Organizer
  • Moderator
  • Joined in 2006
  • *****
  • Posts: 3,200
    • View Profile
    • Donate to Member
Kyrathasoft Christian Prayer Minder (a NANY 2012 entry)
« on: January 19, 2012, 06:27 PM »
Application Name Christian Prayer Minder
Version 1.0.7.3 (attention: prayer files from versions prior to 1.0.0.9 aren't compatible with later versions of the program; If you currently have v1.0.1.1 or earlier installed, please manually install version 1.0.6.9 after uninstalling any previous version. From now on, you should be able to update from within the program as usual. If you have v1.0.1.2 or later installer, you should be able to download the updated installer from within your currently running program.)
Short Descriptionprovides informative texts on prayer-related topics, plus enables easy save/retrieve/edit prayer files, and searching prayer files based on tags and/or author
Supported OSes Windows XP forward
Setup File (4.95 M) http://kyrathaba.dcm...count/click.php?id=8
Memory Footprintroughly 10 Mb
System Requirementsrequires .NET Framework v4.0 (program detects if absent, and will download/install it if permission is given)
Author InfoDC member kyrathaba, developer of these other NANY 2012 entries: Found Money, Kyrathaba's Hangman, and Source Code Line Counter. My past NANY entries include: Crocus Contacts, Blackjack, and NANY Excuse Manager. Later NANY entries include 2x2 List Sorter (download here), and KyrTTS (Kyrathasoft's Text-to-Sound) (download here).
DescriptionI realize that there are relatively few Christianity adherents here. Nevertheless, for those of us who are, I believe that this program offers something valuable. I began thinking about writing this application several weeks ago, after a series of conversations with my pastor in which we discussed how it's often difficult to concentrate while trying to pray. We've also discussed the need for a tool that acts as a prayer reminder, and one that can track written prayers and offer search functionality. Finally, we wanted a tool that allows the user to come back at a later time to a prayer and offer thoughts/insights into prayer-answers, or meditations on the prayer itself.  This tool will also, in future updates, allow the user to customize prompts and prompt-frequencies for various types of prayer (praise, intercession, supplication, etc.) The program could also be used to store diary/journal entries, although that isn't its intended purpose.
Screencast
Features
  • built-in CHM Help file
  • pray at the speed of typing (for me, that's about 85 wpm)
  • enter author, and any related tags to help in future searches (or omit them)
  • main form features fantastic background images, many of them by [url=http://www.jrbell.com/]J. R. Bell
  • twelve fore-/back-color schemes for the "My Prayers" panel
  • option to launch application when Windows starts
  • ten in-depth articles on prayer-related topics
  • articles on spiritual disciplines, and the Biblical plan of salvation
  • ability to print the article, or whatever portion of its text is selected
  • recommended further reading (some titles with accompanying URLs)
  • real-time filesystem watcher monitors for creation/deletion/renaming of prayer files
  • informative message-boxes
  • program uses index files to make searching for specific prayer files faster
  • warns user if they attempt to save a prayer file in a non-MyPrayers directory
  • error-trapping correctly detects and handles case where user attempts to load a non-PrayerMinder file
  • click a Search result in ListBox to view its filename, lastModified date, path to file, Author, and tags
  • double-click the Search result entry to load that prayer file
  • zero Registry footprint
  • you can now increase or decrease font size in the MyPrayers textbox by selecting your desired font size in Options
  • three ways to exit application: close button, file menu, or Escape key
  • optional "Did You Know" dialog at program startup
  • search either by author and/or tags, using indexes (fast: on the order of milliseconds)
  • search within prayer file contents for a search phrase, returning all files that contain that search phrase (slow: seconds, not milliseconds)
  • if you double-click a Search results listbox entry and it is the result of a search-within-for-phrase Search, the search-phrase is highlighted when the prayer file is loaded
  • smart-saving removes any excess whitespace from the prayer before saving it
  • option to set a backup directory (makes program compatible with using Dropbox for backing up the program's data files)
  • option to password individual author-name, so that user can't create files with that author name or load files authored by that author without the proper password
Favorite method in this project: bgWorkerSearch_DoWork()
Spoiler
Code: C# [Select]
  1. void bgWorkerSearch_DoWork (object sender, DoWorkEventArgs e) {
  2.  
  3.             log.write("We have entered the background worker that does the heavy-lifting in Searches...");
  4.             DateTime _start = DateTime.Now;
  5.             clsSearcherArgument arg = (clsSearcherArgument)e.Argument;
  6.  
  7.             #region ifDebuggerAttachedGiveSomeInfo
  8.  
  9.             if (Debugger.IsAttached) {
  10.  
  11.                 string msg = "Search type: " + ((SearchType)arg.SearchType).ToString() + Environment.NewLine;
  12.  
  13.                 msg += "Search ";
  14.                 msg += (arg.SearchType == (int)SearchType.SearchWithinFiles) ? " phrase: " : " tag(s): ";
  15.                 if (arg.searchPhraseOrTags.Length > 0) {
  16.                     msg += arg.searchPhraseOrTags + Environment.NewLine;
  17.                 } else {
  18.                     msg += "[none]" + Environment.NewLine;
  19.                 }
  20.  
  21.                 msg += "Author filter: ";
  22.                 if (arg.searchedForAuthor.Length > 0) {
  23.                     msg += arg.searchedForAuthor + Environment.NewLine;
  24.                 } else {
  25.                     msg += "[none]" + Environment.NewLine;
  26.                 }
  27.  
  28.                 msg += "Time constraint: " + ((TimeConstraint)arg.timeConstraint).ToString();
  29.  
  30.                 MessageBox.Show(msg);
  31.  
  32.             }
  33.  
  34.             #endregion
  35.  
  36.             #region setUpNeededVariables            
  37.  
  38.             DirectoryInfo di = new DirectoryInfo(pathToMyPrayers);
  39.             FileInfo[] fi = di.GetFiles();
  40.             List<clsPrayerInfo> information = new List<clsPrayerInfo>();
  41.            
  42.             int totalPrayerFiles = fi.GetLength(0);
  43.             string searchedForAuthor = arg.searchedForAuthor.Trim().ToLower();
  44.             string searchedForPhrase = arg.searchPhraseOrTags.Trim().ToLower();            
  45.             int examined_so_far = 0;
  46.             int hits = 0;
  47.             int time_constraint = arg.timeConstraint;
  48.             double totalSeconds = 0;
  49.             bool blnPassesTimeConstraint;
  50.             bool blnPassesAuthor;
  51.             bool blnPassesSearchPhrase;
  52.             decimal fraction = 0;
  53.             int the_percent = 0;
  54.  
  55.             for (int i = 0; i < totalPrayerFiles; i++) {
  56.                 if (fi[i].FullName.ToLower().Contains("thumbs.db")) { totalPrayerFiles--; }
  57.             }
  58.  
  59.             #endregion
  60.  
  61.             if (arg.SearchType == (int)SearchType.SearchWithinFiles) {
  62.  
  63.                 log.write("About to enter foreach loop for searching within files...");
  64.                
  65.                 foreach (FileInfo f in fi) {
  66.                
  67.                     blnPassesTimeConstraint = false;
  68.                     blnPassesAuthor = false;
  69.                     blnPassesSearchPhrase = false;
  70.                    
  71.                     if (f.FullName.ToLower().Contains("thumbs.db")) { continue; }
  72.                    
  73.                     #region codeForExaminingWithinPrayerFileContents
  74.                    
  75.                     blnPassesAuthor = true; //because SearchWithinFiles doesn't care about the author                  
  76.                     FileStream fs = new FileStream(f.FullName, FileMode.Open, FileAccess.Read, FileShare.None);
  77.                     clsPrayerInfo oInfo = new clsPrayerInfo();                    
  78.  
  79.                     try {
  80.                         BinaryFormatter bFormatter = new BinaryFormatter();
  81.                         clsPrayer prayer = (clsPrayer)bFormatter.Deserialize(fs);
  82.                         string contents = prayer.content.Trim().ToLower();
  83.                         if (contents.Contains(searchedForPhrase)) {
  84.                             blnPassesSearchPhrase = true;
  85.                             oInfo = new clsPrayerInfo(prayer, f.FullName);
  86.                             int selStart = contents.IndexOf(searchedForPhrase);
  87.                             oInfo.StartOfSelection = selStart;                            
  88.                             #region determineIfWePassTheTimeConstraint
  89.                             if (time_constraint == (int)TimeConstraint.NoConstraint) {
  90.                                 blnPassesTimeConstraint = true;
  91.                             } else {
  92.                                 DateTime rightNow = DateTime.Now;
  93.                                 TimeSpan ts = rightNow.Subtract(oInfo.lastModified);
  94.                                 totalSeconds = ts.TotalSeconds;
  95.                                 switch (time_constraint) {
  96.                                     case (int)TimeConstraint.PastWeek:
  97.                                         if (totalSeconds <= 604800) { blnPassesTimeConstraint = true; }
  98.                                         break;
  99.                                     case (int)TimeConstraint.PastMonth:
  100.                                         if (totalSeconds <= 2592000) { blnPassesTimeConstraint = true; }
  101.                                         break;
  102.                                     case (int)TimeConstraint.PastYear:
  103.                                         if (totalSeconds <= 31536000) { blnPassesTimeConstraint = true; }
  104.                                         break;
  105.                                 }
  106.                             }
  107.                             #endregion
  108.                         } else {
  109.                             blnPassesSearchPhrase = false;
  110.                         }
  111.  
  112.                         examined_so_far++;
  113.                         log.write("We have examined this many files: " + examined_so_far.ToString());
  114.  
  115.                         if (blnPassesTimeConstraint && blnPassesSearchPhrase && blnPassesAuthor) {
  116.                             information.Add(oInfo);                            
  117.                             hits++;
  118.                         }
  119.  
  120.                     } catch (Exception exceptionOpeningPrayerFile) {
  121.                         string msgWithinFilesException = "Error in SearchWithinFiles portion of code in method bgWorkerSearch_DoWork(): " + exceptionOpeningPrayerFile.Message;
  122.                         log.write(msgWithinFilesException);
  123.                         MessageBox.Show(msgWithinFilesException, "Error Opening Prayer File During Search");
  124.                     }
  125.                     finally {
  126.                         if (fs != null) { fs.Close(); }
  127.                     }
  128.                     #endregion
  129.  
  130.                     fraction = (decimal)examined_so_far / (decimal)totalPrayerFiles;
  131.                     the_percent = Convert.ToInt32(fraction * 100);
  132.                     bgWorkerSearch.ReportProgress(the_percent);
  133.                     log.write("Records counted: " + examined_so_far.ToString() + " of " + totalPrayerFiles.ToString() + " (hits: " + hits.ToString() + ") -- " + the_percent.ToString() + " % complete...");
  134.                 }
  135.            
  136.             } else {
  137.  
  138.                 log.write("About to enter foreach loop for searching via tracking files...");
  139.                
  140.                 foreach (FileInfo f in fi) {
  141.  
  142.                     blnPassesTimeConstraint = false;
  143.                     blnPassesAuthor = false;
  144.                     blnPassesSearchPhrase = false;
  145.  
  146.                     if (f.FullName.ToLower().Contains("thumbs.db")) { continue; }
  147.                    
  148.                     #region codeForSearchingAgainstAuthorAndOrTagsUsingTrackingFiles
  149.                    
  150.                     clsPrayerInfo oInfo = new clsPrayerInfo();
  151.                     string pathToTracker = Path.Combine(pathToTrackingDirectory, Path.GetFileNameWithoutExtension(f.FullName));
  152.                     if (!File.Exists(pathToTracker)) {
  153.                         log.write("Tracking file doesn't exist: " + pathToTracker);
  154.                         continue;
  155.                     } else {
  156.                         log.write("The following tracking file DOES exist: " + pathToTracker);
  157.                     }
  158.                    
  159.                     FileStream fs = new FileStream(pathToTracker, FileMode.Open, FileAccess.Read, FileShare.None);
  160.                     try {
  161.  
  162.                         BinaryFormatter bFormatter = new BinaryFormatter();
  163.                         oInfo = (clsPrayerInfo)bFormatter.Deserialize(fs);
  164.                         oInfo.StartOfSelection = -1;
  165.                         DateTime rightNow = DateTime.Now;
  166.                         TimeSpan ts = rightNow.Subtract(oInfo.lastModified);
  167.                         totalSeconds = ts.TotalSeconds;
  168.  
  169.                         log.write("We were able to open the tracker...");
  170.  
  171.                         #region determineIfTheTimeConstraintPasses
  172.                         if (time_constraint == (int)TimeConstraint.NoConstraint) {
  173.                             blnPassesTimeConstraint = true;
  174.                         } else {
  175.                             switch (time_constraint) {
  176.                                 case (int)TimeConstraint.PastWeek:
  177.                                     if (totalSeconds <= 604800) { blnPassesTimeConstraint = true; }
  178.                                     break;
  179.                                 case (int)TimeConstraint.PastMonth:
  180.                                     if (totalSeconds <= 2592000) { blnPassesTimeConstraint = true; }
  181.                                     break;
  182.                                 case (int)TimeConstraint.PastYear:
  183.                                     if (totalSeconds <= 31536000) { blnPassesTimeConstraint = true; }
  184.                                     break;
  185.                             }
  186.                         }
  187.                         #endregion
  188.                         if (blnPassesTimeConstraint) {
  189.                             log.write("TimeConstraint passed in Search using Mode Normal or ExactMatch...");
  190.                             #region determineIfAuthorPasses
  191.                             if (searchedForAuthor.Length == 0) {
  192.                                 blnPassesAuthor = true;
  193.                             } else {
  194.                                 if (searchedForAuthor == oInfo.author.Trim().ToLower()) { blnPassesAuthor = true; }
  195.                             }
  196.                             #endregion
  197.                             if (blnPassesAuthor) {
  198.                                 #region determineIfSearchPhrasePasses
  199.                                 if (searchedForPhrase.Length == 0) {
  200.                                     blnPassesSearchPhrase = (arg.SearchType == (int)SearchType.Normal) ? true : false;
  201.                                 } else {
  202.                                     if (arg.SearchType == (int)SearchType.ExactMatch) {
  203.                                         blnPassesSearchPhrase = (searchedForPhrase == oInfo.tags.Trim().ToLower()) ? true : false;
  204.                                     } else {
  205.                                         blnPassesSearchPhrase = (oInfo.tags.Trim().ToLower().Contains(searchedForPhrase)) ? true : false;
  206.                                     }
  207.                                 }
  208.                                 #endregion
  209.                             }//end if (blnPassesAuthor)
  210.                         }//end if (blnPassesTimeContraint)
  211.  
  212.                         if (blnPassesSearchPhrase && blnPassesAuthor && blnPassesTimeConstraint) {
  213.                             information.Add(oInfo);
  214.                             hits++;
  215.                         }
  216.  
  217.                         examined_so_far++;
  218.                         log.write("We have examined this many files: " + examined_so_far.ToString());
  219.  
  220.                     } catch (Exception exception) {
  221.                         log.write("Exception caught while trying to load clsPrayerInfo data from this tracking file in bgWorkerSearch_DoWork(): " + Path.GetFileName(pathToTracker));
  222.                         log.write(exception.Message);
  223.                     }
  224.                     finally {
  225.                         if (fs != null) { fs.Close(); }
  226.                     }
  227.  
  228.                     #endregion
  229.                    
  230.                     fraction = (decimal)examined_so_far / (decimal)totalPrayerFiles;
  231.                     the_percent = Convert.ToInt32(fraction * 100);
  232.                     bgWorkerSearch.ReportProgress(the_percent);
  233.                     log.write("Records counted: " + examined_so_far.ToString() + " of " + totalPrayerFiles.ToString() + " (hits: " + hits.ToString() + ") -- " + the_percent.ToString() + " % complete...");
  234.                
  235.                 }
  236.            
  237.             }
  238.  
  239.             DateTime _finished = DateTime.Now;
  240.             TimeSpan tsOverall = _finished.Subtract(_start);
  241.             string duration = clsGetDurationDesc.getDurationDesc(tsOverall.TotalMilliseconds);
  242.  
  243.             clsSearcherResults oResults = new clsSearcherResults(information, duration, examined_so_far, hits);
  244.             e.Result = oResults;
  245.  
  246.             log.write("Now exiting bgWorkerSearch_DoWork()...");
  247.  
  248.         }

Screenshots (there are more images in addition to those shown here, but you'll have to download/install the program to discover them...)
Installationrun the Inno Setup installer
Using the applicationpretty standard Windows application menu system, with some additional options.  Should be straightforward, although I intend to author a help file.
UninstallingRun the uninstaller that the installation provides
Known IssuesI've fixed quite a few minor issues. Let me know if you think you've found a bug: it's probably a feature ;)
« Last Edit: February 01, 2013, 10:04 PM by kyrathaba »

kyrathaba

  • N.A.N.Y. Organizer
  • Moderator
  • Joined in 2006
  • *****
  • Posts: 3,200
    • View Profile
    • Donate to Member
Re: Kyrathasoft Christian Prayer Minder (a NANY 2012 entry)
« Reply #1 on: January 26, 2012, 06:42 PM »
v1.0.6.3 is released on 26 Jan 2012.

kyrathaba

  • N.A.N.Y. Organizer
  • Moderator
  • Joined in 2006
  • *****
  • Posts: 3,200
    • View Profile
    • Donate to Member
Re: Kyrathasoft Christian Prayer Minder (a NANY 2012 entry)
« Reply #2 on: January 27, 2012, 08:30 PM »
v1.0.6.4 fixes a bug in the code that creates a startup folder shortcut

kyrathaba

  • N.A.N.Y. Organizer
  • Moderator
  • Joined in 2006
  • *****
  • Posts: 3,200
    • View Profile
    • Donate to Member
Re: Kyrathasoft Christian Prayer Minder (a NANY 2012 entry)
« Reply #3 on: January 29, 2012, 01:49 PM »
v1.0.6.6 finally brings passwording to this program. The user can opt to password particular Author names. If you password the author-name "John Smith", then no files can be created with that associated author-name unless the proper password has been supplied, and any files previously created by "John Smith" cannot be loaded unless the proper password has been supplied. You can set a session author-name and password, so that you don't have to repeatedly enter these each time you try to save or load a file with a particular author-name.

kyrathaba

  • N.A.N.Y. Organizer
  • Moderator
  • Joined in 2006
  • *****
  • Posts: 3,200
    • View Profile
    • Donate to Member
Re: Kyrathasoft Christian Prayer Minder (a NANY 2012 entry)
« Reply #4 on: January 31, 2012, 08:52 AM »
v1.0.6.7 fleshes out what was started in v1.0.6.6. Optional passwording of Author Names provides a degree of privacy and protection for your files. Passwording is now discussed in the relevant sections of the Help file (saving files, loading files, deleting files, searching files).

kyrathaba

  • N.A.N.Y. Organizer
  • Moderator
  • Joined in 2006
  • *****
  • Posts: 3,200
    • View Profile
    • Donate to Member
Re: Kyrathasoft Christian Prayer Minder (a NANY 2012 entry)
« Reply #5 on: February 04, 2012, 05:32 PM »
v1.0.6.9 released. Update program from within the program using the Update menu item. View "Version History" for bug-fixes and features-added in versions 1.0.6.8 and 1.0.6.9.

kyrathaba

  • N.A.N.Y. Organizer
  • Moderator
  • Joined in 2006
  • *****
  • Posts: 3,200
    • View Profile
    • Donate to Member
Re: Kyrathasoft Christian Prayer Minder (a NANY 2012 entry)
« Reply #6 on: February 10, 2012, 09:40 PM »
v1.0.7.0 released.

kyrathaba

  • N.A.N.Y. Organizer
  • Moderator
  • Joined in 2006
  • *****
  • Posts: 3,200
    • View Profile
    • Donate to Member
Re: Kyrathasoft Christian Prayer Minder (a NANY 2012 entry)
« Reply #7 on: February 01, 2013, 10:05 PM »
v1.0.7.3 was the last intended release.