Click here to Skip to main content
Click here to Skip to main content

Merge Firefox json bookmarks

By , 5 Nov 2012
 

Introduction 

If you want to merge bookmarks from 2 machines (ex, work and home) firefox doesn't allow you to merge the bookmarks, it only allow you to replace the current bookmarks.

Background  

this code use jayrock json library to manipulate json text 

http://jayrock.berlios.de

Using the code

firefox bookmark file, are composed mainly of 4 arrays, Tags, Bookmark Menu, Bookmark Toolbar and unsorted bookmark.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Jayrock.Json.Conversion;
using System.Collections;
using System.Windows.Forms;

namespace mergeBookmarks
{
    static class Merge
    {
        static int maxId = 0;
        static IDictionary findItem(string menu, string sUri,  Jayrock.Json.JsonArray jArray)
        {
            IDictionary foundNode = null;
            int i;
            for (i = 0; i < jArray.Count(); i++)
            {

                if (jArray[i].GetType() == typeof(Jayrock.Json.JsonObject))
                {
                    IDictionary node =(IDictionary) jArray[i];
                    if (node.Contains("title"))
                    {
                        if ((node["title"] == null && menu == null) || Convert.ToString(node["title"]).Equals(menu))
                        {
                            foundNode = (IDictionary)jArray[i];
                            if (node.Contains("uri"))
                            {
                                if (Convert.ToString(node["uri"]).Equals(sUri))
                                {
                                    return foundNode;
                                }
                            }
                            else
                            {
                                return foundNode;
                            }
                        }
                    }
                }
                else if (jArray[i].GetType() == typeof(Jayrock.Json.JsonArray))
                {
                }
                else
                {
                }
            }
            return foundNode;

        }
        static int findMaxIndex(Jayrock.Json.JsonArray jArray)
        {
            int index = 0;
            int i;
            for (i = 0; i < jArray.Count(); i++)
            {
                if (jArray[i].GetType() == typeof(Jayrock.Json.JsonObject))
                {
                     IDictionary node =(IDictionary)jArray[i];
                    if (node.Contains("index"))
                    {
                        if (Convert.ToInt32(node["index"])>index)
                            index = Convert.ToInt32(node["index"]);
                    }
                }
                else
                {
                }
            }
            return index;
        }
        static void adjustIds( int parent, Jayrock.Json.JsonArray jArray)
        {
            IEnumerator<object> jTagEnum = jArray.GetEnumerator();
            int index = 0;
            while (jTagEnum.MoveNext())
            {
                IDictionary obj= (IDictionary)jTagEnum.Current;
                obj["id"] = maxId++;
                obj["parent"] = parent;
                if (!obj.Contains("index"))
                {
                    if (index > 0)
                        obj.Add("index", index);
                }
                else
                {
                    obj["index"] = index;
                }
                index++;
                if (obj["type"].ToString().Equals("text/x-moz-place-container"))
                {
                    adjustIds(Convert.ToInt32(obj["id"]), (Jayrock.Json.JsonArray)obj["children"]);
                }
            }
        }

