Overview
SHA1 Hash: | 766bec08cebeb858a874df71c4d6e3961e3a33e8 |
---|---|
Date: | 2009-01-25 19:18:09 |
User: | drh |
Comment: | Documentation tweaks. Change the "Setup" menu title to "Admin". Added pages under Admin to view the RCVFROM table of the database. |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/info.c from [b888c0d485] to [420d4f7587].
@@ -390,14 +390,30 @@ @ <tr><th>Original Comment:</th><td>%w(zComment)</td></tr> }else{ @ <tr><th>Comment:</th><td>%w(zComment)</td></tr> } @ </td></tr> + if( g.okAdmin ){ + db_prepare(&q, + "SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)" + " FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)" + " WHERE blob.rid=%d", + rid + ); + if( db_step(&q)==SQLITE_ROW ){ + const char *zIpAddr = db_column_text(&q, 0); + const char *zUser = db_column_text(&q, 1); + const char *zDate = db_column_text(&q, 2); + if( zUser==0 || zUser[0]==0 ) zUser = "unknown"; + @ <tr><th>Received From:</th> + @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr> + } + db_finalize(&q); + } if( g.okHistory ){ char *zShortUuid = mprintf("%.10s", zUuid); const char *zProjName = db_get("project-name", "unnamed"); - Stmt q; @ <tr><th>Timelines:</th><td> @ <a href="%s(g.zBaseURL)/timeline?p=%d(rid)">ancestors</a> @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)">descendants</a> @ | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)&p=%d(rid)">both</a> db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag " @@ -1127,13 +1143,10 @@ style_footer(); return; } if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){ vinfo_page(); - }else - if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){ - finfo_page(); }else if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)" " WHERE rid=%d AND tagname LIKE 'wiki-%%'", rid) ){ winfo_page(); }else
Modified src/setup.c from [fca5464418] to [9d845dbac4].
@@ -56,11 +56,11 @@ login_check_credentials(); if( !g.okSetup ){ login_needed(); } - style_header("Setup"); + style_header("Server Administration"); @ <table border="0" cellspacing="20"> setup_menu_entry("Users", "setup_ulist", "Grant privileges to individual users."); setup_menu_entry("Access", "setup_access", "Control access settings."); @@ -76,10 +76,12 @@ "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("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", "Display repository statistics"); @ </table> style_footer();
Modified src/shun.c from [ffc8251555] to [a2062a7125].
@@ -26,11 +26,11 @@ #include "config.h" #include "shun.h" #include <assert.h> /* -** Return true if the given UUID should be shunned. +** Return true if the given artifact ID should be shunned. */ int uuid_is_shunned(const char *zUuid){ static Stmt q; int rc; if( zUuid==0 || zUuid[0]==0 ) return 0; @@ -119,14 +119,18 @@ } db_finalize(&q); @ </blockquote> @ <hr> @ <a name="addshun"></a> - @ <p>To shun an artifact, enter its UUID in the + @ <p>To shun an artifact, enter its artifact ID (the 40-character SHA1 + @ hash of the artifact) in the @ following box and press the "Shun" button. This will cause the artifact @ to be removed from the repository and will prevent the artifact from being @ readded to the repository by subsequent sync operation.</p> + @ + @ <p>Note that you must enter the full 40-character artifact ID, not + @ an abbreviation or a symbolic tag.</p> @ @ <p>Warning: Shunning should only be used to remove inappropriate content @ from the repository. Inappropriate content includes such things as @ spam added to Wiki, files that violate copyright or patent agreements, @ or artifacts that by design or accident interfere with the processing @@ -153,10 +157,11 @@ @ <input type="text" name="uuid" size="50"> @ <input type="submit" name="sub" value="Accept"> @ </form> @ </blockquote> @ + @ <hr> @ <p>Press the button below to rebuild the respository. The rebuild @ may take several seconds, so be patient after pressing the button.</p> @ @ <blockquote> @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)"> @@ -188,6 +193,110 @@ db_multi_exec( "DELETE FROM delta WHERE rid IN toshun;" "DELETE FROM blob WHERE rid IN toshun;" "DROP TABLE toshun;" ); +} + +/* +** WEBPAGE: rcvfromlist +** +** Show a listing of RCVFROM table entries. +*/ +void rcvfromlist_page(void){ + int ofst = atoi(PD("ofst","0")); + int cnt; + Stmt q; + + login_check_credentials(); + if( !g.okAdmin ){ + login_needed(); + } + style_header("Content Sources"); + if( ofst>0 ){ + style_submenu_element("Later", "Later", "rcvfromlist?ofst=%d", + ofst>30 ? ofst-30 : 0); + } + db_prepare(&q, + "SELECT rcvid, login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" + " FROM rcvfrom LEFT JOIN user USING(uid)" + " ORDER BY rcvid DESC LIMIT 31 OFFSET %d", + ofst + ); + @ <table cellpadding=0 cellspacing=0 border=0> + @ <tr><th>rcvid</th><th width=15> + @ <th>Date</th><th width=15><th>User</th> + @ <th width=15><th>IP Address</th></tr> + cnt = 0; + while( db_step(&q)==SQLITE_ROW ){ + int rcvid = db_column_int(&q, 0); + const char *zUser = db_column_text(&q, 1); + const char *zDate = db_column_text(&q, 2); + const char *zIpAddr = db_column_text(&q, 3); + if( cnt==30 ){ + style_submenu_element("Earlier", "Earlier", + "rcvfromlist?ofst=%d", ofst+30); + }else{ + cnt++; + @ <tr> + @ <td><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td><td> + @ <td>%s(zDate)</td><td> + @ <td>%h(zUser)</td><td> + @ <td> %s(zIpAddr) </td> + @ </tr> + } + } + db_finalize(&q); + @ </table> + style_footer(); +} + +/* +** WEBPAGE: rcvfrom +** +** Show a single RCVFROM table entry. +*/ +void rcvfrom_page(void){ + int rcvid = atoi(PD("rcvid","0")); + Stmt q; + + login_check_credentials(); + if( !g.okAdmin ){ + login_needed(); + } + style_header("Content Source %d", rcvid); + db_prepare(&q, + "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr" + " FROM rcvfrom LEFT JOIN user USING(uid)" + " WHERE rcvid=%d", + rcvid + ); + @ <table cellspacing=15 cellpadding=0 border=0> + @ <tr><td valign="top" align="right">rcvid:</td> + @ <td valign="top">%d(rcvid)</td></tr> + if( db_step(&q)==SQLITE_ROW ){ + const char *zUser = db_column_text(&q, 0); + const char *zDate = db_column_text(&q, 1); + const char *zIpAddr = db_column_text(&q, 2); + @ <tr><td valign="top" align="right">User:</td> + @ <td valign="top">%s(zUser)</td></tr> + @ <tr><td valign="top" align="right">Date:</td> + @ <td valign="top">%s(zDate)</td></tr> + @ <tr><td valign="top" align="right">IP Address:</td> + @ <td valign="top">%s(zIpAddr)</td></tr> + } + db_finalize(&q); + db_prepare(&q, + "SELECT rid, uuid, size FROM blob WHERE rcvid=%d", rcvid + ); + @ <tr><td valign="top" align="right">Artifacts:</td> + @ <td valign="top"> + while( db_step(&q)==SQLITE_ROW ){ + int rid = db_column_int(&q, 0); + const char *zUuid = db_column_text(&q, 1); + int size = db_column_int(&q, 2); + @ <a href="%s(g.zBaseURL)/info/%s(zUuid)">%s(zUuid)</a> + @ (rid: %d(rid), size: %d(size))<br> + } + @ </td></tr> + @ </table> }
Modified src/style.c from [3c8c1ba929] to [49507955d9].
@@ -221,11 +221,11 @@ @ } @ if {[hascap j]} { @ html "<a href='$baseurl/wiki'>Wiki</a>" @ } @ if {[hascap s]} { -@ html "<a href='$baseurl/setup'>Setup</a>" +@ html "<a href='$baseurl/setup'>Admin</a>" @ } elseif {[hascap a]} { @ html "<a href='$baseurl/setup_ulist'>Users</a>" @ } @ if {[info exists login]} { @ html "<a href='$baseurl/login'>Logout</a>"
Modified www/branching.wiki from [867e5fd1b3] to [eeebbc4b17].
@@ -80,13 +80,13 @@ <tr><td align="center"> <img src="branch03.gif" width=282 height=152><br> Figure 3 </td></tr></table></center> -Check-in 5 is a direct child of check-in 3 because it was created by editing +Check-in 5 is a child of check-in 3 because it was created by editing check-in 3. But check-in 5 also inherits the changes from check-in 4 by -virtual of the merge. So we say that check-in 5 is a <i>merge child</i> +virtue of the merge. So we say that check-in 5 is a <i>merge child</i> of check-in 4 and that it is a <i>direct child</i> of check-in 3. The graph is now back to a single leaf (check-in 5). We have already seen that if fossil is in autosync mode then Bob would have been warned about the potential fork the first time he tried to @@ -109,13 +109,13 @@ instead of as a separate manual step. We will not take sides in that debate. We will simply point out that fossil enables you to do it either way. <h2>Forking Versus Branching</h2> -Forking and having more than one leaf in the check-in tree is usually -considered undesirable, and so forks are usually quickly resolved as -shown in figure 3 above. +Having more than one leaf in the check-in tree is usually +considered undesirable, and so forks are usually either avoided entirely, +as in figure 1, or else quickly resolved as shown in figure 3. But sometimes, one does want to have multiple leaves. For example, a project might have one leaf that is the latest version of the project under development and another leaf that is the latest version that has been tested. When multiple leaves are desirable, we call the phenomenon <i>branching</i> @@ -146,11 +146,11 @@ shown by the dashed merge arrows between check-ins 6 and 7 and between check-ins 9 and 10. In both figures 2 and 4, check-in 2 has two children. In figure 2, we called this a "fork". In diagram 4, we call it a "branch". What is -the difference? As far as the internal fossil data structure are +the difference? As far as the internal fossil data structures are concerned, there is no difference. The distinction is in the intent. In figure 2, the fact that check-in 2 has multiple children is an accident that stems from concurrent development. In figure 4, giving check-in 2 multiple children is a deliberate act. So, to a good approximation, we define forking to be by accident and branching to @@ -172,19 +172,20 @@ <i>property</i> is a name/value pair. Internally, fossil implements tags as properties with a NULL value. So, tags and properties really are much the same thing, and henceforth we will use the word "tag" to mean either a tag or a property. -A tag can be either a one-time tag or an propagating tag or a cancellation. +A tag can be either a one-time tag or an propagating tag or a cancellation tag. A one-time tag only applies to the check-in to which it is attached. A propagating tag applies to the check-in to which it is attached and also to all direct descendants of that check-in. A <i>direct descendant</i> is a descendant through direct children. Tags propagation does not cross merges. Tag propagation also stops as soon as it encounters another check-in with the same tag. A cancellation tag is attached to a single check-in in order to either override a one-time -tag that was placed on that same check-in, or to block tag propagation. +tag that was previously placed on that same check-in, or to block +tag propagation from an ancestor. Every repository is created with a single empty check-in that has two propagating tags. In figure 5, that initial empty check-in is check-in 1. The <b>branch</b> tag tells (by its value) what branch the check-in is a member of. @@ -214,11 +215,11 @@ <b>sym-trunk</b> on check-in 4. The net effect of all of this is that check-ins on the trunk go by the symbolic name of "trunk" and check-ins that are on the test branch go by the symbolic name "test". The <b>bgcolor=blue</b> tag on check-in 4 causes the background color -of timelines to be blue for check-in 4 and its descendants. +of timelines to be blue for check-in 4 and its direct descendants. Figure 5 also shows two one-time tags on check-in 9. (The diagram does not make a graphical distinction between one-time and propagating tags.) The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to using the more meaningful name "release-1.0". The <b>closed</b> tag means @@ -231,10 +232,11 @@ <blockquote><dl> <dt><b>Branch</b></dt> <dd><p>A branch is a set of check-ins that have the same value for their +branch property.</p></dd> <dt><b>Leaf</b></dt> <dd><p>A leaf is a check-in that has no children in the same branch.</p></dd> <dt><b>Closed Leaf</b></dt> <dd><p>A closed leaf is leaf that has the <b>closed</b> tag. Such leaves are intented to never be extended with descendents and hence are omitted
Modified www/newrepo.wiki from [6e108d436b] to [0f60ddea66].
@@ -30,11 +30,11 @@ </verbatim> The <tt>ui</tt> command starts up a server (with an optional <tt>-port NUMBER</tt> argument) and launches a web browser pointing at the fossil server. From there it takes just a few moments to configure the -repo. Most importantly, go to the Setup menu, then the Users link, and +repo. Most importantly, go to the Admin menu, then the Users link, and set your account name and password, and grant your account all access priviledges. (I also like to grant Clone access to the anonymous user, but that's personal preference.) Once you are done, kill the fossil server (with Ctrl-C or equivalent) @@ -154,11 +154,11 @@ remote repository. If you have <tt>autosync</tt> on then this sync happens automatically, otherwise you will need to use the <em>pull</em> command to get remote changes and the <em>push</em> command to push your local commits to the remote repository. You must of course have authorization to commit changes (access is configured -via the Setup/Users page mentioned above). +via the Admin/Users page mentioned above). You may always use the <em>server</em> or <em>ui</em> commands to browse a cloned repository. You can even edit create or wiki entries, etc., and they will be pushed to the remote side the next time you push data to the the remote.
Modified www/quickstart.wiki from [c0029b88f0] to [6b03b1426c].
@@ -73,11 +73,11 @@ After the server is running, fossil will then attempt to launch your web browser and make it point to this web server. If your system has an unusual configuration, fossil might not be able to figure out how to start your web browser. In that case, start the web browser yourself and point it at http://localhost:8080/. Click on the - "Setup" link on the menu bar to start configuring your repository.</p> + "Admin" link on the menu bar to start configuring your repository.</p> <p>By default, fossil does not require a login for HTTP connections coming in from the IP loopback address 127.0.0.1. You can, and perhaps should, change this after you create a few users.</p>