Check-in [43481115ed]
Not logged in
Overview

SHA1 Hash:43481115ed929aec6c2694cd918221bea542da25
Date: 2009-09-21 19:10:35
User: drh
Comment:Add a "logo" image to the local server state. Return this image on all requests to the "/logo" URL. All the administrator to setup that image. Include the image in the default header.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/configure.c from [d749a9aa69] to [ac12a5f70a].

@@ -76,10 +76,12 @@
   int groupMask;       /* Which config groups is it part of */
 } aConfig[] = {
   { "css",                    CONFIGSET_SKIN },
   { "header",                 CONFIGSET_SKIN },
   { "footer",                 CONFIGSET_SKIN },
+  { "logo-mimetype",          CONFIGSET_SKIN },
+  { "logo-image",             CONFIGSET_SKIN },
   { "project-name",           CONFIGSET_PROJ },
   { "project-description",    CONFIGSET_PROJ },
   { "index-page",             CONFIGSET_SKIN },
   { "timeline-block-markup",  CONFIGSET_SKIN },
   { "timeline-max-comment",   CONFIGSET_SKIN },

Modified src/doc.c from [a9193f6c29] to [4e90952b00].

@@ -468,6 +468,95 @@
   db_end_transaction(0);
   style_header("Document Not Found");
   @ <p>No such document: %h(PD("name","tip/index.wiki"))</p>
   style_footer();
   return;
+}
+
+/*
+** The default logo.
+*/
+static const unsigned char aLogo[] = {
+    71,  73,  70,  56,  55,  97,  62,   0,  71,   0, 244,   0,   0,  85,
+   129, 149,  95, 136, 155,  99, 139, 157, 106, 144, 162, 113, 150, 166,
+   116, 152, 168, 127, 160, 175, 138, 168, 182, 148, 176, 188, 159, 184,
+   195, 170, 192, 202, 180, 199, 208, 184, 202, 210, 191, 207, 215, 201,
+   215, 221, 212, 223, 228, 223, 231, 235, 226, 227, 226, 226, 234, 237,
+   233, 239, 241, 240, 244, 246, 244, 247, 248, 255, 255, 255,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  44,   0,   0,
+     0,   0,  62,   0,  71,   0,   0,   5, 255,  96, 100, 141, 100, 105,
+   158, 168,  37,  41, 132, 192, 164, 112,  44, 207, 102,  99,   0,  56,
+    16,  84, 116, 239, 199, 141,  65, 110, 232, 248,  25, 141, 193, 161,
+    82, 113, 108, 202,  32,  55, 229, 210,  73,  61,  41, 164,  88, 102,
+   181,  10,  41,  96, 179,  91, 106,  35, 240,   5, 135, 143, 137, 242,
+    87, 123, 246,  33, 190,  81, 108, 163, 237, 198,  14,  30, 113, 233,
+   131,  78, 115,  72,  11, 115,  87, 101,  19, 124,  51,  66,  74,   8,
+    19,  16,  67, 100,  74, 133,  50,  15, 101, 135,  56,  11,  74,   6,
+   143,  49, 126, 106,  56,   8, 145,  67,   9, 152,  48, 139, 155,   5,
+    22,  13,  74, 115, 161,  41, 147, 101,  13, 130,  57, 132, 170,  40,
+   167, 155,   0,  94,  57,   3, 178,  48, 183, 181,  57, 160, 186,  40,
+    19, 141, 189,   0,  69, 192,  40,  16, 195, 155, 185, 199,  41, 201,
+   189, 191, 205, 193, 188, 131, 210,  49, 175,  88, 209, 214,  38,  19,
+     3,  11,  19, 111, 127,  60, 219,  39,  55, 204,  19,  11,   6, 100,
+     5,  10, 227, 228,  37, 163,   0, 239, 117,  56, 238, 243,  49, 195,
+   177, 247,  48, 158,  56, 251,  50, 216, 254, 197,  56, 128, 107, 158,
+     2, 125, 171, 114,  92, 218, 246,  96,  66,   3,   4,  50, 134, 176,
+   145,   6,  97,  64, 144,  24,  19, 136, 108,  91, 177, 160,   0, 194,
+    19, 253,   0, 216, 107, 214, 224, 192, 129,   5,  16,  83, 255, 244,
+    43, 213, 195,  24, 159,  27, 169,  64, 230,  88, 208, 227, 129, 182,
+    54,   4,  89, 158,  24, 181, 163, 199,   1, 155,  52, 233,   8, 130,
+   176,  83,  24, 128, 137,  50,  18,  32,  48,  48, 114,  11, 173, 137,
+    19, 110,   4,  64, 105,   1, 194,  30, 140,  68,  15,  24,  24, 224,
+    50,  76,  70,   0,  11, 171,  54,  26, 160, 181, 194, 149, 148,  40,
+   174, 148, 122,  64, 180, 208, 161,  17, 207, 112, 164,   1, 128,  96,
+   148,  78,  18,  21, 194,  33, 229,  51, 247,  65, 133,  97,   5, 250,
+    69, 229, 100,  34, 220, 128, 166, 116, 190,  62,   8, 167, 195, 170,
+    47, 163,   0, 130,  90, 152,  11, 160, 173, 170,  27, 154,  26,  91,
+   232, 151, 171,  18,  14, 162, 253,  98, 170,  18,  70, 171,  64, 219,
+    10,  67, 136, 134, 187, 116,  75, 180,  46, 179, 174, 135,   4, 189,
+   229, 231,  78,  40,  10,  62, 226, 164, 172,  64, 240, 167, 170,  10,
+    18, 124, 188,  10, 107,  65, 193,  94,  11,  93, 171,  28, 248,  17,
+   239,  46, 140,  78,  97,  34,  25, 153,  36,  99,  65, 130,   7, 203,
+   183, 168,  51,  34, 136,  25, 140,  10,   6,  16,  28, 255, 145, 241,
+   230, 140,  10,  66, 178, 167, 112,  48, 192, 128, 129,   9,  31, 141,
+    84, 138,  63, 163, 162,   2, 203, 206, 240,  56,  55,  98, 192, 188,
+    15, 185,  50, 160,   6,   0, 125,  62,  33, 214, 195,  33,   5,  24,
+   184,  25, 231,  14, 201, 245, 144,  23, 126, 104, 228,   0, 145,   2,
+    13, 140, 244, 212,  17,  21,  20, 176, 159,  17,  95, 225, 160, 128,
+    16,   1,  32, 224, 142,  32, 227, 125,  87,  64,   0,  16,  54, 129,
+   205,   2, 141,  76,  53, 130, 103,  37, 166,  64, 144, 107,  78, 196,
+     5, 192,   0,  54,  50, 229,   9, 141,  49,  84, 194,  35,  12, 196,
+   153,  48, 192, 137,  57,  84,  24,   7,  87, 159, 249, 240, 215, 143,
+   105, 241, 118, 149,   9, 139,   4,  64, 203, 141,  35, 140, 129, 131,
+    16, 222, 125, 231, 128,   2, 238,  17, 152,  66,   3,   5,  56, 224,
+   159, 103,  16,  76,  25,  75,   5,  11, 164, 215,  96,   9,  14,  16,
+    36, 225,  15,  11,  40, 144, 192, 156,  41,  10, 178, 199,   3,  66,
+    64,  80, 193,   3, 124,  90,  48, 129, 129, 102, 177,  18, 192, 154,
+    49,  84, 240, 208,  92,  22, 149,  96,  39,   9,  31,  74,  17,  94,
+     3,   8, 177, 199,  72,  59,  85,  76,  25, 216,   8, 139, 194, 197,
+   138, 163,  69,  96, 115,   0, 147,  72,  72,  84,  28,  14,  79,  86,
+   233, 230,  23, 113,  26, 160, 128,   3,  10,  58, 129, 103,  14, 159,
+   214, 163, 146, 117, 238, 213, 154, 128, 151, 109,  84,  64, 217,  13,
+    27,  10, 228,  39,   2, 235, 164, 168,  74,   8,   0,  59,
+};
+
+/*
+** WEBPAGE: logo
+**
+** Return the logo image.  This image is available to anybody who can see
+** the login page.  It is designed for use in the upper left-hand corner
+** of the header.
+*/
+void logo_page(void){
+  Blob logo;
+  char *zMime;
+
+  zMime = db_get("logo-mimetype", "image/gif");
+  blob_zero(&logo);
+  db_blob(&logo, "SELECT value FROM config WHERE name='logo-image'");
+  if( blob_size(&logo)==0 ){
+    blob_init(&logo, (char*)aLogo, sizeof(aLogo));
+  }
+  cgi_set_content_type(zMime);
+  cgi_set_content(&logo);
 }

