PageRenderTime 31ms CodeModel.GetById 16ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/BlogEngine/BlogEngine.NET/App_Code/BlogImporter.cs

#
C# | 429 lines | 229 code | 56 blank | 144 comment | 18 complexity | 3840bc915e110abb55b27b9894f6f299 MD5 | raw file
  1namespace App_Code
  2{
  3    using System;
  4    using System.Collections.Generic;
  5    using System.Collections.ObjectModel;
  6    using System.IO;
  7    using System.Linq;
  8    using System.Net;
  9    using System.Web.Script.Services;
 10    using System.Web.Services;
 11    using System.Web.Services.Protocols;
 12
 13    using BlogEngine.Core;
 14
 15    /// <summary>
 16    /// Web Service API for Blog Importer
 17    /// </summary>
 18    [WebService(Namespace = "http://dotnetblogengine.net/")]
 19    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
 20    [ScriptService]
 21    public class BlogImporter : WebService
 22    {
 23        #region Constants and Fields
 24
 25        /// <summary>
 26        /// Gets or sets the authentication header.
 27        /// </summary>
 28        /// <value>The authentication header.</value>
 29        public AuthHeader AuthenticationHeader { get; set; }
 30
 31        #endregion
 32
 33        #region Public Methods
 34
 35        /// <summary>
 36        /// Add Comment to specified post
 37        /// </summary>
 38        /// <param name="postId">
 39        /// postId as string
 40        /// </param>
 41        /// <param name="author">
 42        /// commenter username
 43        /// </param>
 44        /// <param name="email">
 45        /// commenter email
 46        /// </param>
 47        /// <param name="website">
 48        /// commenter url
 49        /// </param>
 50        /// <param name="description">
 51        /// actual comment
 52        /// </param>
 53        /// <param name="date">
 54        /// comment datetime
 55        /// </param>
 56        [SoapHeader("AuthenticationHeader")]
 57        [WebMethod]
 58        public void AddComment(
 59            string postId, string author, string email, string website, string description, DateTime date)
 60        {
 61            Security.ImpersonateUser(AuthenticationHeader.Username, AuthenticationHeader.Password);
 62
 63            if (!Security.IsAuthenticated)
 64            {
 65                throw new InvalidOperationException("Wrong credentials");
 66            }
 67            if (!Security.IsAuthorizedTo(Rights.CreateComments))
 68            {
 69                throw new InvalidOperationException("Insufficient rights to create a comment");
 70            }
 71
 72            // Post post = Post.GetPost(new Guid(postID));
 73            var post = Post.Load(new Guid(postId));
 74            if (post == null)
 75            {
 76                return;
 77            }
 78
 79            var comment = new Comment
 80                {
 81                    Id = Guid.NewGuid(),
 82                    Author = author,
 83                    Email = email,
 84                    Content = description,
 85                    DateCreated = date,
 86                    Parent = post,
 87                    IsApproved = true
 88                };
 89
 90            Uri url;
 91            if (Uri.TryCreate(website, UriKind.Absolute, out url))
 92            {
 93                comment.Website = url;
 94            }
 95
 96            post.ImportComment(comment);
 97            post.Import();
 98        }
 99
100        /// <summary>
101        /// Add new blog post to system
102        /// </summary>
103        /// <param name="import">
104        /// ImportPost object
105        /// </param>
106        /// <param name="previousUrl">
107        /// Old Post Url (for Url re-writing)
108        /// </param>
109        /// <param name="removeDuplicate">
110        /// Search for duplicate post and remove?
111        /// </param>
112        /// <returns>
113        /// string containing unique post identifier
114        /// </returns>
115        [SoapHeader("AuthenticationHeader")]
116        [WebMethod]
117        public string AddPost(ImportPost import, string previousUrl, bool removeDuplicate)
118        {
119            Security.ImpersonateUser(AuthenticationHeader.Username, AuthenticationHeader.Password);
120
121            if (!Security.IsAuthenticated)
122            {
123                throw new InvalidOperationException("Wrong credentials");
124            }
125            if (!Security.IsAuthorizedTo(Rights.CreateNewPosts))
126            {
127                throw new InvalidOperationException("Insufficient rights to create a new post");
128            }
129
130            if (removeDuplicate && !Post.IsTitleUnique(import.Title))
131            {
132                // Search for matching post (by date and title) and delete it
133                foreach (var temp in
134                    Post.GetPostsByDate(import.PostDate.AddDays(-2), import.PostDate.AddDays(2)).Where(
135                        temp => temp.Title == import.Title))
136                {
137                    temp.Delete();
138                    temp.Import();
139                }
140            }
141
142            var post = new Post
143                {
144                    Title = import.Title,
145                    Author = import.Author,
146                    DateCreated = import.PostDate,
147                    DateModified = import.PostDate,
148                    Content = import.Content,
149                    Description = import.Description,
150                    IsPublished = import.Publish
151                };
152
153            // TODO: Save Previous Url?
154            AddCategories(import.Categories, post);
155
156            // Tag Support:
157            // No tags. Use categories. 
158            post.Tags.AddRange(import.Tags.Count == 0 ? import.Categories : import.Tags);
159
160            post.Import();
161
162            return post.Id.ToString();
163        }
164
165        /// <summary>
166        /// Relative File Handler path
167        /// </summary>
168        /// <returns>
169        /// file handler path as string
170        /// </returns>
171        [WebMethod]
172        public string BlogFileHandler()
173        {
174            return "file.axd?file=";
175        }
176
177        /// <summary>
178        /// Relative Image Handler path
179        /// </summary>
180        /// <returns>
181        /// image handler path as string
182        /// </returns>
183        [WebMethod]
184        public string BlogImageHandler()
185        {
186            return "image.axd?picture=";
187        }
188
189        /// <summary>
190        /// Name/Type of Blog Software
191        /// </summary>
192        /// <returns>
193        /// Blog Software name
194        /// </returns>
195        [WebMethod]
196        public string BlogType()
197        {
198            return "BlogEngine.NET";
199        }
200
201        /// <summary>
202        /// Version Number of the Blog
203        /// </summary>
204        /// <returns>
205        /// Version number in string
206        /// </returns>
207        [WebMethod]
208        public string BlogVersion()
209        {
210            return BlogSettings.Instance.Version();
211        }
212
213        /// <summary>
214        /// Force Reload of all posts
215        /// </summary>
216        [SoapHeader("AuthenticationHeader")]
217        [WebMethod]
218        public void ForceReload()
219        {
220            Security.ImpersonateUser(AuthenticationHeader.Username, AuthenticationHeader.Password);
221            
222            if (!Security.IsAuthenticated)
223            {
224                throw new InvalidOperationException("Wrong credentials");
225            }
226            if (!Security.IsAuthorizedTo(Rights.CreateNewPosts))
227            {
228                throw new InvalidOperationException("Insufficient rights to reload posts");
229            }
230
231            Post.Reload();
232        }
233
234        /// <summary>
235        /// Downloads specified file to specified location
236        /// </summary>
237        /// <param name="source">
238        /// source file path
239        /// </param>
240        /// <param name="destination">
241        /// relative destination path
242        /// </param>
243        /// <returns>
244        /// Wether the file was downloaded
245        /// </returns>
246        [SoapHeader("AuthenticationHeader")]
247        [WebMethod]
248        public bool GetFile(string source, string destination)
249        {
250            bool response;
251            try
252            {
253                Security.ImpersonateUser(AuthenticationHeader.Username, AuthenticationHeader.Password);
254
255                if (!Security.IsAuthenticated)
256                {
257                    throw new InvalidOperationException("Wrong credentials");
258                }
259
260                var rootPath = string.Format("{0}files/", Blog.CurrentInstance.StorageLocation);
261                var serverPath = Server.MapPath(rootPath);
262                var saveFolder = serverPath;
263                var fileName = destination;
264
265                // Check/Create Folders & Fix fileName
266                if (fileName.LastIndexOf('/') <= -1 && saveFolder.EndsWith(Path.DirectorySeparatorChar.ToString()))
267                {
268                    saveFolder = saveFolder.Substring(0, saveFolder.Length - 1);
269                }
270                else
271                {
272                    saveFolder += fileName.Substring(0, fileName.LastIndexOf('/'));
273                    saveFolder = saveFolder.Replace('/', Path.DirectorySeparatorChar);
274
275                    fileName = fileName.Substring(fileName.LastIndexOf('/') + 1);
276                }
277
278                if (!Directory.Exists(saveFolder))
279                {
280                    Directory.CreateDirectory(saveFolder);
281                }
282
283                saveFolder += Path.DirectorySeparatorChar;
284
285                using (var client = new WebClient())
286                {
287                    client.DownloadFile(source, saveFolder + fileName);
288                }
289
290                response = true;
291            }
292            catch (Exception ex)
293            {
294                // The file probably didn't exist. No action needed.
295                Utils.Log("BlogImporter.GetFile(): " + ex.Message);
296                response = false;
297            }
298
299            return response;
300        }
301
302        #endregion
303
304        #region Methods
305
306        /// <summary>
307        /// Adds the categories.
308        /// </summary>
309        /// <param name="categories">
310        /// The categories.
311        /// </param>
312        /// <param name="post">
313        /// The post to add to.
314        /// </param>
315        private static void AddCategories(IEnumerable<string> categories, IPublishable post)
316        {
317            try
318            {
319                foreach (var category in categories)
320                {
321                    var added = false;
322                    var category1 = category;
323                    foreach (var cat in
324                        Category.Categories.Where(
325                            cat => cat.Title.Equals(category1, StringComparison.OrdinalIgnoreCase)))
326                    {
327                        post.Categories.Add(cat);
328                        added = true;
329                    }
330
331                    if (added)
332                    {
333                        continue;
334                    }
335
336                    var newCat = new Category(category, string.Empty);
337                    newCat.Save();
338                    post.Categories.Add(newCat);
339                }
340            }
341            catch (Exception ex)
342            {
343                Utils.Log("BlogImporter.AddCategories(): " + ex.Message);
344            }
345        }
346
347        #endregion
348
349        /// <summary>
350        /// The auth header.
351        /// </summary>
352        public class AuthHeader : SoapHeader
353        {
354            #region Constants and Fields
355
356            /// <summary>
357            /// Gets or sets the password.
358            /// </summary>
359            /// <value>The password.</value>
360            public string Password { get; set; }
361
362            /// <summary>
363            /// Gets or sets the username.
364            /// </summary>
365            /// <value>The username.</value>
366            public string Username { get; set; }
367
368            #endregion
369        }
370
371        /// <summary>
372        /// The import post.
373        /// </summary>
374        public class ImportPost
375        {
376            #region Constants and Fields
377
378            /// <summary>
379            /// Gets or sets the author.
380            /// </summary>
381            /// <value>The author.</value>
382            public string Author { get; set; }
383
384            /// <summary>
385            /// Gets or sets the categories.
386            /// </summary>
387            /// <value>The categories.</value>
388            public Collection<string> Categories { get; set; }
389
390            /// <summary>
391            /// Gets or sets the content.
392            /// </summary>
393            /// <value>The content.</value>
394            public string Content { get; set; }
395
396            /// <summary>
397            /// Gets or sets the description.
398            /// </summary>
399            /// <value>The description.</value>
400            public string Description { get; set; }
401
402            /// <summary>
403            /// Gets or sets the post date.
404            /// </summary>
405            /// <value>The post date.</value>
406            public DateTime PostDate { get; set; }
407
408            /// <summary>
409            /// Gets or sets a value indicating whether this <see cref="ImportPost"/> is publish.
410            /// </summary>
411            /// <value><c>true</c> if publish; otherwise, <c>false</c>.</value>
412            public bool Publish { get; set; }
413
414            /// <summary>
415            /// Gets or sets the tags.
416            /// </summary>
417            /// <value>The tags collection.</value>
418            public Collection<string> Tags { get; set; }
419
420            /// <summary>
421            /// Gets or sets the title.
422            /// </summary>
423            /// <value>The title.</value>
424            public string Title { get; set; }
425
426            #endregion
427        }
428    }
429}