From 4dfb651da5b56f3d2839f96dd574a5bc3de115cd Mon Sep 17 00:00:00 2001 From: Silvan Calarco Date: Tue, 15 Oct 2013 00:12:47 +0200 Subject: [PATCH] distroquery: files search and results pagination support --- po/distromatic.pot | 64 ++++++++++-------- po/it.gmo | Bin 1762 -> 1869 bytes po/it.po | 64 ++++++++++-------- src/distroquery.c | 159 +++++++++++++++++++++++++++++++++++++-------- 4 files changed, 204 insertions(+), 83 deletions(-) diff --git a/po/distromatic.pot b/po/distromatic.pot index 03d9a78..b065960 100644 --- a/po/distromatic.pot +++ b/po/distromatic.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: distromatic 1.4.1\n" "Report-Msgid-Bugs-To: silvan.calarco@mambasoft.it\n" -"POT-Creation-Date: 2013-10-14 12:08+0200\n" +"POT-Creation-Date: 2013-10-15 00:07+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,112 +17,120 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: src/distroquery.c:178 +#: src/distroquery.c:181 msgid "Source" msgstr "" -#: src/distroquery.c:204 +#: src/distroquery.c:225 msgid "Search" msgstr "" -#: src/distroquery.c:238 +#: src/distroquery.c:259 msgid "sources" msgstr "" -#: src/distroquery.c:249 +#: src/distroquery.c:270 msgid "Search software packages" msgstr "" -#: src/distroquery.c:354 src/distroquery.c:557 src/distroquery.c:702 +#: src/distroquery.c:374 src/distroquery.c:639 src/distroquery.c:807 msgid "Download" msgstr "" -#: src/distroquery.c:363 +#: src/distroquery.c:383 msgid "Details" msgstr "" -#: src/distroquery.c:380 +#: src/distroquery.c:401 src/distroquery.c:436 #, c-format msgid "Other results in " msgstr "" -#: src/distroquery.c:381 +#: src/distroquery.c:402 src/distroquery.c:437 #, c-format msgid "Results in" msgstr "" -#: src/distroquery.c:384 +#: src/distroquery.c:405 src/distroquery.c:440 msgid "for arch " msgstr "" -#: src/distroquery.c:393 +#: src/distroquery.c:414 msgid "provides" msgstr "" -#: src/distroquery.c:456 +#: src/distroquery.c:449 +msgid "provides file " +msgstr "" + +#: src/distroquery.c:516 msgid "result(s) shown" msgstr "" -#: src/distroquery.c:459 +#: src/distroquery.c:534 msgid "Search results for" msgstr "" -#: src/distroquery.c:523 src/distroquery.c:666 +#: src/distroquery.c:604 src/distroquery.c:769 msgid "Version" msgstr "" -#: src/distroquery.c:528 +#: src/distroquery.c:609 msgid "Size" msgstr "" -#: src/distroquery.c:531 +#: src/distroquery.c:612 msgid "Related packages" msgstr "" -#: src/distroquery.c:559 src/distroquery.c:704 +#: src/distroquery.c:641 src/distroquery.c:809 msgid "Developers details" msgstr "" -#: src/distroquery.c:561 +#: src/distroquery.c:643 msgid "Source package" msgstr "" -#: src/distroquery.c:567 src/distroquery.c:705 +#: src/distroquery.c:649 src/distroquery.c:810 msgid "Maintainer" msgstr "" -#: src/distroquery.c:568 src/distroquery.c:706 +#: src/distroquery.c:650 src/distroquery.c:811 msgid "Build date" msgstr "" -#: src/distroquery.c:571 +#: src/distroquery.c:653 msgid "Obsoletes" msgstr "" -#: src/distroquery.c:583 +#: src/distroquery.c:667 msgid "Provides" msgstr "" -#: src/distroquery.c:597 +#: src/distroquery.c:682 msgid "Requires" msgstr "" -#: src/distroquery.c:673 +#: src/distroquery.c:701 +msgid "Files list" +msgstr "" + +#: src/distroquery.c:776 msgid "Built packages" msgstr "" -#: src/distroquery.c:709 +#: src/distroquery.c:814 msgid "Source files" msgstr "" -#: src/distroquery.c:718 +#: src/distroquery.c:824 msgid "Patches" msgstr "" -#: src/distroquery.c:728 +#: src/distroquery.c:835 msgid "Build requirements" msgstr "" -#: src/distroquery.c:740 +#: src/distroquery.c:849 msgid "Changelog" msgstr "" diff --git a/po/it.gmo b/po/it.gmo index e3ecd76bdba25d59e3deffab7626be552c6951af..4671b616e96fb694d392b682d0582147fec359ed 100644 GIT binary patch delta 796 zcmYk)y=zlZ7{~FGH={9)Hrn`>>b09gLn>II6uO90hfD>h5KLMwrj6Wt>m<$GL6lxv z7m=0@4((9rACRRbgJ=;PS_df=3I#W(LO{R2n=^ReYrE2smW;RURt0(gNpaS4<7-p+r(Ed5PXfIFzbI;cRqsC&NI`5$%JNOp$;w@B0_D}~L-~b+?GIMIj&ruh~iAw7VsFdGBtsArBPq1zO=I9{i z%x(Qpl!5oVIrWAcEeN}*zoprhx8VBE8;;xT?=qh2FE)c(;5zdyKk#T6zvay}7HIqfH!D{` delta 677 zcmXxiJuHJk9LMo%`?U4eqSQ;3RK#FwMMR7&R%V7Kl@JCJwP^Az#!4kmG_fEiVjwY? zBoc`jm`Fq-5=>@;!ApF9b-nbS&)sv+-Tm)>y^X#`+~=6HWhhBozpiZAmJJ)>CXySzv_@5X@P3*xC4xlzp zV+W3-gVT0Aiw*SWP=V!98?2)?E}{Y|V z*tX;Qs0}W#9B`kkm@B3S5V2qqb9(IWv}@U(BU)*_B!E$Uo_Y19#qgpco!XWd=vn RBc}zY?DKj\n" "Language-Team: Italian\n" @@ -17,112 +17,120 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: src/distroquery.c:178 +#: src/distroquery.c:181 msgid "Source" msgstr "Sorgente" -#: src/distroquery.c:204 +#: src/distroquery.c:225 msgid "Search" msgstr "Cerca" -#: src/distroquery.c:238 +#: src/distroquery.c:259 msgid "sources" msgstr "sorgenti" -#: src/distroquery.c:249 +#: src/distroquery.c:270 msgid "Search software packages" msgstr "Cerca pacchetti software" -#: src/distroquery.c:354 src/distroquery.c:557 src/distroquery.c:702 +#: src/distroquery.c:374 src/distroquery.c:639 src/distroquery.c:807 msgid "Download" msgstr "Scarica" -#: src/distroquery.c:363 +#: src/distroquery.c:383 msgid "Details" msgstr "Dettagli" -#: src/distroquery.c:380 +#: src/distroquery.c:401 src/distroquery.c:436 #, c-format msgid "Other results in " msgstr "Altri risultati in " -#: src/distroquery.c:381 +#: src/distroquery.c:402 src/distroquery.c:437 #, c-format msgid "Results in" msgstr "Risultati in" -#: src/distroquery.c:384 +#: src/distroquery.c:405 src/distroquery.c:440 msgid "for arch " msgstr "per l'architettura " -#: src/distroquery.c:393 +#: src/distroquery.c:414 msgid "provides" msgstr "fornisce" -#: src/distroquery.c:456 +#: src/distroquery.c:449 +msgid "provides file " +msgstr "fornisce il file " + +#: src/distroquery.c:516 msgid "result(s) shown" msgstr "risultati mostrati" -#: src/distroquery.c:459 +#: src/distroquery.c:534 msgid "Search results for" msgstr "Risultati della ricerca per" -#: src/distroquery.c:523 src/distroquery.c:666 +#: src/distroquery.c:604 src/distroquery.c:769 msgid "Version" msgstr "Versione" -#: src/distroquery.c:528 +#: src/distroquery.c:609 msgid "Size" msgstr "Dimensione" -#: src/distroquery.c:531 +#: src/distroquery.c:612 msgid "Related packages" msgstr "Pacchetti collegati" -#: src/distroquery.c:559 src/distroquery.c:704 +#: src/distroquery.c:641 src/distroquery.c:809 msgid "Developers details" msgstr "Dettagli per gli sviluppatori" -#: src/distroquery.c:561 +#: src/distroquery.c:643 msgid "Source package" msgstr "Pacchetto sorgente" -#: src/distroquery.c:567 src/distroquery.c:705 +#: src/distroquery.c:649 src/distroquery.c:810 msgid "Maintainer" msgstr "Manutentore" -#: src/distroquery.c:568 src/distroquery.c:706 +#: src/distroquery.c:650 src/distroquery.c:811 msgid "Build date" msgstr "Data di compilazione" -#: src/distroquery.c:571 +#: src/distroquery.c:653 msgid "Obsoletes" msgstr "Rende obsoleti" -#: src/distroquery.c:583 +#: src/distroquery.c:667 msgid "Provides" msgstr "Fornisce" -#: src/distroquery.c:597 +#: src/distroquery.c:682 msgid "Requires" msgstr "Richiede" -#: src/distroquery.c:673 +#: src/distroquery.c:701 +msgid "Files list" +msgstr "Lista dei file" + +#: src/distroquery.c:776 msgid "Built packages" msgstr "Pacchetti compilati" -#: src/distroquery.c:709 +#: src/distroquery.c:814 msgid "Source files" msgstr "File sorgenti" -#: src/distroquery.c:718 +#: src/distroquery.c:824 msgid "Patches" msgstr "Patch" -#: src/distroquery.c:728 +#: src/distroquery.c:835 msgid "Build requirements" msgstr "Requisiti per la compilazione" -#: src/distroquery.c:740 +#: src/distroquery.c:849 msgid "Changelog" msgstr "Modifiche" diff --git a/src/distroquery.c b/src/distroquery.c index 5fe3dc7..0df7276 100644 --- a/src/distroquery.c +++ b/src/distroquery.c @@ -83,6 +83,9 @@ char *query = ""; char *query_package; char *query_repository; char *query_arch = NULL; +int query_limit = 10; +int query_offset = 0; +char query_next[PATH_MAX] = ""; char *lang = ""; int query_archs[ARCHS_MAX] = { 1, 0, 0, 0, 0 }; @@ -184,6 +187,24 @@ void printTagsLine(const char* arch, const char* tag, const char* group, const c tag, group, license); } +char* resolveFilePath(sqlite3 *db, long id, char *buffer) { + + long currid = id; + sqlite3_stmt *stmt; + char sql[PATH_MAX]; + buffer[0]='\0'; + + do { + snprintf(sql, PATH_MAX, "SELECT * FROM files WHERE id=%d", currid); + if (!sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL) == SQLITE_OK) return NULL; + if (sqlite3_step(stmt) != SQLITE_ROW) return NULL; + snprintf(sql, PATH_MAX, "/%s%s", sqlite3_column_text(stmt,1), buffer); + snprintf(buffer, PATH_MAX, "%s", sql); + currid = sqlite3_column_int(stmt,4); /* parent */ + } while (currid >= 0); + return buffer; +} + void printInputForm() { struct configTag *ct = firstconfigtag; @@ -254,6 +275,7 @@ void printQueryData() { int a, i, j, k, numresults = 0, localresults, localprovidesresults; char dbname[PATH_MAX]; + sqlite3 *dbf; sqlite3_stmt *statement, *stmt1; char sql[PATH_MAX]; char buffer[PATH_MAX]; @@ -304,7 +326,7 @@ void printQueryData() { "groupdescr LIKE 'Graphical Desktop/%%' DESC, groupdescr LIKE 'Applications/%%' DESC, " "groupdescr LIKE 'Development/%%' ASC, groupdescr LIKE 'Documentation%%' ASC, groupdescr LIKE 'System/Libraries%%' ASC, " "name LIKE '%%-devel' ASC, name LIKE '%%-debug' ASC " - "LIMIT 100", queryenc, queryenc, queryenc, queryenc, queryenc, queryenc); + "LIMIT %d OFFSET %d", queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, query_limit, query_offset); if (sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[a], sql, strlen(sql), &statement, NULL) == SQLITE_OK) { while (sqlite3_step(statement) == SQLITE_ROW) { numresults++; @@ -359,7 +381,7 @@ void printQueryData() { sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")), query_repositories[i]->arch[a], _("Details")); - + printf("
"); } } @@ -370,7 +392,7 @@ void printQueryData() { "(provides.id_package=packages.id AND provided.id=provides.id_provided) " "AND provided.name LIKE '%%%s%%' " "ORDER BY provided.name = '%s' DESC, provided.name LIKE '%s%%' DESC, provided.name LIKE '%%%s%%' DESC " - "LIMIT 100", queryenc, queryenc, queryenc, queryenc); + "LIMIT %d OFFSET %d", queryenc, queryenc, queryenc, queryenc, query_limit, query_offset); if (sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db[a], sql, strlen(sql), &statement, NULL) == SQLITE_OK) { while (sqlite3_step(statement) == SQLITE_ROW) { numresults++; @@ -392,8 +414,47 @@ void printQueryData() { _("provides"), sqlite3_column_text(statement,sqlite3_find_column_id(statement, "provided", "name"))); } - if (localprovidesresults > 0) printf(""); } + + /* files search */ + snprintf(dbname, PATH_MAX, "%s%s-%s-files.db", + query_repositories[i]->repository_dir, + query_repositories[i]->tag, + query_repositories[i]->arch[a]); + if (!sqlite3_open_v2(dbname, &dbf, SQLITE_OPEN_READONLY, NULL)) { + snprintf(sql, PATH_MAX, "SELECT * FROM files,packages_files_rel " + "WHERE files.name LIKE '%%%s%%' AND " + "packages_files_rel.id_file = files.id " + "ORDER BY files.name = '%s' DESC, files.name LIKE '%s%%' DESC, " + "files.name LIKE '%%%s%%' DESC LIMIT %d OFFSET %d", + queryenc, queryenc, queryenc, queryenc, query_limit, query_offset); + if (sqlite3_prepare_v2(dbf, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) { + while (sqlite3_step(stmt1) == SQLITE_ROW) { + numresults++; + if (++localprovidesresults == 1) { + printf("