Modified src/setup.c from [ddfa4b243d] to [f6793e252c].

@@ -76,10 +76,12 @@
     "Edit the Cascading Style Sheet used by all pages of this repository");
   setup_menu_entry("Header", "setup_header",
     "Edit HTML text inserted at the top of every page");
   setup_menu_entry("Footer", "setup_footer",
     "Edit HTML text inserted at the bottom of every page");
+  setup_menu_entry("Logo", "setup_logo",
+    "Change the logo image for the server");
   setup_menu_entry("Shunned", "shun",
     "Show artifacts that are shunned by this repository");
   setup_menu_entry("Log", "rcvfromlist",
     "A record of received artifacts and their sources");
   setup_menu_entry("Stats", "stat",
@@ -1012,8 +1014,64 @@
   @ <hr>
   @ Here is the default page footer:
   @ <blockquote><pre>
   @ %h(zDefaultFooter)
   @ </pre></blockquote>
+  style_footer();
+  db_end_transaction(0);
+}
+
+/*
+** WEBPAGE: setup_logo
+*/
+void setup_logo(void){
+  const char *zMime = "image/gif";
+  const char *aImg = P("im");
+  int szImg = atoi(PD("im:bytes","0"));
+  if( szImg>0 ){
+    zMime = PD("im:mimetype","image/gif");
+  }
+  login_check_credentials();
+  if( !g.okSetup ){
+    login_needed();
+  }
+  db_begin_transaction();
+  if( P("set")!=0 && zMime && zMime[0] && szImg>0 ){
+    Blob img;
+    Stmt ins;
+    blob_init(&img, aImg, szImg);
+    db_prepare(&ins,
+        "REPLACE INTO config(name, value)"
+        " VALUES('logo-image',:bytes)"
+    );
+    db_bind_blob(&ins, ":bytes", &img);
+    db_step(&ins);
+    db_finalize(&ins);
+    db_multi_exec(
+       "REPLACE INTO config(name, value) VALUES('logo-mimetype',%Q)",
+       zMime
+    );
+  }else if( P("clr")!=0 ){
+    db_multi_exec(
+       "DELETE FROM config WHERE name GLOB 'logo-*'"
+    );
+  }
+  style_header("Edit Project Logo");
+  @ <p>The current project logo has a MIME-Type of <b>%h(zMime)</b> and looks
+  @ like this:</p>
+  @ <blockquote><img src="/logo" alt="logo"></blockquote>
+  @
+  @ <form action="%s(g.zBaseURL)/setup_logo" method="POST"
+  @  enctype="multipart/form-data">
+  @ <p>The logo is accessible to all users at this URL:
+  @ <a href="%s(g.zBaseURL)/logo">%s(g.zBaseURL)/logo</a>.
+  @ To set a new logo image, select a file to use as the logo using
+  @ the entry box below and then press the "Change Logo" button.</p>
+  login_insert_csrf_secret();
+  @ Logo Image file:
+  @ <input type="file" name="im" size="60" accepts="image/*"><br>
+  @ <input type="submit" name="set" value="Change Logo">
+  @ <input type="submit" name="clr" value="Revert To Default">
+  @ </form>
   style_footer();
   db_end_transaction(0);
 }

