From: Wilfried Göesgens Date: Sun, 11 Jan 2009 20:17:57 +0000 (+0000) Subject: * complete the sorting api by non-room based preferences X-Git-Tag: v7.86~1624 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=59d57c03ddbfbb96ae3c5264176e6856b48f3f30 * complete the sorting api by non-room based preferences * add saving of sort orders to preferences * migrate sorting of users to new sorting API. --- diff --git a/webcit/downloads.c b/webcit/downloads.c index ea6ad4d9b..b26666744 100644 --- a/webcit/downloads.c +++ b/webcit/downloads.c @@ -211,7 +211,7 @@ HashList* LoadFileList(StrBuf *Target, WCTemplputParams *TP) Put(Files, SKEY(Entry->Filename), Entry, FreeFiles); } SubTP.ContextType = CTX_FILELIST; - SortIt = RetrieveSort(&SubTP, NULL, HKEY("fileunsorted"), 0); + SortIt = RetrieveSort(&SubTP, NULL, 0, HKEY("fileunsorted"), 0); if (SortIt != NULL) SortByPayload(Files, SortIt); else diff --git a/webcit/messages.c b/webcit/messages.c index 06a69f7b7..3e8d1d054 100644 --- a/webcit/messages.c +++ b/webcit/messages.c @@ -757,7 +757,7 @@ void readloop(long oper) memset(&SubTP, 0, sizeof(WCTemplputParams)); SubTP.ContextType = CTX_NONE; SubTP.Context = NULL; - SortIt = RetrieveSort(&SubTP, NULL, + SortIt = RetrieveSort(&SubTP, NULL, 0, HKEY("date"), defaultsortorder); if (SortIt != NULL) SortByPayload(WCC->summ, SortIt); diff --git a/webcit/preferences.c b/webcit/preferences.c index ad55f0483..e56100900 100644 --- a/webcit/preferences.c +++ b/webcit/preferences.c @@ -493,19 +493,53 @@ void set_PREF_YESNO(const char *key, size_t keylen, long value, int save_to_serv set_preference_backend(key, keylen, value, NULL, PRF_YESNO, save_to_server, NULL); } -int get_room_prefs_backend(const char *key, size_t keylen, Preference **Pref) +int get_room_prefs_backend(const char *key, size_t keylen, + Preference **Pref) { StrBuf *pref_name; int Ret; - pref_name = NewStrBuf (); - StrBufPrintf(pref_name, "%s:%s", key, ChrPtr(WC->wc_roomname)); + pref_name = NewStrBufPlain (HKEY("ROOM:")); + StrBufAppendBuf(pref_name, WC->wc_roomname, 0); + StrBufAppendBufPlain(pref_name, HKEY(":"), 0); + StrBufAppendBufPlain(pref_name, key, keylen, 0); Ret = get_pref_backend(SKEY(pref_name), Pref); FreeStrBuf(&pref_name); return Ret; } +const StrBuf *get_X_PREFS(const char *key, size_t keylen, + const char *xkey, size_t xkeylen) +{ + StrBuf *pref_name; + Preference *Prf; + + pref_name = NewStrBufPlain (HKEY("XPREF:")); + StrBufAppendBufPlain(pref_name, xkey, xkeylen, 0); + StrBufAppendBufPlain(pref_name, HKEY(":"), 0); + StrBufAppendBufPlain(pref_name, key, keylen, 0); + + get_pref_backend(SKEY(pref_name), &Prf); + FreeStrBuf(&pref_name); + + return Prf->Val; +} + +void set_X_PREFS(const char *key, size_t keylen, const char *xkey, size_t xkeylen, StrBuf *value, int save_to_server) +{ + StrBuf *pref_name; + + pref_name = NewStrBufPlain (HKEY("XPREF:")); + StrBufAppendBufPlain(pref_name, xkey, xkeylen, 0); + StrBufAppendBufPlain(pref_name, HKEY(":"), 0); + StrBufAppendBufPlain(pref_name, key, keylen, 0); + + set_preference_backend(SKEY(pref_name), 0, value, PRF_STRING, save_to_server, NULL); + FreeStrBuf(&pref_name); +} + + StrBuf *get_ROOM_PREFS(const char *key, size_t keylen) { Preference *Pref; @@ -524,8 +558,10 @@ void set_ROOM_PREFS(const char *key, size_t keylen, StrBuf *value, int save_to_s { StrBuf *pref_name; - pref_name = NewStrBuf (); - StrBufPrintf(pref_name, "%s:%s", key, ChrPtr(WC->wc_roomname)); + pref_name = NewStrBufPlain (HKEY("ROOM:")); + StrBufAppendBuf(pref_name, WC->wc_roomname, 0); + StrBufAppendBufPlain(pref_name, HKEY(":"), 0); + StrBufAppendBufPlain(pref_name, key, keylen, 0); set_preference_backend(SKEY(pref_name), 0, value, PRF_STRING, save_to_server, NULL); FreeStrBuf(&pref_name); } diff --git a/webcit/preferences.h b/webcit/preferences.h index 779ad3c2a..70db2e36c 100644 --- a/webcit/preferences.h +++ b/webcit/preferences.h @@ -38,3 +38,11 @@ StrBuf *get_ROOM_PREFS(const char *key, size_t keylen); #define set_room_pref(a, b, c) set_ROOM_PREFS(a, sizeof(a) - 1, b, c) void set_ROOM_PREFS(const char *key, size_t keylen, StrBuf *value, int save_to_server); + + +#define get_x_pref(a, b) get_ROOM_PREFS(a, sizeof(a) - 1, b, sizeof(b) - 1) +const StrBuf *get_X_PREFS(const char *key, size_t keylen, + const char *xkey, size_t xkeylen); + +#define set_x_pref(a, b, c) set_ROOM_PREFS(a, sizeof(a) - 1, b, sizeof(b) - 1, c, d) +void set_X_PREFS(const char *key, size_t keylen, const char *xkey, size_t xkeylen, StrBuf *value, int save_to_server); diff --git a/webcit/subst.c b/webcit/subst.c index 351793545..5259828cf 100644 --- a/webcit/subst.c +++ b/webcit/subst.c @@ -1799,7 +1799,8 @@ void RegisterSortFunc(const char *name, long len, Put(SortHash, name, len, NewSort, DestroySortStruct); } -CompareFunc RetrieveSort(WCTemplputParams *TP, const char *OtherPrefix, +CompareFunc RetrieveSort(WCTemplputParams *TP, + const char *OtherPrefix, long OtherPrefixLen, const char *Default, long ldefault, long DefaultDirection) { int isdefault = 0; @@ -1810,13 +1811,19 @@ CompareFunc RetrieveSort(WCTemplputParams *TP, const char *OtherPrefix, if (havebstr("SortBy")) { BSort = sbstr("SortBy"); + if (OtherPrefix == NULL) { + set_room_pref("sort", NewStrBufDup(BSort), 0); + } + else { + set_X_PREFS(HKEY("sort"), OtherPrefix, OtherPrefixLen, NewStrBufDup(BSort), 0); + } } else { /** Try to fallback to our remembered values... */ if (OtherPrefix == NULL) { BSort = get_room_pref("sort"); } else { - /*TODO: nail prefprepend to sort, and lookup this! */ + BSort = get_X_PREFS(HKEY("sort"), OtherPrefix, OtherPrefixLen); } if (BSort != NULL) putbstr("SortBy", NewStrBufDup(BSort)); @@ -1852,7 +1859,7 @@ CompareFunc RetrieveSort(WCTemplputParams *TP, const char *OtherPrefix, SortOrder = StrTol(Buf); } else { - /* TODO: nail prefprepend to sort, and lookup this! */ + BSort = get_X_PREFS(HKEY("SortOrder"), OtherPrefix, OtherPrefixLen); } if (Buf == NULL) @@ -1894,7 +1901,7 @@ ConstStr SortNextOrder[] = { }; -int GetSortMetric(WCTemplputParams *TP, SortStruct **Next, SortStruct **Param, long *SortOrder) +int GetSortMetric(WCTemplputParams *TP, SortStruct **Next, SortStruct **Param, long *SortOrder, int N) { int bSortError = eNOT_SPECIFIED; const StrBuf *BSort; @@ -1911,13 +1918,19 @@ int GetSortMetric(WCTemplputParams *TP, SortStruct **Next, SortStruct **Param, l if (havebstr("SortBy")) { BSort = sbstr("SortBy"); bSortError = eINVALID_PARAM; + if ((*Param)->PrefPrepend == NULL) { + set_room_pref("sort", NewStrBufDup(BSort), 0); + } + else { + set_X_PREFS(HKEY("sort"), TKEY(N), NewStrBufDup(BSort), 0); + } } else { /** Try to fallback to our remembered values... */ if ((*Param)->PrefPrepend == NULL) { BSort = get_room_pref("sort"); } else { - BSort = NULL;/* TODO: nail prefprepend to sort, and lookup this! */ + BSort = get_X_PREFS(HKEY("sort"), TKEY(N)); } } @@ -1936,7 +1949,7 @@ int GetSortMetric(WCTemplputParams *TP, SortStruct **Next, SortStruct **Param, l *SortOrder = StrTol(get_room_pref("SortOrder")); } else { - *SortOrder = 0;/* TODO: nail prefprepend to sort, and lookup this! */ + *SortOrder = StrTol(get_X_PREFS(HKEY("SortOrder"), TKEY(N))); } } if (*SortOrder > 2) @@ -1953,7 +1966,7 @@ void tmplput_SORT_ICON(StrBuf *Target, WCTemplputParams *TP) SortStruct *Param; const ConstStr *SortIcon; - switch (GetSortMetric(TP, &Next, &Param, &SortOrder)){ + switch (GetSortMetric(TP, &Next, &Param, &SortOrder, 2)){ case eNO_SUCH_SORT: LogTemplateError( Target, "Sorter", ERR_PARM1, TP, @@ -1982,7 +1995,7 @@ void tmplput_SORT_NEXT(StrBuf *Target, WCTemplputParams *TP) SortStruct *Next; SortStruct *Param; - switch (GetSortMetric(TP, &Next, &Param, &SortOrder)){ + switch (GetSortMetric(TP, &Next, &Param, &SortOrder, 2)){ case eNO_SUCH_SORT: LogTemplateError( Target, "Sorter", ERR_PARM1, TP, @@ -2008,7 +2021,7 @@ void tmplput_SORT_ORDER(StrBuf *Target, WCTemplputParams *TP) SortStruct *Next; SortStruct *Param; - switch (GetSortMetric(TP, &Next, &Param, &SortOrder)){ + switch (GetSortMetric(TP, &Next, &Param, &SortOrder, 2)){ case eNO_SUCH_SORT: LogTemplateError( Target, "Sorter", ERR_PARM1, TP, @@ -2113,9 +2126,9 @@ InitModule_SUBST (void) { memset(&NoCtx, 0, sizeof(WCTemplputParams)); - RegisterNamespace("SORT:ICON", 1, 1, tmplput_SORT_ICON, CTX_NONE); - RegisterNamespace("SORT:ORDER", 1, 1, tmplput_SORT_ORDER, CTX_NONE); - RegisterNamespace("SORT:NEXT", 1, 1, tmplput_SORT_NEXT, CTX_NONE); + RegisterNamespace("SORT:ICON", 1, 2, tmplput_SORT_ICON, CTX_NONE); + RegisterNamespace("SORT:ORDER", 1, 2, tmplput_SORT_ORDER, CTX_NONE); + RegisterNamespace("SORT:NEXT", 1, 2, tmplput_SORT_NEXT, CTX_NONE); RegisterNamespace("CONTEXTSTR", 0, 1, tmplput_ContextString, CTX_STRBUF); RegisterNamespace("ITERATE", 2, 100, tmpl_iterate_subtmpl, CTX_NONE); RegisterNamespace("DOBOXED", 1, 2, tmpl_do_boxed, CTX_NONE); diff --git a/webcit/subst.h b/webcit/subst.h index 2d669b3e9..fa599ebcb 100644 --- a/webcit/subst.h +++ b/webcit/subst.h @@ -173,8 +173,10 @@ void StrBufAppendTemplate(StrBuf *Target, WCTemplputParams *TP, const StrBuf *Source, int FormatTypeIndex); -CompareFunc RetrieveSort(WCTemplputParams *TP, const char *OtherPrefix, - const char *Default, long ldefault, long DefaultDirection); +CompareFunc RetrieveSort(WCTemplputParams *TP, + const char *OtherPrefix, long OtherPrefixLen, + const char *Default, long ldefault, + long DefaultDirection); void RegisterSortFunc(const char *name, long len, const char *prepend, long preplen, CompareFunc Forward, diff --git a/webcit/useredit.c b/webcit/useredit.c index f4f136ebb..37320a55d 100644 --- a/webcit/useredit.c +++ b/webcit/useredit.c @@ -93,16 +93,22 @@ UserListEntry* NewUserListEntry(StrBuf *SerializedUserList) */ int CompareUserListName(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return strcmp(ChrPtr(u1->UserName), ChrPtr(u2->UserName)); } int CompareUserListNameRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName)); +} +int GroupchangeUserListName(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName)); + return ChrPtr(u2->UserName)[0] != ChrPtr(u1->UserName)[0]; } /* @@ -110,17 +116,24 @@ int CompareUserListNameRev(const void *vUser1, const void *vUser2) */ int CompareAccessLevel(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->AccessLevel > u2->AccessLevel); } int CompareAccessLevelRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + + return (u2->AccessLevel > u1->AccessLevel); +} +int GroupchangeAccessLevel(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return (u2->AccessLevel > u1->AccessLevel); + return u2->AccessLevel != u1->AccessLevel; } @@ -129,17 +142,24 @@ int CompareAccessLevelRev(const void *vUser1, const void *vUser2) */ int CompareUID(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->UID > u2->UID); } int CompareUIDRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + + return (u2->UID > u1->UID); +} +int GroupchangeUID(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return (u2->UID > u1->UID); + return (u2->UID / 10) != (u1->UID / 10); } /* @@ -147,17 +167,24 @@ int CompareUIDRev(const void *vUser1, const void *vUser2) */ int CompareLastLogon(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->LastLogonT > u2->LastLogonT); } int CompareLastLogonRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + + return (u2->LastLogonT > u1->LastLogonT); +} +int GroupchangeLastLogon(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return (u2->LastLogonT > u1->LastLogonT); + return (u2->LastLogonT != u1->LastLogonT); } /* @@ -165,17 +192,24 @@ int CompareLastLogonRev(const void *vUser1, const void *vUser2) */ int ComparenLogons(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->nLogons > u2->nLogons); } int ComparenLogonsRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + + return (u2->nLogons > u1->nLogons); +} +int GroupchangenLogons(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return (u2->nLogons > u1->nLogons); + return (u2->nLogons / 100) != (u1->nLogons / 100); } /* @@ -183,31 +217,40 @@ int ComparenLogonsRev(const void *vUser1, const void *vUser2) */ int ComparenPosts(const void *vUser1, const void *vUser2) { - UserListEntry *u1 = (UserListEntry*) vUser1; - UserListEntry *u2 = (UserListEntry*) vUser2; + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); return (u1->nPosts > u2->nPosts); } int ComparenPostsRev(const void *vUser1, const void *vUser2) +{ + UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1); + UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2); + + return (u2->nPosts > u1->nPosts); +} +int GroupchangenPosts(const void *vUser1, const void *vUser2) { UserListEntry *u1 = (UserListEntry*) vUser1; UserListEntry *u2 = (UserListEntry*) vUser2; - return (u2->nPosts > u1->nPosts); + return (u2->nPosts / 100) != (u1->nPosts / 100); } HashList *iterate_load_userlist(StrBuf *Target, WCTemplputParams *TP) { + CompareFunc SortIt; HashList *Hash; char buf[SIZ]; StrBuf *Buf; UserListEntry* ul; char nnn[64]; int nUsed; - int Order; int len; - + WCTemplputParams SubTP; + + memset(&TP, 0, sizeof(WCTemplputParams)); serv_puts("LIST"); serv_getln(buf, sizeof buf); if (buf[0] == '1') { @@ -224,44 +267,12 @@ HashList *iterate_load_userlist(StrBuf *Target, WCTemplputParams *TP) Put(Hash, nnn, nUsed, ul, DeleteUserListEntry); } FreeStrBuf(&Buf); - Order = ibstr("SortOrder"); - switch (ibstr("SortBy")){ - case 1: /*NAME*/ - SortByPayload(Hash, (Order)? - CompareUserListName: - CompareUserListNameRev); - break; - case 2: /*AccessLevel*/ - SortByPayload(Hash, (Order)? - CompareAccessLevel: - CompareAccessLevelRev); - break; - case 3: /*nLogons*/ - SortByPayload(Hash, (Order)? - ComparenLogons: - ComparenLogonsRev); - break; - case 4: /*UID*/ - SortByPayload(Hash, (Order)? - CompareUID: - CompareUIDRev); - break; - case 5: /*LastLogon*/ - SortByPayload(Hash, (Order)? - CompareLastLogon: - CompareLastLogonRev); - break; - case 6: /* nLogons */ - SortByPayload(Hash, (Order)? - ComparenLogons: - ComparenLogonsRev); - break; - case 7: /* Posts */ - SortByPayload(Hash, (Order)? - ComparenPosts: - ComparenPostsRev); - break; - } + SubTP.ContextType = CTX_USERLIST; + SortIt = RetrieveSort(&SubTP, HKEY("USER"), HKEY("user:uid"), 0); + if (SortIt != NULL) + SortByPayload(Hash, SortIt); + else + SortByPayload(Hash, CompareUID); return Hash; } return NULL; @@ -691,4 +702,47 @@ InitModule_USEREDIT RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST); RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_NOFLAG); + + + RegisterSortFunc(HKEY("user:name"), + HKEY("userlist"), + CompareUserListName, + CompareUserListNameRev, + GroupchangeUserListName, + CTX_USERLIST); + RegisterSortFunc(HKEY("user:accslvl"), + HKEY("userlist"), + CompareAccessLevel, + CompareAccessLevelRev, + GroupchangeAccessLevel, + CTX_USERLIST); + + RegisterSortFunc(HKEY("user:nlogons"), + HKEY("userlist"), + ComparenLogons, + ComparenLogonsRev, + GroupchangenLogons, + CTX_USERLIST); + + RegisterSortFunc(HKEY("user:uid"), + HKEY("userlist"), + CompareUID, + CompareUIDRev, + GroupchangeUID, + CTX_USERLIST); + + RegisterSortFunc(HKEY("user:lastlogon"), + HKEY("userlist"), + CompareLastLogon, + CompareLastLogonRev, + GroupchangeLastLogon, + CTX_USERLIST); + + RegisterSortFunc(HKEY("user:nmsgposts"), + HKEY("userlist"), + ComparenPosts, + ComparenPostsRev, + GroupchangenPosts, + CTX_USERLIST); + }