/* ** WEBPAGE: finfo ** URL: /finfo?name=FILENAME ** ** Show the change history for a single file. ** ** Additional query parameters: ** ** a=DATE Only show changes after DATE ** b=DATE Only show changes before DATE ** n=NUM Show the first NUM changes only ** brbg Background color by branch name ** ubg Background color by user name */ void finfo_page(void) { Stmt q; const char *zFilename; char zPrevDate[20]; const char *zA; const char *zB; int n; Blob title; Blob sql; GraphContext *pGraph; int brBg = P("brbg")!=0; int uBg = P("ubg")!=0; login_check_credentials(); if( !g.perm.Read ) { login_needed(); return; } style_header("File History"); login_anonymous_available(); zPrevDate[0] = 0; zFilename = PD("name",""); blob_zero(&sql); blob_appendf(&sql, "SELECT" " datetime(event.mtime,'localtime')," /* Date of change */ " coalesce(event.ecomment, event.comment)," /* Check-in comment */ " coalesce(event.euser, event.user)," /* User who made chng */ " mlink.pid," /* Parent rid */ " mlink.fid," /* File rid */ " (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */ " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */ " event.bgcolor," /* Background color */ " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0" " AND tagxref.rid=mlink.mid)" /* Tags */ " FROM mlink, event" " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q %s)" " AND event.objid=mlink.mid", TAG_BRANCH, zFilename, filename_collation() ); if( (zA = P("a"))!=0 ) { blob_appendf(&sql, " AND event.mtime>=julianday('%q')", zA); } if( (zB = P("b"))!=0 ) { blob_appendf(&sql, " AND event.mtime<=julianday('%q')", zB); } blob_appendf(&sql," ORDER BY event.mtime DESC /*sort*/"); if( (n = atoi(PD("n","0")))>0 ) { blob_appendf(&sql, " LIMIT %d", n); } db_prepare(&q, blob_str(&sql)); blob_reset(&sql); blob_zero(&title); blob_appendf(&title, "History of "); hyperlinked_path(zFilename, &title, 0); @ <h2>%b(&title)</h2>
/* ** WEBPAGE: dir ** ** Query parameters: ** ** name=PATH Directory to display. Required. ** ci=LABEL Show only files in this check-in. Optional. */ void page_dir(void){ const char *zD = P("name"); int mxLen; int nCol, nRow; int cnt, i; char *zPrefix; Stmt q; const char *zCI = P("ci"); int rid = 0; Blob content; Blob dirname; Manifest m; const char *zSubdirLink; login_check_credentials(); if( !g.okHistory ){ login_needed(); return; } style_header("File List"); sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0, pathelementFunc, 0, 0); /* If the name= parameter is an empty string, make it a NULL pointer */ if( zD && strlen(zD)==0 ){ zD = 0; } /* If a specific check-in is requested, fetch and parse it. */ if( zCI && (rid = name_to_rid(zCI))!=0 && content_get(rid, &content) ){ if( !manifest_parse(&m, &content) || m.type!=CFTYPE_MANIFEST ){ zCI = 0; } } /* Compute the title of the page */ blob_zero(&dirname); if( zD ){ blob_append(&dirname, "in directory ", -1); hyperlinked_path(zD, &dirname); zPrefix = mprintf("%h/", zD); }else{ blob_append(&dirname, "in the top-level directory", -1); zPrefix = ""; } if( zCI ){ char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); char zShort[20]; memcpy(zShort, zUuid, 10); zShort[10] = 0; @ <h2>Files of check-in [<a href="vinfo?name=%T(zUuid)">%s(zShort)</a>] @ %s(blob_str(&dirname))</h2> zSubdirLink = mprintf("%s/dir?ci=%S&name=%T", g.zTop, zUuid, zPrefix); if( zD ){ style_submenu_element("Top", "Top", "%s/dir?ci=%S", g.zTop, zUuid); style_submenu_element("All", "All", "%s/dir?name=%t", g.zTop, zD); }else{ style_submenu_element("All", "All", "%s/dir", g.zBaseURL); } }else{