"); + if (localresults > 0) printf(_("Other results in ")); + else printf(_("Results in")); + printf(" %s %s %s:
", + query_repositories[i]->tag, + _("for arch "), + query_repositories[i]->arch[a]); + } + printf("%s %s %s
", + query_repositories[i]->tag, + sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packages_files_rel", "name")), + query_repositories[i]->arch[a], + sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packages_files_rel", "name")), + _("provides file "), + resolveFilePath(dbf, sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "id_file")), buffer)); + } + sqlite3_finalize(stmt1); + } + sqlite3_close(dbf); + } + if (localprovidesresults > 0) printf("
"); + sqlite3_finalize(statement); } } @@ -403,8 +464,8 @@ void printQueryData() { if (search_sources) { snprintf(sql, PATH_MAX, "SELECT * FROM sources WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%' OR version LIKE '%%%s%%' " - "ORDER BY name = '%s' DESC, name LIKE '%s%%' DESC, name LIKE '%%%s%%' DESC LIMIT 100", - queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, queryenc); + "ORDER BY name = '%s' DESC, name LIKE '%s%%' DESC, name LIKE '%%%s%%' DESC LIMIT %d OFFSET %d", + queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, queryenc, query_limit, query_offset); for (i = 0; query_repositories[i] != NULL; i++) { if (!query_repositories[i]->db[ARCHS_MAX]) { snprintf(dbname, PATH_MAX, "%s%s-sources.db", query_repositories[i]->repository_dir, query_repositories[i]->tag); @@ -452,7 +513,22 @@ void printQueryData() { printf("
"); printf("]]>"); - printf("", numresults, _("result(s) shown")); + printf("", + query_next, query_limit, query_limit * (i-1)); + printf("%d", i); + printf(" "); + } + printf("]]>"); printf("<![CDATA[%s '%s' :: %s]]>", _("Search results for"), @@ -473,7 +549,7 @@ void printPackageData() { int a, i, j, k; char dbname[PATH_MAX]; - sqlite3 *db, *dbs, *dba; + sqlite3 *db, *dbs, *dbf; sqlite3_stmt *statement, *stmt1, *stmt2; char sql[PATH_MAX]; char buffer[PATH_MAX]; @@ -618,6 +694,20 @@ void printPackageData() { } sqlite3_finalize(stmt1); } + + /* files list */ + snprintf(dbname, PATH_MAX, "%s%s-%s-files.db", ct->repository_dir, ct->tag, query_arch); + if (!sqlite3_open_v2(dbname, &dbf, SQLITE_OPEN_READONLY, NULL)) { + printf("

