Fossil

Check-in [c7fe01fe8e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:The "artifact" webpage renders wiki as wiki and html as html but gives submenu items to convert the rendering back to plain text (and hexdump).
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c7fe01fe8ee4e2323157a26da0c3c6522113a21e
User & Date: drh 2009-01-29 02:42:11.000
Context
2009-01-29
02:48
On the taglist and tagtimeline pages, only show non-propagating tags. Omit the branch tags. ... (check-in: 8636eef6e2 user: drh tags: trunk)
02:42
The "artifact" webpage renders wiki as wiki and html as html but gives submenu items to convert the rendering back to plain text (and hexdump). ... (check-in: c7fe01fe8e user: drh tags: trunk)
2009-01-28
22:56
Add a "View" submenu item on the artifact viewer for files with wiki mimetype. ... (check-in: 0a2a1b4dde user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/info.c.
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
639
640
641
642
643
644
645

646




647
648
649
650
651
652
653
654
655
656
657
  if( !g.okRead ){ login_needed(); return; }
  style_header("File History");
  login_anonymous_available();

  zPrevDate[0] = 0;
  zFilename = PD("name","");
  db_prepare(&q,
    "SELECT a.uuid, substr(b.uuid,1,10), datetime(event.mtime,'localtime'),"
    "       coalesce(event.ecomment, event.comment),"
    "       coalesce(event.euser, event.user),"
    "       mlink.pid, mlink.fid, mlink.mid, mlink.fnid"
    "  FROM mlink, blob a, blob b, event"
    " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"
    "   AND a.rid=mlink.mid"
    "   AND b.rid=mlink.fid"
    "   AND event.objid=mlink.mid"
    " ORDER BY event.mtime DESC",
    zFilename
  );
  blob_zero(&title);
  blob_appendf(&title, "History of ");
  hyperlinked_path(zFilename, &title);
  @ <h2>%b(&title)</h2>
  blob_reset(&title);
  @ <table cellspacing=0 border=0 cellpadding=0>
  while( db_step(&q)==SQLITE_ROW ){
    const char *zVers = db_column_text(&q, 0);
    const char *zUuid = db_column_text(&q, 1);
    const char *zDate = db_column_text(&q, 2);
    const char *zCom = db_column_text(&q, 3);
    const char *zUser = db_column_text(&q, 4);
    int fpid = db_column_int(&q, 5);
    int frid = db_column_int(&q, 6);
    int mid = db_column_int(&q, 7);
    int fnid = db_column_int(&q, 8);

    if( memcmp(zDate, zPrevDate, 10) ){
      sprintf(zPrevDate, "%.10s", zDate);
      @ <tr><td colspan=3>
      @ <table cellpadding=2 border=0>
      @ <tr><td bgcolor="#a0b5f4" class="border1">
      @ <table cellpadding=2 cellspacing=0 border=0><tr>
      @ <td bgcolor="#d0d9f4" class="bkgnd1">%s(zPrevDate)</td>
      @ </tr></table>
      @ </td></tr></table>
      @ </td></tr>
    }
    @ <tr><td valign="top">%s(&zDate[11])</td>
    @ <td width="20"></td>
    @ <td valign="top" align="left">

    hyperlink_to_uuid(zVers);




    @ %h(zCom) (By: %h(zUser))
    @ Id: %s(zUuid)/%d(frid)
    if( g.okHistory ){
      @ <a href="%s(g.zBaseURL)/artifact/%d(frid)">[view]</a>
      if( fpid ){
        @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&amp;v2=%d(frid)">[diff]</a>
      }
      @ <a href="%s(g.zBaseURL)/annotate?mid=%d(mid)&amp;fnid=%d(fnid)">
      @ [annotate]</a>
      @ </td>
    }







|



|

<












<
|
|
|
|
|
|
|
|
>














>
|
>
>
>
>

<

<







597
598
599
600
601
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619
620
621

622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

652

653
654
655
656
657
658
659
  if( !g.okRead ){ login_needed(); return; }
  style_header("File History");
  login_anonymous_available();

  zPrevDate[0] = 0;
  zFilename = PD("name","");
  db_prepare(&q,
    "SELECT substr(b.uuid,1,10), datetime(event.mtime,'localtime'),"
    "       coalesce(event.ecomment, event.comment),"
    "       coalesce(event.euser, event.user),"
    "       mlink.pid, mlink.fid, mlink.mid, mlink.fnid"
    "  FROM mlink, blob b, event"
    " WHERE mlink.fnid=(SELECT fnid FROM filename WHERE name=%Q)"

    "   AND b.rid=mlink.fid"
    "   AND event.objid=mlink.mid"
    " ORDER BY event.mtime DESC",
    zFilename
  );
  blob_zero(&title);
  blob_appendf(&title, "History of ");
  hyperlinked_path(zFilename, &title);
  @ <h2>%b(&title)</h2>
  blob_reset(&title);
  @ <table cellspacing=0 border=0 cellpadding=0>
  while( db_step(&q)==SQLITE_ROW ){

    const char *zUuid = db_column_text(&q, 0);
    const char *zDate = db_column_text(&q, 1);
    const char *zCom = db_column_text(&q, 2);
    const char *zUser = db_column_text(&q, 3);
    int fpid = db_column_int(&q, 4);
    int frid = db_column_int(&q, 5);
    int mid = db_column_int(&q, 6);
    int fnid = db_column_int(&q, 7);
    char zShort[20];
    if( memcmp(zDate, zPrevDate, 10) ){
      sprintf(zPrevDate, "%.10s", zDate);
      @ <tr><td colspan=3>
      @ <table cellpadding=2 border=0>
      @ <tr><td bgcolor="#a0b5f4" class="border1">
      @ <table cellpadding=2 cellspacing=0 border=0><tr>
      @ <td bgcolor="#d0d9f4" class="bkgnd1">%s(zPrevDate)</td>
      @ </tr></table>
      @ </td></tr></table>
      @ </td></tr>
    }
    @ <tr><td valign="top">%s(&zDate[11])</td>
    @ <td width="20"></td>
    @ <td valign="top" align="left">
    sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid);
    if( g.okHistory ){
      @ <a href="%s(g.zTop)/artifact/%s(zUuid)">[%s(zShort)]</a>
    }else{
      @ [%s(zShort)]
    }
    @ %h(zCom) (By: %h(zUser))

    if( g.okHistory ){

      if( fpid ){
        @ <a href="%s(g.zBaseURL)/fdiff?v1=%d(fpid)&amp;v2=%d(frid)">[diff]</a>
      }
      @ <a href="%s(g.zBaseURL)/annotate?mid=%d(mid)&amp;fnid=%d(fnid)">
      @ [annotate]</a>
      @ </td>
    }
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744


/*
** Write a description of an object to the www reply.
**
** If the object is a file then mention:
**
**     * It's uuid
**     * All its filenames
**     * The baselines it was checked-in on, with times and users
**
** If the object is a manifest, then mention:
**
**     * It's uuid
**     * date of check-in
**     * Comment & user
*/
static void object_description(
  int rid,                 /* The artifact ID */
  int linkToView,          /* Add viewer link if true */
  Blob *pDownloadName      /* Fill with an appropriate download name */







|





|







726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746


/*
** Write a description of an object to the www reply.
**
** If the object is a file then mention:
**
**     * It's artifact ID
**     * All its filenames
**     * The baselines it was checked-in on, with times and users
**
** If the object is a manifest, then mention:
**
**     * It's artifact ID
**     * date of check-in
**     * Comment & user
*/
static void object_description(
  int rid,                 /* The artifact ID */
  int linkToView,          /* Add viewer link if true */
  Blob *pDownloadName      /* Fill with an appropriate download name */
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
    const char *zVers = db_column_text(&q, 5);
    if( cnt>0 ){
      @ Also file
    }else{
      @ File
    }
    @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a>
    @ uuid %s(zFuuid) part of check-in
    hyperlink_to_uuid(zVers);
    @ %w(zCom) by %h(zUser) on %s(zDate).
    cnt++;
    if( pDownloadName && blob_size(pDownloadName)==0 ){
      blob_append(pDownloadName, zName, -1);
    }
  }
  db_finalize(&q);
  db_prepare(&q, 







|

|







770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
    const char *zVers = db_column_text(&q, 5);
    if( cnt>0 ){
      @ Also file
    }else{
      @ File
    }
    @ <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a>
    @ artifact %s(zFuuid) part of check-in
    hyperlink_to_uuid(zVers);
    @ - %w(zCom) by %h(zUser) on %s(zDate).
    cnt++;
    if( pDownloadName && blob_size(pDownloadName)==0 ){
      blob_append(pDownloadName, zName, -1);
    }
  }
  db_finalize(&q);
  db_prepare(&q, 
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
    const char *zUuid = db_column_text(&q, 3);
    if( cnt>0 ){
      @ Also wiki page
    }else{
      @ Wiki page
    }
    @ [<a href="%s(g.zBaseURL)/wiki?name=%t(zPagename)">%h(zPagename)</a>]
    @ uuid %s(zUuid) by %h(zUser) on %s(zDate).
    nWiki++;
    cnt++;
    if( pDownloadName && blob_size(pDownloadName)==0 ){
      blob_append(pDownloadName, zPagename, -1);
    }
  }
  db_finalize(&q);







|







801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
    const char *zUuid = db_column_text(&q, 3);
    if( cnt>0 ){
      @ Also wiki page
    }else{
      @ Wiki page
    }
    @ [<a href="%s(g.zBaseURL)/wiki?name=%t(zPagename)">%h(zPagename)</a>]
    @ artifact %s(zUuid) by %h(zUser) on %s(zDate).
    nWiki++;
    cnt++;
    if( pDownloadName && blob_size(pDownloadName)==0 ){
      blob_append(pDownloadName, zPagename, -1);
    }
  }
  db_finalize(&q);
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
        @ Ticket change
      }else if( zType[0]=='c' ){
        @ Manifest of baseline
      }else{
        @ Control file referencing
      }
      hyperlink_to_uuid(zUuid);
      @ %w(zCom) by %h(zUser) on %s(zDate).
      if( pDownloadName && blob_size(pDownloadName)==0 ){
        blob_append(pDownloadName, zUuid, -1);
      }
      cnt++;
    }
    db_finalize(&q);
  }







