home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- /* Reading bookmarks.htm into rdf.
- tags in the bookmark file.
- <TITLE>
- <H1>
- <H3>
- <DL></DL>
- <DT>
- <P>
-
- <DT> indicates that an item is coming.
- If the next item is an <a then we have a url
- If the next item is a h3, we have a folder.
- <DL> indicates that the previous item (which should have been a folder)
- is the parent of the next set.
- </DL> indicates pop out a level
- <P> ignore this on reading, but write out one after each <DL>
- <DD> the description for the previous <DT>
-
- Category urls. Make it up out of the add dates. */
-
-
- /*
- This file translates netscape bookmarks into the rdf data model.
- For more information on this file, contact rjc or guha
- For more information on RDF, look at the RDF section of www.mozilla.org
- */
-
-
- #include "bmk2mcf.h"
- #include "glue.h"
- #include "mcff2mcf.h"
- #include "utils.h"
-
-
- /* extern declarations */
- PR_PUBLIC_API(void) HT_WriteOutAsBookmarks (RDF r, PRFileDesc *fp, RDF_Resource u); /* XXX this should be elsewhere */
- extern char *gBookmarkURL;
- extern RDF gNCDB;
-
- /* globals */
- uint16 separatorCounter = 0;
- static char* gBkFolderDate;
-
-
-
- RDF_Resource
- createSeparator(void)
- {
- char url[50];
- RDF_Resource sep;
- PR_snprintf(url, 50, "separator%i", separatorCounter++);
- sep = RDF_GetResource(NULL, url, 1);
- return sep;
- }
-
-
-
- RDF_Resource
- createContainer (char* id)
- {
- RDF_Resource r = RDF_GetResource(NULL, id, true);
- setContainerp(r, 1);
- return r;
- }
-
-
-
- char *
- resourceDescription (RDF rdf, RDF_Resource r)
- {
- return (char*)RDF_GetSlotValue(rdf, r, gWebData->RDF_description, RDF_STRING_TYPE, false, true);
- }
-
-
-
- char *
- resourceLastVisitDate (RDF rdf, RDF_Resource r)
- {
- return (char*)RDF_GetSlotValue(rdf, r, gWebData->RDF_lastVisitDate, RDF_STRING_TYPE, false, true);
- }
-
-
-
- char *
- resourceLastModifiedDate (RDF rdf, RDF_Resource r)
- {
- return (char*)RDF_GetSlotValue(rdf, r, gWebData->RDF_lastModifiedDate, RDF_STRING_TYPE, false, true);
- }
-
-
-
- void
- parseNextBkBlob (RDFFile f, char* blob, int32 size)
- {
- int32 n, last, m;
- PRBool somethingseenp = false;
- n = last = 0;
-
- while (n < size) {
- char c = blob[n];
- m = 0;
- somethingseenp = false;
- memset(f->line, '\0', f->lineSize);
- if (f->holdOver[0] != '\0') {
- memcpy(f->line, f->holdOver, strlen(f->holdOver));
- m = strlen(f->holdOver);
- somethingseenp = true;
- memset(f->holdOver, '\0', RDF_BUF_SIZE);
- }
- while ((m < 300) && (c != '<') && (c != '>') && (n < size)) {
- f->line[m] = c;
- m++;
- somethingseenp = (somethingseenp || ((c != ' ') && (c != '\r') && (c != '\n')));
- n++;
- c = blob[n];
- }
- if (c == '>') f->line[m] = c;
- n++;
- if (m > 0) {
- if ((c == '<') || (c == '>')) {
- last = n;
- if (c == '<') f->holdOver[0] = '<';
- if (somethingseenp == true) parseNextBkToken(f, f->line);
- } else if (size > last) {
- memcpy(f->holdOver, f->line, m);
- }
- } else if (c == '<') f->holdOver[0] = '<';
- }
- }
-
-
-
- void
- parseNextBkToken (RDFFile f, char* token)
- {
- /* printf(token); */
- if (token[0] == '<') {
- bkStateTransition(f, token);
- } else {
- /* ok, we have a piece of content.
- can be the title, or a description or */
- if ((f->status == IN_TITLE) || (f->status == IN_H3) ||
- (f->status == IN_ITEM_TITLE)) {
- if (IN_H3 && gBkFolderDate) {
- char url[150];
- RDF_Resource newFolder;
- sprintf(url, "%s%s.rdf", gBkFolderDate, token);
- newFolder = createContainer(url);
- addSlotValue(f,newFolder, gCoreVocab->RDF_parent, f->stack[f->depth-1],
- RDF_RESOURCE_TYPE, true);
- freeMem(gBkFolderDate);
- gBkFolderDate = NULL;
- f->lastItem = newFolder;
- }
- addSlotValue(f, f->lastItem, gCoreVocab->RDF_name,
- copyString(token), RDF_STRING_TYPE, true);
- if (startsWith("Personal Toolbar", token) && (containerp(f->lastItem)))
- nlocalStoreAssert(gLocalStore, f->lastItem, gCoreVocab->RDF_instanceOf,
- gNavCenter->RDF_PersonalToolbarFolderCategory,
- RDF_RESOURCE_TYPE, true);
- } else if (f->status == IN_ITEM_DESCRIPTION) {
- addDescription(f, f->lastItem, token);
- }
- }
- }
-
-
-
- void
- addDescription (RDFFile f, RDF_Resource r, char* token)
- {
- char* desc = (char*) nlocalStoreGetSlotValue(gLocalStore, r, gWebData->RDF_description,
- RDF_STRING_TYPE, false, true);
- if (desc == NULL) {
- addSlotValue(f, f->lastItem, gWebData->RDF_description, copyString(token),
- RDF_STRING_TYPE, true);
- } else {
- addSlotValue(f, f->lastItem, gWebData->RDF_description,
- append2Strings(desc, token), RDF_STRING_TYPE, true);
- nlocalStoreUnassert(gLocalStore, f->lastItem, gWebData->RDF_description, desc, RDF_STRING_TYPE);
- }
- }
-
-
-
- void
- bkStateTransition (RDFFile f, char* token)
- {
- if (startsWith("<A", token)) {
- newLeafBkItem(f, token);
- f->status = IN_ITEM_TITLE;
- } else if (startsWith(OPEN_H3_STRING, token)) {
- newFolderBkItem(f, token);
- f->status = IN_H3;
- } else if (startsWith(OPEN_TITLE_STRING, token)) {
- f->status = IN_TITLE;
- } else if (startsWith(OPEN_H3_STRING, token)) {
- f->status = IN_H3;
- } else if (startsWith(DD_STRING, token)) {
- if (nlocalStoreGetSlotValue(gLocalStore, f->lastItem, gWebData->RDF_description,
- RDF_STRING_TYPE, false, true)
- == NULL) f->status = IN_ITEM_DESCRIPTION;
- } else if (startsWith(OPEN_DL_STRING, token)) {
- f->stack[f->depth++] = f->lastItem;
- } else if (startsWith(CLOSE_DL_STRING, token)) {
- f->depth--;
- } else if (startsWith("<HR>", token)) {
- addSlotValue(f, createSeparator(), gCoreVocab->RDF_parent, f->stack[f->depth-1],
- RDF_RESOURCE_TYPE, true);
- f->status = 0;
- } else if ((f->status == IN_ITEM_DESCRIPTION) && (startsWith("<BR>", token))) {
- addDescription(f, f->lastItem, token);
- } else f->status = 0;
- }
-
-
-
- void
- newFolderBkItem(RDFFile f, char* token)
- {
- int16 start, end;
- start = charSearch('"', token);
- end = revCharSearch('"', token);
- token[end] = '\0';
- gBkFolderDate = copyString(&token[start+1]);
- }
-
-
-
- void
- newLeafBkItem (RDFFile f, char* token)
- {
- char* url = NULL;
- char* addDate = NULL;
- char* lastVisit = NULL;
- char* lastModified = NULL;
- uint8 current = 0;
- int32 len = strlen(token);
- int32 n = 0;
- char c = token[n++];
- PRBool inString = false;
- RDF_Resource newR;
-
- while (n < len) {
- if (c == '"') {
- if (inString) {
- token[n-1] = '\0';
- inString = false;
- } else {
- inString = true;
- if (current == 0) {
- url = &token[n];
- } else if (current == 1) {
- addDate = &token[n];
- } else if (current == 2) {
- lastVisit = &token[n];
- } else if (current == 3) {
- lastModified = &token[n];
- }
- current++;
- }
- }
- c = token[n++];
- }
- if (url == NULL) return;
- newR = RDF_GetResource(NULL, url, true);
- addSlotValue(f, newR, gCoreVocab->RDF_parent, f->stack[f->depth-1],
- RDF_RESOURCE_TYPE, true);
- /* addSlotValue(f, newR, gWebData->RDF_URL, (void*)copyString(url),
- RDF_STRING_TYPE, true); */
- if (addDate != NULL)
- {
- addSlotValue(f, newR, gNavCenter->RDF_bookmarkAddDate, (void*)copyString(addDate),
- RDF_STRING_TYPE, true);
- }
- if (lastVisit != NULL)
- {
- addSlotValue(f, newR, gWebData->RDF_lastVisitDate, (void*)copyString(lastVisit),
- RDF_STRING_TYPE, true);
- }
- if (lastModified != NULL)
- {
- addSlotValue(f, newR, gWebData->RDF_lastModifiedDate, (void*)copyString(lastModified),
- RDF_STRING_TYPE, true);
- }
- f->lastItem = newR;
- }
-
-
-
- char *
- numericDate(char *url)
- {
- char *date = NULL;
- int len=0;
-
- if (!url) return NULL;
- while (url[len])
- {
- if (!isdigit(url[len])) break;
- ++len;
- }
- if (len > 0)
- {
- if (date = getMem(len+1))
- {
- strncpy(date, url, len);
- }
- }
- return(date);
- }
-
-
-
- PRBool
- bookmarkSlotp (RDF_Resource s)
- {
- return ((s == gCoreVocab->RDF_parent) || (s == gWebData->RDF_lastVisitDate) || (s == gWebData->RDF_description) ||
- (s == gNavCenter->RDF_bookmarkAddDate) || (s == gWebData->RDF_lastModifiedDate) ||
- (s == gCoreVocab->RDF_name));
- }
-
-
- void
- HT_WriteOutAsBookmarks1 (RDF rdf, PRFileDesc *fp, RDF_Resource u, RDF_Resource top, int indent)
- {
- RDF_Cursor c = RDF_GetSources(rdf, u, gCoreVocab->RDF_parent, RDF_RESOURCE_TYPE, true);
- RDF_Resource next;
- char *date, *name, *url;
- int loop;
-
- if (c == NULL) return;
- if (u == top) {
- name = RDF_GetResourceName(rdf, u);
- ht_rjcprintf(fp, "<!DOCTYPE NETSCAPE-Bookmark-file-1>\n", NULL);
- ht_rjcprintf(fp, "<!-- This is an automatically generated file.\n", NULL);
- ht_rjcprintf(fp, "It will be read and overwritten.\n", NULL);
- ht_rjcprintf(fp, "Do Not Edit! -->\n", NULL);
-
- ht_rjcprintf(fp, "<TITLE>%s</TITLE>\n", (name) ? name:"");
- ht_rjcprintf(fp, "<H1>%s</H1>\n<DL><p>\n", (name) ? name:"");
- }
- while (next = RDF_NextValue(c)) {
-
- url = resourceID(next);
- if (containerp(next) && (!startsWith("ftp:",url)) && (!startsWith("file:",url))
- && (!startsWith("IMAP:", url)) && (!startsWith("nes:", url))
- && (!startsWith("mail:", url)) && (!startsWith("cache:", url))
- && (!startsWith("ldap:", url))) {
- for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
-
- date = numericDate(resourceID(next));
- ht_rjcprintf(fp, "<DT><H3 ADD_DATE=\"%s\">", (date) ? date:"");
- if (date) freeMem(date);
- name = RDF_GetResourceName(rdf, next);
- ht_rjcprintf(fp, "%s</H3>\n", name);
-
- for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
- ht_rjcprintf(fp, "<DL><p>\n", NULL);
- HT_WriteOutAsBookmarks1(rdf, fp, next, top, indent+1);
-
- for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
-
- ht_rjcprintf(fp, "</DL><p>\n", NULL);
- }
- else if (isSeparator(next)) {
- for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
- ht_rjcprintf(fp, "<HR>\n", NULL);
- }
- else {
- char* bkAddDate = (char*)RDF_GetSlotValue(rdf, next,
- gNavCenter->RDF_bookmarkAddDate,
- RDF_STRING_TYPE, false, true);
-
- for (loop=0; loop<indent; loop++) ht_rjcprintf(fp, " ", NULL);
-
- ht_rjcprintf(fp, "<DT><A HREF=\"%s\" ", resourceID(next));
- date = numericDate(bkAddDate);
- ht_rjcprintf(fp, "ADD_DATE=\"%s\" ", (date) ? date: "");
- if (date) freeMem(date);
- ht_rjcprintf(fp, "LAST_VISIT=\"%s\" ", resourceLastVisitDate(rdf, next));
- ht_rjcprintf(fp, "LAST_MODIFIED=\"%s\">", resourceLastModifiedDate(rdf, next));
- ht_rjcprintf(fp, "%s</A>\n", RDF_GetResourceName(rdf, next));
-
- if (resourceDescription(rdf, next) != NULL) {
- ht_rjcprintf(fp, "<DD>%s\n", resourceDescription(rdf, next));
- }
- }
- }
- RDF_DisposeCursor(c);
- if (u == top) {
- ht_rjcprintf(fp, "</DL>\n", NULL);
- }
- }
-
-
-
- PR_PUBLIC_API(void)
- HT_WriteOutAsBookmarks (RDF r, PRFileDesc *fp, RDF_Resource u)
- {
- HT_WriteOutAsBookmarks1 (r, fp, u, u, 1);
- }
-
-
-
- void
- flushBookmarks()
- {
- PRFileDesc *bkfp;
-
- if (gBookmarkURL != NULL)
- {
- /*
- delete bookmark.htm as PROpen() with PR_TRUNCATE appears broken (at least on Mac)
- */
- CallPRDeleteFileUsingFileURL(gBookmarkURL);
-
- if ((bkfp = CallPROpenUsingFileURL(gBookmarkURL, (PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE),
- 0644)) != NULL)
- {
- HT_WriteOutAsBookmarks(gNCDB, bkfp, gNavCenter->RDF_BookmarkFolderCategory);
- PR_Close(bkfp);
- }
- }
- }
-