File Annotation
Not logged in
02d1ed6ad2 2008-02-02   stephan: /*
02d1ed6ad2 2008-02-02   stephan: ** Copyright (c) 2007 D. Richard Hipp
2ab3a2f603 2008-02-03   stephan: ** Copyright (c) 2008 Stephan Beal
02d1ed6ad2 2008-02-02   stephan: **
02d1ed6ad2 2008-02-02   stephan: ** This program is free software; you can redistribute it and/or
02d1ed6ad2 2008-02-02   stephan: ** modify it under the terms of the GNU General Public
02d1ed6ad2 2008-02-02   stephan: ** License as published by the Free Software Foundation; either
02d1ed6ad2 2008-02-02   stephan: ** version 2 of the License, or (at your option) any later version.
02d1ed6ad2 2008-02-02   stephan: **
02d1ed6ad2 2008-02-02   stephan: ** This program is distributed in the hope that it will be useful,
02d1ed6ad2 2008-02-02   stephan: ** but WITHOUT ANY WARRANTY; without even the implied warranty of
02d1ed6ad2 2008-02-02   stephan: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
02d1ed6ad2 2008-02-02   stephan: ** General Public License for more details.
02d1ed6ad2 2008-02-02   stephan: **
02d1ed6ad2 2008-02-02   stephan: ** You should have received a copy of the GNU General Public
02d1ed6ad2 2008-02-02   stephan: ** License along with this library; if not, write to the
02d1ed6ad2 2008-02-02   stephan: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
02d1ed6ad2 2008-02-02   stephan: ** Boston, MA  02111-1307, USA.
02d1ed6ad2 2008-02-02   stephan: **
02d1ed6ad2 2008-02-02   stephan: ** Author contact information:
02d1ed6ad2 2008-02-02   stephan: **   drh@hwaci.com
02d1ed6ad2 2008-02-02   stephan: **   http://www.hwaci.com/drh/
02d1ed6ad2 2008-02-02   stephan: **
02d1ed6ad2 2008-02-02   stephan: *******************************************************************************
02d1ed6ad2 2008-02-02   stephan: **
02d1ed6ad2 2008-02-02   stephan: ** Implementation of the Tag View page
02d1ed6ad2 2008-02-02   stephan: */
02d1ed6ad2 2008-02-02   stephan: #include <assert.h>
02d1ed6ad2 2008-02-02   stephan: #include "config.h"
02d1ed6ad2 2008-02-02   stephan: #include "tagview.h"
02d1ed6ad2 2008-02-02   stephan: 
02d1ed6ad2 2008-02-02   stephan: 
2cb3290e67 2008-02-03   stephan: #if 1
2cb3290e67 2008-02-03   stephan: #  define TAGVIEW_DEFAULT_FILTER "AND t.tagname NOT GLOB 'wiki-*' "
2cb3290e67 2008-02-03   stephan: #else
2cb3290e67 2008-02-03   stephan: #  define TAGVIEW_DEFAULT_FILTER
02a7c850b4 2008-02-03   stephan: #endif
02a7c850b4 2008-02-03   stephan: 
2ab3a2f603 2008-02-03   stephan: /*
007d1ce44f 2008-02-07       drh: ** Lists all tags matching the given LIKE clause (which
007d1ce44f 2008-02-07       drh: ** may be 0).
2ab3a2f603 2008-02-03   stephan: */
007d1ce44f 2008-02-07       drh: static void tagview_page_list_tags(const char *zLike){
007d1ce44f 2008-02-07       drh:   char *zLikeClause = 0;
9c01af2d22 2008-02-03   stephan:   const int limit = 10;
007d1ce44f 2008-02-07       drh:   char *zLimit = 0;
007d1ce44f 2008-02-07       drh:   char *zSql;
2ab3a2f603 2008-02-03   stephan: 
007d1ce44f 2008-02-07       drh:   if( zLike && zLike[0] ){
007d1ce44f 2008-02-07       drh:     zLikeClause = mprintf( "AND t.tagname LIKE '%%%q%%'", zLike );
007d1ce44f 2008-02-07       drh:     zLimit = "";
007d1ce44f 2008-02-07       drh:     @ <h2>Tags matching [%h(zLikeClause)]:</h2>
007d1ce44f 2008-02-07       drh:   }else{
007d1ce44f 2008-02-07       drh:     zLimit = mprintf( "LIMIT %d", limit );
007d1ce44f 2008-02-07       drh:     zLikeClause = "";
2ab3a2f603 2008-02-03   stephan:     @ <h2>%d(limit) most recent tags:</h2>
2ab3a2f603 2008-02-03   stephan:   }
007d1ce44f 2008-02-07       drh:   zSql = mprintf(
007d1ce44f 2008-02-07       drh:     "SELECT "
007d1ce44f 2008-02-07       drh:     "   linktagid(t.tagid) AS 'Tag ID',"
007d1ce44f 2008-02-07       drh:     "   linktagname(t.tagname) AS 'Name',"
007d1ce44f 2008-02-07       drh:     "   DATETIME(tx.mtime) AS 'Timestamp',"
007d1ce44f 2008-02-07       drh:     "   linkuuid(b.uuid) AS 'Version'"
007d1ce44f 2008-02-07       drh:     "  FROM tag t, tagxref tx, blob b "
0ff4e918f4 2008-02-13   stephan:     " WHERE t.tagid=tx.tagid AND tx.rid=b.rid"
007d1ce44f 2008-02-07       drh:     "   AND tx.tagtype!=0 %s "
9c01af2d22 2008-02-03   stephan:     TAGVIEW_DEFAULT_FILTER
007d1ce44f 2008-02-07       drh:     " ORDER BY tx.mtime DESC %s",
007d1ce44f 2008-02-07       drh:     zLikeClause, zLimit
007d1ce44f 2008-02-07       drh:   );
007d1ce44f 2008-02-07       drh:   db_generic_query_view(zSql, 1);
007d1ce44f 2008-02-07       drh:   free(zSql);
6d67f3c7c7 2008-02-08   stephan:   if( zLikeClause[0] ) free(zLikeClause);
6d67f3c7c7 2008-02-08   stephan:   if( zLimit[0] ) free(zLimit);
2ab3a2f603 2008-02-03   stephan: }
2ab3a2f603 2008-02-03   stephan: 
007d1ce44f 2008-02-07       drh: /*
007d1ce44f 2008-02-07       drh: ** A small search form which forwards to ?like=SEARCH_STRING
2cb3290e67 2008-02-03   stephan: */
2ab3a2f603 2008-02-03   stephan: static void tagview_page_search_miniform(void){
2ab3a2f603 2008-02-03   stephan:   char const * like = P("like");
2ab3a2f603 2008-02-03   stephan:   @ <div style='font-size:smaller'>
3984b1b2c1 2008-08-04      eric:   @ <form action='tagview' method='post'>
2ab3a2f603 2008-02-03   stephan:   @ Search for tags:
007d1ce44f 2008-02-07       drh:   @ <input type='text' name='like' value='%h((like?like:""))' size='10'/>
2ab3a2f603 2008-02-03   stephan:   @ <input type='submit'/>
2ab3a2f603 2008-02-03   stephan:   @ </form>
2ab3a2f603 2008-02-03   stephan:   @ </div>
2ab3a2f603 2008-02-03   stephan: }
2ab3a2f603 2008-02-03   stephan: 
007d1ce44f 2008-02-07       drh: /*
007d1ce44f 2008-02-07       drh: ** tagview_page_default() renders the default page for tagview_page().
9c01af2d22 2008-02-03   stephan: */
2ab3a2f603 2008-02-03   stephan: static void tagview_page_default(void){
2ab3a2f603 2008-02-03   stephan:   tagview_page_list_tags( 0 );
2ab3a2f603 2008-02-03   stephan: }
2ab3a2f603 2008-02-03   stephan: 
007d1ce44f 2008-02-07       drh: /*
007d1ce44f 2008-02-07       drh: ** Lists all tags matching the given tagid.
02a7c850b4 2008-02-03   stephan: */
007d1ce44f 2008-02-07       drh: static void tagview_page_tag_by_id( int tagid ){
007d1ce44f 2008-02-07       drh:   char *zSql;
9c01af2d22 2008-02-03   stephan:   @ <h2>Tag #%d(tagid):</h2>
007d1ce44f 2008-02-07       drh:   zSql = mprintf(
007d1ce44f 2008-02-07       drh:     "SELECT DISTINCT"
007d1ce44f 2008-02-07       drh:     "       linktagname(t.tagname) AS 'Tag Name',"
007d1ce44f 2008-02-07       drh:     "       DATETIME(tx.mtime) AS 'Timestamp',"
007d1ce44f 2008-02-07       drh:     "       linkuuid(b.uuid) AS 'Version'"
007d1ce44f 2008-02-07       drh:     "  FROM tag t, tagxref tx, blob b"
0ff4e918f4 2008-02-13   stephan:     " WHERE t.tagid=%d AND t.tagid=tx.tagid AND tx.rid=b.rid "
007d1ce44f 2008-02-07       drh:     TAGVIEW_DEFAULT_FILTER
007d1ce44f 2008-02-07       drh:     " ORDER BY tx.mtime DESC",
007d1ce44f 2008-02-07       drh:     tagid
007d1ce44f 2008-02-07       drh:   );
007d1ce44f 2008-02-07       drh:   db_generic_query_view(zSql, 1);
007d1ce44f 2008-02-07       drh:   free(zSql);
b81e93f576 2008-02-03   stephan: }
02a7c850b4 2008-02-03   stephan: 
007d1ce44f 2008-02-07       drh: /*
007d1ce44f 2008-02-07       drh: ** Lists all tags matching the given tag name.
b81e93f576 2008-02-03   stephan: */
007d1ce44f 2008-02-07       drh: static void tagview_page_tag_by_name( char const * tagname ){
007d1ce44f 2008-02-07       drh:   char *zSql;
007d1ce44f 2008-02-07       drh:   @ <h2>Tag '%s(tagname)':</h2>
007d1ce44f 2008-02-07       drh:   zSql = mprintf(
007d1ce44f 2008-02-07       drh:     "SELECT DISTINCT"
007d1ce44f 2008-02-07       drh:     "       linktagid(t.tagid) AS 'Tag ID',"
007d1ce44f 2008-02-07       drh:     "       DATETIME(tx.mtime) AS 'Timestamp',"
007d1ce44f 2008-02-07       drh:     "       linkuuid(b.uuid) AS 'Version'"
007d1ce44f 2008-02-07       drh:     "  FROM tag t, tagxref tx, blob b "
0ff4e918f4 2008-02-13   stephan:     " WHERE t.tagname='%q' AND t.tagid=tx.tagid AND tx.rid=b.rid "
9c01af2d22 2008-02-03   stephan:     TAGVIEW_DEFAULT_FILTER
007d1ce44f 2008-02-07       drh:     " ORDER BY tx.mtime DESC",
007d1ce44f 2008-02-07       drh:     tagname);
007d1ce44f 2008-02-07       drh:   db_generic_query_view(zSql, 1);
007d1ce44f 2008-02-07       drh:   free(zSql);
2cb3290e67 2008-02-03   stephan: }
02a7c850b4 2008-02-03   stephan: 
02d1ed6ad2 2008-02-02   stephan: /*
3984b1b2c1 2008-08-04      eric: ** WEBP AGE: /tagview
02d1ed6ad2 2008-02-02   stephan: */
3984b1b2c1 2008-08-04      eric: void old_tagview_page(void){
908009fdc4 2008-05-07       drh:   char const * check = 0;
9c01af2d22 2008-02-03   stephan:   login_check_credentials();
9c01af2d22 2008-02-03   stephan:   if( !g.okRdWiki ){
9c01af2d22 2008-02-03   stephan:     login_needed();
9c01af2d22 2008-02-03   stephan:   }
9c01af2d22 2008-02-03   stephan:   style_header("Tags");
d57de28756 2008-05-05       drh:   login_anonymous_available();
9c01af2d22 2008-02-03   stephan:   tagview_page_search_miniform();
9c01af2d22 2008-02-03   stephan:   @ <hr/>
007d1ce44f 2008-02-07       drh:   if( 0 != (check = P("tagid")) ){
9c01af2d22 2008-02-03   stephan:     tagview_page_tag_by_id( atoi(check) );
007d1ce44f 2008-02-07       drh:   }else if( 0 != (check = P("like")) ){
9c01af2d22 2008-02-03   stephan:     tagview_page_list_tags( check );
007d1ce44f 2008-02-07       drh:   }else if( 0 != (check = P("name")) ){
9c01af2d22 2008-02-03   stephan:     tagview_page_tag_by_name( check );
02d1ed6ad2 2008-02-02   stephan:   }else{
9c01af2d22 2008-02-03   stephan:     tagview_page_default();
02d1ed6ad2 2008-02-02   stephan:   }
9c01af2d22 2008-02-03   stephan:   style_footer();
2ab3a2f603 2008-02-03   stephan: }
2ab3a2f603 2008-02-03   stephan: 
9c01af2d22 2008-02-03   stephan: #undef TAGVIEW_DEFAULT_FILTER
2ab3a2f603 2008-02-03   stephan: 
0e924820bf 2008-08-24      eric: /*
0e924820bf 2008-08-24      eric: ** Generate a timeline for the chosen tag
0e924820bf 2008-08-24      eric: */
0e924820bf 2008-08-24      eric: void tagview_print_timeline(char const *pName, char const *pPrefix){
0e924820bf 2008-08-24      eric:   char *zSql;
0e924820bf 2008-08-24      eric:   Stmt q;
0e924820bf 2008-08-24      eric:   zSql = mprintf("%s AND EXISTS (SELECT 1"
0e924820bf 2008-08-24      eric:          " FROM tagxref"
0e924820bf 2008-08-24      eric:          "  WHERE tagxref.rid = event.objid"
0e924820bf 2008-08-24      eric:          "  AND tagxref.tagid = (SELECT tagid FROM tag"
0e924820bf 2008-08-24      eric:          "      WHERE tagname = %Q||%Q))"
0e924820bf 2008-08-24      eric:          " ORDER BY 3 desc",
0e924820bf 2008-08-24      eric:          timeline_query_for_www(), pPrefix, pName);
0e924820bf 2008-08-24      eric:   db_prepare(&q, zSql);
0e924820bf 2008-08-24      eric:   free(zSql);
0e924820bf 2008-08-24      eric:   www_print_timeline(&q);
0e924820bf 2008-08-24      eric:   db_finalize(&q);
02d1ed6ad2 2008-02-02   stephan: }
02d1ed6ad2 2008-02-02   stephan: 
02d1ed6ad2 2008-02-02   stephan: /*
02d1ed6ad2 2008-02-02   stephan: ** WEBPAGE: /tagview
02d1ed6ad2 2008-02-02   stephan: */
02d1ed6ad2 2008-02-02   stephan: void tagview_page(void){
3984b1b2c1 2008-08-04      eric:   char const *zName = 0;
3d62a9fb39 2008-10-06       drh:   int nTag = 0;
02d1ed6ad2 2008-02-02   stephan:   login_check_credentials();
3984b1b2c1 2008-08-04      eric:   if( !g.okRead ){
02d1ed6ad2 2008-02-02   stephan:     login_needed();
02d1ed6ad2 2008-02-02   stephan:   }
3984b1b2c1 2008-08-04      eric:   login_anonymous_available();
3984b1b2c1 2008-08-04      eric:   if( 0 != (zName = P("name")) ){
3984b1b2c1 2008-08-04      eric:     Blob uuid;
0e924820bf 2008-08-24      eric:     style_header("Tagged Baselines");
0e924820bf 2008-08-24      eric:     @ <h2>%s(zName):</h2>
3984b1b2c1 2008-08-04      eric:     if( sym_tag_to_uuid(zName, &uuid) > 0){
0e924820bf 2008-08-24      eric:       tagview_print_timeline(zName, "sym-");
5fb14b9a0f 2008-08-21      eric:     }else if( tag_to_uuid(zName, &uuid, "") > 0){
0e924820bf 2008-08-24      eric:       tagview_print_timeline(zName, "");
0e924820bf 2008-08-24      eric:     }else{
3984b1b2c1 2008-08-04      eric:       @ There is no artifact with this tag.
3984b1b2c1 2008-08-04      eric:     }
3984b1b2c1 2008-08-04      eric:   }else{
3984b1b2c1 2008-08-04      eric:     Stmt q;
3984b1b2c1 2008-08-04      eric:     const char *prefix = "sym-";
3984b1b2c1 2008-08-04      eric:     int preflen = strlen(prefix);
3984b1b2c1 2008-08-04      eric:     style_header("Tags");
3984b1b2c1 2008-08-04      eric:     db_prepare(&q,
3984b1b2c1 2008-08-04      eric:       "SELECT tagname"
3984b1b2c1 2008-08-04      eric:       "  FROM tag"
3984b1b2c1 2008-08-04      eric:       " WHERE EXISTS(SELECT 1 FROM tagxref"
3984b1b2c1 2008-08-04      eric:       "               WHERE tagid=tag.tagid"
3984b1b2c1 2008-08-04      eric:       "                 AND tagtype>0)"
5fb14b9a0f 2008-08-21      eric:       " AND tagid > %d"
5fb14b9a0f 2008-08-21      eric:       " AND tagname NOT GLOB 'wiki-*'"
5fb14b9a0f 2008-08-21      eric:       " AND tagname NOT GLOB 'tkt-*'"
5fb14b9a0f 2008-08-21      eric:       " ORDER BY tagname",
5fb14b9a0f 2008-08-21      eric:       MAX_INT_TAG
02a7c850b4 2008-02-03   stephan:     );
3984b1b2c1 2008-08-04      eric:     @ <ul>
3984b1b2c1 2008-08-04      eric:     while( db_step(&q)==SQLITE_ROW ){
3984b1b2c1 2008-08-04      eric:       const char *name = db_column_text(&q, 0);
3d62a9fb39 2008-10-06       drh:       nTag++;
5b87749575 2008-09-06      eric:       if( g.okHistory ){
5b87749575 2008-09-06      eric:         if( strncmp(name, prefix, preflen)==0 ){
5b87749575 2008-09-06      eric:           @ <li><a href=%s(g.zBaseURL)/tagview?name=%s(name+preflen)>
5b87749575 2008-09-06      eric:           @ %s(name+preflen)</a>
5b87749575 2008-09-06      eric:         }else{
5b87749575 2008-09-06      eric:           @ <li><a href=%s(g.zBaseURL)/tagview?name=%s(name)>
5b87749575 2008-09-06      eric:           @ %s(name)</a>
5b87749575 2008-09-06      eric:         }
5fb14b9a0f 2008-08-21      eric:       }else{
5b87749575 2008-09-06      eric:         if( strncmp(name, prefix, preflen)==0 ){
5b87749575 2008-09-06      eric:           @ <li><strong>%s(name+preflen)</strong>
5b87749575 2008-09-06      eric:         }else{
5b87749575 2008-09-06      eric:           @ <li><strong>%s(name)</strong>
5b87749575 2008-09-06      eric:         }
5b87749575 2008-09-06      eric:       }
3984b1b2c1 2008-08-04      eric:       if( strncmp(name, prefix, preflen)==0 ){
5b87749575 2008-09-06      eric:         @ (symbolic label)
3984b1b2c1 2008-08-04      eric:       }
5b87749575 2008-09-06      eric:       @ </li>
3984b1b2c1 2008-08-04      eric:     }
3984b1b2c1 2008-08-04      eric:     @ </ul>
3d62a9fb39 2008-10-06       drh:     if( nTag == 0) {
5b87749575 2008-09-06      eric:       @ There are no relevant tags.
5b87749575 2008-09-06      eric:     }
3984b1b2c1 2008-08-04      eric:     db_finalize(&q);
02d1ed6ad2 2008-02-02   stephan:   }
5b87749575 2008-09-06      eric:   /*
5b87749575 2008-09-06      eric:    * Put in dummy functions since www_print_timeline has generated calls to
5b87749575 2008-09-06      eric:    * them. Some browsers don't seem to care, but better to be safe.
5b87749575 2008-09-06      eric:    * Actually, it would be nice to use the functions on this page, but at
5b87749575 2008-09-06      eric:    * the moment it looks to be too difficult.
5b87749575 2008-09-06      eric:    */
5b87749575 2008-09-06      eric:   @ <script>
5b87749575 2008-09-06      eric:   @ function xin(id){
5b87749575 2008-09-06      eric:   @ }
5b87749575 2008-09-06      eric:   @ function xout(id){
5b87749575 2008-09-06      eric:   @ }
5b87749575 2008-09-06      eric:   @ </script>
02d1ed6ad2 2008-02-02   stephan:   style_footer();
02d1ed6ad2 2008-02-02   stephan: }