Overview
SHA1 Hash: | b2e55c0d4db063caefc3d40f7e6b26f9acc313a6 |
---|---|
Date: | 2007-09-01 21:11:33 |
User: | drh |
Comment: | Add the /wiki and /bwiki web pages. Currently renders content from the check-out as readonly. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/db.c from [ca474c1e96] to [7ab2af8add].
@@ -257,11 +257,11 @@ return sqlite3_column_double(pStmt->pStmt, N); } const char *db_column_text(Stmt *pStmt, int N){ return (char*)sqlite3_column_text(pStmt->pStmt, N); } -const char *db_column_malloc(Stmt *pStmt, int N){ +char *db_column_malloc(Stmt *pStmt, int N){ return mprintf("%s", db_column_text(pStmt, N)); } void db_column_blob(Stmt *pStmt, int N, Blob *pBlob){ blob_append(pBlob, sqlite3_column_blob(pStmt->pStmt, N), sqlite3_column_bytes(pStmt->pStmt, N));
Modified src/info.c from [a7363a7c53] to [1d02bccab4].
@@ -535,12 +535,14 @@ style_footer(); } /* ** WEBPAGE: fview +** URL: /fview/UUID ** -** Show the complete content of a file identified by g.zExtra +** Show the complete content of a file identified by UUID +** as preformatted text. */ void fview_page(void){ int rid; Blob content;
Modified src/main.c from [500655758a] to [17322e8c2b].
@@ -339,11 +339,11 @@ printf("\n"); } } /* -** COMMAND: commands +** COM MAND: commands ** ** Usage: %fossil commands ** List all supported commands. */ void cmd_cmd_list(void){ @@ -385,10 +385,11 @@ int rc, idx; const char *z; if( g.argc!=3 ){ printf("Usage: %s help COMMAND.\nAvailable COMMANDs:\n", g.argv[0]); cmd_cmd_list(); + printf("You are running fossil baseline " MANIFEST_UUID "\n"); return; } rc = name_search(g.argv[2], aCommand, count(aCommand), &idx); if( rc==1 ){ fossil_fatal("unknown command: %s", g.argv[2]); @@ -408,20 +409,10 @@ putchar(*z); z++; } } putchar('\n'); -} - -/* -** COMMAND: baseline -** -** Show the baseline number of the source code from which this -** fossil executable was generated. -*/ -void baseline_cmd(void){ - printf("%s\n", MANIFEST_UUID); } /* ** RSS feeds need to reference absolute URLs so we need to calculate ** the base URL onto which we add components. This is basically
Modified src/wiki.c from [daf8014fa8] to [804763a66e].
@@ -25,20 +25,161 @@ */ #include <assert.h> #include "config.h" #include "wiki.h" + +/* +** Create a fake replicate of the "vfile" table as a TEMP table +** using the manifest identified by manid. +*/ +static void create_fake_vfile(int manid){ + static const char zVfileDef[] = + @ CREATE TEMP TABLE vfile( + @ id INTEGER PRIMARY KEY, -- ID of the checked out file + @ vid INTEGER REFERENCES blob, -- The version this file is part of. + @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add + @ deleted BOOLEAN DEFAULT 0, -- True if deleted + @ rid INTEGER, -- Originally from this repository record + @ mrid INTEGER, -- Based on this record due to a merge + @ pathname TEXT, -- Full pathname + @ UNIQUE(pathname,vid) + @ ); + ; + db_multi_exec(zVfileDef); + load_vfile_from_rid(manid); +} + +/* +** Locate the wiki page with the name zPageName and render it. +*/ +static void locate_and_render_wikipage(const char *zPageName){ + Stmt q; + int id = 0; + int rid = 0; + int chnged = 0; + char *zPathname = 0; + db_prepare(&q, + "SELECT id, rid, chnged, pathname FROM vfile" + " WHERE (pathname='%q.wiki' OR pathname LIKE '%%/%q.wiki')" + " AND NOT deleted", zPageName, zPageName + ); + if( db_step(&q)==SQLITE_ROW ){ + id = db_column_int(&q, 0); + rid = db_column_int(&q, 1); + chnged = db_column_int(&q, 2); + if( chnged || rid==0 ){ + zPathname = db_column_malloc(&q, 3); + } + } + db_finalize(&q); + if( id ){ + Blob page, src; + char *zTitle = "wiki"; + char *z; + blob_zero(&src); + if( zPathname ){ + zPathname = mprintf("%s/%z", g.zLocalRoot, zPathname); + blob_read_from_file(&src, zPathname); + free(zPathname); + }else{ + content_get(rid, &src); + } + + /* The wiki page content is now in src. Check to see if + ** there is a <readonly/> or <appendonly/> element at the + ** beginning of the content. + */ + z = blob_str(&src); + while( isspace(*z) ) z++; + if( strncmp(z, "<readonly/>", 11)==0 ){ + z += 11; + }else if( strncmp(z, "<appendonly/>", 13)==0 ){ + z += 13; + } + + /* Check for <title>...</title> markup and remove it if present. */ + while( isspace(*z) ) z++; + if( strncmp(z, "<title>", 7)==0 ){ + int i; + for(i=7; z[i] && z[i]!='<'; i++){} + if( z[i]=='<' && strncmp(&z[i], "</title>", 8)==0 ){ + zTitle = htmlize(&z[7], i-7); + z = &z[i+8]; + } + } + + /* Render the page */ + style_header(zTitle); + blob_init(&page, z, -1); + wiki_convert(&page, cgi_output_blob(), WIKI_HTML); + blob_reset(&src); + }else{ + style_header("Unknown Wiki Page"); + @ The wiki page "%h(zPageName)" does not exist. + } + style_footer(); +} + /* ** WEBPAGE: wiki +** URL: /wiki/PAGENAME ** -** Render the wiki page that is named after the /wiki/ part of -** the url. +** If the local database is available (which only happens if run +** as "server" instead of "cgi" or "http") then the file is taken +** from the local checkout. If there is no local checkout, then +** the content is taken from the "head" baseline. */ void wiki_page(void){ - style_header("Wiki"); - @ extra=%h(g.zExtra) - style_footer(); + login_check_credentials(); + if( !g.okRdWiki ){ login_needed(); return; } + if( !g.localOpen ){ + int headid = db_int(0, + "SELECT cid FROM plink ORDER BY mtime DESC LIMIT 1" + ); + create_fake_vfile(headid); + } + locate_and_render_wikipage(g.zExtra); +} + +/* +** The g.zExtra value is of the form UUID/otherstuff. +** Extract the UUID and convert it to a record id. Leave +** g.zExtra holding just otherstuff. If UUID does not exist +** or is malformed, return 0 and leave g.zExtra unchanged. +*/ +int extract_uuid_from_url(void){ + int i, rid; + Blob uuid; + for(i=0; g.zExtra[i] && g.zExtra[i]!='/'; i++){} + blob_zero(&uuid); + blob_append(&uuid, g.zExtra, i); + rid = name_to_uuid(&uuid, 0); + blob_reset(&uuid); + if( rid ){ + while( g.zExtra[i]=='/' ){ i++; } + g.zExtra = &g.zExtra[i]; + } + return rid; +} + +/* +** WEBPAGE: bwiki +** URL: /bwiki/UUID/PAGENAME +** +** UUID specifies a baseline. Render the wiki page PAGENAME as +** it appears in that baseline. +*/ +void bwiki_page(void){ + int headid; + login_check_credentials(); + if( !g.okRdWiki || !g.okHistory ){ login_needed(); return; } + headid = extract_uuid_from_url(); + if( headid ){ + create_fake_vfile(headid); + } + locate_and_render_wikipage(g.zExtra); } /* ** WEBPAGE: ambiguous **
Modified src/wikiformat.c from [8a54463d32] to [0d1f6957fe].
@@ -712,14 +712,14 @@ /* TBD */ } /* ** Resolve a hyperlink. The argument is the content of the [...] -** in the wiki. Append the URL to the given blob. +** in the wiki. Append the URL to the output of the Renderer. */ -static void resolveHyperlink(const char *zTarget, Blob *pOut){ - blob_appendf(pOut, "http://www.fossil-scm.org/test-%T", zTarget); +static void resolveHyperlink(const char *zTarget, Renderer *p){ + blob_appendf(p->pOut, "http://www.fossil-scm.org/test-%T", zTarget); } /* ** Check to see if the given parsed markup is the correct ** </verbatim> tag. @@ -804,11 +804,11 @@ zDisplay = zTarget; }else{ while( isspace(*zDisplay) ) zDisplay++; } blob_append(p->pOut, "<a href=\"", -1); - resolveHyperlink(zTarget, p->pOut); + resolveHyperlink(zTarget, p); blob_append(p->pOut, "\">", -1); savedState = p->state; p->state &= ~ALLOW_WIKI; p->state |= FONT_MARKUP_ONLY; wiki_render(p, zDisplay);