Fossil SCM

Enhancements to the /file?brief query parameter. New webpage /docfile that is an alias for /file?brief, but omits the need for the query parameter to avoid the anti-robot captcha.

drh 2025-03-26 13:26 trunk
Commit d098711dfa3ee4109aa61788a4c4b4bda0ccb5b1ed547ba00055107911d55f65
1 file changed +32 -14
+32 -14
--- src/info.c
+++ src/info.c
@@ -2622,24 +2622,28 @@
26222622
26232623
/*
26242624
** WEBPAGE: artifact
26252625
** WEBPAGE: file
26262626
** WEBPAGE: whatis
2627
+** WEBPAGE: docfile
26272628
**
26282629
** Typical usage:
26292630
**
26302631
** /artifact/HASH
26312632
** /whatis/HASH
26322633
** /file/NAME
2634
+** /docfile/NAME
26332635
**
26342636
** Additional query parameters:
26352637
**
26362638
** ln - show line numbers
26372639
** ln=N - highlight line number N
26382640
** ln=M-N - highlight lines M through N inclusive
26392641
** ln=M-N+Y-Z - highlight lines M through N and Y through Z (inclusive)
26402642
** verbose - show more detail in the description
2643
+** brief - show just the document, not the metadata. The
2644
+** /docfile page is an alias for /file?brief
26412645
** download - redirect to the download (artifact page only)
26422646
** name=NAME - filename or hash as a query parameter
26432647
** filename=NAME - alternative spelling for "name="
26442648
** fn=NAME - alternative spelling for "name="
26452649
** ci=VERSION - The specific check-in to use with "name=" to
@@ -2691,10 +2695,14 @@
26912695
26922696
login_check_credentials();
26932697
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
26942698
cgi_check_for_malice();
26952699
style_set_current_feature("artifact");
2700
+ if( fossil_strcmp(g.zPath, "docfile")==0 ){
2701
+ isFile = 1;
2702
+ docOnly = 1;
2703
+ }
26962704
26972705
/* Capture and normalize the name= and ci= query parameters */
26982706
if( zName==0 ){
26992707
zName = P("filename");
27002708
if( zName==0 ){
@@ -2827,17 +2835,19 @@
28272835
}else{
28282836
@ part of check-in %z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a></h2>
28292837
}
28302838
blob_reset(&path);
28312839
}
2832
- style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
28332840
zMime = mimetype_from_name(zName);
2834
- style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2835
- zName, zCI);
2836
- style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
2837
- zName, zCI);
2838
- style_submenu_element("Doc", "%R/doc/%T/%T", zCI, zName);
2841
+ if( !docOnly ){
2842
+ style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
2843
+ style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2844
+ zName, zCI);
2845
+ style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
2846
+ zName, zCI);
2847
+ style_submenu_element("Doc", "%R/doc/%T/%T", zCI, zName);
2848
+ }
28392849
blob_init(&downloadName, zName, -1);
28402850
objType = OBJTYPE_CONTENT;
28412851
}else{
28422852
@ <h2>Artifact
28432853
style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
@@ -2856,11 +2866,11 @@
28562866
cgi_redirectf("%R/raw/%s?at=%T",
28572867
db_text("x", "SELECT uuid FROM blob WHERE rid=%d", rid),
28582868
file_tail(blob_str(&downloadName)));
28592869
/*NOTREACHED*/
28602870
}
2861
- if( g.perm.Admin ){
2871
+ if( g.perm.Admin && !docOnly ){
28622872
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
28632873
if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
28642874
style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#accshun", zUuid);
28652875
}else{
28662876
style_submenu_element("Shun", "%R/shun?shun=%s#addshun",zUuid);
@@ -2901,41 +2911,49 @@
29012911
const char *zIp = db_column_text(&q,2);
29022912
@ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
29032913
}
29042914
db_finalize(&q);
29052915
}
2906
- style_submenu_element("Download", "%R/raw/%s?at=%T", zUuid, file_tail(zName));
2907
- if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
2908
- style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
2916
+ if( !docOnly ){
2917
+ style_submenu_element("Download", "%R/raw/%s?at=%T",zUuid,file_tail(zName));
2918
+ if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
2919
+ style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
2920
+ }
29092921
}
29102922
if( zMime ){
29112923
if( fossil_strcmp(zMime, "text/html")==0 ){
29122924
if( asText ){
29132925
style_submenu_element("Html", "%s", url_render(&url, "txt", 0, 0, 0));
29142926
}else{
29152927
renderAsHtml = 1;
2916
- style_submenu_element("Text", "%s", url_render(&url, "txt", "1", 0, 0));
2928
+ if( !docOnly ){
2929
+ style_submenu_element("Text", "%s", url_render(&url, "txt","1",0,0));
2930
+ }
29172931
}
29182932
}else if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0
29192933
|| fossil_strcmp(zMime, "text/x-markdown")==0
29202934
|| fossil_strcmp(zMime, "text/x-pikchr")==0 ){
29212935
if( asText ){
29222936
style_submenu_element(zMime[7]=='p' ? "Pikchr" : "Wiki",
29232937
"%s", url_render(&url, "txt", 0, 0, 0));
29242938
}else{
29252939
renderAsWiki = 1;
2926
- style_submenu_element("Text", "%s", url_render(&url, "txt", "1", 0, 0));
2940
+ if( !docOnly ){
2941
+ style_submenu_element("Text", "%s", url_render(&url, "txt","1",0,0));
2942
+ }
29272943
}
29282944
}else if( fossil_strcmp(zMime, "image/svg+xml")==0 ){
29292945
if( asText ){
29302946
style_submenu_element("Svg", "%s", url_render(&url, "txt", 0, 0, 0));
29312947
}else{
29322948
renderAsSvg = 1;
2933
- style_submenu_element("Text", "%s", url_render(&url, "txt", "1", 0, 0));
2949
+ if( !docOnly ){
2950
+ style_submenu_element("Text", "%s", url_render(&url, "txt","1",0,0));
2951
+ }
29342952
}
29352953
}
2936
- if( fileedit_is_editable(zName) ){
2954
+ if( !docOnly && fileedit_is_editable(zName) ){
29372955
style_submenu_element("Edit",
29382956
"%R/fileedit?filename=%T&checkin=%!S",
29392957
zName, zCI);
29402958
}
29412959
}
29422960
--- src/info.c
+++ src/info.c
@@ -2622,24 +2622,28 @@
2622
2623 /*
2624 ** WEBPAGE: artifact
2625 ** WEBPAGE: file
2626 ** WEBPAGE: whatis
 
2627 **
2628 ** Typical usage:
2629 **
2630 ** /artifact/HASH
2631 ** /whatis/HASH
2632 ** /file/NAME
 
2633 **
2634 ** Additional query parameters:
2635 **
2636 ** ln - show line numbers
2637 ** ln=N - highlight line number N
2638 ** ln=M-N - highlight lines M through N inclusive
2639 ** ln=M-N+Y-Z - highlight lines M through N and Y through Z (inclusive)
2640 ** verbose - show more detail in the description
 
 
2641 ** download - redirect to the download (artifact page only)
2642 ** name=NAME - filename or hash as a query parameter
2643 ** filename=NAME - alternative spelling for "name="
2644 ** fn=NAME - alternative spelling for "name="
2645 ** ci=VERSION - The specific check-in to use with "name=" to
@@ -2691,10 +2695,14 @@
2691
2692 login_check_credentials();
2693 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2694 cgi_check_for_malice();
2695 style_set_current_feature("artifact");
 
 
 
 
2696
2697 /* Capture and normalize the name= and ci= query parameters */
2698 if( zName==0 ){
2699 zName = P("filename");
2700 if( zName==0 ){
@@ -2827,17 +2835,19 @@
2827 }else{
2828 @ part of check-in %z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a></h2>
2829 }
2830 blob_reset(&path);
2831 }
2832 style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
2833 zMime = mimetype_from_name(zName);
2834 style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2835 zName, zCI);
2836 style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
2837 zName, zCI);
2838 style_submenu_element("Doc", "%R/doc/%T/%T", zCI, zName);
 
 
 