Modified src/style.c from [47b34cf931] to [d209a15931].

@@ -191,12 +191,12 @@
 @       media="screen">
 @ </head>
 @ <body>
 @ <div class="header">
 @   <div class="logo">
-@     <!-- <img src="logo.gif" alt="logo"><br></br> -->
-@     <nobr>$<project_name></nobr>
+@     <img src="/logo" alt="logo">
+@     <br><nobr>$<project_name></nobr>
 @   </div>
 @   <div class="title">$<title></div>
 @   <div class="status"><nobr><th1>
 @      if {[info exists login]} {
 @        puts "Logged in as $login"
@@ -269,11 +269,12 @@
 @ /* The page title centered at the top of each page */
 @ div.title {
 @   display: table-cell;
 @   font-size: 2em;
 @   font-weight: bold;
-@   text-align: center;
+@   text-align: left;
+@   padding: 0 0 0 1em;
 @   color: #558195;
 @   vertical-align: bottom;
 @   width: 100%;
 @ }
 @

Modified src/xfer.c from [05ae6aecee] to [2973354cfc].

@@ -523,15 +523,18 @@
 /*
 ** Send a single config card for configuration item zName
 */
 static void send_config_card(Xfer *pXfer, const char *zName){
   if( zName[0]!='@' ){
-    char *zValue = db_get(zName, 0);
-    if( zValue ){
-      blob_appendf(pXfer->pOut, "config %s %d\n%s\n",
-                   zName, strlen(zValue), zValue);
-      free(zValue);
+    Blob val;
+    blob_zero(&val);
+    db_blob(&val, "SELECT value FROM config WHERE name=%Q", zName);
+    if( blob_size(&val)>0 ){
+      blob_appendf(pXfer->pOut, "config %s %d\n", zName, blob_size(&val));
+      blob_append(pXfer->pOut, blob_buffer(&val), blob_size(&val));
+      blob_reset(&val);
+      blob_append(pXfer->pOut, "\n", 1);
     }
   }else{
     Blob content;
     blob_zero(&content);
     configure_render_special_name(zName, &content);
@@ -768,14 +771,25 @@
         @ error not\sauthorized\sto\spush\sconfiguration
         nErr++;
         break;
       }
       if( zName[0]!='@' ){
-        db_multi_exec(
-            "REPLACE INTO config(name,value) VALUES(%Q,%Q)",
-            zName, blob_str(&content)
-        );
+        if( strcmp(zName, "logo-image")==0 ){
+          Stmt ins;
+          db_prepare(&ins,
+            "REPLACE INTO config(name, value) VALUES(:name, :value)"
+          );
+          db_bind_text(&ins, ":name", zName);
+          db_bind_blob(&ins, ":value", &content);
+          db_step(&ins);
+          db_finalize(&ins);
+        }else{
+          db_multi_exec(
+              "REPLACE INTO config(name,value) VALUES(%Q,%Q)",
+              zName, blob_str(&content)
+          );
+        }
       }else{
         /* Notice that we are evaluating arbitrary SQL received from the
         ** client.  But this can only happen if the client has authenticated
         ** as an administrator, so presumably we trust the client at this
         ** point.
@@ -1130,14 +1144,25 @@
         blob_zero(&content);
         blob_extract(xfer.pIn, size, &content);
         g.okAdmin = g.okRdAddr = 1;
         if( configure_is_exportable(zName) & origConfigRcvMask ){
           if( zName[0]!='@' ){
-            db_multi_exec(
-                "REPLACE INTO config(name,value) VALUES(%Q,%Q)",
-                zName, blob_str(&content)
-            );
+            if( strcmp(zName, "logo-image")==0 ){
+              Stmt ins;
+              db_prepare(&ins,
+                "REPLACE INTO config(name, value) VALUES(:name, :value)"
+              );
+              db_bind_text(&ins, ":name", zName);
+              db_bind_blob(&ins, ":value", &content);
+              db_step(&ins);
+              db_finalize(&ins);
+            }else{
+              db_multi_exec(
+                  "REPLACE INTO config(name,value) VALUES(%Q,%Q)",
+                  zName, blob_str(&content)
+              );
+            }
           }else{
             /* Notice that we are evaluating arbitrary SQL received from the
             ** server.  But this can only happen if we have specifically
             ** requested configuration information from the server, so
             ** presumably the operator trusts the server.