Subversion Repositories vs2008

Rev

Blame | Last modification | View Log | RSS feed

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Xml;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Threading;
using System.Windows.Forms;
using com.jamiehill;

namespace OneNoteImporter {
    class OneNoteImporter {
        private Hashtable imageTypes = new Hashtable();
        private Hashtable textTypes = new Hashtable();
        private Hashtable HTMLTypes = new Hashtable();
        private JPHOneNoteUtilities onp = null;
        private OneNoteXMLObject unfiledNotes;
        private string importDir = "X:\\My Notebooks\\Import";
        private string headersFileName = "headers.txt";
        private XY defaultIconSize = new XY(65, 75);
        private XY initialPosition = new XY(40, 80);
        private XY initialImagePosition = new XY(400, 80);
        private XY defaultImageSize = new XY(240, 180);
        private XY currentPosition;
        private XY currentImagePosition;
        private XY defaultObjectSpacing = new XY(5, 5);

        public OneNoteImporter() {
            onp = new JPHOneNoteUtilities();
            InitializePositionValues();
            InitializeImageTypes();
            InitializeTextTypes();
            InitializeHTMLTypes();
            unfiledNotes = onp.GetUnfiledNotesSection();
        }

        private void InitializePositionValues() {
            currentPosition = initialPosition;
            currentImagePosition = initialImagePosition;
        }

        public bool IsImageExtention(string ext) {
            return (imageTypes.ContainsKey(ext.ToLower()));
        }

        private void InitializeImageTypes() {
            imageTypes[".jpg"] = "auto";
            imageTypes[".jpeg"] = "auto";
            imageTypes[".gif"]  = "auto";
            imageTypes[".png"]  = "auto";
        }

        public bool IsTextExtention(string ext) {
            return (textTypes.ContainsKey(ext.ToLower()));
        }

        private void InitializeTextTypes() {
            textTypes[".txt"] = "txt";
            textTypes[".pl"] = "txt";
            textTypes[".c"] = "txt";
            textTypes[".cs"] = "txt";
            textTypes[".xml"] = "txt";
            textTypes[".js"] = "txt";
        }

        public bool IsHTMLExtention(string ext) {
            System.Console.WriteLine(ext.ToLower());
            return (HTMLTypes.ContainsKey(ext.ToLower()));
        }

        private void InitializeHTMLTypes() {
            HTMLTypes[".html"] = "html";
            HTMLTypes[".htm"] = "html";
        }

        public void SetImportDir(string d) {
            if (Directory.Exists(d)) importDir = d;
        }

        public string GetImportDir() {
            return(importDir);
        }

        public string GetSubject(FileInfo file) {
            string subject = "Untitled page";
            try {
                StreamReader stream = file.OpenText();
                string text;
                while ((text = stream.ReadLine()) != null) {
                    Regex exp = new Regex(@"^Subject: (?<subject>.+)");
                    Match match = exp.Match(text);
                    if (match.Success) {
                        subject = match.Groups["subject"].ToString();
                        break;
                    }
                }
                stream.Close();
            } catch {
                subject = "Untitled page";
            }
            return (subject);
        }

        private string GetOpeningXml(string id, string pageName) {
            string xml = "<?xml version=\"1.0\"?>" +
               "   <one:Page xmlns:one=\"" + onp.GetOneNoteNamespace() + "\" ID=\"" + id + "\">" +
               "      <one:PageSettings RTL=\"false\" color=\"automatic\">" +
               "         <one:PageSize>" +
               "            <one:Automatic/>" +
               "         </one:PageSize>" +
               "         <one:RuleLines visible=\"true\"/>" +
               "      </one:PageSettings>" +
               "      <one:Title style=\"font-family:Calibri;font-size:17.0pt\" lang=\"en-US\">" +
               "         <one:OE alignment=\"left\">" +
               "            <one:T>" +
               "               <![CDATA[" + pageName + "]]>" +
               "            </one:T>" +
               "         </one:OE>" +
               "      </one:Title>";
            return (xml);
        }

        private string GetClosingXml() {
            string xml = "   </one:Page>";
            return (xml);
        }

