1: /*
2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
3:
4: Permission is hereby granted, free of charge, to any person obtaining a copy
5: of this software and associated documentation files (the "Software"), to deal
6: in the Software without restriction, including without limitation the rights
7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: copies of the Software, and to permit persons to whom the Software is
9: furnished to do so, subject to the following conditions:
10:
11: The above copyright notice and this permission notice shall be included in
12: all copies or substantial portions of the Software.
13:
14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: THE SOFTWARE.*/
21:
22: #region Usings
23: using System.Collections.Generic;
24: using System.Text;
25: using System.Text.RegularExpressions;
26: #endregion
27:
28: namespace Utilities.FileFormats
29: {
30: /// <summary>
31: /// Class for creating vCards
32: /// </summary>
33: public class VCard
34: {
35: #region Constructor
36:
37: /// <summary>
38: /// Constructor
39: /// </summary>
40: public VCard()
41: {
42: Relationships = new List<Relationship>();
43: }
44:
45: #endregion
46:
47: #region Public Functions
48:
49: /// <summary>
50: /// Gets the vCard
51: /// </summary>
52: /// <returns>A vCard in string format</returns>
53: public string GetVCard()
54: {
55: StringBuilder Builder = new StringBuilder();
56: Builder.Append("BEGIN:VCARD\r\nVERSION:2.1\r\n");
57: Builder.Append("FN:");
58: if (!string.IsNullOrEmpty(Prefix))
59: {
60: Builder.Append(Prefix).Append(" ");
61: }
62: Builder.Append(FirstName + " ");
63: if (!string.IsNullOrEmpty(MiddleName))
64: {
65: Builder.Append(MiddleName).Append(" ");
66: }
67: Builder.Append(LastName);
68: if (!string.IsNullOrEmpty(Suffix))
69: {
70: Builder.Append(" ").Append(Suffix);
71: }
72: Builder.Append("\r\n");
73:
74: Builder.Append("N:");
75: Builder.Append(LastName).Append(";").Append(FirstName).Append(";")
76: .Append(MiddleName).Append(";").Append(Prefix).Append(";")
77: .Append(Suffix).Append("\r\n");
78: Builder.Append("TEL;WORK:").Append(DirectDial).Append("\r\n");
79: Builder.Append("EMAIL;INTERNET:").Append(StripHTML(Email)).Append("\r\n");
80: Builder.Append("TITLE:").Append(Title).Append("\r\n");
81: Builder.Append("ORG:").Append(Organization).Append("\r\n");
82: Builder.Append("END:VCARD\r\n");
83: return Builder.ToString();
84: }
85:
86: /// <summary>
87: /// Gets the hCard version of the vCard
88: /// </summary>
89: /// <returns>A hCard in string format</returns>
90: public string GetHCard()
91: {
92: StringBuilder Builder = new StringBuilder();
93: Builder.Append("<div class=\"vcard\">");
94: if (string.IsNullOrEmpty(Url))
95: {
96: Builder.Append("<div class=\"fn\">");
97: if (!string.IsNullOrEmpty(Prefix))
98: {
99: Builder.Append(Prefix).Append(" ");
100: }
101: Builder.Append(FirstName).Append(" ");
102: if (!string.IsNullOrEmpty(MiddleName))
103: {
104: Builder.Append(MiddleName).Append(" ");
105: }
106: Builder.Append(LastName);
107: if (!string.IsNullOrEmpty(Suffix))
108: {
109: Builder.Append(" ").Append(Suffix);
110: }
111: Builder.Append("</div>");
112: }
113: else
114: {
115: Builder.Append("<a class=\"fn url\" href=\"").Append(Url).Append("\"");
116: if (Relationships.Count > 0)
117: {
118: Builder.Append(" rel=\"");
119: foreach (Relationship Relationship in Relationships)
120: {
121: Builder.Append(Relationship.ToString()).Append(" ");
122: }
123: Builder.Append("\"");
124: }
125: Builder.Append(">");
126: if (!string.IsNullOrEmpty(Prefix))
127: {
128: Builder.Append(Prefix).Append(" ");
129: }
130: Builder.Append(FirstName).Append(" ");
131: if (!string.IsNullOrEmpty(MiddleName))
132: {
133: Builder.Append(MiddleName).Append(" ");
134: }
135: Builder.Append(LastName);
136: if (!string.IsNullOrEmpty(Suffix))
137: {
138: Builder.Append(" ").Append(Suffix);
139: }
140: Builder.Append("</a>");
141: }
142: Builder.Append("<span class=\"n\" style=\"display:none;\"><span class=\"family-name\">").Append(LastName).Append("</span><span class=\"given-name\">").Append(FirstName).Append("</span></span>");
143: if (!string.IsNullOrEmpty(DirectDial))
144: {
145: Builder.Append("<div class=\"tel\"><span class=\"type\">Work</span> ").Append(DirectDial).Append("</div>");
146: }
147: if (!string.IsNullOrEmpty(Email))
148: {
149: Builder.Append("<div>Email: <a class=\"email\" href=\"mailto:").Append(StripHTML(Email)).Append("\">").Append(StripHTML(Email)).Append("</a></div>");
150: }
151: if (!string.IsNullOrEmpty(Organization))
152: {
153: Builder.Append("<div>Organization: <span class=\"org\">").Append(Organization).Append("</span></div>");
154: }
155: if (!string.IsNullOrEmpty(Title))
156: {
157: Builder.Append("<div>Title: <span class=\"title\">").Append(Title).Append("</span></div>");
158: }
159: Builder.Append("</div>");
160: return Builder.ToString();
161: }
162: #endregion
163:
164: #region Private Functions
165:
166: private static string StripHTML(string HTML)
167: {
168: if (string.IsNullOrEmpty(HTML))
169: return string.Empty;
170:
171: HTML = STRIP_HTML_REGEX.Replace(HTML, string.Empty);
172: HTML = HTML.Replace(" ", " ");
173: return HTML.Replace(" ", string.Empty);
174: }
175:
176: private static readonly Regex STRIP_HTML_REGEX = new Regex("<[^>]*>", RegexOptions.Compiled);
177:
178: #endregion
179:
180: #region Properties
181: /// <summary>
182: /// First name
183: /// </summary>
184: public string FirstName { get; set; }
185:
186: /// <summary>
187: /// Last name
188: /// </summary>
189: public string LastName { get; set; }
190:
191: /// <summary>
192: /// Middle name
193: /// </summary>
194: public string MiddleName { get; set; }
195:
196: /// <summary>
197: /// Prefix
198: /// </summary>
199: public string Prefix { get; set; }
200:
201: /// <summary>
202: /// Suffix
203: /// </summary>
204: public string Suffix { get; set; }
205:
206: /// <summary>
207: /// Work phone number of the individual
208: /// </summary>
209: public string DirectDial { get; set; }
210:
211: /// <summary>
212: /// Email of the individual
213: /// </summary>
214: public string Email { get; set; }
215:
216: /// <summary>
217: /// Title of the person
218: /// </summary>
219: public string Title { get; set; }
220:
221: /// <summary>
222: /// Organization the person belongs to
223: /// </summary>
224: public string Organization { get; set; }
225:
226: /// <summary>
227: /// Relationship to the person (uses XFN)
228: /// </summary>
229: public List<Relationship> Relationships { get; set; }
230:
231: /// <summary>
232: /// Url to the person's site
233: /// </summary>
234: public string Url { get; set; }
235:
236: #endregion
237: }
238:
239: #region Enums
240: /// <summary>
241: /// Enum defining relationships (used for XFN markup)
242: /// </summary>
243: public enum Relationship
244: {
245: Friend,
246: Acquaintance,
247: Contact,
248: Met,
249: CoWorker,
250: Colleague,
251: CoResident,
252: Neighbor,
253: Child,
254: Parent,
255: Sibling,
256: Spouse,
257: Kin,
258: Muse,
259: Crush,
260: Date,
261: Sweetheart,
262: Me
263: }
264: #endregion
265: }