Fossil SCM

Initial support for managing technotes from the command-line.

djv 2015-12-19 14:12 UTC trunk
Commit 0a13f4cb5fe4d5da9ee8555046bf4b5f6f24a32a
2 files changed +162 -81 +136 -64
+162 -81
--- src/event.c
+++ src/event.c
@@ -219,10 +219,114 @@
219219
@ </pre>
220220
}
221221
style_footer();
222222
manifest_destroy(pTNote);
223223
}
224
+
225
+/*
226
+** Add or update a new tech note to the repository.
227
+**
228
+** returns 1 if the tech note was added or updated, 0 if the
229
+** update failed making an invalid artifact
230
+*/
231
+int event_commit_common(
232
+ int rid, /* prior version of the technote, if any */
233
+ const char *zId, /* UUID for the technote */
234
+ const char *zBody, /* The content of the technote */
235
+ char *zETime, /* Timestamp for the technote */
236
+ const char *zMimetype, /* Mimetype to use. May be NULL */
237
+ const char *zComment, /* Timeline comment */
238
+ const char *zTags, /* Tags for the technote */
239
+ const char *zClr /* Background color */
240
+){
241
+ Blob event;
242
+ char *zDate;
243
+ Blob cksum;
244
+ int nrid, n;
245
+
246
+ blob_init(&event, 0, 0);
247
+ db_begin_transaction();
248
+ while( fossil_isspace(zComment[0]) ) zComment++;
249
+ n = strlen(zComment);
250
+ while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; }
251
+ if( n>0 ){
252
+ blob_appendf(&event, "C %#F\n", n, zComment);
253
+ }
254
+ zDate = date_in_standard_format("now");
255
+ blob_appendf(&event, "D %s\n", zDate);
256
+ free(zDate);
257
+
258
+ zETime[10] = 'T';
259
+ blob_appendf(&event, "E %s %s\n", zETime, zId);
260
+ zETime[10] = ' ';
261
+ if( rid ){
262
+ char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
263
+ blob_appendf(&event, "P %s\n", zUuid);
264
+ free(zUuid);
265
+ }
266
+ if( zMimetype && zMimetype[0] ){
267
+ blob_appendf(&event, "N %s\n", zMimetype);
268
+ }
269
+ if( zClr && zClr[0] ){
270
+ blob_appendf(&event, "T +bgcolor * %F\n", zClr);
271
+ }
272
+ if( zTags && zTags[0] ){
273
+ Blob tags, one;
274
+ int i, j;
275
+ Stmt q;
276
+ char *zBlob;
277
+
278
+ /* Load the tags string into a blob */
279
+ blob_zero(&tags);
280
+ blob_append(&tags, zTags, -1);
281
+
282
+ /* Collapse all sequences of whitespace and "," characters into
283
+ ** a single space character */
284
+ zBlob = blob_str(&tags);
285
+ for(i=j=0; zBlob[i]; i++, j++){
286
+ if( fossil_isspace(zBlob[i]) || zBlob[i]==',' ){
287
+ while( fossil_isspace(zBlob[i+1]) ){ i++; }
288
+ zBlob[j] = ' ';
289
+ }else{
290
+ zBlob[j] = zBlob[i];
291
+ }
292
+ }
293
+ blob_resize(&tags, j);
294
+
295
+ /* Parse out each tag and load it into a temporary table for sorting */
296
+ db_multi_exec("CREATE TEMP TABLE newtags(x);");
297
+ while( blob_token(&tags, &one) ){
298
+ db_multi_exec("INSERT INTO newtags VALUES(%B)", &one);
299
+ }
300
+ blob_reset(&tags);
301
+
302
+ /* Extract the tags in sorted order and make an entry in the
303
+ ** artifact for each. */
304
+ db_prepare(&q, "SELECT x FROM newtags ORDER BY x");
305
+ while( db_step(&q)==SQLITE_ROW ){
306
+ blob_appendf(&event, "T +sym-%F *\n", db_column_text(&q, 0));
307
+ }
308
+ db_finalize(&q);
309
+ }
310
+ if( !login_is_nobody() ){
311
+ blob_appendf(&event, "U %F\n", login_name());
312
+ }
313
+ blob_appendf(&event, "W %d\n%s\n", strlen(zBody), zBody);
314
+ md5sum_blob(&event, &cksum);
315
+ blob_appendf(&event, "Z %b\n", &cksum);
316
+ blob_reset(&cksum);
317
+ nrid = content_put(&event);
318
+ db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
319
+ if( manifest_crosslink(nrid, &event, MC_NONE)==0 ){
320
+ db_end_transaction(1);
321
+ return 0;
322
+ }
323
+ assert( blob_is_reset(&event) );
324
+ content_deltify(rid, nrid, 0);
325
+ db_end_transaction(0);
326
+ return 1;
327
+}
224328
225329
/*
226330
** WEBPAGE: technoteedit
227331
** WEBPAGE: eventedit
228332
**
@@ -323,97 +427,19 @@
323427
);
324428
}
325429
}
326430
zETime = db_text(0, "SELECT coalesce(datetime(%Q),datetime('now'))", zETime);
327431
if( P("submit")!=0 && (zBody!=0 && zComment!=0) ){
328
- char *zDate;
329
- Blob cksum;
330
- int nrid, n;
331
- blob_init(&event, 0, 0);
332
- db_begin_transaction();
333432
login_verify_csrf_secret();
334
- while( fossil_isspace(zComment[0]) ) zComment++;
335
- n = strlen(zComment);
336
- while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; }
337
- if( n>0 ){
338
- blob_appendf(&event, "C %#F\n", n, zComment);
339
- }
340
- zDate = date_in_standard_format("now");
341
- blob_appendf(&event, "D %s\n", zDate);
342
- free(zDate);
343
- zETime[10] = 'T';
344
- blob_appendf(&event, "E %s %s\n", zETime, zId);
345
- zETime[10] = ' ';
346
- if( rid ){
347
- char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
348
- blob_appendf(&event, "P %s\n", zUuid);
349
- free(zUuid);
350
- }
351
- if( zMimetype && zMimetype[0] ){
352
- blob_appendf(&event, "N %s\n", zMimetype);
353
- }
354
- if( zClr && zClr[0] ){
355
- blob_appendf(&event, "T +bgcolor * %F\n", zClr);
356
- }
357
- if( zTags && zTags[0] ){
358
- Blob tags, one;
359
- int i, j;
360
- Stmt q;
361
- char *zBlob;
362
-
363
- /* Load the tags string into a blob */
364
- blob_zero(&tags);
365
- blob_append(&tags, zTags, -1);
366
-
367
- /* Collapse all sequences of whitespace and "," characters into
368
- ** a single space character */
369
- zBlob = blob_str(&tags);
370
- for(i=j=0; zBlob[i]; i++, j++){
371
- if( fossil_isspace(zBlob[i]) || zBlob[i]==',' ){
372
- while( fossil_isspace(zBlob[i+1]) ){ i++; }
373
- zBlob[j] = ' ';
374
- }else{
375
- zBlob[j] = zBlob[i];
376
- }
377
- }
378
- blob_resize(&tags, j);
379
-
380
- /* Parse out each tag and load it into a temporary table for sorting */
381
- db_multi_exec("CREATE TEMP TABLE newtags(x);");
382
- while( blob_token(&tags, &one) ){
383
- db_multi_exec("INSERT INTO newtags VALUES(%B)", &one);
384
- }
385
- blob_reset(&tags);
386
-
387
- /* Extract the tags in sorted order and make an entry in the
388
- ** artifact for each. */
389
- db_prepare(&q, "SELECT x FROM newtags ORDER BY x");
390
- while( db_step(&q)==SQLITE_ROW ){
391
- blob_appendf(&event, "T +sym-%F *\n", db_column_text(&q, 0));
392
- }
393
- db_finalize(&q);
394
- }
395
- if( !login_is_nobody() ){
396
- blob_appendf(&event, "U %F\n", login_name());
397
- }
398
- blob_appendf(&event, "W %d\n%s\n", strlen(zBody), zBody);
399
- md5sum_blob(&event, &cksum);
400
- blob_appendf(&event, "Z %b\n", &cksum);
401
- blob_reset(&cksum);
402
- nrid = content_put(&event);
403
- db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
404
- if( manifest_crosslink(nrid, &event, MC_NONE)==0 ){
405
- db_end_transaction(1);
433
+ if ( !event_commit_common(rid, zId, zBody, zETime, zMimetype,
434
+ zComment, zTags, zClr) ){
406435
style_header("Error");
407436
@ Internal error: Fossil tried to make an invalid artifact for
408
- @ the edited technode.
437
+ @ the edited technote.
409438
style_footer();
410439
return;
411440
}
412
- assert( blob_is_reset(&event) );
413
- content_deltify(rid, nrid, 0);
414
- db_end_transaction(0);
415441
cgi_redirectf("technote?name=%T", zId);
416442
}
417443
if( P("cancel")!=0 ){
418444
cgi_redirectf("technote?name=%T", zId);
419445
return;
@@ -497,5 +523,60 @@
497523
@ <input type="submit" name="cancel" value="Cancel" />
498524
@ </td></tr></table>
499525
@ </div></form>
500526
style_footer();
501527
}
528
+
529
+/*
530
+** Add a new tech note to the repository. The timestamp is
531
+** given by the zETime parameter. isNew must be true to create
532
+** a new page. If no previous page with the name zPageName exists
533
+** and isNew is false, then this routine throws an error.
534
+*/
535
+int event_cmd_commit(
536
+ char *zETime, /* Timestamp */
537
+ int isNew, /* Create a new page if true */
538
+ Blob *pContent, /* Content of the new page */
539
+ const char *zMimeType, /* Mime-type or NULL */
540
+ const char *zComment, /* Timeline comment */
541
+ const char *zTags, /* List of tags */
542
+ const char *zClr /* Background color */
543
+){
544
+ int rid; /* Artifact id of the tech note */
545
+ const char *zId; /* id of the tech note */
546
+ rid = db_int(0, "SELECT objid FROM event"
547
+ " WHERE datetime(mtime)=datetime('%q') AND type = 'e'"
548
+ " LIMIT 1",
549
+ zETime
550
+ );
551
+ if( rid==0 && !isNew ){
552
+#ifdef FOSSIL_ENABLE_JSON
553
+ g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
554
+#endif
555
+ fossil_fatal("no such tech note: %s", zETime);
556
+ }
557
+ if( rid!=0 && isNew ){
558
+#ifdef FOSSIL_ENABLE_JSON
559
+ g.json.resultCode = FSL_JSON_E_RESOURCE_ALREADY_EXISTS;
560
+#endif
561
+ fossil_fatal("tech note %s already exists", zETime);
562
+ }
563
+
564
+ if ( isNew ){
565
+ zId = db_text(0, "SELECT lower(hex(randomblob(20)))");
566
+ }else{
567
+ zId = db_text(0,
568
+ "SELECT substr(tagname,7) FROM tag"
569
+ " WHERE tagid=(SELECT tagid FROM event WHERE objid='%d')",
570
+ rid
571
+ );
572
+ }
573
+
574
+ user_select();
575
+ if (event_commit_common(rid, zId, blob_str(pContent), zETime,
576
+ zMimeType, zComment, zTags, zClr)==0 ){
577
+#ifdef FOSSIL_ENABLE_JSON
578
+ g.json.resultCode = FSL_JSON_E_ASSERT;
579
+#endif
580
+ fossil_fatal("tried to make an invalid artifact for the technote.\n");
581
+ }
582
+}
502583
--- src/event.c
+++ src/event.c
@@ -219,10 +219,114 @@
219 @ </pre>
220 }
221 style_footer();
222 manifest_destroy(pTNote);
223 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
225 /*
226 ** WEBPAGE: technoteedit
227 ** WEBPAGE: eventedit
228 **
@@ -323,97 +427,19 @@
323 );
324 }
325 }
326 zETime = db_text(0, "SELECT coalesce(datetime(%Q),datetime('now'))", zETime);
327 if( P("submit")!=0 && (zBody!=0 && zComment!=0) ){
328 char *zDate;
329 Blob cksum;
330 int nrid, n;
331 blob_init(&event, 0, 0);
332 db_begin_transaction();
333 login_verify_csrf_secret();
334 while( fossil_isspace(zComment[0]) ) zComment++;
335 n = strlen(zComment);
336 while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; }
337 if( n>0 ){
338 blob_appendf(&event, "C %#F\n", n, zComment);
339 }
340 zDate = date_in_standard_format("now");
341 blob_appendf(&event, "D %s\n", zDate);
342 free(zDate);
343 zETime[10] = 'T';
344 blob_appendf(&event, "E %s %s\n", zETime, zId);
345 zETime[10] = ' ';
346 if( rid ){
347 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
348 blob_appendf(&event, "P %s\n", zUuid);
349 free(zUuid);
350 }
351 if( zMimetype && zMimetype[0] ){
352 blob_appendf(&event, "N %s\n", zMimetype);
353 }
354 if( zClr && zClr[0] ){
355 blob_appendf(&event, "T +bgcolor * %F\n", zClr);
356 }
357 if( zTags && zTags[0] ){
358 Blob tags, one;
359 int i, j;
360 Stmt q;
361 char *zBlob;
362
363 /* Load the tags string into a blob */
364 blob_zero(&tags);
365 blob_append(&tags, zTags, -1);
366
367 /* Collapse all sequences of whitespace and "," characters into
368 ** a single space character */
369 zBlob = blob_str(&tags);
370 for(i=j=0; zBlob[i]; i++, j++){
371 if( fossil_isspace(zBlob[i]) || zBlob[i]==',' ){
372 while( fossil_isspace(zBlob[i+1]) ){ i++; }
373 zBlob[j] = ' ';
374 }else{
375 zBlob[j] = zBlob[i];
376 }
377 }
378 blob_resize(&tags, j);
379
380 /* Parse out each tag and load it into a temporary table for sorting */
381 db_multi_exec("CREATE TEMP TABLE newtags(x);");
382 while( blob_token(&tags, &one) ){
383 db_multi_exec("INSERT INTO newtags VALUES(%B)", &one);
384 }
385 blob_reset(&tags);
386
387 /* Extract the tags in sorted order and make an entry in the
388 ** artifact for each. */
389 db_prepare(&q, "SELECT x FROM newtags ORDER BY x");
390 while( db_step(&q)==SQLITE_ROW ){
391 blob_appendf(&event, "T +sym-%F *\n", db_column_text(&q, 0));
392 }
393 db_finalize(&q);
394 }
395 if( !login_is_nobody() ){
396 blob_appendf(&event, "U %F\n", login_name());
397 }
398 blob_appendf(&event, "W %d\n%s\n", strlen(zBody), zBody);
399 md5sum_blob(&event, &cksum);
400 blob_appendf(&event, "Z %b\n", &cksum);
401 blob_reset(&cksum);
402 nrid = content_put(&event);
403 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
404 if( manifest_crosslink(nrid, &event, MC_NONE)==0 ){
405 db_end_transaction(1);
406 style_header("Error");
407 @ Internal error: Fossil tried to make an invalid artifact for
408 @ the edited technode.
409 style_footer();
410 return;
411 }
412 assert( blob_is_reset(&event) );
413 content_deltify(rid, nrid, 0);
414 db_end_transaction(0);
415 cgi_redirectf("technote?name=%T", zId);
416 }
417 if( P("cancel")!=0 ){
418 cgi_redirectf("technote?name=%T", zId);
419 return;
@@ -497,5 +523,60 @@
497 @ <input type="submit" name="cancel" value="Cancel" />
498 @ </td></tr></table>
499 @ </div></form>
500 style_footer();
501 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
--- src/event.c
+++ src/event.c
@@ -219,10 +219,114 @@
219 @ </pre>
220 }
221 style_footer();
222 manifest_destroy(pTNote);
223 }
224
225 /*
226 ** Add or update a new tech note to the repository.
227 **
228 ** returns 1 if the tech note was added or updated, 0 if the
229 ** update failed making an invalid artifact
230 */
231 int event_commit_common(
232 int rid, /* prior version of the technote, if any */
233 const char *zId, /* UUID for the technote */
234 const char *zBody, /* The content of the technote */
235 char *zETime, /* Timestamp for the technote */
236 const char *zMimetype, /* Mimetype to use. May be NULL */
237 const char *zComment, /* Timeline comment */
238 const char *zTags, /* Tags for the technote */
239 const char *zClr /* Background color */
240 ){
241 Blob event;
242 char *zDate;
243 Blob cksum;
244 int nrid, n;
245
246 blob_init(&event, 0, 0);
247 db_begin_transaction();
248 while( fossil_isspace(zComment[0]) ) zComment++;
249 n = strlen(zComment);
250 while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; }
251 if( n>0 ){
252 blob_appendf(&event, "C %#F\n", n, zComment);
253 }
254 zDate = date_in_standard_format("now");
255 blob_appendf(&event, "D %s\n", zDate);
256 free(zDate);
257
258 zETime[10] = 'T';
259 blob_appendf(&event, "E %s %s\n", zETime, zId);
260 zETime[10] = ' ';
261 if( rid ){
262 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
263 blob_appendf(&event, "P %s\n", zUuid);
264 free(zUuid);
265 }
266 if( zMimetype && zMimetype[0] ){
267 blob_appendf(&event, "N %s\n", zMimetype);
268 }
269 if( zClr && zClr[0] ){
270 blob_appendf(&event, "T +bgcolor * %F\n", zClr);
271 }
272 if( zTags && zTags[0] ){
273 Blob tags, one;
274 int i, j;
275 Stmt q;
276 char *zBlob;
277
278 /* Load the tags string into a blob */
279 blob_zero(&tags);
280 blob_append(&tags, zTags, -1);
281
282 /* Collapse all sequences of whitespace and "," characters into
283 ** a single space character */
284 zBlob = blob_str(&tags);
285 for(i=j=0; zBlob[i]; i++, j++){
286 if( fossil_isspace(zBlob[i]) || zBlob[i]==',' ){
287 while( fossil_isspace(zBlob[i+1]) ){ i++; }
288 zBlob[j] = ' ';
289 }else{
290 zBlob[j] = zBlob[i];
291 }
292 }
293 blob_resize(&tags, j);
294
295 /* Parse out each tag and load it into a temporary table for sorting */
296 db_multi_exec("CREATE TEMP TABLE newtags(x);");
297 while( blob_token(&tags, &one) ){
298 db_multi_exec("INSERT INTO newtags VALUES(%B)", &one);
299 }
300 blob_reset(&tags);
301
302 /* Extract the tags in sorted order and make an entry in the
303 ** artifact for each. */
304 db_prepare(&q, "SELECT x FROM newtags ORDER BY x");
305 while( db_step(&q)==SQLITE_ROW ){
306 blob_appendf(&event, "T +sym-%F *\n", db_column_text(&q, 0));
307 }
308 db_finalize(&q);
309 }
310 if( !login_is_nobody() ){
311 blob_appendf(&event, "U %F\n", login_name());
312 }
313 blob_appendf(&event, "W %d\n%s\n", strlen(zBody), zBody);
314 md5sum_blob(&event, &cksum);
315 blob_appendf(&event, "Z %b\n", &cksum);
316 blob_reset(&cksum);
317 nrid = content_put(&event);
318 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
319 if( manifest_crosslink(nrid, &event, MC_NONE)==0 ){
320 db_end_transaction(1);
321 return 0;
322 }
323 assert( blob_is_reset(&event) );
324 content_deltify(rid, nrid, 0);
325 db_end_transaction(0);
326 return 1;
327 }
328
329 /*
330 ** WEBPAGE: technoteedit
331 ** WEBPAGE: eventedit
332 **
@@ -323,97 +427,19 @@
427 );
428 }
429 }
430 zETime = db_text(0, "SELECT coalesce(datetime(%Q),datetime('now'))", zETime);
431 if( P("submit")!=0 && (zBody!=0 && zComment!=0) ){
 
 
 
 
 
432 login_verify_csrf_secret();
433 if ( !event_commit_common(rid, zId, zBody, zETime, zMimetype,
434 zComment, zTags, zClr) ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435 style_header("Error");
436 @ Internal error: Fossil tried to make an invalid artifact for
437 @ the edited technote.
438 style_footer();
439 return;
440 }
 
 
 
441 cgi_redirectf("technote?name=%T", zId);
442 }
443 if( P("cancel")!=0 ){
444 cgi_redirectf("technote?name=%T", zId);
445 return;
@@ -497,5 +523,60 @@
523 @ <input type="submit" name="cancel" value="Cancel" />
524 @ </td></tr></table>
525 @ </div></form>
526 style_footer();
527 }
528
529 /*
530 ** Add a new tech note to the repository. The timestamp is
531 ** given by the zETime parameter. isNew must be true to create
532 ** a new page. If no previous page with the name zPageName exists
533 ** and isNew is false, then this routine throws an error.
534 */
535 int event_cmd_commit(
536 char *zETime, /* Timestamp */
537 int isNew, /* Create a new page if true */
538 Blob *pContent, /* Content of the new page */
539 const char *zMimeType, /* Mime-type or NULL */
540 const char *zComment, /* Timeline comment */
541 const char *zTags, /* List of tags */
542 const char *zClr /* Background color */
543 ){
544 int rid; /* Artifact id of the tech note */
545 const char *zId; /* id of the tech note */
546 rid = db_int(0, "SELECT objid FROM event"
547 " WHERE datetime(mtime)=datetime('%q') AND type = 'e'"
548 " LIMIT 1",
549 zETime
550 );
551 if( rid==0 && !isNew ){
552 #ifdef FOSSIL_ENABLE_JSON
553 g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
554 #endif
555 fossil_fatal("no such tech note: %s", zETime);
556 }
557 if( rid!=0 && isNew ){
558 #ifdef FOSSIL_ENABLE_JSON
559 g.json.resultCode = FSL_JSON_E_RESOURCE_ALREADY_EXISTS;
560 #endif
561 fossil_fatal("tech note %s already exists", zETime);
562 }
563
564 if ( isNew ){
565 zId = db_text(0, "SELECT lower(hex(randomblob(20)))");
566 }else{
567 zId = db_text(0,
568 "SELECT substr(tagname,7) FROM tag"
569 " WHERE tagid=(SELECT tagid FROM event WHERE objid='%d')",
570 rid
571 );
572 }
573
574 user_select();
575 if (event_commit_common(rid, zId, blob_str(pContent), zETime,
576 zMimeType, zComment, zTags, zClr)==0 ){
577 #ifdef FOSSIL_ENABLE_JSON
578 g.json.resultCode = FSL_JSON_E_ASSERT;
579 #endif
580 fossil_fatal("tried to make an invalid artifact for the technote.\n");
581 }
582 }
583
+136 -64
--- src/wiki.c
+++ src/wiki.c
@@ -584,11 +584,12 @@
584584
@ <br /><textarea name="w" class="wikiedit" cols="80"
585585
@ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
586586
@ <br />
587587
if( db_get_boolean("wysiwyg-wiki", 0) ){
588588
@ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor"
589
- @ onclick='return confirm("Switching to WYSIWYG-mode\nwill erase your markup\nedits. Continue?")' />
589
+ @ onclick='return confirm("Switching to WYSIWYG-mode\n"+
590
+ @ "will erase your markup\nedits. Continue?")' />
590591
}
591592
@ <input type="submit" name="preview" value="Preview Your Changes" />
592593
}else{
593594
/* Wysiwyg editing */
594595
Blob html, temp;
@@ -602,11 +603,12 @@
602603
blob_reset(&temp);
603604
wysiwygEditor("w", blob_str(&html), 60, n);
604605
blob_reset(&html);
605606
@ <br />
606607
@ <input type="submit" name="edit-markup" value="Markup Editor"
607
- @ onclick='return confirm("Switching to markup-mode\nwill erase your WYSIWYG\nedits. Continue?")' />
608
+ @ onclick='return confirm("Switching to markup-mode\n"+
609
+ @ "will erase your WYSIWYG\nedits. Continue?")' />
608610
}
609611
login_insert_csrf_secret();
610612
@ <input type="submit" name="submit" value="Apply These Changes" />
611613
@ <input type="hidden" name="name" value="%h(zPageName)" />
612614
@ <input type="submit" name="cancel" value="Cancel"
@@ -1137,36 +1139,44 @@
11371139
}
11381140
11391141
/*
11401142
** COMMAND: wiki*
11411143
**
1142
-** Usage: %fossil wiki (export|create|commit|list) WikiName
1143
-**
1144
-** Run various subcommands to work with wiki entries.
1145
-**
1146
-** %fossil wiki export PAGENAME ?FILE?
1147
-**
1148
-** Sends the latest version of the PAGENAME wiki
1149
-** entry to the given file or standard output.
1150
-**
1151
-** %fossil wiki commit PAGENAME ?FILE? [-mimetype TEXT-FORMAT]
1152
-**
1153
-** Commit changes to a wiki page from FILE or from standard
1154
-** input. The -mimetype (-M) flag specifies the mime type,
1155
-** defaulting to the type used by the previous version of
1156
-** the page or (for new pages) text/x-fossil-wiki.
1157
-**
1158
-** %fossil wiki create PAGENAME ?FILE? [-mimetype TEXT-FORMAT]
1159
-**
1160
-** Create a new wiki page with initial content taken from
1161
-** FILE or from standard input.
1162
-**
1163
-** %fossil wiki list
1164
-** %fossil wiki ls
1165
-**
1166
-** Lists all wiki entries, one per line, ordered
1167
-** case-insensitively by name.
1144
+** Usage: ../fossil wiki (export|create|commit|list) WikiName
1145
+**
1146
+** Run various subcommands to work with wiki entries or tech notes.
1147
+**
1148
+** ../fossil wiki export ?PAGENAME? ?FILE? [-t|--technote DATETIME]
1149
+**
1150
+** Sends the latest version of either the PAGENAME wiki entry
1151
+** or the DATETIME tech note to the given file or standard
1152
+** output. One of PAGENAME or DATETIME must be specified.
1153
+**
1154
+** ../fossil wiki (create|commit) PAGENAME ?FILE? ?OPTIONS?
1155
+**
1156
+** Create a new or commit changes to an existing wiki page or
1157
+** technote from FILE or from standard input.
1158
+**
1159
+** Options:
1160
+** -M|--mimetype TEXT-FORMAT The mime type of the update defaulting
1161
+** defaulting to the type used by the
1162
+** previous version of the page or (for
1163
+** new pages) text/x-fossil-wiki.
1164
+** -t|--technote DATETIME Specifies the timestamp of the technote
1165
+** to be created or updated.
1166
+** --technote-tags TAGS The set of tags for a technote.
1167
+** --technote-bgcolor COLOR The color used for the technote on the
1168
+** timeline.
1169
+**
1170
+** ../fossil wiki list ?-technote?
1171
+** ../fossil wiki ls ?-technote?
1172
+**
1173
+** Lists all wiki entries, one per line, ordered
1174
+** case-insensitively by name. The -technote flag
1175
+** specifies that technotes will be listed instead of
1176
+** the wiki entries, which will be listed in order
1177
+** timestamp.
11681178
**
11691179
*/
11701180
void wiki_cmd(void){
11711181
int n;
11721182
db_find_and_open_repository(0, 0);
@@ -1179,33 +1189,54 @@
11791189
}
11801190
11811191
if( strncmp(g.argv[2],"export",n)==0 ){
11821192
const char *zPageName; /* Name of the wiki page to export */
11831193
const char *zFile; /* Name of the output file (0=stdout) */
1194
+ const char *zETime; /* The name of the technote to export */
11841195
int rid; /* Artifact ID of the wiki page */
11851196
int i; /* Loop counter */
11861197
char *zBody = 0; /* Wiki page content */
11871198
Blob body; /* Wiki page content */
11881199
Manifest *pWiki = 0; /* Parsed wiki page content */
1189
- if( (g.argc!=4) && (g.argc!=5) ){
1190
- usage("export PAGENAME ?FILE?");
1191
- }
1192
- zPageName = g.argv[3];
1193
- rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1194
- " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1195
- " ORDER BY x.mtime DESC LIMIT 1",
1196
- zPageName
1197
- );
1198
- if( (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
1199
- zBody = pWiki->zWiki;
1200
- }
1201
- if( zBody==0 ){
1202
- fossil_fatal("wiki page [%s] not found",zPageName);
1200
+
1201
+ zETime = find_option("technote","t",1);
1202
+ if( !zETime ){
1203
+ if( (g.argc!=4) && (g.argc!=5) ){
1204
+ usage("export PAGENAME ?FILE?");
1205
+ }
1206
+ zPageName = g.argv[3];
1207
+ rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1208
+ " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1209
+ " ORDER BY x.mtime DESC LIMIT 1",
1210
+ zPageName
1211
+ );
1212
+ if( (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
1213
+ zBody = pWiki->zWiki;
1214
+ }
1215
+ if( zBody==0 ){
1216
+ fossil_fatal("wiki page [%s] not found",zPageName);
1217
+ }
1218
+ zFile = (g.argc==4) ? "-" : g.argv[4];
1219
+ }else{
1220
+ if( (g.argc!=3) && (g.argc!=4) ){
1221
+ usage("export ?FILE? --technote DATETIME");
1222
+ }
1223
+ rid = db_int(0, "SELECT objid FROM event"
1224
+ " WHERE datetime(mtime)=datetime('%q') AND type='e'"
1225
+ " ORDER BY mtime DESC LIMIT 1",
1226
+ zETime
1227
+ );
1228
+ if( (pWiki = manifest_get(rid, CFTYPE_EVENT, 0))!=0 ){
1229
+ zBody = pWiki->zWiki;
1230
+ }
1231
+ if( zBody==0 ){
1232
+ fossil_fatal("technote [%s] not found",zPageName);
1233
+ }
1234
+ zFile = (g.argc==3) ? "-" : g.argv[3];
12031235
}
12041236
for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){}
12051237
zBody[i] = 0;
1206
- zFile = (g.argc==4) ? "-" : g.argv[4];
12071238
blob_init(&body, zBody, -1);
12081239
blob_append(&body, "\n", 1);
12091240
blob_write_to_file(&body, zFile);
12101241
blob_reset(&body);
12111242
manifest_destroy(pWiki);
@@ -1215,37 +1246,71 @@
12151246
const char *zPageName; /* page name */
12161247
Blob content; /* Input content */
12171248
int rid;
12181249
Manifest *pWiki = 0; /* Parsed wiki page content */
12191250
const char *zMimeType = find_option("mimetype", "M", 1);
1251
+ const char *zETime = find_option("technote", "t", 1);
1252
+ const char *zTags = find_option("technote-tags", NULL, 1);
1253
+ const char *zClr = find_option("technote-bgcolor", NULL, 1);
12201254
if( g.argc!=4 && g.argc!=5 ){
1221
- usage("commit|create PAGENAME ?FILE? [-mimetype TEXT-FORMAT]");
1255
+ usage("commit|create PAGENAME ?FILE? [--mimetype TEXT-FORMAT] "
1256
+ "[--technote DATETIME] [--technote-tags TAGS] "
1257
+ "[--technote-bgcolor COLOR]");
12221258
}
12231259
zPageName = g.argv[3];
12241260
if( g.argc==4 ){
12251261
blob_read_from_channel(&content, stdin, -1);
12261262
}else{
12271263
blob_read_from_file(&content, g.argv[4]);
12281264
}
12291265
if(!zMimeType || !*zMimeType){
12301266
/* Try to deduce the mime type based on the prior version. */
1231
- rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1232
- " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1233
- " ORDER BY x.mtime DESC LIMIT 1",
1234
- zPageName
1235
- );
1236
- if(rid>0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0
1237
- && (pWiki->zMimetype && *pWiki->zMimetype)){
1238
- zMimeType = pWiki->zMimetype;
1239
- }
1240
- }
1241
- if( g.argv[2][1]=='r' ){
1242
- wiki_cmd_commit(zPageName, 1, &content, zMimeType, 1);
1243
- fossil_print("Created new wiki page %s.\n", zPageName);
1244
- }else{
1245
- wiki_cmd_commit(zPageName, 0, &content, zMimeType, 1);
1246
- fossil_print("Updated wiki page %s.\n", zPageName);
1267
+ if ( !zETime ){
1268
+ rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1269
+ " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1270
+ " ORDER BY x.mtime DESC LIMIT 1",
1271
+ zPageName
1272
+ );
1273
+ if(rid>0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0
1274
+ && (pWiki->zMimetype && *pWiki->zMimetype)){
1275
+ zMimeType = pWiki->zMimetype;
1276
+ }
1277
+ }else{
1278
+ rid = db_int(0, "SELECT objid FROM event"
1279
+ " WHERE datetime(mtime)=datetime('%q') AND type='e'"
1280
+ " ORDER BY mtime DESC LIMIT 1",
1281
+ zPageName
1282
+ );
1283
+ if(rid>0 && (pWiki = manifest_get(rid, CFTYPE_EVENT, 0))!=0
1284
+ && (pWiki->zMimetype && *pWiki->zMimetype)){
1285
+ zMimeType = pWiki->zMimetype;
1286
+ }
1287
+ }
1288
+ }
1289
+ if( !zETime ){
1290
+ if( g.argv[2][1]=='r' ){
1291
+ wiki_cmd_commit(zPageName, 1, &content, zMimeType, 1);
1292
+ fossil_print("Created new wiki page %s.\n", zPageName);
1293
+ }else{
1294
+ wiki_cmd_commit(zPageName, 0, &content, zMimeType, 1);
1295
+ fossil_print("Updated wiki page %s.\n", zPageName);
1296
+ }
1297
+ }else{
1298
+ char *zMETime; /* Normalized, mutable version of zETime */
1299
+ zMETime = db_text(0,
1300
+ "SELECT coalesce(datetime(%Q),datetime('now'))", zETime
1301
+ );
1302
+ if( g.argv[2][1]=='r' ){
1303
+ event_cmd_commit(zMETime, 1, &content, zMimeType, zPageName,
1304
+ zTags, zClr);
1305
+ fossil_print("Created new tech note %s.\n", zMETime);
1306
+ }else{
1307
+ event_cmd_commit(zMETime, 0, &content, zMimeType, zPageName,
1308
+ zTags, zClr);
1309
+ fossil_print("Updated tech note %s.\n", zMETime);
1310
+ }
1311
+ free(zMETime);
12471312
}
12481313
manifest_destroy(pWiki);
12491314
blob_reset(&content);
12501315
}else if( strncmp(g.argv[2],"delete",n)==0 ){
12511316
if( g.argc!=5 ){
@@ -1253,14 +1318,21 @@
12531318
}
12541319
fossil_fatal("delete not yet implemented.");
12551320
}else if(( strncmp(g.argv[2],"list",n)==0 )
12561321
|| ( strncmp(g.argv[2],"ls",n)==0 )){
12571322
Stmt q;
1258
- db_prepare(&q,
1259
- "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'"
1260
- " ORDER BY lower(tagname) /*sort*/"
1261
- );
1323
+ if ( !find_option("technote","t",0) ){
1324
+ db_prepare(&q,
1325
+ "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'"
1326
+ " ORDER BY lower(tagname) /*sort*/"
1327
+ );
1328
+ }else{
1329
+ db_prepare(&q,
1330
+ "SELECT datetime(mtime) FROM event WHERE type='e'"
1331
+ " ORDER BY mtime /*sort*/"
1332
+ );
1333
+ }
12621334
while( db_step(&q)==SQLITE_ROW ){
12631335
const char *zName = db_column_text(&q, 0);
12641336
fossil_print( "%s\n",zName);
12651337
}
12661338
db_finalize(&q);
12671339
--- src/wiki.c
+++ src/wiki.c
@@ -584,11 +584,12 @@
584 @ <br /><textarea name="w" class="wikiedit" cols="80"
585 @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
586 @ <br />
587 if( db_get_boolean("wysiwyg-wiki", 0) ){
588 @ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor"
589 @ onclick='return confirm("Switching to WYSIWYG-mode\nwill erase your markup\nedits. Continue?")' />
 
590 }
591 @ <input type="submit" name="preview" value="Preview Your Changes" />
592 }else{
593 /* Wysiwyg editing */
594 Blob html, temp;
@@ -602,11 +603,12 @@
602 blob_reset(&temp);
603 wysiwygEditor("w", blob_str(&html), 60, n);
604 blob_reset(&html);
605 @ <br />
606 @ <input type="submit" name="edit-markup" value="Markup Editor"
607 @ onclick='return confirm("Switching to markup-mode\nwill erase your WYSIWYG\nedits. Continue?")' />
 
608 }
609 login_insert_csrf_secret();
610 @ <input type="submit" name="submit" value="Apply These Changes" />
611 @ <input type="hidden" name="name" value="%h(zPageName)" />
612 @ <input type="submit" name="cancel" value="Cancel"
@@ -1137,36 +1139,44 @@
1137 }
1138
1139 /*
1140 ** COMMAND: wiki*
1141 **
1142 ** Usage: %fossil wiki (export|create|commit|list) WikiName
1143 **
1144 ** Run various subcommands to work with wiki entries.
1145 **
1146 ** %fossil wiki export PAGENAME ?FILE?
1147 **
1148 ** Sends the latest version of the PAGENAME wiki
1149 ** entry to the given file or standard output.
1150 **
1151 ** %fossil wiki commit PAGENAME ?FILE? [-mimetype TEXT-FORMAT]
1152 **
1153 ** Commit changes to a wiki page from FILE or from standard
1154 ** input. The -mimetype (-M) flag specifies the mime type,
1155 ** defaulting to the type used by the previous version of
1156 ** the page or (for new pages) text/x-fossil-wiki.
1157 **
1158 ** %fossil wiki create PAGENAME ?FILE? [-mimetype TEXT-FORMAT]
1159 **
1160 ** Create a new wiki page with initial content taken from
1161 ** FILE or from standard input.
1162 **
1163 ** %fossil wiki list
1164 ** %fossil wiki ls
1165 **
1166 ** Lists all wiki entries, one per line, ordered
1167 ** case-insensitively by name.
 
 
 
 
 
 
 
 
1168 **
1169 */
1170 void wiki_cmd(void){
1171 int n;
1172 db_find_and_open_repository(0, 0);
@@ -1179,33 +1189,54 @@
1179 }
1180
1181 if( strncmp(g.argv[2],"export",n)==0 ){
1182 const char *zPageName; /* Name of the wiki page to export */
1183 const char *zFile; /* Name of the output file (0=stdout) */
 
1184 int rid; /* Artifact ID of the wiki page */
1185 int i; /* Loop counter */
1186 char *zBody = 0; /* Wiki page content */
1187 Blob body; /* Wiki page content */
1188 Manifest *pWiki = 0; /* Parsed wiki page content */
1189 if( (g.argc!=4) && (g.argc!=5) ){
1190 usage("export PAGENAME ?FILE?");
1191 }
1192 zPageName = g.argv[3];
1193 rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1194 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1195 " ORDER BY x.mtime DESC LIMIT 1",
1196 zPageName
1197 );
1198 if( (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
1199 zBody = pWiki->zWiki;
1200 }
1201 if( zBody==0 ){
1202 fossil_fatal("wiki page [%s] not found",zPageName);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1203 }
1204 for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){}
1205 zBody[i] = 0;
1206 zFile = (g.argc==4) ? "-" : g.argv[4];
1207 blob_init(&body, zBody, -1);
1208 blob_append(&body, "\n", 1);
1209 blob_write_to_file(&body, zFile);
1210 blob_reset(&body);
1211 manifest_destroy(pWiki);
@@ -1215,37 +1246,71 @@
1215 const char *zPageName; /* page name */
1216 Blob content; /* Input content */
1217 int rid;
1218 Manifest *pWiki = 0; /* Parsed wiki page content */
1219 const char *zMimeType = find_option("mimetype", "M", 1);
 
 
 
