distroquery: complete source and binary packages info pages with current db available information
This commit is contained in:
parent
948e63c538
commit
78e98aa262
@ -59,6 +59,8 @@ struct Packager *firstPackager() {
|
|||||||
return firstpackager;
|
return firstpackager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long packagerListId = 0;
|
||||||
|
|
||||||
struct Packager *
|
struct Packager *
|
||||||
getPackagerByName(char *name, int create)
|
getPackagerByName(char *name, int create)
|
||||||
{
|
{
|
||||||
@ -101,6 +103,7 @@ getPackagerByName(char *name, int create)
|
|||||||
newpackager->changes_count = 0;
|
newpackager->changes_count = 0;
|
||||||
newpackager->packages_count = 0;
|
newpackager->packages_count = 0;
|
||||||
newpackager->role = 0;
|
newpackager->role = 0;
|
||||||
|
newpackager->id = ++packagerListId;
|
||||||
if (lastpackager)
|
if (lastpackager)
|
||||||
lastpackager->next = newpackager;
|
lastpackager->next = newpackager;
|
||||||
if (!firstpackager)
|
if (!firstpackager)
|
||||||
|
@ -78,7 +78,7 @@ static struct configTag *firstconfigtag = NULL, *configtag = NULL;
|
|||||||
char *query;
|
char *query;
|
||||||
char *query_package;
|
char *query_package;
|
||||||
char *query_repository;
|
char *query_repository;
|
||||||
char *query_arch;
|
char *query_arch = NULL;
|
||||||
int query_archs[ARCHS_MAX];
|
int query_archs[ARCHS_MAX];
|
||||||
|
|
||||||
struct configTag *query_repositories[100];
|
struct configTag *query_repositories[100];
|
||||||
@ -135,6 +135,34 @@ char *url_decode(char *str) {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sqlite3_find_column_id(sqlite3_stmt *stmt, const char* table, const char* name) {
|
||||||
|
const char* colname;
|
||||||
|
const char* tablename;
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
|
while (colname = sqlite3_column_name(stmt, id)) {
|
||||||
|
if (!strcmp(colname, name)) {
|
||||||
|
if (table) {
|
||||||
|
if (!strcmp(sqlite3_column_table_name(stmt, id), table)) return id;
|
||||||
|
} else {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int find_query_arch(char* arch) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARCHS_MAX; i++) {
|
||||||
|
if (!strcmp(arch, ARCHS[i]) && query_archs[i]) return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void printInputForm() {
|
void printInputForm() {
|
||||||
struct configTag *ct = firstconfigtag;
|
struct configTag *ct = firstconfigtag;
|
||||||
|
|
||||||
@ -175,15 +203,6 @@ void printInputForm() {
|
|||||||
printf("]]></queryform>");
|
printf("]]></queryform>");
|
||||||
}
|
}
|
||||||
|
|
||||||
int find_query_arch(char* arch) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARCHS_MAX; i++) {
|
|
||||||
if (!strcmp(arch, ARCHS[i]) && query_archs[i]) return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void printQueryData() {
|
void printQueryData() {
|
||||||
|
|
||||||
int a, i, j, k, numresults = 0;
|
int a, i, j, k, numresults = 0;
|
||||||
@ -236,14 +255,14 @@ void printQueryData() {
|
|||||||
"<b>%s</b> %s-%s<br>%s",
|
"<b>%s</b> %s-%s<br>%s",
|
||||||
query_repositories[i]->arch[a],
|
query_repositories[i]->arch[a],
|
||||||
query_repositories[i]->tag,
|
query_repositories[i]->tag,
|
||||||
sqlite3_column_text(statement,7),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "groupdescr")),
|
||||||
sqlite3_column_text(statement,1),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
|
||||||
sqlite3_column_text(statement,4),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
|
||||||
sqlite3_column_text(statement,5),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
|
||||||
sqlite3_column_text(statement,6));
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")));
|
||||||
|
|
||||||
printf("<br><br><div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div>",
|
printf("<br><br><div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div>",
|
||||||
sqlite3_column_text(statement,8));
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")));
|
||||||
|
|
||||||
/* install */
|
/* install */
|
||||||
/* printf("<div align=right style='position:absolute;top:5px;right:0;padding:5px;'>"
|
/* printf("<div align=right style='position:absolute;top:5px;right:0;padding:5px;'>"
|
||||||
@ -259,15 +278,15 @@ void printQueryData() {
|
|||||||
"<a href=\"%s%s/SRPMS.base/%s-%s-%s.src.rpm\" style=\"color:white\"> Download </a></div>",
|
"<a href=\"%s%s/SRPMS.base/%s-%s-%s.src.rpm\" style=\"color:white\"> Download </a></div>",
|
||||||
query_repositories[i]->download_prefix,
|
query_repositories[i]->download_prefix,
|
||||||
query_repositories[i]->download_dir,
|
query_repositories[i]->download_dir,
|
||||||
sqlite3_column_text(statement,1),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
|
||||||
sqlite3_column_text(statement,4),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
|
||||||
sqlite3_column_text(statement,5));
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")));
|
||||||
/* details */
|
/* details */
|
||||||
printf(" <div style='display:inline;background-color:lightblue;font-weight:strong'>"
|
printf(" <div style='display:inline;background-color:lightblue;font-weight:strong'>"
|
||||||
"<a href='javascript:distroquery_request("
|
"<a href='javascript:distroquery_request("
|
||||||
"\"repository=%s&package=%s&arch=%s\")' style=\"color:black\"> Details </a></div>",
|
"\"repository=%s&package=%s&arch=%s\")' style=\"color:black\"> Details </a></div>",
|
||||||
query_repositories[i]->tag,
|
query_repositories[i]->tag,
|
||||||
sqlite3_column_text(statement,1),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
|
||||||
query_repositories[i]->arch[a]);
|
query_repositories[i]->arch[a]);
|
||||||
|
|
||||||
printf("</div></div><br>");
|
printf("</div></div><br>");
|
||||||
@ -302,14 +321,19 @@ void printQueryData() {
|
|||||||
"<b>%s</b> %s-%s<br>%s<br>License: %s</br>URL: %s<br><br>"
|
"<b>%s</b> %s-%s<br>%s<br>License: %s</br>URL: %s<br><br>"
|
||||||
"<div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div><br>",
|
"<div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div><br>",
|
||||||
query_repositories[i]->tag,
|
query_repositories[i]->tag,
|
||||||
sqlite3_column_text(statement,8),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "groupdescr")),
|
||||||
sqlite3_column_text(statement,1),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
|
||||||
sqlite3_column_text(statement,4),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
|
||||||
sqlite3_column_text(statement,5),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
|
||||||
sqlite3_column_text(statement,6),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),
|
||||||
sqlite3_column_text(statement,11),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "license")),
|
||||||
sqlite3_column_text(statement,10),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "url")),
|
||||||
sqlite3_column_text(statement,9));
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")));
|
||||||
|
printf(" <div style='display:inline;background-color:lightblue;font-weight:strong'>"
|
||||||
|
"<a href='javascript:distroquery_request("
|
||||||
|
"\"repository=%s&package=%s\")' style=\"color:black\"> Details </a></div>",
|
||||||
|
query_repositories[i]->tag,
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,10 +357,11 @@ void printPackageData() {
|
|||||||
|
|
||||||
int a, i, j, k, numresults = 0;
|
int a, i, j, k, numresults = 0;
|
||||||
char dbname[PATH_MAX];
|
char dbname[PATH_MAX];
|
||||||
sqlite3 *db;
|
sqlite3 *db, *dbs;
|
||||||
sqlite3_stmt *statement;
|
sqlite3_stmt *statement, *stmt1;
|
||||||
char sql[PATH_MAX];
|
char sql[PATH_MAX];
|
||||||
struct configTag* ct = findRepositoryByTag(query_repository);
|
struct configTag* ct = findRepositoryByTag(query_repository);
|
||||||
|
sizeString strsize;
|
||||||
|
|
||||||
printf("<queryreply><![CDATA[");
|
printf("<queryreply><![CDATA[");
|
||||||
|
|
||||||
@ -355,47 +380,140 @@ void printPackageData() {
|
|||||||
numresults++;
|
numresults++;
|
||||||
printf("<hr><br><div style='display:inline;color:white;background-color:green'> %s </div> "
|
printf("<hr><br><div style='display:inline;color:white;background-color:green'> %s </div> "
|
||||||
"<div style='display:inline;color:black;background-color:yellow'> %s </div><br>"
|
"<div style='display:inline;color:black;background-color:yellow'> %s </div><br>"
|
||||||
"<b>%s</b> %s-%s<br>%s<br>Group: %s"
|
"<b>%s</b> %s-%s<br>%s<br>Group: %s<br>Size: %s",
|
||||||
"<br><br><div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div><br>",
|
query_arch,
|
||||||
query_repositories[i]->arch[a],
|
|
||||||
query_repositories[i]->tag,
|
query_repositories[i]->tag,
|
||||||
sqlite3_column_text(statement,1),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
|
||||||
sqlite3_column_text(statement,4),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
|
||||||
sqlite3_column_text(statement,5),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
|
||||||
sqlite3_column_text(statement,6),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),
|
||||||
sqlite3_column_text(statement,7),
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "groupdescr")),
|
||||||
sqlite3_column_text(statement,8));
|
humanSize(sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "size")), &strsize));
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
/* if (search_sources) {
|
printf("<br>Source package:");
|
||||||
snprintf(sql, PATH_MAX, "SELECT * FROM sources WHERE name LIKE '%%%s%%' OR summary LIKE '%%%s%%' OR description LIKE '%%%s%%'", query, query, query);
|
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository_dir, ct->tag);
|
||||||
for (i = 0; query_repositories[i] != NULL; i++) {
|
if (!sqlite3_open_v2(dbname, &dbs, SQLITE_OPEN_READONLY, NULL)) {
|
||||||
if (query_repositories[i]->db &&
|
snprintf(sql, PATH_MAX, "SELECT * FROM sources WHERE id=%d",
|
||||||
(sqlite3_prepare_v2((sqlite3*)query_repositories[i]->db, sql, strlen(sql), &statement, NULL) == SQLITE_OK)) {
|
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id_source")));
|
||||||
while (sqlite3_step(statement) == SQLITE_ROW) {
|
if (sqlite3_prepare_v2(dbs, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK)
|
||||||
numresults++;
|
while (sqlite3_step(stmt1) == SQLITE_ROW)
|
||||||
printf("<hr><br><div style='display:inline;color:black;background-color:red'> Source </div> "
|
printf(" <a href='javascript:distroquery_request(\"repository=%s&package=%s\")'>%s</a>",
|
||||||
"<div style='display:inline;color:black;background-color:yellow'> %s </div><br>"
|
ct->tag,
|
||||||
"<b>%s</b> %s-%s<br>%s<br>Group: %s<br>License: %s</br>URL: %s<br><br>"
|
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")),
|
||||||
"<div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div><br>",
|
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")));
|
||||||
query_repositories[i]->tag,
|
sqlite3_close(dbs);
|
||||||
sqlite3_column_text(statement,1),
|
|
||||||
sqlite3_column_text(statement,4),
|
|
||||||
sqlite3_column_text(statement,5),
|
|
||||||
sqlite3_column_text(statement,6),
|
|
||||||
sqlite3_column_text(statement,8),
|
|
||||||
sqlite3_column_text(statement,11),
|
|
||||||
sqlite3_column_text(statement,10),
|
|
||||||
sqlite3_column_text(statement,9));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("<br><br><div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div><br>",
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")));
|
||||||
|
|
||||||
}
|
}
|
||||||
printf("\n");
|
}
|
||||||
}
|
printf("]]></queryreply>");
|
||||||
|
|
||||||
|
sqlite3_close(db);
|
||||||
|
db = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printSourcePackageData() {
|
||||||
|
|
||||||
|
int a, i, j, k, numresults = 0;
|
||||||
|
char dbname[PATH_MAX];
|
||||||
|
sqlite3 *db, *dba;
|
||||||
|
sqlite3_stmt *statement, *stmt1;
|
||||||
|
char sql[PATH_MAX];
|
||||||
|
struct configTag* ct = findRepositoryByTag(query_repository);
|
||||||
|
humanDate strdate;
|
||||||
|
sizeString strsize;
|
||||||
|
|
||||||
|
printf("<queryreply><![CDATA[");
|
||||||
|
|
||||||
|
snprintf(dbname, PATH_MAX, "%s%s-sources.db", ct->repository_dir, ct->tag);
|
||||||
|
if (sqlite3_open_v2(dbname, &db, SQLITE_OPEN_READONLY, NULL)) {
|
||||||
|
if (db) sqlite3_close(db);
|
||||||
|
db = NULL;
|
||||||
|
fprintf(stderr, "ERROR: unable to open sqlite3 db %s; aborting.\n", dbname);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("<hr><br>%d result(s) found.", numresults);*/
|
snprintf(sql, PATH_MAX,
|
||||||
|
"SELECT * FROM sources,packagers WHERE sources.name = '%s' AND sources.id_packager=packagers.id", query_package);
|
||||||
|
if (db &&
|
||||||
|
(sqlite3_prepare_v2(db, sql, strlen(sql), &statement, NULL) == SQLITE_OK)) {
|
||||||
|
while (sqlite3_step(statement) == SQLITE_ROW) {
|
||||||
|
numresults++;
|
||||||
|
printf("<hr><br><div style='display:inline;color:white;background-color:red'> Source </div> "
|
||||||
|
"<div style='display:inline;color:black;background-color:yellow'> %s </div><br>"
|
||||||
|
"<b>%s</b> %s-%s<br>%s<br>Group: %s<br>Maintainer: %s<br>License: %s<br>URL: <a href=\"%s\" target=_new>%s</a><br>Size: %s"
|
||||||
|
"<br><br><div style='text-align:justify;text-justify:inter-word;font-style:italic'>%s</div><br>",
|
||||||
|
query_repositories[i]->tag,
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "name")),
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "version")),
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "release")),
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "summary")),
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "groupdescr")),
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, "packagers", "name")),
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "license")),
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "url")),
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "url")),
|
||||||
|
humanSize(sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "size")), &strsize),
|
||||||
|
sqlite3_column_text(statement,sqlite3_find_column_id(statement, NULL, "description")));
|
||||||
|
|
||||||
|
printf("<br>Sources:");
|
||||||
|
snprintf(sql, PATH_MAX,
|
||||||
|
"SELECT * FROM sources_source WHERE id_source=%d",
|
||||||
|
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
|
||||||
|
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK)
|
||||||
|
while (sqlite3_step(stmt1) == SQLITE_ROW) {
|
||||||
|
printf(" %s", sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "source")));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("<br>Patches:");
|
||||||
|
snprintf(sql, PATH_MAX,
|
||||||
|
"SELECT * FROM sources_patch WHERE id_source=%d",
|
||||||
|
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
|
||||||
|
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK)
|
||||||
|
while (sqlite3_step(stmt1) == SQLITE_ROW) {
|
||||||
|
printf(" %s", sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "patch")));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("<br>Build time: %s",
|
||||||
|
simpleTimeToHuman(sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "buildtime")), (humanDate *) & strdate));
|
||||||
|
|
||||||
|
printf("<br>Built packages:");
|
||||||
|
for (a = 0; a < ARCHS_MAX && ct->arch[a]; a++) {
|
||||||
|
snprintf(dbname, PATH_MAX, "%s%s-%s.db", ct->repository_dir, ct->tag, ct->arch[a]);
|
||||||
|
if (!sqlite3_open_v2(dbname, &dba, SQLITE_OPEN_READONLY, NULL)) {
|
||||||
|
snprintf(sql, PATH_MAX, "SELECT * FROM packages WHERE id_source=%d",
|
||||||
|
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
|
||||||
|
if (sqlite3_prepare_v2(dba, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK)
|
||||||
|
while (sqlite3_step(stmt1) == SQLITE_ROW)
|
||||||
|
printf(" <a href='javascript:distroquery_request(\"repository=%s&package=%s&arch=%s\")'>%s(%s)</a>",
|
||||||
|
ct->tag,
|
||||||
|
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")),
|
||||||
|
ct->arch[a],
|
||||||
|
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "name")),
|
||||||
|
ct->arch[a]);
|
||||||
|
sqlite3_close(dba);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("<br><br>Changelog:<br>");
|
||||||
|
snprintf(sql, PATH_MAX,
|
||||||
|
"SELECT * FROM changelog,packagers WHERE id_source=%d AND changelog.id_packager=packagers.id",
|
||||||
|
sqlite3_column_int(statement,sqlite3_find_column_id(statement, NULL, "id")));
|
||||||
|
if (sqlite3_prepare_v2(db, sql, strlen(sql), &stmt1, NULL) == SQLITE_OK)
|
||||||
|
while (sqlite3_step(stmt1) == SQLITE_ROW) {
|
||||||
|
printf("%s - %s (%s)<br><pre>%s</pre>",
|
||||||
|
simpleTimeToHuman(sqlite3_column_int(stmt1,sqlite3_find_column_id(stmt1, NULL, "time")), (humanDate *) & strdate),
|
||||||
|
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, "packagers", "name")),
|
||||||
|
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "release")),
|
||||||
|
sqlite3_column_text(stmt1,sqlite3_find_column_id(stmt1, NULL, "text")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
printf("]]></queryreply>");
|
printf("]]></queryreply>");
|
||||||
|
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
@ -480,7 +598,10 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (query_package && strlen(query_package)) {
|
if (query_package && strlen(query_package)) {
|
||||||
printPackageData();
|
if (query_arch)
|
||||||
|
printPackageData();
|
||||||
|
else
|
||||||
|
printSourcePackageData();
|
||||||
} else if (query && strlen(query)) {
|
} else if (query && strlen(query)) {
|
||||||
printQueryData();
|
printQueryData();
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user