Back to index

lightning-sunbird  0.9+nobinonly
genopendir.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <stdlib.h>
00039 #include <string.h>
00040 #include <stdio.h>
00041 #include "rdf.h"
00042 #include "gs.h"
00043 
00044 void describeItem (WriteClientProc callBack, void* obj, RDF_Resource u) ;
00045 void describeItemSimple (WriteClientProc callBack, void* obj, RDF_Resource u) ;
00046 extern int startsWith(const char* prefix, const char* pattern);
00047 
00048 
00049 RDF_Resource    gNarrow;
00050 RDF_Resource    gLink; 
00051 RDF_Resource    gName; 
00052 RDF_Resource    gTopic;
00053 RDF_Resource    gDesc; 
00054 RDF_Resource    gEditor; 
00055 RDF_Resource    gNewsGroup;
00056 char*           gTemplate;
00057 int gInited = 0;
00058 #define MAX_TEMPLATE_SIZE 20000
00059 
00060 RDF_Resource 
00061 getNodeFromQuery (char* query) {
00062   RDF_Resource ans;
00063   if (!(ans = RDF_GetResource(query, 0))) {
00064     return RDF_GetResource("Top", 1);
00065   } else return ans;
00066 }
00067 
00068 #define ROW_WIDTH 3
00069 
00070 #define PREFIX "<form method=get action=\"OpenDir?\"><B>Search:</B> <input size=25 name=search> <input type=submit value=search><br><BR><BR></form><div align=right><a href=\"/odoptions.html\">Personalize</a></div>"
00071 
00072 void
00073 SortResourceList (RDF_Resource* list, size_t n, char sortType) {
00074   if (sortType == 'd') {
00075   } else {
00076   }
00077 }
00078 
00079 void
00080 listParents(WriteClientProc callBack, void* obj, RDF_Resource node, int depth) {
00081   RDF_Resource narrow = RDF_GetResource("narrow", 1);
00082   RDF_Resource parent = RDF_OnePropSource(0, node, narrow);
00083 
00084   char* id = RDF_ResourceID(node);
00085   char* nm = (char*) RDF_OnePropValue(0, node, gName, RDF_STRING_TYPE);
00086   char* cnm = strrchr(id, '/');
00087   char buff[500];
00088   if (!nm || strchr(nm, '/')) nm = (cnm ? cnm + 1 : id);
00089   if ((depth < 10) && parent) listParents(callBack, obj, parent, depth+1);
00090   sprintf(buff, "<B><a href=\"OpenDir?browse=%s\">%s</a> > </B> ", id, nm);
00091 
00092   (*callBack)(obj, buff); 
00093 }
00094 
00095 char
00096 cookiePropValue (char* cookie, char* prop) {
00097   size_t len = strlen(prop);
00098   char*  str = strstr(cookie, prop);
00099   if (!str) {
00100     return 0;
00101   } else {
00102     return *(str + len + 1);
00103   }
00104 }
00105 
00106 void
00107 Init () {
00108   if (!gInited) {
00109     int n = 0;
00110     FILE *templateFile = fopen("template.html", "r");
00111     if (!templateFile) printf("Could not open template!\n");
00112     gInited = 1;    
00113     gNarrow = RDF_GetResource("narrow", 1);
00114     gLink = RDF_GetResource("link", 1);
00115     gName = RDF_GetResource("Title", 1);
00116     gTopic = RDF_GetResource("Topic", 1);
00117     gDesc = RDF_GetResource("Description", 1);
00118     gEditor = RDF_GetResource("editor", 1);
00119     gNewsGroup = RDF_GetResource("newsGroup", 1);
00120     gTemplate = (char*) calloc(MAX_TEMPLATE_SIZE+1, 1);
00121     n = fread(gTemplate, 1, MAX_TEMPLATE_SIZE, templateFile);
00122     gTemplate[n] = '\0';
00123     fclose(templateFile);
00124   }
00125 }
00126 
00127 char*
00128 resourceName (RDF_Resource u) {
00129   char* nm = (char*) RDF_OnePropValue(0, u, gName, RDF_STRING_TYPE);
00130   char* id = RDF_ResourceID(u);
00131   if (!nm || strchr(nm, '/')) nm = strrchr(id, '/') +1;
00132   return nm;
00133 }
00134 
00135 void
00136 outputTopicName (WriteClientProc callBack, void* obj, RDF_Resource node) {
00137   char* nm = (char*) RDF_OnePropValue(0, node, gName, RDF_STRING_TYPE);
00138   char* id = RDF_ResourceID(node);
00139 
00140   if (!nm || strchr(nm, '/')) 
00141          if (strchr(id, '/')) {
00142                 nm = strrchr(id, '/') +1;
00143          } else {
00144                 nm = id;
00145          }
00146 
00147   (*callBack)(obj, nm);
00148 }
00149   
00150 void
00151 listSubTopics (WriteClientProc callBack, void* obj, RDF_Resource node, char* cookie, RDF_Resource p) {
00152   if (node) {
00153     RDF_Cursor c = RDF_GetTargets(0, node, p, RDF_RESOURCE_TYPE);
00154     char        widthc = cookiePropValue(cookie, "cols");
00155     RDF_Resource u;
00156     char buff[5000];
00157     RDF_Resource subTopicList[200];
00158     int n = 0;
00159     int w = 0;
00160     while (u =  (RDF_Resource) RDF_NextValue(c)) {
00161       subTopicList[n++] = u;
00162     }
00163     for (w = 0; w < n; w++) {
00164       char* id;
00165       if (((w == 0) || (w == ((n+1)/2))) && (p == gNarrow)) {
00166         if (w != 0)  (*callBack)(obj, "</td>");
00167         (*callBack)(obj, "</UL>\n<TD width=\"40%\" valign=top><UL><FONT Face=\"sans-serif, Arial, Helvetica\">\n<UL>\n");
00168       }
00169       u = subTopicList[n-w-1];
00170       id = RDF_ResourceID(u);
00171       if (p == gNarrow) {
00172         sprintf(buff, "<li><a href=\"OpenDir?browse=%s\"><B>%s</B></a>\n", id, resourceName(u));
00173       } else {
00174         char* des = (char*) RDF_OnePropValue(0, u, gDesc, RDF_STRING_TYPE);
00175         sprintf(buff, "<li><a href=\"%s\">%s</a> %s %s\n", id, resourceName(u), 
00176                 (des ? " : " : ""), (des ? des : ""));
00177       }        
00178       (*callBack)(obj, buff);
00179     }
00180   }
00181 }
00182 
00183 void 
00184 AnswerOpenDirQuery (WriteClientProc callBack, void* obj, char *query, char* cookie) {
00185   RDF_Resource node = getNodeFromQuery(query);
00186   size_t n = 0;
00187   char buff[MAX_TEMPLATE_SIZE];
00188   char* pbegin = 0;
00189   char* begin;  
00190   Init();
00191   begin = gTemplate;
00192   while (pbegin = strstr(begin, "&Topic")) {
00193     memset(buff, '\0', 10000);
00194     memcpy(buff, begin, pbegin-begin);
00195     (*callBack)(obj, buff);
00196     if (startsWith("&TopicName;", pbegin)) {
00197       outputTopicName(callBack, obj, node);
00198     } else if (startsWith("&TopicPath;", pbegin)) {
00199       listParents(callBack, obj, node, 0);
00200     } else if (startsWith("&TopicSubTopics;", pbegin)) {
00201       listSubTopics(callBack, obj, node, cookie, gNarrow);
00202     } else if (startsWith("&TopicItems;", pbegin)) {
00203       listSubTopics(callBack, obj, node, cookie, gLink);
00204     } else if (startsWith("&TopicAddURL;", pbegin)) {
00205       (*callBack)(obj, "http://directory.mozilla.org/cgi-bin/add.cgi?where=");
00206       (*callBack)(obj, RDF_ResourceID(node));
00207     } else if (startsWith("&TopicBecomeEditor;", pbegin)) {
00208       (*callBack)(obj, "http://directory.mozilla.org/cgi-bin/apply.cgi?where=");
00209       (*callBack)(obj, RDF_ResourceID(node));
00210     }
00211     begin = pbegin + (strchr(pbegin, ';') - pbegin) + 1; 
00212 
00213   }
00214   (*callBack)(obj, begin);
00215 }
00216   
00217 
00218 
00219 void describeCategory (WriteClientProc callBack, void* obj, RDF_Resource u) {
00220   char buff[1000];
00221   sprintf(buff, "<li><B><a href=\"OpenDir?browse=%s\">%s</a></B>", RDF_ResourceID(u),
00222   RDF_ResourceID(u));
00223   (*callBack)(obj, buff);
00224 }
00225 
00226 #define MRN 1000
00227 
00228 RDF_Resource
00229 stToProp (char c) {
00230   if (!c || (c == 'a')) {
00231     return 0;
00232   } else if (c == 'n') {
00233     return gName;
00234   } else if (c == 'd') {
00235     return gDesc;
00236   } else return 0;
00237 }
00238 
00239 void 
00240 AnswerSearchQuery (WriteClientProc callBack, void* obj, char *query, char* cookie) {
00241     char      st = cookiePropValue(cookie, "searchTarget");
00242     RDF_Cursor c = RDFGS_Search(0, query, stToProp(st));
00243     RDF_Resource topic = RDF_GetResource("Topic", 1);
00244     RDF_Resource type = RDF_GetResource("type", 1);
00245     RDF_Resource u ;
00246     size_t catn = 0;
00247     size_t itemn = 0;    
00248     size_t index;
00249     RDF_Resource* cats = (RDF_Resource*)calloc(MRN+1, sizeof(RDF_Resource));
00250     RDF_Resource* items =  (RDF_Resource*)calloc(MRN+1, sizeof(RDF_Resource));
00251     char showDesc = cookiePropValue(cookie, "searchDesc");
00252 
00253     (*callBack)(obj, PREFIX);
00254     (*callBack)(obj, "<B>Search : ");
00255     (*callBack)(obj, query);
00256     (*callBack)(obj, "</B>");
00257 
00258     while ((u = (RDF_Resource) RDFGS_NextValue(c)) && 
00259            (itemn < MRN-1) && (catn < MRN-1)) {
00260       if (RDF_HasAssertion(0, u, type, topic, RDF_RESOURCE_TYPE)) {
00261         cats[catn++] = u;  
00262       } else {
00263         items[itemn++] = u;  
00264       }
00265     }
00266 
00267     RDFGS_DisposeCursor(c);
00268     if (catn > 0) {            
00269       (*callBack)(obj, "<HR><B>Matching Categories :</B><BR>");
00270       (*callBack)(obj, "<UL>");
00271       for (index = 0; index < catn ; index++) {
00272         if (cats[index]) describeCategory(callBack, obj, cats[index]);
00273       }
00274       (*callBack)(obj, "</UL>");
00275     }
00276 
00277     if (itemn > 0) {
00278       (*callBack)(obj, "<HR><B>Matching Links :</B><BR><UL>");
00279       for (index = 0; index < itemn ; index++) {
00280         if (items[index]) {
00281           if (showDesc == 'n') {
00282             describeItemSimple(callBack, obj, items[index]);
00283           } else {
00284             describeItem(callBack, obj, items[index]);
00285           }
00286         } 
00287       }
00288       (*callBack)(obj, "</UL>");      
00289     }
00290 
00291    free(items);
00292    free(cats);
00293 }
00294 
00295 
00296 void
00297 describeItemSimple (WriteClientProc callBack, void* obj, RDF_Resource u) {
00298   char buff[5000];
00299   char* nm = (char*) RDF_OnePropValue(0, u, gName, RDF_STRING_TYPE);
00300   char* id = RDF_ResourceID(u);
00301   sprintf(buff, "<li><a href=\"%s\">%s</a>", id, (nm ? nm : id));
00302   (*callBack)(obj, buff);
00303 }
00304 
00305 void
00306 describeItem (WriteClientProc callBack, void* obj, RDF_Resource u) {
00307   char buff[5000];
00308   char* nm = (char*) RDF_OnePropValue(0, u, gName, RDF_STRING_TYPE);
00309   char* id = RDF_ResourceID(u);
00310   char* des = (char*) RDF_OnePropValue(0, u, gDesc, RDF_STRING_TYPE);
00311   sprintf(buff, "<li><a href=\"%s\">%s</a> %s %s", id, (nm ? nm : id), 
00312           (des ? " : " : ""), (des ? des : ""));
00313   (*callBack)(obj, buff);
00314 }
00315     
00316   
00317   
00318   
00319 
00320 
00321 
00322 
00323