root/lang/csharp/IrcSendOnly/ChatLogger.cs

Revision 913, 4.5 kB (checked in by gyuque, 15 months ago)

lang/csharp/IrcSendOnly

Line 
1using System;
2using System.IO;
3using System.Xml;
4using System.Collections;
5using System.Text.RegularExpressions;
6
7namespace IrcSend
8{
9        public class ChatLogger : IDisposable
10        {
11                private string mFileName;
12                private XmlDocument mDocument;
13                private XmlElement mBodyElement;
14                private Hashtable mChannelsMap;
15                int mFlushCount;
16
17                private static Regex LinkRegex = new Regex("https?://[/0-9a-zA-Z%+.$,;:&=?!*~@#_()\\-]+", RegexOptions.Singleline | RegexOptions.Compiled);
18
19                public ChatLogger(string filename)
20                {
21                        mFlushCount = 10;
22                        mFileName = filename;
23
24                        if (!File.Exists(filename))
25                                initLogFile();
26
27                        XmlDocument doc = new XmlDocument();
28                        doc.Load(filename);
29
30                        XmlNodeList bodies = doc.GetElementsByTagName("body");
31                        if (bodies.Count == 0)
32                                throw new Exception("Log html doesn't have body!");
33
34                        XmlElement body = bodies[0] as XmlElement;
35
36                        mDocument = doc;
37                        mBodyElement = body;
38                        mChannelsMap = new Hashtable();
39
40                        scanChannelSections();
41                }
42
43                public void flush()
44                {
45                        if (mDocument != null)
46                                mDocument.Save(mFileName);
47
48                        mFlushCount = 10;
49                }
50
51                public void addChannelMessage(string chname, string nick, string message)
52                {
53                        lock(this)
54                        {
55                                if (!mChannelsMap.ContainsKey(chname))
56                                        createChannelSection(chname);
57
58                                ChannelSection sobj = (ChannelSection)mChannelsMap[chname];
59
60                                XmlElement li  = mDocument.CreateElement("li");
61
62                                DateTime now = DateTime.Now;
63               
64                                string min = now.Minute.ToString();
65                                if (min.Length == 1)
66                                        min = "0"+min;
67
68                                string tm = now.Hour.ToString() +":"+  min;
69
70                                Match mch = LinkRegex.Match(message);
71                                if (mch == null || mch.Value.Length == 0)
72                                        li.InnerText = tm+" "+nick+"> "+message;
73                                else
74                                {
75                                        message = message.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;");
76                                        string url = mch.Value.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;");
77                                        message = message.Replace(url, "<a href=\""+url+"\">"+url+"</a>");
78
79                                        li.InnerXml = tm+" "+nick+"&gt; "+message;
80                                }
81
82                                sobj.posts_list.AppendChild(li);
83
84                                if (--mFlushCount < 1)
85                                        flush();
86                        }
87                }
88
89                private void createChannelSection(string chname)
90                {
91                        XmlElement div = mDocument.CreateElement("div");
92                        XmlElement ul  = mDocument.CreateElement("ul");
93                        XmlElement h2  = mDocument.CreateElement("h2");
94
95                        div.SetAttribute("class", "channel");
96                        h2.InnerText = chname;
97                        div.AppendChild(h2);
98                        div.AppendChild(ul);
99
100                        mBodyElement.AppendChild(div);
101
102                        ChannelSection sobj = new ChannelSection();
103                        sobj.heading = h2;
104                        sobj.posts_list = ul;
105                        sobj.section = div;
106
107                        mChannelsMap[chname] = sobj;
108                }
109
110                private void scanChannelSections()
111                {
112                        int len = mBodyElement.ChildNodes.Count;
113                        for (int i = 0;i < len;i++)
114                        {
115                                XmlNode n = mBodyElement.ChildNodes.Item(i);
116                                if (n.NodeType == XmlNodeType.Element)
117                                {
118                                        XmlElement el = n as XmlElement;
119                                        if (el.LocalName.Equals("div") && el.GetAttribute("class").Equals("channel"))
120                                        {
121                                                XmlNodeList h2s = el.GetElementsByTagName("h2");
122                                                if (h2s.Count > 0)
123                                                {
124                                                        XmlElement h2 = h2s.Item(0) as XmlElement;
125                                                        string chname = h2.InnerText;
126                                                       
127                                                        XmlNodeList uls = el.GetElementsByTagName("ul");
128                                                        XmlElement ul;
129                                                        if (uls.Count == 0)
130                                                        {
131                                                                ul = mDocument.CreateElement("ul");
132                                                                el.AppendChild(ul);
133                                                        }
134                                                        else
135                                                                ul = uls.Item(0) as XmlElement;
136
137                                                       
138                                                        ChannelSection sobj = new ChannelSection();
139                                                        sobj.section = el;
140                                                        sobj.heading = h2;
141                                                        sobj.posts_list = ul;
142                                                        mChannelsMap[chname] = sobj;
143                                                }
144                                        }
145                                }
146                        }
147                }
148
149                private void initLogFile()
150                {
151                        StreamWriter w = File.CreateText(mFileName);
152                       
153                        w.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
154                        w.WriteLine("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
155                        w.WriteLine("<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"ja\" xml:lang=\"ja\">");
156
157                        w.WriteLine(" <head><link rel=\"stylesheet\" href=\"chatlog.css\" type=\"text/css\" /></head>");
158
159                        w.WriteLine(" <body>");
160                        w.WriteLine(" </body>");
161
162                        w.WriteLine("</html>");
163
164                        w.Close();
165                }
166
167                #region IDisposable
168
169                public void Dispose()
170                {
171                        if (mDocument != null)
172                                mDocument.Save(mFileName);
173                }
174
175                #endregion
176        }
177
178        struct ChannelSection
179        {
180                public XmlElement heading;
181                public XmlElement section;
182                public XmlElement posts_list;
183        }
184}
Note: See TracBrowser for help on using the browser.