Fossil SCM

Implemented /json/wiki/save.

stephan 2011-09-22 17:56 UTC json
Commit 2162c86d9ec34458dd5db2a5a3f93b00f0914078
--- ajax/wiki-editor.html
+++ ajax/wiki-editor.html
@@ -186,10 +186,11 @@
186186
TheApp.jqe.currentAuthToken.text("");
187187
};
188188
189189
TheApp.showPage = function(name){
190190
function doShow(page){
191
+ TheApp.currentPage = page;
191192
TheApp.jqe.spanPageName.text('('+page.name+')');
192193
TheApp.jqe.taPageContent.val(page.content);
193194
}
194195
var p = ('object' === typeof name) ? name : TheApp.pages[name];
195196
if('object' === typeof p) {
@@ -235,10 +236,28 @@
235236
}
236237
});
237238
return false /*for click handlers*/;
238239
}
239240
241
+ TheApp.savePage = function(p){
242
+ p = p || TheApp.currentPage || TheApp.pages[TheApp.currentPage];
243
+ if( 'object' !== typeof p ){
244
+ p = TheApp.pages[p];
245
+ }
246
+ if('object' !== typeof p){
247
+ alert("savePage() argument is not a page object or known page name.");
248
+ }
249
+ TheApp.pages[p.name] = p;
250
+ p.content = TheApp.jqe.taPageContent.val();
251
+ var req = {
252
+ name:p.name,
253
+ content:p.content
254
+ };
255
+ if(! confirm("Really save wiki page ["+p.name+"]?") ) return;
256
+ TheApp.cgi.sendCommand('/json/wiki/save',req);
257
+ };
258
+
240259
});
241260
242261
</script>
243262
244263
</head>
@@ -265,10 +284,13 @@
265284
<input type='button' value='version' onclick='TheApp.cgi.sendCommand("/json/version")' />
266285
<input type='button' value='stat' onclick='TheApp.cgi.sendCommand("/json/stat")' />
267286
<input type='button' value='whoami' onclick='TheApp.cgi.sendCommand("/json/whoami")' />
268287
<input type='button' value='cap' onclick='TheApp.cgi.sendCommand("/json/cap")' />
269288
<input type='button' value='wiki/list' onclick='TheApp.loadPageList()' />
289
+<!--
290
+<input type='button' value='timeline/ci' onclick='TheApp.cgi.sendCommand("/json/timeline/ci")' />
291
+-->
270292
271293
<!--
272294
<input type='button' value='get whiki' onclick='TheApp.cgi.getPages("whiki")' />
273295
<input type='button' value='get more' onclick='TheApp.cgi.getPages("HelloWorld/WhikiNews")' />
274296
<input type='button' value='get client data' onclick='TheApp.cgi.getPageClientData("HelloWorld/whiki/WhikiCommands")' />
@@ -284,10 +306,11 @@
284306
<tr>
285307
<td width='25%' valign='top'>
286308
<div id='pageListArea'></div>
287309
</td>
288310
<td width='75%' valign='top'>
311
+ <input type='button' value='Save' onclick='TheApp.savePage()' /><br/>
289312
<textarea id='taPageContent' rows='20' cols='60'></textarea>
290313
</td>
291314
</tr>
292315
<tr>
293316
<th colspan='2'>Response <span id='timer'></span></th>
294317
--- ajax/wiki-editor.html
+++ ajax/wiki-editor.html
@@ -186,10 +186,11 @@
186 TheApp.jqe.currentAuthToken.text("");
187 };
188
189 TheApp.showPage = function(name){
190 function doShow(page){
 
191 TheApp.jqe.spanPageName.text('('+page.name+')');
192 TheApp.jqe.taPageContent.val(page.content);
193 }
194 var p = ('object' === typeof name) ? name : TheApp.pages[name];
195 if('object' === typeof p) {
@@ -235,10 +236,28 @@
235 }
236 });
237 return false /*for click handlers*/;
238 }
239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240 });
241
242 </script>
243
244 </head>
@@ -265,10 +284,13 @@
265 <input type='button' value='version' onclick='TheApp.cgi.sendCommand("/json/version")' />
266 <input type='button' value='stat' onclick='TheApp.cgi.sendCommand("/json/stat")' />
267 <input type='button' value='whoami' onclick='TheApp.cgi.sendCommand("/json/whoami")' />
268 <input type='button' value='cap' onclick='TheApp.cgi.sendCommand("/json/cap")' />
269 <input type='button' value='wiki/list' onclick='TheApp.loadPageList()' />
 
 
 