1220 if( g.argc!=4 && g.argc!=5 ){
1221 usage("commit|create PAGENAME ?FILE? [-mimetype TEXT-FORMAT]");
 
 
1222 }
1223 zPageName = g.argv[3];
1224 if( g.argc==4 ){
1225 blob_read_from_channel(&content, stdin, -1);
1226 }else{
1227 blob_read_from_file(&content, g.argv[4]);
1228 }
1229 if(!zMimeType || !*zMimeType){
1230 /* Try to deduce the mime type based on the prior version. */
1231 rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1232 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1233 " ORDER BY x.mtime DESC LIMIT 1",
1234 zPageName
1235 );
1236 if(rid>0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0
1237 && (pWiki->zMimetype && *pWiki->zMimetype)){
1238 zMimeType = pWiki->zMimetype;
1239 }
1240 }
1241 if( g.argv[2][1]=='r' ){
1242 wiki_cmd_commit(zPageName, 1, &content, zMimeType, 1);
1243 fossil_print("Created new wiki page %s.\n", zPageName);
1244 }else{
1245 wiki_cmd_commit(zPageName, 0, &content, zMimeType, 1);
1246 fossil_print("Updated wiki page %s.\n", zPageName);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1247 }
1248 manifest_destroy(pWiki);
1249 blob_reset(&content);
1250 }else if( strncmp(g.argv[2],"delete",n)==0 ){
1251 if( g.argc!=5 ){
@@ -1253,14 +1318,21 @@
1253 }
1254 fossil_fatal("delete not yet implemented.");
1255 }else if(( strncmp(g.argv[2],"list",n)==0 )
1256 || ( strncmp(g.argv[2],"ls",n)==0 )){
1257 Stmt q;
1258 db_prepare(&q,
1259 "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'"
1260 " ORDER BY lower(tagname) /*sort*/"
1261 );
 
 
 
 
 
 
 
1262 while( db_step(&q)==SQLITE_ROW ){
1263 const char *zName = db_column_text(&q, 0);
1264 fossil_print( "%s\n",zName);
1265 }
1266 db_finalize(&q);
1267
--- src/wiki.c
+++ src/wiki.c
@@ -584,11 +584,12 @@
584 @ <br /><textarea name="w" class="wikiedit" cols="80"
585 @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
586 @ <br />
587 if( db_get_boolean("wysiwyg-wiki", 0) ){
588 @ <input type="submit" name="edit-wysiwyg" value="Wysiwyg Editor"
589 @ onclick='return confirm("Switching to WYSIWYG-mode\n"+
590 @ "will erase your markup\nedits. Continue?")' />
591 }
592 @ <input type="submit" name="preview" value="Preview Your Changes" />
593 }else{
594 /* Wysiwyg editing */
595 Blob html, temp;
@@ -602,11 +603,12 @@
603 blob_reset(&temp);
604 wysiwygEditor("w", blob_str(&html), 60, n);
605 blob_reset(&html);
606 @ <br />
607 @ <input type="submit" name="edit-markup" value="Markup Editor"
608 @ onclick='return confirm("Switching to markup-mode\n"+
609 @ "will erase your WYSIWYG\nedits. Continue?")' />
610 }
611 login_insert_csrf_secret();
612 @ <input type="submit" name="submit" value="Apply These Changes" />
613 @ <input type="hidden" name="name" value="%h(zPageName)" />
614 @ <input type="submit" name="cancel" value="Cancel"
@@ -1137,36 +1139,44 @@
1139 }
1140
1141 /*
1142 ** COMMAND: wiki*
1143 **
1144 ** Usage: ../fossil wiki (export|create|commit|list) WikiName
1145 **
1146 ** Run various subcommands to work with wiki entries or tech notes.
1147 **
1148 ** ../fossil wiki export ?PAGENAME? ?FILE? [-t|--technote DATETIME]
1149 **
1150 ** Sends the latest version of either the PAGENAME wiki entry
1151 ** or the DATETIME tech note to the given file or standard
1152 ** output. One of PAGENAME or DATETIME must be specified.
1153 **
1154 ** ../fossil wiki (create|commit) PAGENAME ?FILE? ?OPTIONS?
1155 **
1156 ** Create a new or commit changes to an existing wiki page or
1157 ** technote from FILE or from standard input.
1158 **
1159 ** Options:
1160 ** -M|--mimetype TEXT-FORMAT The mime type of the update defaulting
1161 ** defaulting to the type used by the
1162 ** previous version of the page or (for
1163 ** new pages) text/x-fossil-wiki.
1164 ** -t|--technote DATETIME Specifies the timestamp of the technote
1165 ** to be created or updated.
1166 ** --technote-tags TAGS The set of tags for a technote.
1167 ** --technote-bgcolor COLOR The color used for the technote on the
1168 ** timeline.
1169 **
1170 ** ../fossil wiki list ?-technote?
1171 ** ../fossil wiki ls ?-technote?
1172 **
1173 ** Lists all wiki entries, one per line, ordered
1174 ** case-insensitively by name. The -technote flag
1175 ** specifies that technotes will be listed instead of
1176 ** the wiki entries, which will be listed in order
1177 ** timestamp.
1178 **
1179 */
1180 void wiki_cmd(void){
1181 int n;
1182 db_find_and_open_repository(0, 0);
@@ -1179,33 +1189,54 @@
1189 }
1190
1191 if( strncmp(g.argv[2],"export",n)==0 ){
1192 const char *zPageName; /* Name of the wiki page to export */
1193 const char *zFile; /* Name of the output file (0=stdout) */
1194 const char *zETime; /* The name of the technote to export */
1195 int rid; /* Artifact ID of the wiki page */
1196 int i; /* Loop counter */
1197 char *zBody = 0; /* Wiki page content */
1198 Blob body; /* Wiki page content */
1199 Manifest *pWiki = 0; /* Parsed wiki page content */
1200
1201 zETime = find_option("technote","t",1);
1202 if( !zETime ){
1203 if( (g.argc!=4) && (g.argc!=5) ){
1204 usage("export PAGENAME ?FILE?");
1205 }
1206 zPageName = g.argv[3];
1207 rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1208 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1209 " ORDER BY x.mtime DESC LIMIT 1",
1210 zPageName
1211 );
1212 if( (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0 ){
1213 zBody = pWiki->zWiki;
1214 }
1215 if( zBody==0 ){
1216 fossil_fatal("wiki page [%s] not found",zPageName);
1217 }
1218 zFile = (g.argc==4) ? "-" : g.argv[4];
1219 }else{
1220 if( (g.argc!=3) && (g.argc!=4) ){
1221 usage("export ?FILE? --technote DATETIME");
1222 }
1223 rid = db_int(0, "SELECT objid FROM event"
1224 " WHERE datetime(mtime)=datetime('%q') AND type='e'"
1225 " ORDER BY mtime DESC LIMIT 1",
1226 zETime
1227 );
1228 if( (pWiki = manifest_get(rid, CFTYPE_EVENT, 0))!=0 ){
1229 zBody = pWiki->zWiki;
1230 }
1231 if( zBody==0 ){
1232 fossil_fatal("technote [%s] not found",zPageName);
1233 }
1234 zFile = (g.argc==3) ? "-" : g.argv[3];
1235 }
1236 for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){}
1237 zBody[i] = 0;
 
