Version 21.62: Nov 24, 2021 Code refactoring in photos.

This commit is contained in:
acanas 2021-11-24 20:54:54 +01:00
parent 401c38181b
commit b81c85b6ac
6 changed files with 387 additions and 437 deletions

View File

@ -602,13 +602,14 @@ TODO: FIX BUG, URGENT! En las fechas como par
TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo. TODO: En las encuestas, que los estudiantes no puedan ver los resultados hasta que no finalice el plazo.
*/ */
#define Log_PLATFORM_VERSION "SWAD 21.61 (2021-11-24)" #define Log_PLATFORM_VERSION "SWAD 21.62 (2021-11-24)"
#define CSS_FILE "swad21.59.css" #define CSS_FILE "swad21.59.css"
#define JS_FILE "swad21.59.js" #define JS_FILE "swad21.59.js"
/* /*
TODO: Rename CENTRE to CENTER in help wiki. TODO: Rename CENTRE to CENTER in help wiki.
TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams TODO: Rename ASSESSMENT.Announcements to ASSESSMENT.Calls_for_exams
Version 21.62: Nov 24, 2021 Code refactoring in photos. (319415 lines)
Version 21.61: Nov 24, 2021 User's photo is shown near a mention. (319454 lines) Version 21.61: Nov 24, 2021 User's photo is shown near a mention. (319454 lines)
Version 21.60.1: Nov 24, 2021 Code optimization in insertion of links in a string. (319233 lines) Version 21.60.1: Nov 24, 2021 Code optimization in insertion of links in a string. (319233 lines)
Version 21.60: Nov 24, 2021 Code refactoring inserting links in a string. (319208 lines) Version 21.60: Nov 24, 2021 Code refactoring inserting links in a string. (319208 lines)

View File

@ -90,10 +90,7 @@ bool Nck_CheckIfNickWithArrIsValid (const char *NickWithArr)
for (Ptr = CopyOfNick; // Leading arrobas already removed for (Ptr = CopyOfNick; // Leading arrobas already removed
*Ptr; *Ptr;
Ptr++) Ptr++)
if (!((*Ptr >= 'a' && *Ptr <= 'z') || if (!Str_ChIsAlphaNum (*Ptr))
(*Ptr >= 'A' && *Ptr <= 'Z') ||
(*Ptr >= '0' && *Ptr <= '9') ||
(*Ptr == '_')))
return false; return false;
return true; return true;

View File

@ -1034,12 +1034,13 @@ bool Pho_CheckIfPrivPhotoExists (long UsrCod,char PathPrivRelPhoto[PATH_MAX + 1]
} }
/*****************************************************************************/ /*****************************************************************************/
/*************************** Show a user's photo *****************************/ /********************* Build HTML code for user's photo **********************/
/*****************************************************************************/ /*****************************************************************************/
void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL, void Pho_BuildHTMLUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
const char *ClassPhoto,Pho_Zoom_t Zoom, const char *ClassPhoto,Pho_Zoom_t Zoom,
bool FormUnique) char **ImgStr,
char **CaptionStr)
{ {
extern const char *Rol_Icons[Rol_NUM_ROLES]; extern const char *Rol_Icons[Rol_NUM_ROLES];
extern const char *Txt_Following; extern const char *Txt_Following;
@ -1051,99 +1052,144 @@ void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
bool BrowserTabIs1stTab = (BrowserTab == Act_BRW_1ST_TAB || bool BrowserTabIs1stTab = (BrowserTab == Act_BRW_1ST_TAB ||
BrowserTab == Act_AJAX_NORMAL || BrowserTab == Act_AJAX_NORMAL ||
BrowserTab == Act_AJAX_RFRESH); BrowserTab == Act_AJAX_RFRESH);
bool PutLinkToPublicProfile = !Gbl.Form.Inside && // Only if not inside another form
BrowserTabIs1stTab; // Only in main browser tab (or AJAX)
bool PutZoomCode = (Zoom == Pho_ZOOM) && // Make zoom bool PutZoomCode = (Zoom == Pho_ZOOM) && // Make zoom
BrowserTabIs1stTab; // Only in main browser tab (or AJAX) BrowserTabIs1stTab; // Only in main browser tab (or AJAX)
char IdCaption[Frm_MAX_BYTES_ID + 1]; char IdCaption[Frm_MAX_BYTES_ID + 1];
char CtyName[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + 1];
struct Ins_Instit Ins;
char MainDegreeShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1]; char MainDegreeShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1];
Rol_Role_t MaxRole; // Maximum user's role in his/her main degree Rol_Role_t MaxRole; // Maximum user's role in his/her main degree
struct
/***** Begin form to go to public profile *****/
if (PutLinkToPublicProfile)
{ {
if (FormUnique) char *Name;
Frm_BeginFormUnique (ActSeeOthPubPrf); char *Nick;
else char *InsCty;
Frm_BeginForm (ActSeeOthPubPrf); char *MainDeg;
Usr_PutParamUsrCodEncrypted (UsrDat->EnUsrCod); char *Follow;
} Caption;
HTM_BUTTON_SUBMIT_Begin (NULL,"BT_LINK",NULL);
}
/***** Hidden div to pass user's name to Javascript *****/ /***** Hidden div to pass user's name to Javascript *****/
if (PutZoomCode) if (PutZoomCode)
{ {
Frm_SetUniqueId (IdCaption);
HTM_DIV_Begin ("id=\"%s\" class=\"NOT_SHOWN\"",IdCaption);
/* First name and surnames */ /* First name and surnames */
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_N_BOLD\""); // Limited width if (asprintf (&Caption.Name,"<div class=\"ZOOM_TXT_LINE DAT_N_BOLD\">" // Limited width
Usr_WriteFirstNameBRSurnames (UsrDat); "%s<br />"
HTM_DIV_End (); "%s%s%s"
"</div>",
UsrDat->FrstName,
UsrDat->Surname1,
UsrDat->Surname2[0] ? "&nbsp;" :
"",
UsrDat->Surname2[0] ? UsrDat->Surname2 :
"") < 0)
Err_NotEnoughMemoryExit ();
/* Nickname */ /* Nickname */
if (UsrDat->Nickname[0]) if (UsrDat->Nickname[0])
{ {
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_SMALL_N\""); if (asprintf (&Caption.Nick,"<div class=\"ZOOM_TXT_LINE DAT_SMALL_N\">"
HTM_TxtF ("@%s",UsrDat->Nickname); "@%s"
HTM_DIV_End (); "</div>",
UsrDat->Nickname) < 0)
Err_NotEnoughMemoryExit ();
} }
else if (asprintf (&Caption.Nick,"%s","") < 0)
Err_NotEnoughMemoryExit ();
/* Institution full name and institution country */ /* Institution full name and institution country */
if (UsrDat->InsCod > 0) if (UsrDat->InsCod > 0)
{ {
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_SMALL\""); /* Get institution short name and country name */
Ins_WriteInstitutionNameAndCty (UsrDat->InsCod); Ins.InsCod = UsrDat->InsCod;
HTM_DIV_End (); Ins_GetShrtNameAndCtyOfInstitution (&Ins,CtyName);
/* Write institution short name and country name */
if (asprintf (&Caption.InsCty,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
"%s&nbsp;(%s)"
"</div>",
Ins.ShrtName,CtyName) < 0)
Err_NotEnoughMemoryExit ();
} }
/* User's country */
else if (UsrDat->CtyCod > 0) else if (UsrDat->CtyCod > 0)
{ {
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_SMALL\""); /* Get country name */
Cty_WriteCountryName (UsrDat->CtyCod, Cty_GetCountryName (UsrDat->CtyCod,Gbl.Prefs.Language,CtyName);
NULL); // Don't put link to country
HTM_DIV_End (); /* Write country name */
if (asprintf (&Caption.InsCty,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
"%s"
"</div>",
CtyName) < 0)
Err_NotEnoughMemoryExit ();
} }
else if (asprintf (&Caption.InsCty,"%s","") < 0)
Err_NotEnoughMemoryExit ();
/* Main degree (in which the user has more courses) short name */ /* Main degree (in which the user has more courses) short name */
Deg_GetUsrMainDeg (UsrDat->UsrCod,MainDegreeShrtName,&MaxRole); Deg_GetUsrMainDeg (UsrDat->UsrCod,MainDegreeShrtName,&MaxRole);
if (MainDegreeShrtName[0]) if (MainDegreeShrtName[0])
{ {
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE DAT_SMALL\""); if (asprintf (&Caption.MainDeg,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
HTM_DIV_Begin ("class=\"ZOOM_DEG\" style=\"background-image:url('%s/%s');\"", "<div class=\"ZOOM_DEG\" style=\"background-image:url('%s/%s');\">"
Cfg_URL_ICON_PUBLIC,Rol_Icons[MaxRole]); "%s"
HTM_Txt (MainDegreeShrtName); "</div>"
HTM_DIV_End (); "</div>",
HTM_DIV_End (); Cfg_URL_ICON_PUBLIC,Rol_Icons[MaxRole],
MainDegreeShrtName) < 0)
Err_NotEnoughMemoryExit ();
} }
else if (asprintf (&Caption.MainDeg,"%s","") < 0)
Err_NotEnoughMemoryExit ();
/* Following and followers */ /* Following and followers */
if (UsrDat->Nickname[0]) // Get social data only if nickname is retrieved (in some actions) if (UsrDat->Nickname[0]) // Get social data only if nickname is retrieved (in some actions)
{ {
Fol_GetNumFollow (UsrDat->UsrCod,&NumFollowing,&NumFollowers); Fol_GetNumFollow (UsrDat->UsrCod,&NumFollowing,&NumFollowers);
HTM_DIV_Begin ("class=\"ZOOM_TXT_LINE\""); if (asprintf (&Caption.Follow,"<div class=\"ZOOM_TXT_LINE\">"
"<span class=\"DAT_N_BOLD\">"
HTM_SPAN_Begin ("class=\"DAT_N_BOLD\""); "%u"
HTM_Unsigned (NumFollowing); "</span>"
HTM_SPAN_End (); "<span class=\"DAT_SMALL\">"
"&nbsp;%s&nbsp;"
HTM_SPAN_Begin ("class=\"DAT_SMALL\""); "</span>"
HTM_TxtF ("&nbsp;%s&nbsp;",Txt_Following); "<span class=\"DAT_N_BOLD\">"
HTM_SPAN_End (); "%u"
"</span>"
HTM_SPAN_Begin ("class=\"DAT_N_BOLD\""); "<span class=\"DAT_SMALL\">"
HTM_Unsigned (NumFollowers); "&nbsp;%s"
HTM_SPAN_End (); "</span>"
"</div>",
HTM_SPAN_Begin ("class=\"DAT_SMALL\""); NumFollowing,
HTM_TxtF ("&nbsp;%s",Txt_Followers); Txt_Following,
HTM_SPAN_End (); NumFollowers,
Txt_Followers) < 0)
HTM_DIV_End (); Err_NotEnoughMemoryExit ();
} }
else if (asprintf (&Caption.Follow,"%s","") < 0)
Err_NotEnoughMemoryExit ();
HTM_DIV_End (); /* Hidden div */
Frm_SetUniqueId (IdCaption);
if (asprintf (CaptionStr,"<div id=\"%s\" class=\"NOT_SHOWN\">"
"%s%s%s%s%s"
"</div>",
IdCaption,
Caption.Name,
Caption.Nick,
Caption.InsCty,
Caption.MainDeg,
Caption.Follow) < 0)
Err_NotEnoughMemoryExit ();
free (Caption.Follow);
free (Caption.MainDeg);
free (Caption.InsCty);
free (Caption.Nick);
free (Caption.Name);
}
else
{
if (asprintf (CaptionStr,"%s","") < 0)
Err_NotEnoughMemoryExit ();
} }
/***** Image zoom *****/ /***** Image zoom *****/
@ -1154,33 +1200,85 @@ void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
if (PutZoomCode) if (PutZoomCode)
{ {
if (PhotoExists) if (PhotoExists)
HTM_IMG (PhotoURL,NULL,UsrDat->FullName, {
"class=\"%s\"" if (asprintf (ImgStr,"<img src=\"%s\" alt=\"\" title=\"%s\" class=\"%s\""
" onmouseover=\"zoom(this,'%s','%s');\"" " onmouseover=\"zoom(this,'%s','%s');\""
" onmouseout=\"noZoom();\"", " onmouseout=\"noZoom();\""
ClassPhoto,PhotoURL,IdCaption); " />",
PhotoURL,UsrDat->FullName,ClassPhoto,
PhotoURL,IdCaption) < 0)
Err_NotEnoughMemoryExit ();
}
else else
HTM_IMG (Cfg_URL_ICON_PUBLIC,"usr_bl.jpg",UsrDat->FullName, {
"class=\"%s\"" if (asprintf (ImgStr,"<img src=\"%s/usr_bl.jpg\" alt=\"\" title=\"%s\" class=\"%s\""
" onmouseover=\"zoom(this,'%s/usr_bl.jpg','%s');\"" " onmouseover=\"zoom(this,'%s/usr_bl.jpg','%s');\""
" onmouseout=\"noZoom();\"", " onmouseout=\"noZoom();\""
ClassPhoto,Cfg_URL_ICON_PUBLIC,IdCaption); " />",
Cfg_URL_ICON_PUBLIC,UsrDat->FullName,ClassPhoto,
Cfg_URL_ICON_PUBLIC,IdCaption) < 0)
Err_NotEnoughMemoryExit ();
}
} }
else else
{ {
if (PhotoExists) if (PhotoExists)
HTM_IMG (PhotoURL,NULL,UsrDat->FullName, {
"class=\"%s\"",ClassPhoto); if (asprintf (ImgStr,"<img src=\"%s\" alt=\"\" title=\"%s\" class=\"%s\" />",
else PhotoURL,UsrDat->FullName,ClassPhoto) < 0)
HTM_IMG (Cfg_URL_ICON_PUBLIC,"usr_bl.jpg",UsrDat->FullName, Err_NotEnoughMemoryExit ();
"class=\"%s\"",ClassPhoto);
} }
else
{
if (asprintf (ImgStr,"<img src=\"%s/usr_bl.jpg\" alt=\"\" title=\"%s\" class=\"%s\" />",
Cfg_URL_ICON_PUBLIC,UsrDat->FullName,ClassPhoto) < 0)
Err_NotEnoughMemoryExit ();
}
}
}
/*****************************************************************************/
/*************************** Show a user's photo *****************************/
/*****************************************************************************/
void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
const char *ClassPhoto,Pho_Zoom_t Zoom,
bool FormUnique)
{
Act_BrowserTab_t BrowserTab = Act_GetBrowserTab (Gbl.Action.Act);
bool BrowserTabIs1stTab = (BrowserTab == Act_BRW_1ST_TAB ||
BrowserTab == Act_AJAX_NORMAL ||
BrowserTab == Act_AJAX_RFRESH);
bool PutLinkToPublicProfile = !Gbl.Form.Inside && // Only if not inside another form
BrowserTabIs1stTab; // Only in main browser tab (or AJAX)
char *CaptionStr;
char *ImgStr;
/***** Begin form to go to public profile *****/
if (PutLinkToPublicProfile)
{
if (FormUnique)
Frm_BeginFormUnique (ActSeeOthPubPrf);
else
Frm_BeginForm (ActSeeOthPubPrf);
Usr_PutParamUsrCodEncrypted (UsrDat->EnUsrCod);
HTM_BUTTON_SUBMIT_Begin (NULL,"BT_LINK",NULL);
}
/***** Hidden div to pass user's name to Javascript *****/
Pho_BuildHTMLUsrPhoto (UsrDat,PhotoURL,
ClassPhoto,Zoom,
&CaptionStr,
&ImgStr);
HTM_Txt (CaptionStr);
HTM_Txt (ImgStr);
free (ImgStr);
free (CaptionStr);
/***** End form to go to public profile *****/ /***** End form to go to public profile *****/
if (PutLinkToPublicProfile) if (PutLinkToPublicProfile)
{ {
HTM_BUTTON_End (); HTM_BUTTON_End ();
Frm_EndForm (); Frm_EndForm ();
} }
} }

