[Tux4kids-commits] r398 - in tuxmath/trunk: doc src
tholy-guest at alioth.debian.org
tholy-guest at alioth.debian.org
Mon Dec 31 13:04:09 UTC 2007
Author: tholy-guest
Date: 2007-12-31 13:04:09 +0000 (Mon, 31 Dec 2007)
New Revision: 398
Modified:
tuxmath/trunk/doc/changelog
tuxmath/trunk/src/tuxmathadmin.c
Log:
Add a --consolidatelogs feature to tuxmathadmin. This completes the
basic functionality that I think is needed for school use!
Modified: tuxmath/trunk/doc/changelog
===================================================================
--- tuxmath/trunk/doc/changelog 2007-12-31 11:54:08 UTC (rev 397)
+++ tuxmath/trunk/doc/changelog 2007-12-31 13:04:09 UTC (rev 398)
@@ -1,3 +1,9 @@
+2007.Dec.31 (svn.debian.org/tux4kids - revision 398)
+ Code:
+ Add a "--consolidatelogs" feature to tuxmathadmin.
+
+ Tim Holy <holy at wustl.edu>
+
2007.Dec.31 (svn.debian.org/tux4kids - revision 397)
Code:
Add some additional reporting about student progress: a log.csv
Modified: tuxmath/trunk/src/tuxmathadmin.c
===================================================================
--- tuxmath/trunk/src/tuxmathadmin.c 2007-12-31 11:54:08 UTC (rev 397)
+++ tuxmath/trunk/src/tuxmathadmin.c 2007-12-31 13:04:09 UTC (rev 398)
@@ -47,7 +47,7 @@
#define PATH_MAX 4096
#define MAX_USERS 100000
-#define ADMINVERSION "0.1"
+#define ADMINVERSION "0.1.1"
void display_help(void);
void usage(int err, char * cmd);
@@ -59,7 +59,9 @@
void unconfig_highscores(const char *path);
void clear_highscores(const char *path);
void clear_goldstars(const char *path);
+void consolidate_logs(const char *path);
void clear_file(const char *path,const char *filename,const char *invoke_name);
+char* eatwhite(char *buf);
char *directory[MAX_USERS];
int directory_level[MAX_USERS];
@@ -75,6 +77,7 @@
int is_unconfighighscores = 0;
int is_clearinggoldstars = 0;
int is_clearinghighscores = 0;
+ int is_consolidatinglogs = 0;
char *path = NULL;
char *file = NULL;
int level = 0;
@@ -177,6 +180,9 @@
else if (strcmp(argv[i], "--cleargoldstars") == 0) {
is_clearinggoldstars = 1;
}
+ else if (strcmp(argv[i], "--consolidatelogs") == 0) {
+ is_consolidatinglogs = 1;
+ }
else {
fprintf(stderr,"Error: option %s not recognized.\n",argv[i]);
exit(EXIT_FAILURE);
@@ -222,6 +228,13 @@
clear_goldstars(path);
}
+ // Consolidate logs
+ if (is_consolidatinglogs) {
+ consolidate_logs(path);
+ }
+
+ free(path);
+
return EXIT_SUCCESS;
}
@@ -239,7 +252,7 @@
"\nUsage: %s {--help | --usage | --copyright}\n"
" %s [--path <directory>] --createhomedirs <file>\n"
" %s [--level <levelnum>] --confighighscores\n"
- " %s [--path <directory>] [--clearhighscores] [--cleargoldstars]\n"
+ " %s [--path <directory>] [--clearhighscores] [--cleargoldstars] [--consolidatelogs]\n"
"\n", cmd, cmd, cmd, cmd);
exit (err);
@@ -248,7 +261,7 @@
void display_help(void)
{
printf("\ntuxmathadmin\n"
- "This program allows you to administer tuxmath, and is particularly\n"
+ "This program facilitates administering tuxmath, and is particularly\n"
"useful for schools and the like that may have many users.\n\n"
"Examples:\n"
" tuxmathadmin --path /servervolume/tuxmath_users --createhomedirs users.csv\n"
@@ -274,7 +287,13 @@
" tuxmathadmin --cleargoldstars\n"
" Clears the gold stars for all users.\n\n"
" tuxmathadmin --path /servervolume/tuxmath_users/1st\\ grade/Mrs.\\ Smith --cleargoldstars\n"
- " Clears the gold stars for all users in Mrs. Smith's first grade class.\n"
+ " Clears the gold stars for all users in Mrs. Smith's first grade class.\n\n"
+ " tuxmathadmin --consolidatelogs\n"
+ " Creates consolidated_log.csv files at one level above the lowest level\n"
+ " of the directory hierarchy. These files can be opened with a spreadsheet\n"
+ " program. This may be useful for tracking student progress.\n"
+ " Note also that each student has a personal log.csv file in his/her own\n"
+ " directory.\n\n"
);
}
@@ -307,10 +326,8 @@
mask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_IXUSR | S_IXGRP | S_IXOTH;
umask(0x0); // make dirs read/write for everyone
while (fgets (buf, PATH_MAX, fp)) {
- line_begin = buf;
- // Skip leading whitespace
- while (isspace(*line_begin))
- line_begin++;
+ // Skip leading & trailing whitespace
+ line_begin = eatwhite(buf);
// Skip comments
if ((*line_begin == ';') || (*line_begin == '#'))
continue;
@@ -577,6 +594,91 @@
clear_file(path,GOLDSTAR_FILENAME,"cleargoldstars");
}
+// Create consolidated log files at the next-to-lowest level of the
+// hierarchy. This is basically performing a "cat" operation on all
+// the log.csv files that are below a given point in a directory
+// hierarchy.
+void consolidate_logs(const char *path)
+{
+ int n_dirs;
+ int max_level;
+ int i;
+ int column_names_written = 0;
+ FILE *fplogwrite, *fplogread, *fpusersread;
+ char buf[PATH_MAX], buf2[PATH_MAX], buf3[PATH_MAX];
+ char *line_begin;
+
+ // Determine the maximum level
+ n_dirs = directory_crawl(path);
+ max_level = 0;
+ for (i = 0; i < n_dirs; i++)
+ if (directory_level[i] > max_level)
+ max_level = directory_level[i];
+
+ // For every directory on the next-to-maximum level,...
+ for (i = 0; i < n_dirs; i++) {
+ if (directory_level[i] != max_level-1)
+ continue;
+
+ // Open the user_menu_entries file, so that we can cycle through
+ // all subdirectories
+ strncpy(buf,directory[i],PATH_MAX);
+ strncat(buf,USER_MENU_ENTRIES_FILENAME,PATH_MAX-strlen(buf)-1);
+ if (strlen(buf) >= PATH_MAX-1) {
+ error(EXIT_FAILURE,0,"consolidatelogs: pathname %s is truncated, exiting.\n",buf);
+ }
+ fpusersread = fopen(buf,"r");
+ if (!fpusersread)
+ error(EXIT_FAILURE,errno,"consolidatelogs: file:\n %s",buf);
+
+ // Create a blank consolidated_log.csv file
+ strncpy(buf,directory[i],PATH_MAX);
+ strncat(buf,"consolidated_log.csv",PATH_MAX-strlen(buf)-1);
+ if (strlen(buf) >= PATH_MAX-1) {
+ error(EXIT_FAILURE,0,"consolidatelogs: pathname %s is truncated, exiting.\n",buf);
+ }
+ fplogwrite = fopen(buf,"w");
+ if (!fplogwrite)
+ error(EXIT_FAILURE,errno,"consolidatelogs: file:\n %s",buf);
+
+ // Loop over different users
+ while (fgets(buf, PATH_MAX, fpusersread)) {
+ // Skip over white space, and especially blank lines
+ line_begin = eatwhite(buf);
+ if (strlen(line_begin) == 0)
+ continue;
+ // Create the full path & filename of the user's log.csv file
+ strncpy(buf2,directory[i],PATH_MAX);
+ strncat(buf2,line_begin,PATH_MAX-strlen(buf2)-1);
+ strncat(buf2,"/log.csv",PATH_MAX-strlen(buf2)-1);
+ fplogread = fopen(buf2,"r");
+ if (fplogread) {
+ // Copy the relevant lines from the user's log.csv file to the
+ // consolidated log file. Make sure only one copy of the
+ // column names is written.
+ while(fgets(buf3, PATH_MAX, fplogread)) {
+ line_begin = eatwhite(buf3);
+ if (strlen(line_begin) == 0)
+ continue;
+ if (strncmp(line_begin,"\"User",5) == 0) {
+ if (!column_names_written) {
+ fprintf(fplogwrite,"%s\n",line_begin);
+ column_names_written = 1;
+ }
+ } else {
+ fprintf(fplogwrite,"%s\n",line_begin);
+ }
+ }
+ fclose(fplogread);
+ }
+ }
+ fclose(fpusersread);
+ fclose(fplogwrite);
+ }
+
+ free_directories(n_dirs);
+}
+
// Deletes a named filetype in the directory hierarchy
void clear_file(const char *path,const char *filename,const char *invoke_name)
{
@@ -680,7 +782,6 @@
int isdone;
int i;
char *line_begin;
- char *line_end;
DIR *dir;
current_length = 1;
@@ -717,19 +818,12 @@
fprintf(stderr,"Error: maximum number of users exceeded.");
exit(EXIT_FAILURE);
}
- // Skip over white space, and especially blank lines
- line_begin = buf;
- while (isspace(*line_begin))
- line_begin++;
- // Eliminate the \n at the end of the line
- line_end = line_begin+strlen(line_begin)-1;
- while (line_end >= line_begin && (*line_end == '\n' || *line_end == '\r')) {
- *line_end = '\0';
- line_end--;
- }
-
+ // Skip over leading & trailing white space, and
+ // especially blank lines
+ line_begin = eatwhite(buf);
if (strlen(line_begin) == 0)
continue;
+
directory[current_length] = (char *) malloc((strlen(directory[i])+strlen(line_begin)+2)*sizeof(char));
if (directory[current_length] == NULL) {
fprintf(stderr,"Memory allocation error in directory_crawl.\n");
@@ -768,3 +862,23 @@
}
}
+// Modify a string to eliminate leading and trailing
+// whitespace. Returns a pointer to the first non-space character.
+// Note the input string is modified in-place!
+char* eatwhite(char *buf)
+{
+ char *line_begin, *line_end;
+
+ // Eliminate leading whitespace
+ line_begin = buf;
+ while (isspace(*line_begin))
+ line_begin++;
+ // Eliminate trailing whitespace, especially the \n at the end of the line
+ line_end = line_begin+strlen(line_begin)-1;
+ while (line_end >= line_begin && isspace(*line_end)) {
+ *line_end = '\0';
+ line_end--;
+ }
+
+ return line_begin;
+}
More information about the Tux4kids-commits
mailing list