1238 blob_init(&body, zBody, -1);
1239 blob_append(&body, "\n", 1);
1240 blob_write_to_file(&body, zFile);
1241 blob_reset(&body);
1242 manifest_destroy(pWiki);
@@ -1215,37 +1246,71 @@
1246 const char *zPageName; /* page name */
1247 Blob content; /* Input content */
1248 int rid;
1249 Manifest *pWiki = 0; /* Parsed wiki page content */
1250 const char *zMimeType = find_option("mimetype", "M", 1);
1251 const char *zETime = find_option("technote", "t", 1);
1252 const char *zTags = find_option("technote-tags", NULL, 1);
1253 const char *zClr = find_option("technote-bgcolor", NULL, 1);
1254 if( g.argc!=4 && g.argc!=5 ){
1255 usage("commit|create PAGENAME ?FILE? [--mimetype TEXT-FORMAT] "
1256 "[--technote DATETIME] [--technote-tags TAGS] "
1257 "[--technote-bgcolor COLOR]");
1258 }
1259 zPageName = g.argv[3];
1260 if( g.argc==4 ){
1261 blob_read_from_channel(&content, stdin, -1);
1262 }else{
1263 blob_read_from_file(&content, g.argv[4]);
1264 }
1265 if(!zMimeType || !*zMimeType){
1266 /* Try to deduce the mime type based on the prior version. */
1267 if ( !zETime ){
1268 rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1269 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1270 " ORDER BY x.mtime DESC LIMIT 1",
1271 zPageName
1272 );
1273 if(rid>0 && (pWiki = manifest_get(rid, CFTYPE_WIKI, 0))!=0
1274 && (pWiki->zMimetype && *pWiki->zMimetype)){
1275 zMimeType = pWiki->zMimetype;
1276 }
1277 }else{
1278 rid = db_int(0, "SELECT objid FROM event"
1279 " WHERE datetime(mtime)=datetime('%q') AND type='e'"
1280 " ORDER BY mtime DESC LIMIT 1",
1281 zPageName
1282 );
1283 if(rid>0 && (pWiki = manifest_get(rid, CFTYPE_EVENT, 0))!=0
1284 && (pWiki->zMimetype && *pWiki->zMimetype)){
1285 zMimeType = pWiki->zMimetype;
1286 }
1287 }
1288 }
1289 if( !zETime ){
1290 if( g.argv[2][1]=='r' ){
1291 wiki_cmd_commit(zPageName, 1, &content, zMimeType, 1);
1292 fossil_print("Created new wiki page %s.\n", zPageName);
1293 }else{
1294 wiki_cmd_commit(zPageName, 0, &content, zMimeType, 1);
1295 fossil_print("Updated wiki page %s.\n", zPageName);
1296 }
1297 }else{
1298 char *zMETime; /* Normalized, mutable version of zETime */
1299 zMETime = db_text(0,
1300 "SELECT coalesce(datetime(%Q),datetime('now'))", zETime
1301 );
1302 if( g.argv[2][1]=='r' ){
1303 event_cmd_commit(zMETime, 1, &content, zMimeType, zPageName,
1304 zTags, zClr);
1305 fossil_print("Created new tech note %s.\n", zMETime);
1306 }else{
1307 event_cmd_commit(zMETime, 0, &content, zMimeType, zPageName,
1308 zTags, zClr);
1309 fossil_print("Updated tech note %s.\n", zMETime);
1310 }
1311 free(zMETime);
1312 }
1313 manifest_destroy(pWiki);
1314 blob_reset(&content);
1315 }else if( strncmp(g.argv[2],"delete",n)==0 ){
1316 if( g.argc!=5 ){
@@ -1253,14 +1318,21 @@
1318 }
1319 fossil_fatal("delete not yet implemented.");
1320 }else if(( strncmp(g.argv[2],"list",n)==0 )
1321 || ( strncmp(g.argv[2],"ls",n)==0 )){
1322 Stmt q;
1323 if ( !find_option("technote","t",0) ){
1324 db_prepare(&q,
1325 "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'"
1326 " ORDER BY lower(tagname) /*sort*/"
1327 );
1328 }else{
1329 db_prepare(&q,
1330 "SELECT datetime(mtime) FROM event WHERE type='e'"
1331 " ORDER BY mtime /*sort*/"
1332 );
1333 }
1334 while( db_step(&q)==SQLITE_ROW ){
1335 const char *zName = db_column_text(&q, 0);
1336 fossil_print( "%s\n",zName);
1337 }
1338 db_finalize(&q);
1339

Keyboard Shortcuts

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