%s:
", _("Files list")); + snprintf(sql, PATH_MAX, "SELECT * FROM packages_files_rel WHERE name='%s'", query_package); + if (sqlite3_prepare_v2(dbf, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK) { + while (sqlite3_step(stmt1) == SQLITE_ROW) { + printf(" %s
", resolveFilePath(dbf, sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "id_file")), buffer)); + } + sqlite3_finalize(stmt1); + } + sqlite3_close(dbf); + } sqlite3_close(dbs); } snprintf(buffer, PATH_MAX, "%s - %s", @@ -801,41 +891,56 @@ void parse_request_variables(char *data) { query_package = valuetok; } else if (!strcmp(vartok, "arch")) { query_arch = valuetok; - } else if (!strcmp(vartok, "query")) { - query = url_decode(valuetok); - } else if (!strcmp(vartok, "search_milestone2")) { - search_milestone2 = strstr(valuetok, "false") != valuetok; - } else if (!strcmp(vartok, "search_milestone1")) { - search_milestone1 = strstr(valuetok, "false") != valuetok; - } else if (!strcmp(vartok, "search_devel")) { - search_devel = strstr(valuetok, "false") != valuetok; - } else if (!strcmp(vartok, "search_i586")) { - query_archs[0] = strstr(valuetok, "false") != valuetok; - } else if (!strcmp(vartok, "search_x86_64")) { - query_archs[1] = strstr(valuetok, "false") != valuetok; - } else if (!strcmp(vartok, "search_arm")) { - query_archs[2] = strstr(valuetok, "false") != valuetok; - } else if (!strcmp(vartok, "search_sources")) { - search_sources = strstr(valuetok, "false") != valuetok; + } else if (!strcmp(vartok, "offset")) { + query_offset = atoi(url_decode(valuetok)); + if (query_offset < 0) query_offset = 0; + } else if (!strcmp(vartok, "limit")) { + query_limit = atoi(url_decode(valuetok)); + if (query_limit < 0) query_limit = 10; + else if (query_limit > 20) query_limit = 20; } else if (!strcmp(vartok, "searchbox")) { searchbox = strstr(valuetok, "false") != valuetok; } else if (!strcmp(vartok, "lang")) { lang = valuetok; + } else { + /* fields to make reusable query string for next pages */ + if (!strcmp(vartok, "query")) { + query = url_decode(valuetok); + } else if (!strcmp(vartok, "search_milestone2")) { + search_milestone2 = strstr(valuetok, "false") != valuetok; + } else if (!strcmp(vartok, "search_milestone1")) { + search_milestone1 = strstr(valuetok, "false") != valuetok; + } else if (!strcmp(vartok, "search_devel")) { + search_devel = strstr(valuetok, "false") != valuetok; + } else if (!strcmp(vartok, "search_i586")) { + query_archs[0] = strstr(valuetok, "false") != valuetok; + } else if (!strcmp(vartok, "search_x86_64")) { + query_archs[1] = strstr(valuetok, "false") != valuetok; + } else if (!strcmp(vartok, "search_arm")) { + query_archs[2] = strstr(valuetok, "false") != valuetok; + } else if (!strcmp(vartok, "search_sources")) { + search_sources = strstr(valuetok, "false") != valuetok; + } + strcat(query_next, vartok); + strcat(query_next, "="); + strcat(query_next, valuetok); + strcat(query_next, "&"); } } + if (query_next[strlen(query_next)] == '&') query_next[strlen(query_next)] = '\0'; - ct = firstconfigtag; + ct = firstconfigtag; i = 0; while (ct) { if ((strstr(ct->tag, "devel") == ct->tag) && search_devel) query_repositories[i++] = ct; ct = ct->next; } - ct = firstconfigtag; + ct = firstconfigtag; while (ct) { if ((strstr(ct->tag, "milestone2") == ct->tag) && search_milestone2) query_repositories[i++] = ct; ct = ct->next; } - ct = firstconfigtag; + ct = firstconfigtag; while (ct) { if ((strstr(ct->tag, "milestone1") == ct->tag) && search_milestone1) query_repositories[i++] = ct; ct = ct->next;