        static void doMergeLists(IDictionary node1, IDictionary node2)
        {
            string sType1, sType2;
            sType1 = node1["type"].ToString();
            sType2 = node2["type"].ToString();
            if (!sType1.Equals("text/x-moz-place-container") || !sType2.Equals("text/x-moz-place-container"))
            {
                throw new Exception("not container");
            }

            Jayrock.Json.JsonArray jArray1 = (Jayrock.Json.JsonArray)node1["children"];
            int TagsId = Convert.ToInt32(node1["id"]);
            Jayrock.Json.JsonArray jArray2 = (Jayrock.Json.JsonArray)node2["children"];
            int maxTagsIndex = findMaxIndex(jArray1) + 1;
            IEnumerator<object> jArray2Enum = jArray2.GetEnumerator();
            while (jArray2Enum.MoveNext())
            {
                IDictionary node = (IDictionary)jArray2Enum.Current;
                if (node.Contains("title"))
                {
                    string title=null;
                    if (node["title"] != null)
                        title = node["title"].ToString();
                    else
                        title = null;
                    string sItemType2 = node["type"].ToString();
                    if ((title != null && (title.Equals("Recently Bookmarked") || title.Equals("Recent Tags"))) || sItemType2 == "text/x-moz-place-separator")
                    {
                        continue;
                    }
                    IDictionary obj = null;
                    if (node.Contains("uri"))
                    {
                        string sUri = node["uri"].ToString();
                         obj = findItem(title, sUri, jArray1);
                    }
                    else
                    {
                         obj = findItem(title, "", jArray1);
                    }
                    if (obj != null)
                    {
                        string sItemType1 = obj["type"].ToString();
                        if (sItemType1.Equals(sItemType2))
                        {
                            // equal Types, then will do merge
                            if(sItemType1.Equals("text/x-moz-place"))
                            {
                                string sUri = node["uri"].ToString();
                                if (node["uri"].ToString().Equals(obj["uri"].ToString()))
                                {
                                    // equal title and uri, do nothing
                                }
                                else
                                {
                                    // equal title, but different uri, rename node
                                    int i = 1;
                                    IDictionary tObj;
                                    if (title != null)
                                    {
                                        while ((tObj = findItem(title + "(" + i + ")", sUri, jArray1)) != null)
                                        {
                                            i++;
                                        }
                                    }
                                    string obj1Text = node.ToString();
                                    if (!node.Contains("index"))
                                    {
                                        obj1Text = obj1Text.Insert(1, "\"index\":" + maxTagsIndex.ToString() + ",");
                                    }
                                    IDictionary obj1 = (IDictionary)JsonConvert.Import(obj1Text);
                                    int objId = maxId++;
                                    if(title != null)
                                        obj1["title"] = obj1["title"].ToString() + "(" + i + ")";

                                    obj1["id"] = objId;
                                    obj1["parent"] = TagsId;
                                    obj1["index"] = maxTagsIndex++;
                                    if (obj1["type"].ToString().Equals("text/x-moz-place-container"))
                                        adjustIds(objId, (Jayrock.Json.JsonArray)obj1["children"]);
                                    jArray1.Add(obj1);
                                }
                            }
                            else
                            {
                                // merge lists
                                doMergeLists(obj, node);
                            }
                        }
                        else
                        {
                            // types not equal, rename node
                            int i = 1;
                            IDictionary tObj;
                            string sUri1 = null;
                            if(node.Contains("uri"))
                                 sUri1 = node["uri"].ToString();
                            while ((tObj = findItem(title + "(" + i + ")",sUri1, jArray1)) != null)
                            {
                                i++;
                            }
                            string obj1Text = node.ToString();
                            if (!node.Contains("index"))
                            {
                                obj1Text = obj1Text.Insert(1, "\"index\":" + maxTagsIndex.ToString() + ",");
                            }
                            IDictionary obj1 = (IDictionary)JsonConvert.Import(obj1Text);
                            int objId = maxId++;
                            obj1["title"] = obj1["title"].ToString() + "(" + i + ")";
                            obj1["id"] = objId;
                            obj1["parent"] = TagsId;
                            obj1["index"] = maxTagsIndex++;
                            adjustIds(Convert.ToInt32(obj1["id"]), (Jayrock.Json.JsonArray)obj1["children"]);
                            jArray1.Add(obj1);

                        }
                    }
                    else
                    {
                        // not duplicate node
                            string obj1Text = node.ToString();
                            if (!node.Contains("index"))
                            {
                                obj1Text = obj1Text.Insert(1, "\"index\":" + maxTagsIndex.ToString() + ",");
                            }
                            IDictionary obj1 = (IDictionary)JsonConvert.Import(obj1Text);
                            int objId = maxId++;
                            obj1["id"] = objId;
                            obj1["parent"] = TagsId;
                            obj1["index"] = maxTagsIndex++;
                            if(sItemType2.Equals("text/x-moz-place-container"))
                                adjustIds(Convert.ToInt32(obj1["id"]), (Jayrock.Json.JsonArray)obj1["children"]);
                            jArray1.Add(obj1);
                    }
                }
            }
        }

        static int findMaxId( ref int id,Jayrock.Json.JsonArray jArray )
        {
            int i;
            for (i = 0; i < jArray.Count(); i++)
            {
                if (jArray[i].GetType() == typeof(Jayrock.Json.JsonObject))
                {
                    findMaxId(ref id, (IDictionary)jArray[i]);

                }
                else if (jArray[i].GetType() == typeof(Jayrock.Json.JsonArray))
                {
                    findMaxId(ref id, (Jayrock.Json.JsonArray)jArray[i]);
                }
                else
                {
//                    parseItem(jArray[i]);
                    Console.WriteLine(" {0,-25} {1}", ((DictionaryEntry)jArray[i]).Key, ((DictionaryEntry)jArray[i]).Value.GetType().ToString(), ((DictionaryEntry)jArray[i]).Value.ToString());
                }
            }
            return id;
        }
        static int findMaxId(ref int id, IDictionary node)
        {
            
            if(node.Contains("id")){
                if(Convert.ToInt32( node["id"]) > id)
                    id=Convert.ToInt32(node["id"]);
            }
            IDictionaryEnumerator dict = node.GetEnumerator();
            while (dict.MoveNext())
            {
                if (dict.Value == null)
                {
                }
                else if (dict.Value.GetType() == typeof(Jayrock.Json.JsonArray))
                {
                    findMaxId(ref id, (Jayrock.Json.JsonArray)dict.Value);
                }
                else if (dict.Value.GetType() == typeof(Jayrock.Json.JsonObject))
                {
                    findMaxId(ref id, (IDictionary)dict.Value);
                }
            } 

            return id;
        }
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new frmMerge());
        }
        public static void MergeBookmarks(string srcFile1, string srcFile2, string DstFile)
        {
            string jsontext = System.IO.File.ReadAllText(srcFile1);
            IDictionary root1 = (IDictionary)JsonConvert.Import(jsontext);
             jsontext = System.IO.File.ReadAllText(srcFile2);
            IDictionary root2 = (IDictionary)JsonConvert.Import(jsontext);
            int id = 0;
            findMaxId(ref id, root1);
            maxId = id+1;
            doMergeLists(root1, root2);
            System.IO.File.WriteAllText(DstFile, root1.ToString());
        }
    }
}



Points of Interest

jayrock json library is very nice and easy to use tool

History

 first release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

AmrEmam
Canada Canada
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionHow to use thia code?memberSimon K B12 Feb '13 - 4:28 
QuestionHow do I use this exactly?member5moufl28 Aug '12 - 23:08 
GeneralMy vote of 4memberKlaus Luedenscheidt17 Jun '12 - 17:18 
GeneralRe: My vote of 4memberAmrEmam20 Jun '12 - 13:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 5 Nov 2012
Article Copyright 2012 by AmrEmam
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid