mirror of https://github.com/acanas/swad-core.git
Version 14.75
This commit is contained in:
parent
e5ab83f457
commit
7c0195766f
|
@ -103,11 +103,12 @@
|
||||||
/****************************** Public constants *****************************/
|
/****************************** Public constants *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define Log_PLATFORM_VERSION "SWAD 14.74.12 (2015/02/23)"
|
#define Log_PLATFORM_VERSION "SWAD 14.75 (2015/02/27)"
|
||||||
|
|
||||||
// Number of lines (includes comments but not blank lines) has been got with the following command:
|
// Number of lines (includes comments but not blank lines) has been got with the following command:
|
||||||
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h | tail -1
|
// nl swad*.c swad*.h css/swad*.css py/swad*.py js/swad*.js soap/swad*.h | tail -1
|
||||||
/*
|
/*
|
||||||
|
Version 14.75: Feb 27, 2015 Fixed bug when getting user's IDs from marks tables. (178172 lines)
|
||||||
Version 14.74.12: Feb 23, 2015 Fixed bug in file browser, reported by Germán Luzón González and Javier Fernández Baldomero. (178119 lines)
|
Version 14.74.12: Feb 23, 2015 Fixed bug in file browser, reported by Germán Luzón González and Javier Fernández Baldomero. (178119 lines)
|
||||||
Version 14.74.11: Feb 10, 2015 Changes in swad.js. (178060 lines)
|
Version 14.74.11: Feb 10, 2015 Changes in swad.js. (178060 lines)
|
||||||
Version 14.74.10: Feb 10, 2015 Removed meta tag. (178060 lines)
|
Version 14.74.10: Feb 10, 2015 Removed meta tag. (178060 lines)
|
||||||
|
|
177
swad_mark.c
177
swad_mark.c
|
@ -66,12 +66,15 @@ const char *Mrk_HeadOrFootStr[2] = // Names of columns in database, so don't cha
|
||||||
"Footer",
|
"Footer",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define Mrk_MAX_BYTES_IN_CELL_CONTENT 1024 // Cell of a table containing one or several user's IDs
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************************** Internal prototypes *****************************/
|
/*************************** Internal prototypes *****************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void Mrk_GetNumRowsHeaderAndFooter (struct MarksProperties *Marks);
|
static void Mrk_GetNumRowsHeaderAndFooter (struct MarksProperties *Marks);
|
||||||
static void Mrk_ChangeNumRowsHeaderOrFooter (Brw_HeadOrFoot_t HeaderOrFooter);
|
static void Mrk_ChangeNumRowsHeaderOrFooter (Brw_HeadOrFoot_t HeaderOrFooter);
|
||||||
|
static bool Mrk_CheckIfCellContainsOnlyIDs (const char *CellContent);
|
||||||
static bool Mrk_GetUsrMarks (FILE *FileUsrMarks,struct UsrData *UsrDat,
|
static bool Mrk_GetUsrMarks (FILE *FileUsrMarks,struct UsrData *UsrDat,
|
||||||
const char *PathFileAllMarks,
|
const char *PathFileAllMarks,
|
||||||
struct MarksProperties *Marks);
|
struct MarksProperties *Marks);
|
||||||
|
@ -297,9 +300,11 @@ bool Mrk_CheckFileOfMarks (const char *Path,struct MarksProperties *Marks)
|
||||||
extern const char *Txt_There_are_more_than_one_table_in_the_file_of_marks;
|
extern const char *Txt_There_are_more_than_one_table_in_the_file_of_marks;
|
||||||
extern const char *Txt_Table_not_found_in_the_file_of_marks;
|
extern const char *Txt_Table_not_found_in_the_file_of_marks;
|
||||||
// extern const char *Txt_X_header_rows_Y_student_rows_and_Z_footer_rows_found;
|
// extern const char *Txt_X_header_rows_Y_student_rows_and_Z_footer_rows_found;
|
||||||
|
char CellContent[Mrk_MAX_BYTES_IN_CELL_CONTENT+1];
|
||||||
FILE *FileAllMarks;
|
FILE *FileAllMarks;
|
||||||
char StrRead[ID_MAX_LENGTH_USR_ID+1];
|
bool EndOfHead = false;
|
||||||
bool EndOfHead = false,EndOfTable = false,FileIsCorrect = true;
|
bool EndOfTable = false;
|
||||||
|
bool FileIsCorrect = true;
|
||||||
unsigned NumRowsStds = 0;
|
unsigned NumRowsStds = 0;
|
||||||
|
|
||||||
Marks->Header = Marks->Footer = 0;
|
Marks->Header = Marks->Footer = 0;
|
||||||
|
@ -329,41 +334,46 @@ bool Mrk_CheckFileOfMarks (const char *Path,struct MarksProperties *Marks)
|
||||||
/* We assume that the structure of the table has several rows of header until the first row of students is found,
|
/* We assume that the structure of the table has several rows of header until the first row of students is found,
|
||||||
then it has a number of rows of students, including some dummy rows without students,
|
then it has a number of rows of students, including some dummy rows without students,
|
||||||
and finally it has several rows of footer from the last row of students until the end of the table */
|
and finally it has several rows of footer from the last row of students until the end of the table */
|
||||||
/* Count rows of header */
|
|
||||||
|
/***** Count rows of header *****/
|
||||||
while (!EndOfHead)
|
while (!EndOfHead)
|
||||||
if (Str_FindStrInFile (FileAllMarks,"<tr",Str_NO_SKIP_HTML_COMMENTS)) // Go to the next row
|
if (Str_FindStrInFile (FileAllMarks,"<tr",Str_NO_SKIP_HTML_COMMENTS)) // Go to the next row
|
||||||
{
|
{
|
||||||
// Every user's ID must be in the first column of the row
|
// All user's IDs must be in the first column of the row
|
||||||
Str_GetCellFromHTMLTableSkipComments (FileAllMarks,StrRead,ID_MAX_LENGTH_USR_ID);
|
Str_GetCellFromHTMLTableSkipComments (FileAllMarks,CellContent,Mrk_MAX_BYTES_IN_CELL_CONTENT);
|
||||||
// Users' IDs are always stored internally in capitals and without leading zeros
|
|
||||||
Str_RemoveLeadingZeros (StrRead);
|
/* Check if only user's IDs
|
||||||
Str_ConvertToUpperText (StrRead);
|
or other stuff found in this table cell */
|
||||||
if (ID_CheckIfUsrIDIsValid (StrRead))
|
if (Mrk_CheckIfCellContainsOnlyIDs (CellContent))
|
||||||
{
|
{
|
||||||
EndOfHead = true;
|
// Only user's IDs found in this cell
|
||||||
NumRowsStds++;
|
EndOfHead = true;
|
||||||
}
|
NumRowsStds++;
|
||||||
else
|
}
|
||||||
Marks->Header++;
|
else
|
||||||
|
// Other stuff found ==> continue in header
|
||||||
|
Marks->Header++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EndOfHead = true; // No more rows
|
EndOfHead = true; // No more rows
|
||||||
|
|
||||||
/* Count rows of students and rows of footer */
|
/***** Count rows of students and rows of footer *****/
|
||||||
while (!EndOfTable)
|
while (!EndOfTable)
|
||||||
if (Str_FindStrInFile (FileAllMarks,"<tr",Str_NO_SKIP_HTML_COMMENTS)) // Go to the next row
|
if (Str_FindStrInFile (FileAllMarks,"<tr",Str_NO_SKIP_HTML_COMMENTS)) // Go to the next row
|
||||||
{
|
{
|
||||||
// Each user's ID must be in the first column of the row
|
// All user's IDs must be in the first column of the row
|
||||||
Str_GetCellFromHTMLTableSkipComments (FileAllMarks,StrRead,ID_MAX_LENGTH_USR_ID);
|
Str_GetCellFromHTMLTableSkipComments (FileAllMarks,CellContent,Mrk_MAX_BYTES_IN_CELL_CONTENT);
|
||||||
// Users' IDs are always stored internally in capitals and without leading zeros
|
|
||||||
Str_RemoveLeadingZeros (StrRead);
|
/* Check if only user's IDs
|
||||||
Str_ConvertToUpperText (StrRead);
|
or other stuff found in this table cell */
|
||||||
if (ID_CheckIfUsrIDIsValid (StrRead))
|
if (Mrk_CheckIfCellContainsOnlyIDs (CellContent))
|
||||||
{
|
{
|
||||||
|
// Only user's IDs found in this cell
|
||||||
NumRowsStds++;
|
NumRowsStds++;
|
||||||
Marks->Footer = 0;
|
Marks->Footer = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
// Other stuff found ==> continue in header
|
||||||
Marks->Footer++;
|
Marks->Footer++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -388,6 +398,38 @@ bool Mrk_CheckFileOfMarks (const char *Path,struct MarksProperties *Marks)
|
||||||
return FileIsCorrect;
|
return FileIsCorrect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/******* Check if only user's IDs or other stuff found in a table cell *******/
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static bool Mrk_CheckIfCellContainsOnlyIDs (const char *CellContent)
|
||||||
|
{
|
||||||
|
char UsrIDFromTable[ID_MAX_LENGTH_USR_ID+1];
|
||||||
|
const char *Ptr = CellContent;
|
||||||
|
bool UsrIDFound = false;
|
||||||
|
bool StuffNotUsrIDFound = false;
|
||||||
|
|
||||||
|
/***** Get strings in this table cell
|
||||||
|
and check if they look like user's IDs or not *****/
|
||||||
|
while (*Ptr && !StuffNotUsrIDFound)
|
||||||
|
{
|
||||||
|
/* Find next string in text until space, comma or semicolon (leading and trailing spaces are removed) */
|
||||||
|
Str_GetNextStringUntilSeparator (&Ptr,UsrIDFromTable,ID_MAX_LENGTH_USR_ID);
|
||||||
|
|
||||||
|
// Users' IDs are always stored internally in capitals and without leading zeros
|
||||||
|
Str_RemoveLeadingZeros (UsrIDFromTable);
|
||||||
|
Str_ConvertToUpperText (UsrIDFromTable);
|
||||||
|
if (ID_CheckIfUsrIDIsValid (UsrIDFromTable))
|
||||||
|
UsrIDFound = true;
|
||||||
|
else
|
||||||
|
StuffNotUsrIDFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***** Check if only user's IDs
|
||||||
|
or other stuff found in this table cell *****/
|
||||||
|
return (UsrIDFound && !StuffNotUsrIDFound);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/*************************** Show the marks of a user ************************/
|
/*************************** Show the marks of a user ************************/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -398,14 +440,15 @@ static bool Mrk_GetUsrMarks (FILE *FileUsrMarks,struct UsrData *UsrDat,
|
||||||
{
|
{
|
||||||
extern const char *Txt_THE_USER_X_is_not_found_in_the_file_of_marks;
|
extern const char *Txt_THE_USER_X_is_not_found_in_the_file_of_marks;
|
||||||
unsigned Row;
|
unsigned Row;
|
||||||
|
char CellContent[Mrk_MAX_BYTES_IN_CELL_CONTENT+1];
|
||||||
|
const char *Ptr;
|
||||||
char UsrIDFromTable[ID_MAX_LENGTH_USR_ID+1];
|
char UsrIDFromTable[ID_MAX_LENGTH_USR_ID+1];
|
||||||
FILE *FileAllMarks;
|
FILE *FileAllMarks;
|
||||||
unsigned NumID;
|
unsigned NumID;
|
||||||
const char *UsrID = NULL; // Initialized to avoid warning
|
bool UsrIDFound;
|
||||||
bool UsrIDFound = true;
|
bool EndOfTable;
|
||||||
bool EndOfTable = false;
|
|
||||||
|
|
||||||
/***** Open file with the table of marks *****/
|
/***** Open HTML file with the table of marks *****/
|
||||||
if (!(FileAllMarks = fopen (PathFileAllMarks,"rb")))
|
if (!(FileAllMarks = fopen (PathFileAllMarks,"rb")))
|
||||||
{ // Can't open the file with the table of marks
|
{ // Can't open the file with the table of marks
|
||||||
strcpy (Gbl.Message,"Can not open file of marks.");
|
strcpy (Gbl.Message,"Can not open file of marks.");
|
||||||
|
@ -428,26 +471,29 @@ static bool Mrk_GetUsrMarks (FILE *FileUsrMarks,struct UsrData *UsrDat,
|
||||||
while (!UsrIDFound && !EndOfTable)
|
while (!UsrIDFound && !EndOfTable)
|
||||||
if (Str_FindStrInFile (FileAllMarks,"<tr",Str_NO_SKIP_HTML_COMMENTS)) // Go to the next row
|
if (Str_FindStrInFile (FileAllMarks,"<tr",Str_NO_SKIP_HTML_COMMENTS)) // Go to the next row
|
||||||
{
|
{
|
||||||
// Each user's ID must be in the first column of the row
|
// All user's IDs must be in the first column of the row
|
||||||
Str_GetCellFromHTMLTableSkipComments (FileAllMarks,UsrIDFromTable,ID_MAX_LENGTH_USR_ID);
|
Str_GetCellFromHTMLTableSkipComments (FileAllMarks,CellContent,Mrk_MAX_BYTES_IN_CELL_CONTENT);
|
||||||
// Users' IDs are always stored internally in capitals and without leading zeros
|
|
||||||
Str_RemoveLeadingZeros (UsrIDFromTable);
|
/* Get user's IDs */
|
||||||
Str_ConvertToUpperText (UsrIDFromTable);
|
Ptr = CellContent;
|
||||||
if (ID_CheckIfUsrIDIsValid (UsrIDFromTable))
|
while (*Ptr && !UsrIDFound)
|
||||||
// A valid user's ID is found in the first column of table, and stored in UsrIDFromTable.
|
{
|
||||||
// Possible final alpha letter is removed from it. TODO: In future versions, final alpha letter should not be removed
|
/* Find next string in text until comma or semicolon (leading and trailing spaces are removed) */
|
||||||
{
|
Str_GetNextStringUntilSeparator (&Ptr,UsrIDFromTable,ID_MAX_LENGTH_USR_ID);
|
||||||
// Compare UsrIDFromTable with all the confirmed user's IDs in list
|
|
||||||
for (NumID = 0;
|
// Users' IDs are always stored internally in capitals and without leading zeros
|
||||||
NumID < UsrDat->IDs.Num && !UsrIDFound;
|
Str_RemoveLeadingZeros (UsrIDFromTable);
|
||||||
NumID++)
|
Str_ConvertToUpperText (UsrIDFromTable);
|
||||||
if (UsrDat->IDs.List[NumID].Confirmed)
|
if (ID_CheckIfUsrIDIsValid (UsrIDFromTable))
|
||||||
if (!strcasecmp (UsrDat->IDs.List[NumID].ID,UsrIDFromTable))
|
// A valid user's ID is found in the first column of table, and stored in UsrIDFromTable.
|
||||||
{
|
// Compare UsrIDFromTable with all the confirmed user's IDs in list
|
||||||
UsrIDFound = true;
|
for (NumID = 0;
|
||||||
UsrID = UsrDat->IDs.List[NumID].ID;
|
NumID < UsrDat->IDs.Num && !UsrIDFound;
|
||||||
}
|
NumID++)
|
||||||
}
|
if (UsrDat->IDs.List[NumID].Confirmed)
|
||||||
|
if (!strcasecmp (UsrDat->IDs.List[NumID].ID,UsrIDFromTable))
|
||||||
|
UsrIDFound = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EndOfTable = true; // No more rows
|
EndOfTable = true; // No more rows
|
||||||
|
@ -474,16 +520,29 @@ static bool Mrk_GetUsrMarks (FILE *FileUsrMarks,struct UsrData *UsrDat,
|
||||||
while (!UsrIDFound && !EndOfTable)
|
while (!UsrIDFound && !EndOfTable)
|
||||||
if (Str_FindStrInFile (FileAllMarks,"<tr",Str_NO_SKIP_HTML_COMMENTS)) // Go to the next row
|
if (Str_FindStrInFile (FileAllMarks,"<tr",Str_NO_SKIP_HTML_COMMENTS)) // Go to the next row
|
||||||
{
|
{
|
||||||
// Each user's ID must be in the first column of the row
|
// All user's IDs must be in the first column of the row
|
||||||
Str_GetCellFromHTMLTableSkipComments (FileAllMarks,UsrIDFromTable,ID_MAX_LENGTH_USR_ID);
|
Str_GetCellFromHTMLTableSkipComments (FileAllMarks,CellContent,Mrk_MAX_BYTES_IN_CELL_CONTENT);
|
||||||
// Users' IDs are always stored internally in capitals and without leading zeros
|
|
||||||
Str_RemoveLeadingZeros (UsrIDFromTable);
|
/* Get user's IDs */
|
||||||
Str_ConvertToUpperText (UsrIDFromTable);
|
Ptr = CellContent;
|
||||||
if (ID_CheckIfUsrIDIsValid (UsrIDFromTable))
|
while (*Ptr && !UsrIDFound)
|
||||||
// A valid user's ID is found in the first column of table, and stored in UsrIDFromTable.
|
{
|
||||||
// Possible final alpha letter is removed from it
|
/* Find next string in text until comma or semicolon (leading and trailing spaces are removed) */
|
||||||
if (!strcasecmp (UsrID,UsrIDFromTable))
|
Str_GetNextStringUntilSeparator (&Ptr,UsrIDFromTable,ID_MAX_LENGTH_USR_ID);
|
||||||
UsrIDFound = true;
|
|
||||||
|
// Users' IDs are always stored internally in capitals and without leading zeros
|
||||||
|
Str_RemoveLeadingZeros (UsrIDFromTable);
|
||||||
|
Str_ConvertToUpperText (UsrIDFromTable);
|
||||||
|
if (ID_CheckIfUsrIDIsValid (UsrIDFromTable))
|
||||||
|
// A valid user's ID is found in the first column of table, and stored in UsrIDFromTable.
|
||||||
|
// Compare UsrIDFromTable with all the confirmed user's IDs in list
|
||||||
|
for (NumID = 0;
|
||||||
|
NumID < UsrDat->IDs.Num && !UsrIDFound;
|
||||||
|
NumID++)
|
||||||
|
if (UsrDat->IDs.List[NumID].Confirmed)
|
||||||
|
if (!strcasecmp (UsrDat->IDs.List[NumID].ID,UsrIDFromTable))
|
||||||
|
UsrIDFound = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EndOfTable = true; // No more rows
|
EndOfTable = true; // No more rows
|
||||||
|
|
|
@ -1585,7 +1585,7 @@ static int Str_ReadCharAndSkipCommentsBackward (FILE *FileSrc,Str_SkipHTMLCommen
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/****** Scan next string in file FileSrc until find </td> *******/
|
/****** Scan next string in file FileSrc until find </td> *******/
|
||||||
/****** ( skipping comments <!--...-->, directives <...>, and ) *******/
|
/****** ( skipping comments <!--...--> and directives <...> ) *******/
|
||||||
/****** and write string into Str (MaxLength characters as much) *******/
|
/****** and write string into Str (MaxLength characters as much) *******/
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
@ -1596,6 +1596,7 @@ char *Str_GetCellFromHTMLTableSkipComments (FILE *FileSrc,char *Str,int MaxLengt
|
||||||
long PosTD;
|
long PosTD;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int Ch;
|
int Ch;
|
||||||
|
bool SpaceFound;
|
||||||
char StrAux[1+1]; // To find next "/td>" or "nbsp;"
|
char StrAux[1+1]; // To find next "/td>" or "nbsp;"
|
||||||
|
|
||||||
Str[0] = '\0';
|
Str[0] = '\0';
|
||||||
|
@ -1655,6 +1656,8 @@ char *Str_GetCellFromHTMLTableSkipComments (FILE *FileSrc,char *Str,int MaxLengt
|
||||||
break; // If it's </td>
|
break; // If it's </td>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpaceFound = false;
|
||||||
|
|
||||||
/***** Skip *****/
|
/***** Skip *****/
|
||||||
if (Ch == (int) '&')
|
if (Ch == (int) '&')
|
||||||
{
|
{
|
||||||
|
@ -1685,14 +1688,17 @@ char *Str_GetCellFromHTMLTableSkipComments (FILE *FileSrc,char *Str,int MaxLengt
|
||||||
Str_FindStrInFile (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Skip &
|
Str_FindStrInFile (FileSrc,"&",Str_NO_SKIP_HTML_COMMENTS); // Skip &
|
||||||
}
|
}
|
||||||
else // It's
|
else // It's
|
||||||
continue;
|
SpaceFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** Skip spaces *****/
|
/***** Skip spaces *****/
|
||||||
if (isspace (Ch) || Ch == 0xA0) // Microsoft Excel uses A0 also as space!
|
if (isspace (Ch) || Ch == 0xA0) // Microsoft Excel uses A0 also as space!
|
||||||
continue;
|
SpaceFound = true;
|
||||||
|
|
||||||
if (i < MaxLength) // && isprint (Ch))
|
if (SpaceFound)
|
||||||
|
Ch = (int) ' ';
|
||||||
|
|
||||||
|
if (i < MaxLength)
|
||||||
Str[i++] = (char) Ch;
|
Str[i++] = (char) Ch;
|
||||||
}
|
}
|
||||||
Str[i] = '\0';
|
Str[i] = '\0';
|
||||||
|
|
Loading…
Reference in New Issue