        private string GetInsertedFileXml(FileInfo file) {
            string xml = "    <one:InsertedFile pathSource=\"" + file.FullName + "\"/>";
            return (xml);
        }

        private string GetInsertedFileXml(FileInfo file, XY position) {
            string xml = "    <one:InsertedFile pathSource=\""+ file.FullName +"\">" +
                         "      <one:Position x=\""+position.x+"\" y=\""+position.y+"\"/>" +
                         "    </one:InsertedFile>";
  
            return (xml);
        }

        private string GetImageXml(FileInfo file, XY position, XY size) {
            string xml = "    <one:Image format=\"auto\">" +
                         "      <one:Position x=\""+position.x+"\" y=\""+position.y+"\"/>" +
                         "      <one:Size width=\""+size.x+"\" height=\""+size.y+"\"/>" +
                         "      <one:File path=\""+file.FullName+"\"/>" +
                         "    </one:Image>";
            xml += GetInsertedFileXml(file, position);
            return (xml);
        }

        private string GetTextXml(FileInfo file, XY position) {
            return (GetTextXml(file, position, new XY(0, 0)));
        }

        private string GetTextXml(FileInfo file, XY position, XY size) {
            string xml = "     <one:Outline >";
            if (size.x != 0 || size.y != 0) {
               xml += "         <one:Size width=\""+size.x+"\" height=\""+size.y+"\"/>";
            }
            if (position.x != 0 || position.y != 0) {
                xml += "         <one:Position x=\"" + position.x + "\" y=\"" + position.y + "\"/>";
            }
            xml += "         <one:OEChildren style=\"font-family:Courier New;font-size:10.0pt\">";

            StreamReader stream = null;
            try {
                stream = file.OpenText();
            } catch {
                xml += "            <one:OE alignment=\"left\" style=\"font-weight:bold;font-family:Calibri;font-size:11.0pt\">" +
                       "               <one:T>" +
                       "                  <![CDATA[Couldn't open file "+file.Name+"]]>" +
                       "               </one:T>" +
                       "            </one:OE>";
                xml += "         </one:OEChildren>" +
                       "      </one:Outline>";
                return (xml);
            }
            /*
            xml += "            <one:OE alignment=\"left\">";
            xml += GetInsertedFileXml(file) +
                   "            </one:OE>";
            */

            xml += "            <one:OE alignment=\"left\" style=\"font-weight:bold;font-family:Calibri;font-size:11.0pt\">" +
                   "               <one:T>" +
                   "                  <![CDATA[File: " + file.Name + "]]>" +
                   "               </one:T>" +
                   "            </one:OE>";

            xml += "            <one:OE alignment=\"left\">" +
                   "               <one:T>" +
                   "                  <![CDATA[]]>" +
                   "               </one:T>" +
                   "            </one:OE>";

            string text = stream.ReadLine();
            do {
                // If this is a plain text file, then let's replace all of the > to prevent an
                // accidentally xml cdata closing tag match
                text = Regex.Replace(text, ">", "&gt;");
                text = Regex.Replace(text, "<", "&lt;");
 
                xml += "            <one:OE alignment=\"left\">" +
                       "               <one:T>" +
                       "                  <![CDATA["+text+"]]>" +
                       "               </one:T>" +
                       "            </one:OE>";
                text = stream.ReadLine();
            } while (text != null);
                

            stream.Close();

            xml += "         </one:OEChildren>" +
                   "      </one:Outline>";

            return (xml);
        }

        private string GetHtmlXml(FileInfo file, XY position, XY size) {
            string xml = "     <one:Outline>";
            if (size.x != 0 || size.y != 0) {
                xml += "         <one:Size width=\"" + size.x + "\" height=\"" + size.y + "\"/>";
            }
            if (position.x != 0 || position.y != 0) {
                xml += "         <one:Position x=\"" + position.x + "\" y=\"" + position.y + "\"/>";
            }

            xml += "         <one:OEChildren>" +
                   "           <one:OE alignment=\"left\">" +
                   "             <one:T>" +
                   "               <![CDATA[<span style='font-weight:bold'>File: " + file.Name + "</span>]]>" +
                   "             </one:T>" +
                   "           </one:OE>" +
                   "           <one:OE alignment=\"left\">" +
                   "             <one:T>" +
                   "               <![CDATA[]]>" +
                   "             </one:T>" +
                   "           </one:OE>" +
                   "           <one:HTMLBlock>" +
                   "             <one:File path=\"" + file.FullName + "\"/>" +
                   "           </one:HTMLBlock>" +
                   "         </one:OEChildren>" +
                   "       </one:Outline>";
            return (xml);
        }