View File

@ -122,6 +122,10 @@ bool Pho_ShowingUsrPhotoIsAllowed (struct UsrData *UsrDat,
char PhotoURL[PATH_MAX + 1]); char PhotoURL[PATH_MAX + 1]);
bool Pho_BuildLinkToPhoto (const struct UsrData *UsrDat,char PhotoURL[PATH_MAX + 1]); bool Pho_BuildLinkToPhoto (const struct UsrData *UsrDat,char PhotoURL[PATH_MAX + 1]);
bool Pho_CheckIfPrivPhotoExists (long UsrCod,char PathPrivRelPhoto[PATH_MAX + 1]); bool Pho_CheckIfPrivPhotoExists (long UsrCod,char PathPrivRelPhoto[PATH_MAX + 1]);
void Pho_BuildHTMLUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
const char *ClassPhoto,Pho_Zoom_t Zoom,
char **ImgStr,
char **CaptionStr);
void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL, void Pho_ShowUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
const char *ClassPhoto,Pho_Zoom_t Zoom, const char *ClassPhoto,Pho_Zoom_t Zoom,
bool FormUnique); bool FormUnique);

View File

@ -35,15 +35,13 @@
#include <string.h> // For string functions #include <string.h> // For string functions
#include "swad_error.h" #include "swad_error.h"
#include "swad_follow.h" // TODO: Remove?
#include "swad_form.h" #include "swad_form.h"
#include "swad_global.h" #include "swad_global.h"
#include "swad_ID.h" #include "swad_ID.h"
#include "swad_institution.h" // TODO: Remove?
#include "swad_nickname_database.h" #include "swad_nickname_database.h"
#include "swad_notification_database.h" #include "swad_notification_database.h"
#include "swad_parameter.h" #include "swad_parameter.h"
#include "swad_photo.h" // TODO: Remove? #include "swad_photo.h"
#include "swad_string.h" #include "swad_string.h"
/*****************************************************************************/ /*****************************************************************************/
@ -93,18 +91,14 @@ static void Str_CreateFirstLink (struct Str_Link **Link,
static void Str_CreateNextLink (struct Str_Link **Link, static void Str_CreateNextLink (struct Str_Link **Link,
struct Str_Link **LastLink); struct Str_Link **LastLink);
static void Str_FreeLinks (struct Str_Link *LastLink); static void Str_FreeLinks (struct Str_Link *LastLink);
static Str_LinkType_t Str_CheckURL (char **PtrSrc, static Str_LinkType_t Str_CheckURL (char **PtrSrc,char PrevCh,
struct Str_Link **Link, struct Str_Link **Link,
struct Str_Link **LastLink, struct Str_Link **LastLink,
size_t MaxCharsURLOnScreen); size_t MaxCharsURLOnScreen);
static Str_LinkType_t Str_CheckNickname (char **PtrSrc, static Str_LinkType_t Str_CheckNickname (char **PtrSrc,char PrevCh,
struct Str_Link **Link, struct Str_Link **Link,
struct Str_Link **LastLink); struct Str_Link **LastLink);
static void Str_CopySubstring (const struct Str_Substring *PtrSrc,char **PtrDst); static void Str_CopySubstring (const struct Str_Substring *PtrSrc,char **PtrDst);
static void Str_GetUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL,
const char *ClassPhoto,
char **CaptionStr,
char **ImgStr);
static unsigned Str_GetNextASCIICharFromStr (const char *Ptr,unsigned char *Ch); static unsigned Str_GetNextASCIICharFromStr (const char *Ptr,unsigned char *Ch);
@ -193,6 +187,7 @@ static const struct Str_Substring NickAnchor3 =
void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScreen) void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScreen)
{ {
size_t TxtLength; size_t TxtLength;
char PrevCh = '\0';
char *PtrSrc; char *PtrSrc;
char *PtrDst; char *PtrDst;
struct Str_Link *Link; struct Str_Link *Link;
@ -212,14 +207,17 @@ void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScre
for (PtrSrc = Txt; for (PtrSrc = Txt;
*PtrSrc;) *PtrSrc;)
/* Check if the next char is the start of a URL */ /* Check if the next char is the start of a URL */
if ((Link->Type = Str_CheckURL (&PtrSrc, if ((Link->Type = Str_CheckURL (&PtrSrc,PrevCh,
&Link,&LastLink, &Link,&LastLink,
MaxCharsURLOnScreen)) == Str_LINK_UNKNOWN) MaxCharsURLOnScreen)) == Str_LINK_UNKNOWN)
/* Check if the next char is the start of a nickname */ /* Check if the next char is the start of a nickname */
if ((Link->Type = Str_CheckNickname (&PtrSrc, if ((Link->Type = Str_CheckNickname (&PtrSrc,PrevCh,
&Link,&LastLink)) == Str_LINK_UNKNOWN) &Link,&LastLink)) == Str_LINK_UNKNOWN)
{
/* The next char is not the start of a URL or a nickname */ /* The next char is not the start of a URL or a nickname */
PrevCh = *PtrSrc;
PtrSrc++; PtrSrc++;
}
/**********************************************************************/ /**********************************************************************/
/***** If there are one or more links (URLs or nicknames) in text *****/ /***** If there are one or more links (URLs or nicknames) in text *****/
@ -373,7 +371,7 @@ static void Str_FreeLinks (struct Str_Link *LastLink)
/**************************** Check if a URL found ***************************/ /**************************** Check if a URL found ***************************/
static Str_LinkType_t Str_CheckURL (char **PtrSrc, static Str_LinkType_t Str_CheckURL (char **PtrSrc,char PrevCh,
struct Str_Link **Link, struct Str_Link **Link,
struct Str_Link **LastLink, struct Str_Link **LastLink,
size_t MaxCharsURLOnScreen) size_t MaxCharsURLOnScreen)
@ -387,6 +385,7 @@ static Str_LinkType_t Str_CheckURL (char **PtrSrc,
/***** Check if the next char is the start of a URL *****/ /***** Check if the next char is the start of a URL *****/
if (tolower ((int) *(*PtrSrc)) == (int) 'h') if (tolower ((int) *(*PtrSrc)) == (int) 'h')
if (!Str_ChIsAlphaNum (PrevCh))
{ {
(*Link)->URLorNick.Str = (*PtrSrc); (*Link)->URLorNick.Str = (*PtrSrc);
if (tolower ((int) *++(*PtrSrc)) == (int) 't') // ht... if (tolower ((int) *++(*PtrSrc)) == (int) 't') // ht...
@ -441,7 +440,8 @@ static Str_LinkType_t Str_CheckURL (char **PtrSrc,
} }
/***** Compute number of bytes added until here *****/ /***** Compute number of bytes added until here *****/
(*Link)->AddedLengthUntilHere = (*Link)->Prev ? (*Link)->Prev->AddedLengthUntilHere : 0; (*Link)->AddedLengthUntilHere = (*Link)->Prev ? (*Link)->Prev->AddedLengthUntilHere :
0;
(*Link)->URLorNick.Len = (size_t) (PtrEnd + 1 - (*Link)->URLorNick.Str); (*Link)->URLorNick.Len = (size_t) (PtrEnd + 1 - (*Link)->URLorNick.Str);
if ((*Link)->URLorNick.Len <= MaxCharsURLOnScreen) if ((*Link)->URLorNick.Len <= MaxCharsURLOnScreen)
(*Link)->AddedLengthUntilHere += URL_ANCHOR_TOTAL_LENGTH + (*Link)->AddedLengthUntilHere += URL_ANCHOR_TOTAL_LENGTH +
@ -467,11 +467,12 @@ static Str_LinkType_t Str_CheckURL (char **PtrSrc,
/************************* Check if a nickname found *************************/ /************************* Check if a nickname found *************************/
static Str_LinkType_t Str_CheckNickname (char **PtrSrc, static Str_LinkType_t Str_CheckNickname (char **PtrSrc,char PrevCh,
struct Str_Link **Link, struct Str_Link **Link,
struct Str_Link **LastLink) struct Str_Link **LastLink)
{ {
extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES]; extern const char *Lan_STR_LANG_ID[1 + Lan_NUM_LANGUAGES];
char Ch;
size_t Length; size_t Length;
char ParamsStr[Frm_MAX_BYTES_PARAMS_STR]; char ParamsStr[Frm_MAX_BYTES_PARAMS_STR];
struct UsrData UsrDat; struct UsrData UsrDat;
@ -480,10 +481,14 @@ static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
char *CaptionStr; char *CaptionStr;
char *ImgStr; char *ImgStr;
char NickWithoutArr[Nck_MAX_BYTES_NICK_WITHOUT_ARROBA + 1]; char NickWithoutArr[Nck_MAX_BYTES_NICK_WITHOUT_ARROBA + 1];
bool NickSeemsValid;
Str_LinkType_t Type = Str_LINK_UNKNOWN; Str_LinkType_t Type = Str_LINK_UNKNOWN;
/***** Check if the next char is the start of a nickname *****/ /***** Check if the next char is the start of a nickname *****/
if ((int) *(*PtrSrc) == (int) '@') Ch = *(*PtrSrc);
if (Ch == '@') // Current is @
if (!Str_ChIsAlphaNum (PrevCh)) // Previous is not alphanumeric
if (Str_ChIsAlphaNum (*((*PtrSrc) + 1))) // Next is alphanumeric
{ {
(*Link)->URLorNick.Str = (*PtrSrc); (*Link)->URLorNick.Str = (*PtrSrc);
@ -494,11 +499,11 @@ static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
for (; for (;
*(*PtrSrc); *(*PtrSrc);
(*PtrSrc)++) (*PtrSrc)++)
if (!((*(*PtrSrc) >= 'a' && *(*PtrSrc) <= 'z') || {
(*(*PtrSrc) >= 'A' && *(*PtrSrc) <= 'Z') || Ch = *(*PtrSrc);
(*(*PtrSrc) >= '0' && *(*PtrSrc) <= '9') || if (!Str_ChIsAlphaNum (Ch))
(*(*PtrSrc) == '_')))
break; break;
}
/***** Calculate length of this nickname *****/ /***** Calculate length of this nickname *****/
(*Link)->URLorNick.Len = (size_t) ((*PtrSrc) - (*Link)->URLorNick.Str); (*Link)->URLorNick.Len = (size_t) ((*PtrSrc) - (*Link)->URLorNick.Str);
@ -506,24 +511,25 @@ static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
/***** A nick (without arroba) must have a number of characters /***** A nick (without arroba) must have a number of characters
Nck_MIN_CHARS_NICK_WITHOUT_ARROBA <= Length <= Nck_MAX_CHARS_NICK_WITHOUT_ARROBA *****/ Nck_MIN_CHARS_NICK_WITHOUT_ARROBA <= Length <= Nck_MAX_CHARS_NICK_WITHOUT_ARROBA *****/
Length = (*Link)->URLorNick.Len - 1; // Do not count the initial @ Length = (*Link)->URLorNick.Len - 1; // Do not count the initial @
if (Length >= Nck_MIN_CHARS_NICK_WITHOUT_ARROBA && NickSeemsValid = Length >= Nck_MIN_CHARS_NICK_WITHOUT_ARROBA &&
Length <= Nck_MAX_CHARS_NICK_WITHOUT_ARROBA) Length <= Nck_MAX_CHARS_NICK_WITHOUT_ARROBA;
if (NickSeemsValid)
{ {
/***** Get user's code using nickname *****/
Usr_UsrDataConstructor (&UsrDat);
strncpy (NickWithoutArr,(*Link)->URLorNick.Str + 1,Length); strncpy (NickWithoutArr,(*Link)->URLorNick.Str + 1,Length);
NickWithoutArr[Length] = '\0'; NickWithoutArr[Length] = '\0';
if ((UsrDat.UsrCod = Nck_DB_GetUsrCodFromNickname (NickWithoutArr)) > 0)
{
Type = Str_LINK_NICK; Type = Str_LINK_NICK;
Usr_GetUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS);
} }
if (Type == Str_LINK_NICK) if (Type == Str_LINK_NICK)
{ {
/***** Get user's code using nickname *****/
Usr_UsrDataConstructor (&UsrDat);
UsrDat.UsrCod = Nck_DB_GetUsrCodFromNickname (NickWithoutArr);
if (UsrDat.UsrCod > 0)
Usr_GetUsrDataFromUsrCod (&UsrDat,
Usr_DONT_GET_PREFS,
Usr_DONT_GET_ROLE_IN_CURRENT_CRS);
/***** Reset anchors (checked on freeing) *****/ /***** Reset anchors (checked on freeing) *****/
(*Link)->Nick.Anchor1.Str = (*Link)->Nick.Anchor1.Str =
(*Link)->Nick.Anchor2.Str = (*Link)->Nick.Anchor2.Str =
@ -564,14 +570,13 @@ static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
/***** Store third part of anchor *****/ /***** Store third part of anchor *****/
ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&UsrDat,PhotoURL); ShowPhoto = Pho_ShowingUsrPhotoIsAllowed (&UsrDat,PhotoURL);
Str_GetUsrPhoto (&UsrDat,ShowPhoto ? PhotoURL : Pho_BuildHTMLUsrPhoto (&UsrDat,ShowPhoto ? PhotoURL :
NULL, NULL,
"PHOTO15x20", "PHOTO15x20",Pho_ZOOM,
&CaptionStr, &CaptionStr,
&ImgStr); &ImgStr);
if (asprintf (&(*Link)->Nick.Anchor3.Str, if (asprintf (&(*Link)->Nick.Anchor3.Str,
"</a></form>" "</a></form>%s%s",
"%s%s",
CaptionStr, CaptionStr,
ImgStr) < 0) ImgStr) < 0)
Err_NotEnoughMemoryExit (); Err_NotEnoughMemoryExit ();
@ -583,7 +588,8 @@ static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
Usr_UsrDataDestructor (&UsrDat); Usr_UsrDataDestructor (&UsrDat);
/***** Compute number of bytes added until here *****/ /***** Compute number of bytes added until here *****/
(*Link)->AddedLengthUntilHere = (*Link)->Prev ? (*Link)->Prev->AddedLengthUntilHere : 0; (*Link)->AddedLengthUntilHere = (*Link)->Prev ? (*Link)->Prev->AddedLengthUntilHere :
0;
(*Link)->AddedLengthUntilHere += (*Link)->Nick.Anchor1.Len + (*Link)->AddedLengthUntilHere += (*Link)->Nick.Anchor1.Len +
(*Link)->URLorNick.Len + (*Link)->URLorNick.Len +
(*Link)->Nick.Anchor2.Len + (*Link)->Nick.Anchor2.Len +
@ -593,6 +599,7 @@ static Str_LinkType_t Str_CheckNickname (char **PtrSrc,
Str_CreateNextLink (Link,LastLink); Str_CreateNextLink (Link,LastLink);
} }
} }
}
return Type; return Type;
} }
@ -638,175 +645,15 @@ static void Str_CopySubstring (const struct Str_Substring *Src,char **Dst)
} }
/*****************************************************************************/ /*****************************************************************************/
/*************************** Show a user's photo *****************************/ /*********** Check if a character is in set { a-z, A-Z, 0-9, _ } *************/
/*****************************************************************************/ /*****************************************************************************/
static void Str_GetUsrPhoto (const struct UsrData *UsrDat,const char *PhotoURL, bool Str_ChIsAlphaNum (char Ch)
const char *ClassPhoto,
char **CaptionStr,
char **ImgStr)
{ {
extern const char *Rol_Icons[Rol_NUM_ROLES]; return ((Ch >= 'a' && Ch <= 'z') ||
extern const char *Txt_Following; (Ch >= 'A' && Ch <= 'Z') ||
extern const char *Txt_Followers; (Ch >= '0' && Ch <= '9') ||
unsigned NumFollowing; (Ch == '_'));
unsigned NumFollowers;
bool PhotoExists;
char IdCaption[Frm_MAX_BYTES_ID + 1];
char CtyName[Cns_HIERARCHY_MAX_BYTES_FULL_NAME + 1];
struct Ins_Instit Ins;
char MainDegreeShrtName[Cns_HIERARCHY_MAX_BYTES_SHRT_NAME + 1];
Rol_Role_t MaxRole; // Maximum user's role in his/her main degree
struct
{
char *Name;
char *Nick;
char *InsCty;
char *MainDeg;
char *Follow;
} Caption;
/***** First name and surnames *****/
if (asprintf (&Caption.Name,"<div class=\"ZOOM_TXT_LINE DAT_N_BOLD\">" // Limited width
"%s<br />"
"%s%s%s"
"</div>",
UsrDat->FrstName,
UsrDat->Surname1,
UsrDat->Surname2[0] ? "&nbsp;" :
"",
UsrDat->Surname2[0] ? UsrDat->Surname2 :
"") < 0)
Err_NotEnoughMemoryExit ();
/***** Nickname *****/
if (UsrDat->Nickname[0])
{
if (asprintf (&Caption.Nick,"<div class=\"ZOOM_TXT_LINE DAT_SMALL_N\">"
"@%s"
"</div>",
UsrDat->Nickname) < 0)
Err_NotEnoughMemoryExit ();
}
else if (asprintf (&Caption.Nick,"%s","") < 0)
Err_NotEnoughMemoryExit ();
/***** Institution full name and institution country *****/
if (UsrDat->InsCod > 0)
{
/***** Get institution short name and country name *****/
Ins.InsCod = UsrDat->InsCod;
Ins_GetShrtNameAndCtyOfInstitution (&Ins,CtyName);
/***** Write institution short name and country name *****/
if (asprintf (&Caption.InsCty,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
"%s&nbsp;(%s)"
"</div>",
Ins.ShrtName,CtyName) < 0)
Err_NotEnoughMemoryExit ();
}
else if (UsrDat->CtyCod > 0)
{
/***** Get country name *****/
Cty_GetCountryName (UsrDat->CtyCod,Gbl.Prefs.Language,CtyName);
/***** Write country name *****/
if (asprintf (&Caption.InsCty,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
"%s"
"</div>",
CtyName) < 0)
Err_NotEnoughMemoryExit ();
}
else if (asprintf (&Caption.InsCty,"%s","") < 0)
Err_NotEnoughMemoryExit ();
/***** Main degree (in which the user has more courses) short name *****/
Deg_GetUsrMainDeg (UsrDat->UsrCod,MainDegreeShrtName,&MaxRole);
if (MainDegreeShrtName[0])
{
if (asprintf (&Caption.MainDeg,"<div class=\"ZOOM_TXT_LINE DAT_SMALL\">"
"<div class=\"ZOOM_DEG\" style=\"background-image:url('%s/%s');\">"
"%s"
"</div>"
"</div>",
Cfg_URL_ICON_PUBLIC,Rol_Icons[MaxRole],
MainDegreeShrtName) < 0)
Err_NotEnoughMemoryExit ();
}
else if (asprintf (&Caption.MainDeg,"%s","") < 0)
Err_NotEnoughMemoryExit ();
/***** Following and followers *****/
if (UsrDat->Nickname[0]) // Get social data only if nickname is retrieved (in some actions)
{
Fol_GetNumFollow (UsrDat->UsrCod,&NumFollowing,&NumFollowers);
if (asprintf (&Caption.Follow,"<div class=\"ZOOM_TXT_LINE\">"
"<span class=\"DAT_N_BOLD\">"
"%u"
"</span>"
"<span class=\"DAT_SMALL\">"
"&nbsp;%s&nbsp;"
"</span>"
"<span class=\"DAT_N_BOLD\">"
"%u"
"</span>"
"<span class=\"DAT_SMALL\">"
"&nbsp;%s"
"</span>"
"</div>",
NumFollowing,
Txt_Following,
NumFollowers,
Txt_Followers) < 0)
Err_NotEnoughMemoryExit ();
}
else if (asprintf (&Caption.Follow,"%s","") < 0)
Err_NotEnoughMemoryExit ();
/***** Hidden div *****/
Frm_SetUniqueId (IdCaption);
if (asprintf (CaptionStr,"<div id=\"%s\" class=\"NOT_SHOWN\">"
"%s%s%s%s%s"
"</div>",
IdCaption,
Caption.Name,
Caption.Nick,
Caption.InsCty,
Caption.MainDeg,
Caption.Follow) < 0)
Err_NotEnoughMemoryExit ();
free (Caption.Follow);
free (Caption.MainDeg);
free (Caption.InsCty);
free (Caption.Nick);
free (Caption.Name);
/***** Image zoom *****/
PhotoExists = false;
if (PhotoURL)
if (PhotoURL[0])
PhotoExists = true;
if (PhotoExists)
{
if (asprintf (ImgStr,"<img src=\"%s\" alt=\"%s\" title=\"%s\" class=\"%s\""
" onmouseover=\"zoom(this,'%s','%s');\""
" onmouseout=\"noZoom();\""
" />",
PhotoURL,UsrDat->FullName,UsrDat->FullName,ClassPhoto,
PhotoURL,IdCaption) < 0)
Err_NotEnoughMemoryExit ();
}
else
{
if (asprintf (ImgStr,"<img src=\"%s/usr_bl.jpg\" alt=\"%s\" title=\"%s\" class=\"%s\""
" onmouseover=\"zoom(this,'%s/usr_bl.jpg','%s');\""
" onmouseout=\"noZoom();\""
" />",
Cfg_URL_ICON_PUBLIC,UsrDat->FullName,UsrDat->FullName,ClassPhoto,
Cfg_URL_ICON_PUBLIC,IdCaption) < 0)
Err_NotEnoughMemoryExit ();
}
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -83,6 +83,9 @@ typedef enum
/*****************************************************************************/ /*****************************************************************************/
void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScreen); void Str_InsertLinks (char *Txt,unsigned long MaxLength,size_t MaxCharsURLOnScreen);
bool Str_ChIsAlphaNum (char Ch);
size_t Str_LimitLengthHTMLStr (char *Str,size_t MaxCharsOnScreen); size_t Str_LimitLengthHTMLStr (char *Str,size_t MaxCharsOnScreen);
void Str_AnalyzeTxtAndStoreNotifyEventToMentionedUsrs (long PubCod,const char *Txt); void Str_AnalyzeTxtAndStoreNotifyEventToMentionedUsrs (long PubCod,const char *Txt);