2839 blob_init(&downloadName, zName, -1);
2840 objType = OBJTYPE_CONTENT;
2841 }else{
2842 @ <h2>Artifact
2843 style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
@@ -2856,11 +2866,11 @@
2856 cgi_redirectf("%R/raw/%s?at=%T",
2857 db_text("x", "SELECT uuid FROM blob WHERE rid=%d", rid),
2858 file_tail(blob_str(&downloadName)));
2859 /*NOTREACHED*/
2860 }
2861 if( g.perm.Admin ){
2862 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
2863 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
2864 style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#accshun", zUuid);
2865 }else{
2866 style_submenu_element("Shun", "%R/shun?shun=%s#addshun",zUuid);
@@ -2901,41 +2911,49 @@
2901 const char *zIp = db_column_text(&q,2);
2902 @ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
2903 }
2904 db_finalize(&q);
2905 }
2906 style_submenu_element("Download", "%R/raw/%s?at=%T", zUuid, file_tail(zName));
2907 if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
2908 style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
 
 
2909 }
2910 if( zMime ){
2911 if( fossil_strcmp(zMime, "text/html")==0 ){
2912 if( asText ){
2913 style_submenu_element("Html", "%s", url_render(&url, "txt", 0, 0, 0));
2914 }else{
2915 renderAsHtml = 1;
2916 style_submenu_element("Text", "%s", url_render(&url, "txt", "1", 0, 0));
 
 
2917 }
2918 }else if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0
2919 || fossil_strcmp(zMime, "text/x-markdown")==0
2920 || fossil_strcmp(zMime, "text/x-pikchr")==0 ){
2921 if( asText ){
2922 style_submenu_element(zMime[7]=='p' ? "Pikchr" : "Wiki",
2923 "%s", url_render(&url, "txt", 0, 0, 0));
2924 }else{
2925 renderAsWiki = 1;
2926 style_submenu_element("Text", "%s", url_render(&url, "txt", "1", 0, 0));
 
 
2927 }
2928 }else if( fossil_strcmp(zMime, "image/svg+xml")==0 ){
2929 if( asText ){
2930 style_submenu_element("Svg", "%s", url_render(&url, "txt", 0, 0, 0));
2931 }else{
2932 renderAsSvg = 1;
2933 style_submenu_element("Text", "%s", url_render(&url, "txt", "1", 0, 0));
 
 
2934 }
2935 }
2936 if( fileedit_is_editable(zName) ){
2937 style_submenu_element("Edit",
2938 "%R/fileedit?filename=%T&checkin=%!S",
2939 zName, zCI);
2940 }
2941 }
2942
--- src/info.c
+++ src/info.c
@@ -2622,24 +2622,28 @@
2622
2623 /*
2624 ** WEBPAGE: artifact
2625 ** WEBPAGE: file
2626 ** WEBPAGE: whatis
2627 ** WEBPAGE: docfile
2628 **
2629 ** Typical usage:
2630 **
2631 ** /artifact/HASH
2632 ** /whatis/HASH
2633 ** /file/NAME
2634 ** /docfile/NAME
2635 **
2636 ** Additional query parameters:
2637 **
2638 ** ln - show line numbers
2639 ** ln=N - highlight line number N
2640 ** ln=M-N - highlight lines M through N inclusive
2641 ** ln=M-N+Y-Z - highlight lines M through N and Y through Z (inclusive)
2642 ** verbose - show more detail in the description
2643 ** brief - show just the document, not the metadata. The
2644 ** /docfile page is an alias for /file?brief
2645 ** download - redirect to the download (artifact page only)
2646 ** name=NAME - filename or hash as a query parameter
2647 ** filename=NAME - alternative spelling for "name="
2648 ** fn=NAME - alternative spelling for "name="
2649 ** ci=VERSION - The specific check-in to use with "name=" to
@@ -2691,10 +2695,14 @@
2695
2696 login_check_credentials();
2697 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
2698 cgi_check_for_malice();
2699 style_set_current_feature("artifact");
2700 if( fossil_strcmp(g.zPath, "docfile")==0 ){
2701 isFile = 1;
2702 docOnly = 1;
2703 }
2704
2705 /* Capture and normalize the name= and ci= query parameters */
2706 if( zName==0 ){
2707 zName = P("filename");
2708 if( zName==0 ){
@@ -2827,17 +2835,19 @@
2835 }else{
2836 @ part of check-in %z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a></h2>
2837 }
2838 blob_reset(&path);
2839 }
 