270
271 <!--
272 <input type='button' value='get whiki' onclick='TheApp.cgi.getPages("whiki")' />
273 <input type='button' value='get more' onclick='TheApp.cgi.getPages("HelloWorld/WhikiNews")' />
274 <input type='button' value='get client data' onclick='TheApp.cgi.getPageClientData("HelloWorld/whiki/WhikiCommands")' />
@@ -284,10 +306,11 @@
284 <tr>
285 <td width='25%' valign='top'>
286 <div id='pageListArea'></div>
287 </td>
288 <td width='75%' valign='top'>
 
289 <textarea id='taPageContent' rows='20' cols='60'></textarea>
290 </td>
291 </tr>
292 <tr>
293 <th colspan='2'>Response <span id='timer'></span></th>
294
--- ajax/wiki-editor.html
+++ ajax/wiki-editor.html
@@ -186,10 +186,11 @@
186 TheApp.jqe.currentAuthToken.text("");
187 };
188
189 TheApp.showPage = function(name){
190 function doShow(page){
191 TheApp.currentPage = page;
192 TheApp.jqe.spanPageName.text('('+page.name+')');
193 TheApp.jqe.taPageContent.val(page.content);
194 }
195 var p = ('object' === typeof name) ? name : TheApp.pages[name];
196 if('object' === typeof p) {
@@ -235,10 +236,28 @@
236 }
237 });
238 return false /*for click handlers*/;
239 }
240
241 TheApp.savePage = function(p){
242 p = p || TheApp.currentPage || TheApp.pages[TheApp.currentPage];
243 if( 'object' !== typeof p ){
244 p = TheApp.pages[p];
245 }
246 if('object' !== typeof p){
247 alert("savePage() argument is not a page object or known page name.");
248 }
249 TheApp.pages[p.name] = p;
250 p.content = TheApp.jqe.taPageContent.val();
251 var req = {
252 name:p.name,
253 content:p.content
254 };
255 if(! confirm("Really save wiki page ["+p.name+"]?") ) return;
256 TheApp.cgi.sendCommand('/json/wiki/save',req);
257 };
258
259 });
260
261 </script>
262
263 </head>
@@ -265,10 +284,13 @@
284 <input type='button' value='version' onclick='TheApp.cgi.sendCommand("/json/version")' />
285 <input type='button' value='stat' onclick='TheApp.cgi.sendCommand("/json/stat")' />
286 <input type='button' value='whoami' onclick='TheApp.cgi.sendCommand("/json/whoami")' />
287 <input type='button' value='cap' onclick='TheApp.cgi.sendCommand("/json/cap")' />
288 <input type='button' value='wiki/list' onclick='TheApp.loadPageList()' />
289 <!--
290 <input type='button' value='timeline/ci' onclick='TheApp.cgi.sendCommand("/json/timeline/ci")' />
291 -->
292
293 <!--
294 <input type='button' value='get whiki' onclick='TheApp.cgi.getPages("whiki")' />
295 <input type='button' value='get more' onclick='TheApp.cgi.getPages("HelloWorld/WhikiNews")' />
296 <input type='button' value='get client data' onclick='TheApp.cgi.getPageClientData("HelloWorld/whiki/WhikiCommands")' />
@@ -284,10 +306,11 @@
306 <tr>
307 <td width='25%' valign='top'>
308 <div id='pageListArea'></div>
309 </td>
310 <td width='75%' valign='top'>
311 <input type='button' value='Save' onclick='TheApp.savePage()' /><br/>
312 <textarea id='taPageContent' rows='20' cols='60'></textarea>
313 </td>
314 </tr>
315 <tr>
316 <th colspan='2'>Response <span id='timer'></span></th>
317
+73 -28
--- src/json.c
+++ src/json.c
@@ -481,10 +481,22 @@
481481
}
482482
}
483483
}
484484
return g.json.authToken;
485485
}
486
+
487
+/*
488
+** IFF json.reqPayload.o is not NULL then this returns
489
+** cson_object_get(json.reqPayload.o,pKey), else it returns NULL.
490
+**
491
+** The returned value is owned by (or shared with) json.reqPayload.v.
492
+*/
493
+cson_value * json_req_payload_get(char const *pKey){
494
+ return g.json.reqPayload.o
495
+ ? cson_object_get(g.json.reqPayload.o,pKey)
496
+ : NULL;
497
+}
486498
487499
/*
488500
** Initializes some JSON bits which need to be initialized relatively
489501
** early on. It should only be called from cgi_init() or
490502
** json_cmd_top() (early on in those functions).
@@ -942,10 +954,24 @@
942954
static cson_value * json_julian_to_timestamp(double j){
943955
return cson_value_new_integer((cson_int_t)
944956
db_int64(0,"SELECT strftime('%%s',%lf)",j)
945957
);
946958
}
959
+/*
960
+** Returns a timestamp value.
961
+*/
962
+static cson_int_t json_timestamp(){
963
+ return (cson_int_t)time(0);
964
+}
965
+/*
966
+** Returns a new JSON value (owned by the caller) representing
967
+** a timestamp. If timeVal is < 0 then time(0) is used to fetch
968
+** the time, else timeVal is used as-is
969
+*/
970
+static cson_value * json_new_timestamp(cson_int_t timeVal){
971
+ return cson_value_new_integer((timeVal<0) ? (cson_int_t)time(0) : timeVal);
972
+}
947973
948974
/*
949975
** Creates a new Fossil/JSON response envelope skeleton. It is owned
950976
** by the caller, who must eventually free it using cson_value_free(),
951977
** or add it to a cson container to transfer ownership. Returns NULL
@@ -986,35 +1012,11 @@
9861012
9871013
tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
9881014
SET("fossil");
9891015
9901016
{/* timestamp */
991
- cson_int_t jsTime;
992
-#if 1
993
- jsTime = (cson_int_t)time(0);
994
-#elif 1
995
- /* Ge Weijers has pointed out that time(0) commonly returns
996
- UTC, but is not required to by The Standard.
997
-
998
- There is a mkfmtime() function in cgi.c but it requires
999
- a (tm *), and i don't have that without calling gmtime()
1000
- or populating the tm myself (which is what i'm trying to
1001
- have done for me!).
1002
- */
1003
- time_t const t = (time_t)time(0);
1004
- struct tm gt = *gmtime(&t);
1005
- gt.tm_isdst = -1;
1006
- jsTime = (cson_int_t)mktime(&gt);
1007
-#else
1008
- /* i'm not 100% sure that the above actually does what i expect,
1009
- but we can't use the following because this function can be
1010
- called in response to error handling if the db cannot be opened
1011
- (or before that).
1012
- */
1013
- jsTime = (cson_int_t)db_int64(0, "SELECT strftime('%%s','now')");
1014
-#endif
1015
- tmp = cson_value_new_integer(jsTime);
1017
+ tmp = json_new_timestamp(-1);
10161018
SET(FossilJsonKeys.timestamp);
10171019
}
10181020
if( 0 != resultCode ){
10191021
if( ! pMsg ) pMsg = json_err_str(resultCode);
10201022
tmp = json_rc_string(resultCode);
@@ -1478,17 +1480,18 @@
14781480
}
14791481
14801482
14811483
static cson_value * json_wiki_list(unsigned int depth);
14821484
static cson_value * json_wiki_get(unsigned int depth);
1485
+static cson_value * json_wiki_save(unsigned int depth);
14831486
/*
14841487
** Mapping of /json/wiki/XXX commands/paths to callbacks.
14851488
*/
14861489
static const JsonPageDef JsonPageDefs_Wiki[] = {
14871490
{"get", json_wiki_get, 0},
14881491
{"list", json_wiki_list, 0},
1489
-{"save", json_page_nyi, 1},
1492
+{"save", json_wiki_save, 1},
14901493
/* Last entry MUST have a NULL name. */
14911494
{NULL,NULL,0}
14921495
};
14931496
14941497
/*
@@ -1578,20 +1581,62 @@
15781581
cson_object_set(pay,"version",json_new_string(pWiki->zBaseline))
15791582
/*FIXME: pWiki->zBaseline is NULL. How to get the version number?*/
15801583
;
15811584
cson_object_set(pay,"rid",cson_value_new_integer((cson_int_t)rid));
15821585
cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser));
1583
- cson_object_set(pay,"timestamp", json_julian_to_timestamp(pWiki->rDate));
1586
+ cson_object_set(pay,FossilJsonKeys.timestamp, json_julian_to_timestamp(pWiki->rDate));
15841587
cson_object_set(pay,"contentLength",cson_value_new_integer((cson_int_t)len));
15851588
cson_object_set(pay,"contentFormat",json_new_string(doParse?"html":"raw"));
15861589
cson_object_set(pay,"content",cson_value_new_string(zBody,len));
15871590
/*TODO: add 'T' (tag) fields*/
15881591
/*TODO: add the 'A' card (file attachment) entries?*/
15891592
manifest_destroy(pWiki);
15901593
return payV;
15911594
}
15921595
}
1596
+
1597
+/*
1598
+** Implementation of /json/wiki/save.
1599
+*/
1600
+static cson_value * json_wiki_save(unsigned int depth){
1601
+ Blob content = empty_blob;
1602
+ cson_value * nameV;
1603
+ cson_value * contentV;
1604
+ cson_value * payV = NULL;
1605
+ cson_object * pay = NULL;
1606
+ cson_string const * jstr = NULL;
1607
+ char const * zContent;
1608
+ char const * zBody = NULL;
1609
+ char const * zPageName;
1610
+ if( !g.perm.WrWiki ){
1611
+ g.json.resultCode = FSL_JSON_E_DENIED;
1612
+ return NULL;
1613
+ }
1614
+ nameV = json_req_payload_get("name");
1615
+ contentV = nameV ? json_req_payload_get("content") : NULL;
1616
+ if(!nameV || !contentV){
1617
+ g.json.resultCode = FSL_JSON_E_MISSING_ARGS;
1618
+ return NULL;
1619
+ }
1620
+ if( !cson_value_is_string(nameV)
1621
+ || !cson_value_is_string(contentV)){
1622
+ g.json.resultCode = FSL_JSON_E_INVALID_ARGS;
1623
+ return NULL;
1624
+ }
1625
+ zPageName = cson_string_cstr(cson_value_get_string(nameV));
1626
+ jstr = cson_value_get_string(contentV);
1627
+ blob_append(&content, cson_string_cstr(jstr),(int)cson_string_length_bytes(jstr));
1628
+ wiki_cmd_commit(zPageName, 0, &content);
1629
+ blob_reset(&content);
1630
+
1631
+ payV = cson_value_new_object();
1632
+ pay = cson_value_get_object(payV);
1633
+ cson_object_set( pay, "name", nameV );
1634
+ cson_object_set( pay, FossilJsonKeys.timestamp,
1635
+ json_new_timestamp(-1) );
1636
+ return payV;
1637
+}
15931638
15941639
/*
15951640
** Implementation of /json/wiki/list.
15961641
*/
15971642
static cson_value * json_wiki_list(unsigned int depth){
@@ -1987,11 +2032,11 @@
19872032
{"tag", json_page_nyi,0},
19882033
{"ticket", json_page_nyi,0},
19892034
{"timeline", json_page_timeline,0},
19902035
{"user", json_page_nyi,0},
19912036
{"version",json_page_version,0},
1992
-{"whoami",json_page_whoami,1},
2037
+{"whoami",json_page_whoami,1/*FIXME: work in CLI mode*/},
19932038
{"wiki",json_page_wiki,0},
19942039
/* Last entry MUST have a NULL name. */
19952040
{NULL,NULL,0}
19962041
};
19972042
19982043
--- src/json.c
+++ src/json.c
@@ -481,10 +481,22 @@
481 }
482 }
483 }
484 return g.json.authToken;
485 }
 
 
 
 
 
 
 
 
 
 
 
 
486
487 /*
488 ** Initializes some JSON bits which need to be initialized relatively
489 ** early on. It should only be called from cgi_init() or
490 ** json_cmd_top() (early on in those functions).
@@ -942,10 +954,24 @@
942 static cson_value * json_julian_to_timestamp(double j){
943 return cson_value_new_integer((cson_int_t)
944 db_int64(0,"SELECT strftime('%%s',%lf)",j)
945 );
946 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
947
948 /*
949 ** Creates a new Fossil/JSON response envelope skeleton. It is owned
950 ** by the caller, who must eventually free it using cson_value_free(),
951 ** or add it to a cson container to transfer ownership. Returns NULL
@@ -986,35 +1012,11 @@
986
987 tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
988 SET("fossil");
989
990 {/* timestamp */
991 cson_int_t jsTime;
992 #if 1
993 jsTime = (cson_int_t)time(0);
994 #elif 1
995 /* Ge Weijers has pointed out that time(0) commonly returns
996 UTC, but is not required to by The Standard.
997
998 There is a mkfmtime() function in cgi.c but it requires
999 a (tm *), and i don't have that without calling gmtime()
1000 or populating the tm myself (which is what i'm trying to
1001 have done for me!).
1002 */
1003 time_t const t = (time_t)time(0);
1004 struct tm gt = *gmtime(&t);
1005 gt.tm_isdst = -1;
1006 jsTime = (cson_int_t)mktime(&gt);
1007 #else
1008 /* i'm not 100% sure that the above actually does what i expect,
1009 but we can't use the following because this function can be
1010 called in response to error handling if the db cannot be opened
1011 (or before that).
1012 */
1013 jsTime = (cson_int_t)db_int64(0, "SELECT strftime('%%s','now')");
1014 #endif
1015 tmp = cson_value_new_integer(jsTime);
1016 SET(FossilJsonKeys.timestamp);
1017 }
1018 if( 0 != resultCode ){
1019 if( ! pMsg ) pMsg = json_err_str(resultCode);
1020 tmp = json_rc_string(resultCode);
@@ -1478,17 +1480,18 @@
1478 }
1479
1480
1481 static cson_value * json_wiki_list(unsigned int depth);
1482 static cson_value * json_wiki_get(unsigned int depth);
 
