Fossil SCM

Got basic /fileedit page skeleton in place. It can load/display a file, with some limits, but cannot yet do anything with it.

stephan 2020-05-01 07:47 UTC checkin-without-checkout
Commit b5e3bc9e41127bbd1db145bad2bbb1a037f9ca159fe1cbbd1f2620341ae3d409
+133
--- src/checkin.c
+++ src/checkin.c
@@ -3489,5 +3489,138 @@
34893489
"with regards to this commit. It needs to be "
34903490
"'update'd or 'close'd and re-'open'ed.");
34913491
}
34923492
CheckinMiniInfo_cleanup(&cinf);
34933493
}
3494
+
3495
+
3496
+/*
3497
+** Returns true if the given filename qualified for online editing
3498
+** by the current user.
3499
+**
3500
+** Currently only looks at the user's permissions, pending decisions
3501
+** on whether we want to filter them based on a glob list or mimetype
3502
+** list.
3503
+*/
3504
+int file_is_online_editable(const char *zFilename){
3505
+ if(g.perm.Write){
3506
+ return 1;
3507
+ }
3508
+ return 0;
3509
+}
3510
+
3511
+/*
3512
+** WEBPAGE: fileedit
3513
+**
3514
+** EXPERIMENTAL and subject to change and removal at any time. The goal
3515
+** is to allow online edits of files.
3516
+**
3517
+** Query parameters:
3518
+**
3519
+** file=FILE Repo-relative path to the file.
3520
+** r=VERSION Checkin version
3521
+**
3522
+** Parameters intended to be passed in only via the editor's own form:
3523
+**
3524
+** diff If true, show diff from prev version.
3525
+** preview If true, preview (how depends on mimetype).
3526
+** content File content.
3527
+**
3528
+**
3529
+*/
3530
+void fileedit_page(){
3531
+ const char * zFilename = PD("file",P("name")); /* filename */
3532
+ const char * zRev = P("r"); /* checkin version */
3533
+ const char * zContent = P("content"); /* file content */
3534
+ const char * zComment = P("comment"); /* checkin comment */
3535
+ char * zRevResolved = 0; /* Resolved zRev */
3536
+ int vid, frid; /* checkin/file rids */
3537
+ char * zFileUuid = 0;
3538
+ Blob content = empty_blob;
3539
+
3540
+ login_check_credentials();
3541
+ if( !g.perm.Write ){
3542
+ login_needed(g.anon.Write);
3543
+ return;
3544
+ }
3545
+ /*
3546
+ ** TODOs include, but are not limited to:
3547
+ **
3548
+ ** - On initial hit, fetch file content and stuff it in a textarea.
3549
+ **
3550
+ ** - Preview button + view
3551
+ **
3552
+ ** - Diff button + view
3553
+ **
3554
+ ** - Checkbox options: allow fork, dry-run, convert EOL,
3555
+ ** allow merge conflict, allow older (just in case server time
3556
+ ** is messed up or someone checked something in w/ a future
3557
+ ** timestamp)
3558
+ **
3559
+ */
3560
+ if(!zRev || !*zRev || !zFilename || !*zFilename){
3561
+ webpage_error("Missing required URL parameters.");
3562
+ }
3563
+ vid = symbolic_name_to_rid(zRev, "ci");
3564
+ if(0==vid){
3565
+ webpage_error("Could not resolve checkin version.");
3566
+ }
3567
+ zRevResolved = rid_to_uuid(vid);
3568
+ zFileUuid = db_text(0,"SELECT uuid FROM files_of_checkin WHERE "
3569
+ "filename=%Q %s AND checkinID=%d",
3570
+ zFilename, filename_collation(), vid);
3571
+ if(!zFileUuid){
3572
+ webpage_error("Checkin [%S] does not contain file: %T",
3573
+ zRevResolved, zFilename);
3574
+ }
3575
+
3576
+ frid = fast_uuid_to_rid(zFileUuid);
3577
+ assert(frid);
3578
+ if(zContent==0){
3579
+ content_get(frid, &content);
3580
+ zContent = blob_size(&content) ? blob_str(&content) : NULL;
3581
+ }else{
3582
+ blob_init(&content,zContent,-1);
3583
+ }
3584
+ if(looks_like_binary(&content)){
3585
+ webpage_error("File appears to be binary. Cannot edit: %T",
3586
+ zFilename);
3587
+ }
3588
+
3589
+ style_header("File Editor");
3590
+#define fp fossil_print
3591
+ /* ^^^ Appologies, Richard, but the @ form plays havoc with emacs */
3592
+
3593
+ fp("<h1>Editing: %T</h1>",zFilename);
3594
+ fp("<p>This page is <em>far from complete</em>.</p>");
3595
+
3596
+ fp("<form action=\"%R/fileedit\" method=\"POST\" class=\"fileedit-form\">");
3597
+ fp("<input type=\"hidden\" name=\"r\" value=\"%s\">", zRevResolved);
3598
+ fp("<input type=\"hidden\" name=\"file\" value=\"%T\">",
3599
+ zFilename);
3600
+ fp("<h3>Comment</h3>");
3601
+ fp("<textarea name=\"comment\" rows=\"3\" cols=\"80\">");
3602
+ if(zComment && *zComment){
3603
+ fp("%T"/*%T?*/, zComment);
3604
+ }
3605
+ fp("</textarea>");
3606
+ fp("<h3>Content</h3>");
3607
+ fp("<textarea name=\"content\" rows=\"20\" cols=\"80\">");
3608
+ if(zContent && *zContent){
3609
+ fp("%s", zContent);
3610
+ }
3611
+ fp("</textarea>");
3612
+
3613
+ fp("<div class=\"fileedit-options\">");
3614
+ /* Put checkboxes here... */
3615
+ fp("Many buttons and checkboxes to put here");
3616
+ fp("</div>");
3617
+
3618
+ fp("</form>");
3619
+
3620
+ blob_reset(&content);
3621
+ fossil_free(zRevResolved);
3622
+ fossil_free(zFileUuid);
3623
+
3624
+ style_footer();
3625
+#undef fp
3626
+}
34943627
--- src/checkin.c
+++ src/checkin.c
@@ -3489,5 +3489,138 @@
3489 "with regards to this commit. It needs to be "
3490 "'update'd or 'close'd and re-'open'ed.");
3491 }
3492 CheckinMiniInfo_cleanup(&cinf);
3493 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3494
--- src/checkin.c
+++ src/checkin.c
@@ -3489,5 +3489,138 @@
3489 "with regards to this commit. It needs to be "
3490 "'update'd or 'close'd and re-'open'ed.");
3491 }
3492 CheckinMiniInfo_cleanup(&cinf);
3493 }
3494
3495
3496 /*
3497 ** Returns true if the given filename qualified for online editing
3498 ** by the current user.
3499 **
3500 ** Currently only looks at the user's permissions, pending decisions
3501 ** on whether we want to filter them based on a glob list or mimetype
3502 ** list.
3503 */
3504 int file_is_online_editable(const char *zFilename){
3505 if(g.perm.Write){
3506 return 1;
3507 }
3508 return 0;
3509 }
3510
3511 /*
3512 ** WEBPAGE: fileedit
3513 **
3514 ** EXPERIMENTAL and subject to change and removal at any time. The goal
3515 ** is to allow online edits of files.
3516 **
3517 ** Query parameters:
3518 **
3519 ** file=FILE Repo-relative path to the file.
3520 ** r=VERSION Checkin version
3521 **
3522 ** Parameters intended to be passed in only via the editor's own form:
3523 **
3524 ** diff If true, show diff from prev version.
3525 ** preview If true, preview (how depends on mimetype).
3526 ** content File content.
3527 **
3528 **
3529 */
3530 void fileedit_page(){
3531 const char * zFilename = PD("file",P("name")); /* filename */
3532 const char * zRev = P("r"); /* checkin version */
3533 const char * zContent = P("content"); /* file content */
3534 const char * zComment = P("comment"); /* checkin comment */
3535 char * zRevResolved = 0; /* Resolved zRev */
3536 int vid, frid; /* checkin/file rids */
3537 char * zFileUuid = 0;
3538 Blob content = empty_blob;
3539
3540 login_check_credentials();
3541 if( !g.perm.Write ){
3542 login_needed(g.anon.Write);
3543 return;
3544 }
3545 /*
3546 ** TODOs include, but are not limited to:
3547 **
3548 ** - On initial hit, fetch file content and stuff it in a textarea.
3549 **
3550 ** - Preview button + view
3551 **
3552 ** - Diff button + view
3553 **
3554 ** - Checkbox options: allow fork, dry-run, convert EOL,
3555 ** allow merge conflict, allow older (just in case server time
3556 ** is messed up or someone checked something in w/ a future
3557 ** timestamp)
3558 **
3559 */
3560 if(!zRev || !*zRev || !zFilename || !*zFilename){
3561 webpage_error("Missing required URL parameters.");
3562 }
3563 vid = symbolic_name_to_rid(zRev, "ci");
3564 if(0==vid){
3565 webpage_error("Could not resolve checkin version.");
3566 }
3567 zRevResolved = rid_to_uuid(vid);
3568 zFileUuid = db_text(0,"SELECT uuid FROM files_of_checkin WHERE "
3569 "filename=%Q %s AND checkinID=%d",
3570 zFilename, filename_collation(), vid);
3571 if(!zFileUuid){
3572 webpage_error("Checkin [%S] does not contain file: %T",
3573 zRevResolved, zFilename);
3574 }
3575
3576 frid = fast_uuid_to_rid(zFileUuid);
3577 assert(frid);
3578 if(zContent==0){
3579 content_get(frid, &content);
3580 zContent = blob_size(&content) ? blob_str(&content) : NULL;
3581 }else{
3582 blob_init(&content,zContent,-1);
3583 }
3584 if(looks_like_binary(&content)){
3585 webpage_error("File appears to be binary. Cannot edit: %T",
3586 zFilename);
3587 }
3588
3589 style_header("File Editor");
3590 #define fp fossil_print
3591 /* ^^^ Appologies, Richard, but the @ form plays havoc with emacs */
3592
3593 fp("<h1>Editing: %T</h1>",zFilename);
3594 fp("<p>This page is <em>far from complete</em>.</p>");
3595
3596 fp("<form action=\"%R/fileedit\" method=\"POST\" class=\"fileedit-form\">");
3597 fp("<input type=\"hidden\" name=\"r\" value=\"%s\">", zRevResolved);
3598 fp("<input type=\"hidden\" name=\"file\" value=\"%T\">",
3599 zFilename);
3600 fp("<h3>Comment</h3>");
3601 fp("<textarea name=\"comment\" rows=\"3\" cols=\"80\">");
3602 if(zComment && *zComment){
3603 fp("%T"/*%T?*/, zComment);
3604 }
3605 fp("</textarea>");
3606 fp("<h3>Content</h3>");
3607 fp("<textarea name=\"content\" rows=\"20\" cols=\"80\">");
3608 if(zContent && *zContent){
3609 fp("%s", zContent);
3610 }
3611 fp("</textarea>");
3612
3613 fp("<div class=\"fileedit-options\">");
3614 /* Put checkboxes here... */
3615 fp("Many buttons and checkboxes to put here");
3616 fp("</div>");
3617
3618 fp("</form>");
3619
3620 blob_reset(&content);
3621 fossil_free(zRevResolved);
3622 fossil_free(zFileUuid);
3623
3624 style_footer();
3625 #undef fp
3626 }
3627
--- src/default_css.txt
+++ src/default_css.txt
@@ -860,5 +860,14 @@
860860
// }
861861
// #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
862862
// max-width: 30em;
863863
// overflow: auto;
864864
// }
865
+// .fileedit-XXX => /fileedit page
866
+.fileedit-form textarea {
867
+ width: 100%;
868
+}
869
+.fileedit-form .fileedit-options {
870
+ padding: 0.5em;
871
+ margin: 1em 0 0 0;
872
+ border: 2px inset #a0a0a0;
873
+}
865874
--- src/default_css.txt
+++ src/default_css.txt
@@ -860,5 +860,14 @@
860 // }
861 // #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
862 // max-width: 30em;
863 // overflow: auto;
864 // }
 
 
 
 
 
 
 
 
 
865
--- src/default_css.txt
+++ src/default_css.txt
@@ -860,5 +860,14 @@
860 // }
861 // #setup_skinedit_css_defaults > tbody > tr > td:nth-of-type(2) > div {
862 // max-width: 30em;
863 // overflow: auto;
864 // }
865 // .fileedit-XXX => /fileedit page
866 .fileedit-form textarea {
867 width: 100%;
868 }
869 .fileedit-form .fileedit-options {
870 padding: 0.5em;
871 margin: 1em 0 0 0;
872 border: 2px inset #a0a0a0;
873 }
874

Keyboard Shortcuts

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