2840 zMime = mimetype_from_name(zName);
2841 if( !docOnly ){
2842 style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
2843 style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2844 zName, zCI);
2845 style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
2846 zName, zCI);
2847 style_submenu_element("Doc", "%R/doc/%T/%T", zCI, zName);
2848 }
2849 blob_init(&downloadName, zName, -1);
2850 objType = OBJTYPE_CONTENT;
2851 }else{
2852 @ <h2>Artifact
2853 style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
@@ -2856,11 +2866,11 @@
2866 cgi_redirectf("%R/raw/%s?at=%T",
2867 db_text("x", "SELECT uuid FROM blob WHERE rid=%d", rid),
2868 file_tail(blob_str(&downloadName)));
2869 /*NOTREACHED*/
2870 }
2871 if( g.perm.Admin && !docOnly ){
2872 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
2873 if( db_exists("SELECT 1 FROM shun WHERE uuid=%Q", zUuid) ){
2874 style_submenu_element("Unshun", "%R/shun?accept=%s&sub=1#accshun", zUuid);
2875 }else{
2876 style_submenu_element("Shun", "%R/shun?shun=%s#addshun",zUuid);
@@ -2901,41 +2911,49 @@
2911 const char *zIp = db_column_text(&q,2);
2912 @ <p>Received on %s(zDate) from %h(zUser) at %h(zIp).</p>
2913 }
2914 db_finalize(&q);
2915 }
2916 if( !docOnly ){
2917 style_submenu_element("Download", "%R/raw/%s?at=%T",zUuid,file_tail(zName));
2918 if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
2919 style_submenu_element("Check-ins Using", "%R/timeline?uf=%s", zUuid);
2920 }
2921 }
2922 if( zMime ){
2923 if( fossil_strcmp(zMime, "text/html")==0 ){
2924 if( asText ){
2925 style_submenu_element("Html", "%s", url_render(&url, "txt", 0, 0, 0));
2926 }else{
2927 renderAsHtml = 1;
2928 if( !docOnly ){
2929 style_submenu_element("Text", "%s", url_render(&url, "txt","1",0,0));
2930 }
2931 }
2932 }else if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0
2933 || fossil_strcmp(zMime, "text/x-markdown")==0
2934 || fossil_strcmp(zMime, "text/x-pikchr")==0 ){
2935 if( asText ){
2936 style_submenu_element(zMime[7]=='p' ? "Pikchr" : "Wiki",
2937 "%s", url_render(&url, "txt", 0, 0, 0));
2938 }else{
2939 renderAsWiki = 1;
2940 if( !docOnly ){
2941 style_submenu_element("Text", "%s", url_render(&url, "txt","1",0,0));
2942 }
2943 }
2944 }else if( fossil_strcmp(zMime, "image/svg+xml")==0 ){
2945 if( asText ){
2946 style_submenu_element("Svg", "%s", url_render(&url, "txt", 0, 0, 0));
2947 }else{
2948 renderAsSvg = 1;
2949 if( !docOnly ){
2950 style_submenu_element("Text", "%s", url_render(&url, "txt","1",0,0));
2951 }
2952 }
2953 }
2954 if( !docOnly && fileedit_is_editable(zName) ){
2955 style_submenu_element("Edit",
2956 "%R/fileedit?filename=%T&checkin=%!S",
2957 zName, zCI);
2958 }
2959 }
2960

Keyboard Shortcuts

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