1483 /*
1484 ** Mapping of /json/wiki/XXX commands/paths to callbacks.
1485 */
1486 static const JsonPageDef JsonPageDefs_Wiki[] = {
1487 {"get", json_wiki_get, 0},
1488 {"list", json_wiki_list, 0},
1489 {"save", json_page_nyi, 1},
1490 /* Last entry MUST have a NULL name. */
1491 {NULL,NULL,0}
1492 };
1493
1494 /*
@@ -1578,20 +1581,62 @@
1578 cson_object_set(pay,"version",json_new_string(pWiki->zBaseline))
1579 /*FIXME: pWiki->zBaseline is NULL. How to get the version number?*/
1580 ;
1581 cson_object_set(pay,"rid",cson_value_new_integer((cson_int_t)rid));
1582 cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser));
1583 cson_object_set(pay,"timestamp", json_julian_to_timestamp(pWiki->rDate));
1584 cson_object_set(pay,"contentLength",cson_value_new_integer((cson_int_t)len));
1585 cson_object_set(pay,"contentFormat",json_new_string(doParse?"html":"raw"));
1586 cson_object_set(pay,"content",cson_value_new_string(zBody,len));
1587 /*TODO: add 'T' (tag) fields*/
1588 /*TODO: add the 'A' card (file attachment) entries?*/
1589 manifest_destroy(pWiki);
1590 return payV;
1591 }
1592 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1593
1594 /*
1595 ** Implementation of /json/wiki/list.
1596 */
1597 static cson_value * json_wiki_list(unsigned int depth){
@@ -1987,11 +2032,11 @@
1987 {"tag", json_page_nyi,0},
1988 {"ticket", json_page_nyi,0},
1989 {"timeline", json_page_timeline,0},
1990 {"user", json_page_nyi,0},
1991 {"version",json_page_version,0},
1992 {"whoami",json_page_whoami,1},
1993 {"wiki",json_page_wiki,0},
1994 /* Last entry MUST have a NULL name. */
1995 {NULL,NULL,0}
1996 };
1997
1998
--- src/json.c
+++ src/json.c
@@ -481,10 +481,22 @@
481 }
482 }
483 }
484 return g.json.authToken;
485 }
486
487 /*
488 ** IFF json.reqPayload.o is not NULL then this returns
489 ** cson_object_get(json.reqPayload.o,pKey), else it returns NULL.
490 **
491 ** The returned value is owned by (or shared with) json.reqPayload.v.
492 */
493 cson_value * json_req_payload_get(char const *pKey){
494 return g.json.reqPayload.o
495 ? cson_object_get(g.json.reqPayload.o,pKey)
496 : NULL;
497 }
498
499 /*
500 ** Initializes some JSON bits which need to be initialized relatively
501 ** early on. It should only be called from cgi_init() or
502 ** json_cmd_top() (early on in those functions).
@@ -942,10 +954,24 @@
954 static cson_value * json_julian_to_timestamp(double j){
955 return cson_value_new_integer((cson_int_t)
956 db_int64(0,"SELECT strftime('%%s',%lf)",j)
957 );
958 }
959 /*
960 ** Returns a timestamp value.
961 */
962 static cson_int_t json_timestamp(){
963 return (cson_int_t)time(0);
964 }
965 /*
966 ** Returns a new JSON value (owned by the caller) representing
967 ** a timestamp. If timeVal is < 0 then time(0) is used to fetch
968 ** the time, else timeVal is used as-is
969 */
970 static cson_value * json_new_timestamp(cson_int_t timeVal){
971 return cson_value_new_integer((timeVal<0) ? (cson_int_t)time(0) : timeVal);
972 }
973
974 /*
975 ** Creates a new Fossil/JSON response envelope skeleton. It is owned
976 ** by the caller, who must eventually free it using cson_value_free(),
977 ** or add it to a cson container to transfer ownership. Returns NULL
@@ -986,35 +1012,11 @@
1012
1013 tmp = cson_value_new_string(MANIFEST_UUID,strlen(MANIFEST_UUID));
1014 SET("fossil");
1015
1016 {/* timestamp */
1017 tmp = json_new_timestamp(-1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1018 SET(FossilJsonKeys.timestamp);
1019 }
1020 if( 0 != resultCode ){
1021 if( ! pMsg ) pMsg = json_err_str(resultCode);
1022 tmp = json_rc_string(resultCode);
@@ -1478,17 +1480,18 @@
1480 }
1481
1482
1483 static cson_value * json_wiki_list(unsigned int depth);
1484 static cson_value * json_wiki_get(unsigned int depth);
1485 static cson_value * json_wiki_save(unsigned int depth);
1486 /*
1487 ** Mapping of /json/wiki/XXX commands/paths to callbacks.
1488 */
1489 static const JsonPageDef JsonPageDefs_Wiki[] = {
1490 {"get", json_wiki_get, 0},
1491 {"list", json_wiki_list, 0},
1492 {"save", json_wiki_save, 1},
1493 /* Last entry MUST have a NULL name. */
1494 {NULL,NULL,0}
1495 };
1496
1497 /*
@@ -1578,20 +1581,62 @@
1581 cson_object_set(pay,"version",json_new_string(pWiki->zBaseline))
1582 /*FIXME: pWiki->zBaseline is NULL. How to get the version number?*/
1583 ;
1584 cson_object_set(pay,"rid",cson_value_new_integer((cson_int_t)rid));
1585 cson_object_set(pay,"lastSavedBy",json_new_string(pWiki->zUser));
1586 cson_object_set(pay,FossilJsonKeys.timestamp, json_julian_to_timestamp(pWiki->rDate));
1587 cson_object_set(pay,"contentLength",cson_value_new_integer((cson_int_t)len));
1588 cson_object_set(pay,"contentFormat",json_new_string(doParse?"html":"raw"));
1589 cson_object_set(pay,"content",cson_value_new_string(zBody,len));
1590 /*TODO: add 'T' (tag) fields*/
1591 /*TODO: add the 'A' card (file attachment) entries?*/
1592 manifest_destroy(pWiki);
1593 return payV;
1594 }
1595 }
1596
1597 /*
1598 ** Implementation of /json/wiki/save.
1599 */
1600 static cson_value * json_wiki_save(unsigned int depth){
1601 Blob content = empty_blob;
1602 cson_value * nameV;
1603 cson_value * contentV;
1604 cson_value * payV = NULL;
1605 cson_object * pay = NULL;
1606 cson_string const * jstr = NULL;
1607 char const * zContent;
1608 char const * zBody = NULL;
1609 char const * zPageName;
1610 if( !g.perm.WrWiki ){
1611 g.json.resultCode = FSL_JSON_E_DENIED;
1612 return NULL;
1613 }
1614 nameV = json_req_payload_get("name");
1615 contentV = nameV ? json_req_payload_get("content") : NULL;
1616 if(!nameV || !contentV){
1617 g.json.resultCode = FSL_JSON_E_MISSING_ARGS;
1618 return NULL;
1619 }
1620 if( !cson_value_is_string(nameV)
1621 || !cson_value_is_string(contentV)){
1622 g.json.resultCode = FSL_JSON_E_INVALID_ARGS;
1623 return NULL;
1624 }
1625 zPageName = cson_string_cstr(cson_value_get_string(nameV));
1626 jstr = cson_value_get_string(contentV);
1627 blob_append(&content, cson_string_cstr(jstr),(int)cson_string_length_bytes(jstr));
1628 wiki_cmd_commit(zPageName, 0, &content);
1629 blob_reset(&content);
1630
1631 payV = cson_value_new_object();
1632 pay = cson_value_get_object(payV);
1633 cson_object_set( pay, "name", nameV );
1634 cson_object_set( pay, FossilJsonKeys.timestamp,
1635 json_new_timestamp(-1) );
1636 return payV;
1637 }
1638
1639 /*
1640 ** Implementation of /json/wiki/list.
1641 */
1642 static cson_value * json_wiki_list(unsigned int depth){
@@ -1987,11 +2032,11 @@
2032 {"tag", json_page_nyi,0},
2033 {"ticket", json_page_nyi,0},
2034 {"timeline", json_page_timeline,0},
2035 {"user", json_page_nyi,0},
2036 {"version",json_page_version,0},
2037 {"whoami",json_page_whoami,1/*FIXME: work in CLI mode*/},
2038 {"wiki",json_page_wiki,0},
2039 /* Last entry MUST have a NULL name. */
2040 {NULL,NULL,0}
2041 };
2042
2043
+2
--- src/wiki.c
+++ src/wiki.c
@@ -801,13 +801,15 @@
801801
" WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
802802
" ORDER BY x.mtime DESC LIMIT 1",
803803
zPageName
804804
);
805805
if( rid==0 && !isNew ){
806
+ g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
806807
fossil_fatal("no such wiki page: %s", zPageName);
807808
}
808809
if( rid!=0 && isNew ){
810
+ g.json.resultCode = FSL_JSON_E_DENIED/*need a better code for this*/;
809811
fossil_fatal("wiki page %s already exists", zPageName);
810812
}
811813
812814
blob_zero(&wiki);
813815
zDate = date_in_standard_format("now");
814816
--- src/wiki.c
+++ src/wiki.c
@@ -801,13 +801,15 @@
801 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
802 " ORDER BY x.mtime DESC LIMIT 1",
803 zPageName
804 );
805 if( rid==0 && !isNew ){
 
806 fossil_fatal("no such wiki page: %s", zPageName);
807 }
808 if( rid!=0 && isNew ){
 
809 fossil_fatal("wiki page %s already exists", zPageName);
810 }
811
812 blob_zero(&wiki);
813 zDate = date_in_standard_format("now");
814
--- src/wiki.c
+++ src/wiki.c
@@ -801,13 +801,15 @@
801 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
802 " ORDER BY x.mtime DESC LIMIT 1",
803 zPageName
804 );
805 if( rid==0 && !isNew ){
806 g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
807 fossil_fatal("no such wiki page: %s", zPageName);
808 }
809 if( rid!=0 && isNew ){
810 g.json.resultCode = FSL_JSON_E_DENIED/*need a better code for this*/;
811 fossil_fatal("wiki page %s already exists", zPageName);
812 }
813
814 blob_zero(&wiki);
815 zDate = date_in_standard_format("now");
816

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button