bug-gtypist
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-gtypist] [Kenan Kalajdzic] [PATCH] Add an option to log all typing


From: Felix Natter
Subject: [bug-gtypist] [Kenan Kalajdzic] [PATCH] Add an option to log all typing results to a file
Date: Sat, 10 Nov 2018 17:33:45 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux)

hi Mihai,

here is a patch (old, so it probably doesn't apply cleanly) with a new
idea.

Cheers and Best Regards,
Felix

--- Begin Message --- Subject: [bug-gtypist] [PATCH] Add an option to log all typing results to a file Date: Wed, 28 Sep 2016 17:59:55 +0200 User-agent: Mutt/1.7.0 (2016-08-17)
Hi everyone!

I wish to propose a new feature for gtypist.

I've been using gtypist for a couple of weeks with a group of students to help 
them practice touch typing. So far I've tracked their results through:

  1. the --personal-best option,
  2. screenshots.

What I have been missing is a feature to log every attempt they make, 
regardless of whether it is successful or not. The log file should store as 
much information as possible to enable the user to perform various analyses and 
produce graphs for easier progress tracking.  

To implement this functionality, I just borrowed the code from put_best_speed() 
and extended it a little bit to log a few more fields, including the username 
(storing the username in each log entry allows for results from multiple users 
to be collected in a single file).

Cheers,
Kenan

---
Add an option to log all typing results to a file

Signed-off-by: Kenan Kalajdzic <address@hidden>
---
 src/cmdline.c | 54 +++++++++++++++++++++++++++++++++----------------
 src/cmdline.h |  4 ++++
 src/gtypist.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 106 insertions(+), 17 deletions(-)

diff --git a/src/cmdline.c b/src/cmdline.c
index 5078cf9..e084cac 100644
--- a/src/cmdline.c
+++ b/src/cmdline.c
@@ -36,6 +36,7 @@ const char *gengetopt_args_info_description = "";
 const char *gengetopt_args_info_help[] = {
   "  -h, --help                   Print help and exit",
   "  -V, --version                Print version and exit",
+  "  -a, --log-all-to=FILE        log (append) all typing results to a given 
file",
   "  -b, --personal-best          track personal best typing speeds  
(default=off)",
   "  -e, --max-error=FLOAT        default maximum error percentage; valid 
values\n                                 are between 0.0 and 100.0  
(default=`3.0')",
   "  -n, --notimer                turn off WPM timer in drills  (default=off)",
@@ -108,6 +109,7 @@ void clear_given (struct gengetopt_args_info *args_info)
 {
   args_info->help_given = 0 ;
   args_info->version_given = 0 ;
+  args_info->all_results_log_given = 0 ;
   args_info->personal_best_given = 0 ;
   args_info->max_error_given = 0 ;
   args_info->notimer_given = 0 ;
@@ -130,6 +132,8 @@ static
 void clear_args (struct gengetopt_args_info *args_info)
 {
   FIX_UNUSED (args_info);
+  args_info->all_results_log_arg = NULL;
+  args_info->all_results_log_orig = NULL;
   args_info->personal_best_flag = 0;
   args_info->max_error_arg = 3.0;
   args_info->max_error_orig = NULL;
@@ -162,22 +166,23 @@ void init_args_info(struct gengetopt_args_info *args_info)
 
   args_info->help_help = gengetopt_args_info_help[0] ;
   args_info->version_help = gengetopt_args_info_help[1] ;
-  args_info->personal_best_help = gengetopt_args_info_help[2] ;
-  args_info->max_error_help = gengetopt_args_info_help[3] ;
-  args_info->notimer_help = gengetopt_args_info_help[4] ;
-  args_info->term_cursor_help = gengetopt_args_info_help[5] ;
-  args_info->curs_flash_help = gengetopt_args_info_help[6] ;
-  args_info->colours_help = gengetopt_args_info_help[7] ;
-  args_info->silent_help = gengetopt_args_info_help[8] ;
-  args_info->quiet_help = gengetopt_args_info_help[9] ;
-  args_info->start_label_help = gengetopt_args_info_help[10] ;
-  args_info->word_processor_help = gengetopt_args_info_help[11] ;
-  args_info->no_skip_help = gengetopt_args_info_help[12] ;
-  args_info->show_errors_help = gengetopt_args_info_help[13] ;
-  args_info->always_sure_help = gengetopt_args_info_help[14] ;
-  args_info->banner_colors_help = gengetopt_args_info_help[15] ;
-  args_info->scoring_help = gengetopt_args_info_help[16] ;
-  args_info->no_welcome_screen_help = gengetopt_args_info_help[17] ;
+  args_info->all_results_log_help = gengetopt_args_info_help[2] ;
+  args_info->personal_best_help = gengetopt_args_info_help[3] ;
+  args_info->max_error_help = gengetopt_args_info_help[4] ;
+  args_info->notimer_help = gengetopt_args_info_help[5] ;
+  args_info->term_cursor_help = gengetopt_args_info_help[6] ;
+  args_info->curs_flash_help = gengetopt_args_info_help[7] ;
+  args_info->colours_help = gengetopt_args_info_help[8] ;
+  args_info->silent_help = gengetopt_args_info_help[9] ;
+  args_info->quiet_help = gengetopt_args_info_help[10] ;
+  args_info->start_label_help = gengetopt_args_info_help[11] ;
+  args_info->word_processor_help = gengetopt_args_info_help[12] ;
+  args_info->no_skip_help = gengetopt_args_info_help[13] ;
+  args_info->show_errors_help = gengetopt_args_info_help[14] ;
+  args_info->always_sure_help = gengetopt_args_info_help[15] ;
+  args_info->banner_colors_help = gengetopt_args_info_help[16] ;
+  args_info->scoring_help = gengetopt_args_info_help[17] ;
+  args_info->no_welcome_screen_help = gengetopt_args_info_help[18] ;
   
 }
 
@@ -264,6 +269,8 @@ static void
 cmdline_parser_release (struct gengetopt_args_info *args_info)
 {
   unsigned int i;
+  free_string_field (&(args_info->all_results_log_arg));
+  free_string_field (&(args_info->all_results_log_orig));
   free_string_field (&(args_info->max_error_orig));
   free_string_field (&(args_info->curs_flash_orig));
   free_string_field (&(args_info->colours_arg));
@@ -353,6 +360,8 @@ cmdline_parser_dump(FILE *outfile, struct 
gengetopt_args_info *args_info)
     write_into_file(outfile, "help", 0, 0 );
   if (args_info->version_given)
     write_into_file(outfile, "version", 0, 0 );
+  if (args_info->all_results_log_given)
+    write_into_file(outfile, "log-all-to", args_info->all_results_log_orig, 0 
);
   if (args_info->personal_best_given)
     write_into_file(outfile, "personal-best", 0, 0 );
   if (args_info->max_error_given)
@@ -678,7 +687,7 @@ cmdline_parser_internal (
         { 0,  0, 0, 0 }
       };
 
-      c = getopt_long (argc, argv, "hVbe:ntf:c:sql:wkiS", long_options, 
&option_index);
+      c = getopt_long (argc, argv, "hVa:be:ntf:c:sql:wkiS", long_options, 
&option_index);
 
       if (c == -1) break;      /* Exit from `while (1)' loop.  */
 
@@ -694,6 +703,17 @@ cmdline_parser_internal (
           cmdline_parser_free (&local_args_info);
           exit (EXIT_SUCCESS);
 
+        case 'a':      /* log all results to file  */
+          if (update_arg( (void *)&(args_info->all_results_log_arg), 
+               &(args_info->all_results_log_orig), 
&(args_info->all_results_log_given),
+              &(local_args_info.all_results_log_given), optarg, 0, 0, 
ARG_STRING,
+              check_ambiguity, override, 0, 0,
+              "log-all-to", 'a',
+              additional_error))
+            goto failure;
+        
+          break;
+
         case 'b':      /* track personal best typing speeds.  */
         
         
diff --git a/src/cmdline.h b/src/cmdline.h
index febd0f6..d44384a 100644
--- a/src/cmdline.h
+++ b/src/cmdline.h
@@ -45,6 +45,9 @@ struct gengetopt_args_info
 {
   const char *help_help; /**< @brief Print help and exit help description.  */
   const char *version_help; /**< @brief Print version and exit help 
description.  */
+  char *all_results_log_arg;   /**< @brief log file for all results.  */
+  char *all_results_log_orig;  /**< @brief log file for all results original 
value given at command line.  */
+  const char *all_results_log_help; /**< @brief log file for all results help 
description.  */
   int personal_best_flag;      /**< @brief track personal best typing speeds 
(default=off).  */
   const char *personal_best_help; /**< @brief track personal best typing 
speeds help description.  */
   float max_error_arg; /**< @brief default maximum error percentage; valid 
values are between 0.0 and 100.0 (default='3.0').  */
@@ -86,6 +89,7 @@ struct gengetopt_args_info
   
   unsigned int help_given ;    /**< @brief Whether help was given.  */
   unsigned int version_given ; /**< @brief Whether version was given.  */
+  unsigned int all_results_log_given ; /**< @brief Whether log-all-to was 
given.  */
   unsigned int personal_best_given ;   /**< @brief Whether personal-best was 
given.  */
   unsigned int max_error_given ;       /**< @brief Whether max-error was 
given.  */
   unsigned int notimer_given ; /**< @brief Whether notimer was given.  */
diff --git a/src/gtypist.c b/src/gtypist.c
index 87bd6de..f26871f 100644
--- a/src/gtypist.c
+++ b/src/gtypist.c
@@ -35,6 +35,7 @@
 #include <ncursesw/ncurses.h>
 #endif
 
+#include <pwd.h>
 #include <time.h>
 #include <errno.h>
 #include <string.h>
@@ -188,6 +189,9 @@ static bool get_best_speed( const char *script_filename,
 static void put_best_speed( const char *script_filename,
                            const char *excersise_label, double adjusted_cpm );
 const char *get_bestlog_filename();
+static void log_all( const char *script_filename, const char *exercise_label,
+                int total_chars, int errcount, double test_time,
+                double cpm, double adjusted_cpm );
 
 void bind_F12 (const char *label)
 {
@@ -360,6 +364,13 @@ static void display_speed( int total_chars, double 
elapsed_time, int errcount )
        put_best_speed( global_script_filename, __last_label, adjusted_cpm );
     }
 
+  /* save the results to a log file */
+  if( cl_args.all_results_log_given )
+    {
+      log_all( global_script_filename, __last_label, total_chars,
+               errcount, test_time, cpm, adjusted_cpm );
+    }
+
   /* draw speed box */
   do_speed_box( total_chars, errcount, cpm, adjusted_cpm,
                cl_args.scoring_arg == scoring_arg_cpm? TRUE : FALSE,
@@ -2009,6 +2020,60 @@ const char *get_bestlog_filename()
     return filename;
 }
 
+void log_all( const char *script_filename, const char *exercise_label,
+              int total_chars, int errcount, double test_time,
+              double cpm, double adjusted_cpm )
+{
+  FILE *logfile;
+  char *fixed_script_filename;
+  char *p;
+
+  /* open log file */
+  logfile = fopen( cl_args.all_results_log_arg, "a" );
+  if( logfile == NULL )
+    {
+       perror( "fopen" );
+       fatal_error( _("internal error: fopen" ), NULL );
+    }
+
+  /* fix-up script filename */
+  fixed_script_filename = strdup( script_filename );
+  if( fixed_script_filename == NULL )
+    {
+       perror( "malloc" );
+       fatal_error( _( "internal error: malloc" ), NULL );
+    }
+  p = fixed_script_filename;
+  while( *p != '\0' )
+    {
+      if( *p == ' ' )
+       *p = '+';
+      p++;
+    }
+
+  /* get time */
+  time_t nowts = time( NULL );
+  struct tm *now = localtime( &nowts );
+
+  /* get username */
+  struct passwd *pwd = getpwuid(getuid());
+  if( pwd == NULL )
+    {
+       perror( "getpwuid" );
+       fatal_error( _( "internal error: getpwuid" ), NULL );
+    }
+
+  /* append results */
+  fprintf( logfile, "%04d-%02d-%02d %02d:%02d:%02d %s %s:%s %d %d %g %g %g 
%g\n",
+           now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour,
+           now->tm_min, now->tm_sec, pwd->pw_name, fixed_script_filename,
+           exercise_label, total_chars, errcount, global_error_max,
+           test_time, cpm, adjusted_cpm );
+
+  /* cleanup */
+  free( fixed_script_filename );
+  fclose( logfile );
+}
 
 /*
   Local Variables:
-- 
2.5.0

_______________________________________________
bug-gtypist mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/bug-gtypist


--- End Message ---

-- 
Felix Natter
debian/rules!

reply via email to

[Prev in Thread] Current Thread [Next in Thread]