        private XY GetImageConstraints(XY current, XY desired) {
            XY pos = new XY(0,0);
            float x = 0.00000f;
            float y = 0.00000f;

            if (current.x < desired.x && current.y < desired.y) {
                pos.x = current.x;
                pos.y = current.y;
            } else if (current.x > 0 && current.y > 0) {
                if (current.y > desired.y) {
                    float ratio = (float)desired.y / (float)current.y;
                    x = (float)current.x * ratio;
                    y = (float)desired.y;
                }
                if (current.x > desired.x) {
                    float ratio = (float)desired.x / (float)current.x;
                    y = (float)current.y * ratio;
                    x = (float)desired.x;
                }

                if (x % 2 != 0) x--;
                if (y % 2 != 0) y--;

                pos.x = (int)x;
                pos.y = (int)y;
            }

            return(pos);
        }

        private string MakeFirstLetterUpper(string str) {
            int len = str.Length;

            if (len <= 0) return (str);
            if (len == 1) return (str.ToUpper());

            char[] letters = str.ToCharArray();
            letters[0] = Char.ToUpper(letters[0]);

            return (new string(letters));
        }

        public void DoImport() {
            DirectoryInfo dir = new DirectoryInfo(importDir);
            DirectoryInfo[] dirSubs = dir.GetDirectories();
            foreach (DirectoryInfo dirSub in dirSubs) {
                if ((dirSub.Attributes & FileAttributes.Hidden) != 0) continue;
                if (dirSub.Name.ToLower() == "done") continue;
              
                InitializePositionValues();
                
                //-------------------------------------------------------------
                // Each directory will require that a  new page is created,
                // but we should ensure there are files in the dir before
                // taking that step
                //-------------------------------------------------------------
                OneNoteXMLObject newPage = new OneNoteXMLObject(null,null,null,null,null,null,null,false);
                if (dirSub.GetFiles().Length > 0) {
                    try {
                        newPage = onp.CreatePage(ref unfiledNotes);
                    } catch (Exception e) {
                        DialogResult dr = MessageBox.Show(e.ToString(), "Error", MessageBoxButtons.OK);
                        continue;
                    }
                }
                
                if (newPage.id.Length <= 0) continue;

                string headersLoc = dirSub.FullName + "\\" + headersFileName;
                FileInfo headersFile = new FileInfo(headersLoc);
                string email_subject = MakeFirstLetterUpper(GetSubject(headersFile));
                string xml = GetOpeningXml(newPage.id, email_subject);

                //-------------------------------------------------------------
                // Create embedded files along the top.  Skip images, they will
                // be handled separately.
                //-------------------------------------------------------------
                FileInfo[] files = dirSub.GetFiles();
                Array.Sort(files, new CompareFileName());
                int i = 1;
                int hasImages = 0;
                if (headersFile.Exists) xml += GetInsertedFileXml(headersFile, currentPosition);
                foreach (FileInfo file in files) {
                    // Skip the headers file and skip images, as we will embed the file onto of the image
                    if (file.Name == headersFileName) continue;
                    if (IsImageExtention(file.Extension)) {
                        hasImages++;
                        continue;
                    }

                    // If we run up against the default image space, then we need to wrap the icons onto another line
                    if ((currentPosition.x + (defaultIconSize.x * 2) + defaultObjectSpacing.x) >= initialImagePosition.x) {
                        currentPosition.x = initialPosition.x;
                        currentPosition.y += defaultIconSize.y + defaultObjectSpacing.y;
                        i = 0;
                    }

                    XY fileloc;
                    if (i != 0) {
                        fileloc = new XY(currentPosition.x + defaultIconSize.x + defaultObjectSpacing.x, currentPosition.y);
                    } else {
                        fileloc = new XY(currentPosition.x, currentPosition.y);
                    }
                    i++;
                    currentPosition.x = fileloc.x;
                    xml += GetInsertedFileXml(file,fileloc);
                }
                currentPosition.x = initialPosition.x;
                currentPosition.y += defaultIconSize.y + defaultObjectSpacing.y;

                XY empty = new XY(0,0);
                XY size;
                if (hasImages > 0) size = new XY(initialImagePosition.x - 50, 1);
                else size = new XY(0, 0);

                //-------------------------------------------------------------
                // Insert text and html files.  They need to come in this order
                // this way we don't need to know size information; the default
                // OneNote layout manager will handle it for us.  Though we do
                // limit the width if there are images.
                //-------------------------------------------------------------
                xml += GetTextXml(headersFile, empty, size);
                foreach (FileInfo file in files) {
                    if (file.Name == headersFileName || (!IsTextExtention(file.Extension) && !IsHTMLExtention(file.Extension))) continue;

                    //if (((string)file.Extension).ToLower().CompareTo(".txt") == 0)
                    if (IsTextExtention(file.Extension))
                        xml += GetTextXml(file,empty,size);
                    //else if (((string)file.Extension).ToLower().CompareTo(".html") == 0 || ((string)file.Extension).ToLower().CompareTo(".htm") == 0)
                    else if (IsHTMLExtention(file.Extension))
                        xml += GetHtmlXml(file,empty,size);
                }

                i = 0;
                XY last = initialImagePosition;
                //-------------------------------------------------------------
                // If there are image files, let's insert and embed them down
                // the right hand size of the page.
                //-------------------------------------------------------------
                foreach (FileInfo file in files) {
                    if (!IsImageExtention(file.Extension)) continue;

                    XY imageloc;
                    if (i != 0) {
                        // If the image height is shorter than the default icon size, then we'll need more vertical space
                        if (last.y < defaultIconSize.y) last.y = defaultIconSize.y;
                        imageloc = new XY(currentImagePosition.x, currentImagePosition.y + last.y + defaultObjectSpacing.y);
                    } else {
                        imageloc = new XY(currentImagePosition.x, currentImagePosition.y);
                    }
                    i++;
                    currentImagePosition.y = imageloc.y;

                    Image img = Image.FromFile(file.FullName);
                    XY currentSize = new XY(img.Width, img.Height);
                    last = GetImageConstraints(currentSize, defaultImageSize);
                    
                    xml += GetImageXml(file, currentImagePosition, last);
                }
                
                xml += GetClosingXml();


                try {
                    onp.UpdatePage(xml);
                } catch (Exception e) {
                    DialogResult dr = MessageBox.Show(e.ToString(), "Error", MessageBoxButtons.OK);
                    try {
                        onp.DeletePage(ref newPage);
                    } catch (Exception ee) {
                        dr = MessageBox.Show(ee.ToString(), "Error", MessageBoxButtons.OK);
                    }
                    continue;
                }

                //-------------------------------------------------------------
                // We are sometimes trying to make the dir before windows has 
                // releases its lock.  I'm hoping a little delay will take 
                // care of this issue.
                //-------------------------------------------------------------
                Thread.Sleep(5000);

                try {
                    dirSub.MoveTo(importDir+"\\done\\"+dirSub.Name);
                    //dirSub.Delete(true);
                } catch (Exception e) {
                    DialogResult dr = MessageBox.Show("Move directory failed: "+e.ToString(), "Error", MessageBoxButtons.OK);
                }
            }
        }
    }

    class CompareFileName : IComparer {
        public int Compare(object x, object y) {
            FileInfo f1 = (FileInfo)x;
            FileInfo f2 = (FileInfo)y;

            //return (f1.Name.CompareTo(f2.Name));
            return (f2.Extension.CompareTo(f1.Extension));
        }
    }

    class MyMain {
        static void Main(string[] args) {
            OneNoteImporter oni = new OneNoteImporter();

            if (args.Length > 0) oni.SetImportDir(args[0]);
            
            oni.DoImport();
        }
    }
}