|







836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
        @ Ticket change
      }else if( zType[0]=='c' ){
        @ Manifest of baseline
      }else{
        @ Control file referencing
      }
      hyperlink_to_uuid(zUuid);
      @ - %w(zCom) by %h(zUser) on %s(zDate).
      if( pDownloadName && blob_size(pDownloadName)==0 ){
        blob_append(pDownloadName, zUuid, -1);
      }
      cnt++;
    }
    db_finalize(&q);
  }
1016
1017
1018
1019
1020
1021
1022


1023
1024
1025
1026
1027
1028
1029
** as preformatted text.
*/
void artifact_page(void){
  int rid;
  Blob content;
  const char *zMime;
  Blob downloadName;



  rid = name_to_rid(PD("name","0"));
  login_check_credentials();
  if( !g.okRead ){ login_needed(); return; }
  if( rid==0 ){ cgi_redirect("/home"); }
  if( g.okAdmin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);







>
>







1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
** as preformatted text.
*/
void artifact_page(void){
  int rid;
  Blob content;
  const char *zMime;
  Blob downloadName;
  int renderAsWiki = 0;
  int renderAsHtml = 0;

  rid = name_to_rid(PD("name","0"));
  login_check_credentials();
  if( !g.okRead ){ login_needed(); return; }
  if( rid==0 ){ cgi_redirect("/home"); }
  if( g.okAdmin ){
    const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1041
1042
1043
1044
1045
1046
1047

1048
1049





1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061

1062
1063

1064
1065
1066
1067
1068
1069
1070
1071







1072

1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1094
1095
  blob_zero(&downloadName);
  object_description(rid, 0, &downloadName);
  style_submenu_element("Download", "Download", 
          "%s/raw/%T?name=%d", g.zTop, blob_str(&downloadName), rid);
  zMime = mimetype_from_name(blob_str(&downloadName));
  if( zMime ){
    if( strcmp(zMime, "text/html")==0 ){

      style_submenu_element("View", "View",
            "%s/raw?name=%d&m=text/html", g.zTop, rid);





    }else if( strcmp(zMime, "application/x-fossil-wiki")==0 ){
      Stmt q;
      db_prepare(&q, 
         "SELECT blob.uuid || '/' || filename.name"
         "  FROM mlink, filename, blob"
         " WHERE mlink.fid=%d"
         "   AND filename.fnid=mlink.fnid"
         "   AND filename.name GLOB '*.wiki'"
         "   AND blob.rid=mlink.mid",
         rid
      );
      if( db_step(&q)==SQLITE_ROW ){

        const char *zCI = db_column_text(&q, 0);
        style_submenu_element("View", "View", "%s/doc/%s", g.zTop, zCI);

      }
      db_finalize(&q);
    }
  }
  @ </blockquote>
  @ <hr>
  @ <blockquote>
  content_get(rid, &content);







  zMime = mimetype_from_content(&content);

  if( zMime==0 ){
    @ <pre>
    @ %h(blob_str(&content))
    @ </pre>
    style_submenu_element("Hex","Hex", "%s/hexdump?name=%d", g.zTop, rid);
  }else if( strncmp(zMime, "image/", 6)==0 ){
    @ <img src="%s(g.zBaseURL)/raw?name=%d(rid)&m=%s(zMime)"></img>
    style_submenu_element("Hex","Hex", "%s/hexdump?name=%d", g.zTop, rid);
  }else{
    @ <pre>
    hexdump(&content);
    @ </pre>
  }
  @ </blockquote>

  style_footer();
}

/*
** WEBPAGE: tinfo
** URL: /tinfo?name=ARTIFACTID
**
** Show the details of a ticket change control artifact.
*/







>
|
|
>
>
>
>
>

<
<
<
<
<
<
|
|
|
<
<
>
|
|
>

<




<

>
>
>
>
>
>
>
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>

|







1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060






1061
1062
1063


1064
1065
1066
1067
1068

1069
1070
1071
1072

1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
  blob_zero(&downloadName);
  object_description(rid, 0, &downloadName);
  style_submenu_element("Download", "Download", 
          "%s/raw/%T?name=%d", g.zTop, blob_str(&downloadName), rid);
  zMime = mimetype_from_name(blob_str(&downloadName));
  if( zMime ){
    if( strcmp(zMime, "text/html")==0 ){
      if( P("txt") ){
        style_submenu_element("Html", "Html",
                              "%s/artifact?name=%d", g.zTop, rid);
      }else{
        renderAsHtml = 1;
        style_submenu_element("Text", "Text",
                              "%s/artifact?name=%d&txt=1", g.zTop, rid);
      }
    }else if( strcmp(zMime, "application/x-fossil-wiki")==0 ){






      if( P("txt") ){
        style_submenu_element("Wiki", "Wiki",
                              "%s/artifact?name=%d", g.zTop, rid);


      }else{
        renderAsWiki = 1;
        style_submenu_element("Text", "Text",
                              "%s/artifact?name=%d&txt=1", g.zTop, rid);
      }

    }
  }
  @ </blockquote>
  @ <hr>

  content_get(rid, &content);
  if( renderAsWiki ){
    wiki_convert(&content, 0, 0);
  }else if( renderAsHtml ){
    @ <div>
    cgi_append_content(blob_buffer(&content), blob_size(&content));
    @ </div>
  }else{
    zMime = mimetype_from_content(&content);
    @ <blockquote>
    if( zMime==0 ){
      @ <pre>
      @ %h(blob_str(&content))
      @ </pre>
      style_submenu_element("Hex","Hex", "%s/hexdump?name=%d", g.zTop, rid);
    }else if( strncmp(zMime, "image/", 6)==0 ){
      @ <img src="%s(g.zBaseURL)/raw?name=%d(rid)&m=%s(zMime)"></img>
      style_submenu_element("Hex","Hex", "%s/hexdump?name=%d", g.zTop, rid);
    }else{
      @ <pre>
      hexdump(&content);
      @ </pre>
    }
    @ </blockquote>
  }
  style_footer();
}  

/*
** WEBPAGE: tinfo
** URL: /tinfo?name=ARTIFACTID
**
** Show the details of a ticket change control artifact.
*/