BlogEngine - MultiPost

Как вы знаете, я транслирую свои записи в несколько популярных блогомест в интернете (за исключением ЖЖ). И это я делаю не с помощью встроенных средств копирования постов, а с помощью самописного модуля (Extension) для движка BlogEngine.Net, работающем под ASP.NET. Почему так? Да потому, что часто при задании копирования постов с помощью сторонних средств, таких как трансляции на Ya.ru, посты помещаемые в блог выпадают из поискового индекса и ссылки в них не учитываются.

1) Модуль получился расширяемый, что позволяет дописать копирование постов куда вам только захочется. В вышеуказанный архив я вложил только два класса, которые позволяют копировать посты на Хабр и на Ярушечку. Так как ярушечка имеет херовый интерфейс, и код выглядит очень сложным (и, кстати, не рабовает, если Вы недавно заходили под своим же аккаунтом с другой машины), а также придется добавить следующие строчки в web.config:
  1. <system.net>
  2.    <settings>
  3.      <httpWebRequest useUnsafeHeaderParsing="true" />
  4.      <servicePointManager expect100Continue="false"/>
  5.    </settings>
  6.  </system.net>


2) Далее, в настройках интерфейса у Вас появится такая вот картинка, позволяющая настроить копирование постов:
Отмечу, что все селективные значения прописываются вручную, так как в текущей версии BlogEngine нет возможностей задавать параметр группы настроек модуля в виде выбора из списка. Надеюсь это сделают в следующей версии, которую обещают в конце Января. Итак, первый параметр отвечает за копирование постов (bool=true/false). Второй за название категории, только из которой , если она указана, будут копироваться посты. Третий - BlogType - название класса отвечающего за копирование. Далее логин-пароль в удаленной системе. BlogParam - это дополнительный параметр, который может понадобиться для определенный систем. В частности для Яндекса я передаю номер моего блога, чтобы не извлекать его каждый раз. MaxAttempts(int) - количество попыток кпирования поста, если неуспех, то бросаем это дело. Последний - PostType(Public/Private/OnlyFriends) - тип записи. Как видим, для хабра стоит Private, что означает, что я планирую подредактировать запись и вставить в нее кат, прежде чем делать общедоступной хабрачанцам.

3) Из внутренностей работы модуля рассмотрю класс MultiPost:
  1. namespace MultiPost
  2. {
  3.     /// <summary>
  4.     /// Copy all your posts to blog at http://wow.ya.ru
  5.     /// You have to assign an login and password inside constructor
  6.     /// </summary>
  7.     /// <remarks>
  8.     /// Based on pure code - http://ya.topbot.ru
  9.     /// </remarks>
  10.     [Extension("Copy all your posts to blogs", "0.1.1", "http://ya.topbot.ru")]
  11.     public class MultiPost
  12.     {
  13.         /// <summary>
  14.         /// Name of Module
  15.         /// </summary>
  16.         private static String sExtensionName = "MultiPost";
  17.  
  18.         static protected ExtensionSettings _settings = null;
  19.         /*....*/
  20.     }
  21. }
Как видим к атрибутах класса задаются настройки модуля, чтобы BlogEngine его воспринял как расширение. Конструктор достаточно простой, подписываемся на событие о размещении нового поста:
  1. static MultiPost()
  2. {
  3.     // create settings object. You need to pass exactly your
  4.     // extension class name (case sencitive)
  5.     ExtensionSettings settings = new ExtensionSettings(sExtensionName);
  6.     /*.......*/
  7.     ExtensionManager.ImportSettings(settings);
  8.     _settings = ExtensionManager.GetSettings(sExtensionName);
  9.     Post.Saved += new EventHandler<SavedEventArgs>(Post_Saved);
  10. }
И кода происходит новый пост, то обрабатываем его создавая новый поток для этих целей
  1. /// <summary>
  2.  /// Occurs on new post
  3.  /// <remarks>
  4.  /// It opens a new thread and executes
  5.  /// because it takes some time to complete.
  6.  /// </remarks>
  7.  /// </summary>
  8.  private static void Post_Saved(object sender, SavedEventArgs e)
  9.  {
  10.      if (e.Action != SaveAction.Insert)
  11.          return;
  12.  
  13.      IPublishable item = (IPublishable)sender;
  14.  
  15.      //(HttpContext.Current == null || !HttpContext.Current.Request.IsLocal)
  16.      if (item.IsVisible)
  17.      {
  18.          //getting new thread to do all crap
  19.           ThreadPool.QueueUserWorkItem(delegate {
  20.               PostCycle(item);
  21.           });
  22.      }
  23.  }
  24.  
  25.  /// <summary>
  26.  /// Main process to post
  27.  /// </summary>
  28.  /// <param name="item"></param>
  29.  public static void PostCycle(IPublishable item){
  30.      //перечисляем все блоги, что активны...
  31.      DataTable dt = _settings.GetDataTable();
  32.      //pure code, coz i cant change Categories class
  33.      string catsline = "";
  34.      foreach (Category c in item.Categories)
  35.      {
  36.          catsline += c.Title + ",";
  37.      }
  38.      for (int i = dt.Rows.Count - 1; i >= 0; i--)
  39.      {
  40.          SettingsCollection sets = new SettingsCollection(dt.Rows[i].ItemArray);
  41.          if (!sets.Enabled ||
  42.              (!String.IsNullOrEmpty(sets.CopyOnTags.Trim())
  43.              && catsline.Contains(sets.CopyOnTags))
  44.              )
  45.          {//not allowed to post
  46.              dt.Rows.RemoveAt(i);
  47.          }
  48.      }
  49.      //lets finish the others
  50.      for (int i = dt.Rows.Count - 1; dt.Rows.Count > 0; i--)
  51.      {
  52.          Thread.Sleep(5000);
  53.          if (i < 0)//new cycle...bad...bad
  54.          {
  55.              i = dt.Rows.Count;
  56.          }
  57.          try
  58.          {
  59.              SettingsCollection sets = new SettingsCollection(dt.Rows[i].ItemArray);
  60.              Type tBlog = Type.GetType("MultiPost.Blogs."+sets.BlogType);
  61.              Object theBlog = Activator.CreateInstance(tBlog,
  62.                  new object[1] { sets });
  63.              Type[] paramTypes = {
  64.                      typeof(IPublishable)
  65.                        };
  66.              Object[] ps = new object[1] { item };
  67.              MethodInfo mDefaults = tBlog.GetMethod("ProcessItem", paramTypes);
  68.              if ((Boolean)mDefaults.Invoke(theBlog, ps))//if success
  69.              {
  70.                  dt.Rows.RemoveAt(i);
  71.              }
  72.              //failed, lets continue
  73.          }
  74.          catch(Exception e)//toomanyattempts
  75.          {
  76.              dt.Rows.RemoveAt(i);
  77.          }
  78.  
  79.      }
  80.  }
В основном цикле, мы создаем объект класса, и вызываем нужную функцию размещения поста, передавая ей настройки. Как видно попытка разместить пост происходит каждые 5 секунд. Обработка объектов идет на объекте Rows, что некрасиво, но просто. Остальное Вы можете найти внутри выложенного архива. PS: Чтобы иметь возможность править настройки рекомендую заменить компонент admin/Extension Manager/Settings.ascx.cs на файл, вложенный архив. Там исправлена некоторая ошибка в функции редактирования настроек.


Метки: ,   Категории:BlogEngine | Code | life


blog comments powered by Disqus

Добавить комментарий

Кто я?

Программист. Я слежу за блогосферой и знаю, как будет развиваться интернет. Когда у меня есть время я даже прилагаю для этого усилия. Подробнее

Последние комментарии

Не отображать

Topbot at FeedsBurner

Мои Твиты

Twitter октября 18, 06:44
Яндекс атаковал Израиль http://dlvr.it/QnhhCy

Twitter октября 17, 16:07
Как разверифицироваться в Твиттере? http://dlvr.it/Qnddsc https://twitter.com/f1ashr/status/1052591848303120390/photo/1

Twitter октября 17, 16:07
На батуте в космос http://dlvr.it/QnddrT

Twitter октября 17, 16:07
Estonian Fitsme http://dlvr.it/Qnddn3

Twitter октября 17, 16:07
Россия будет воевать http://dlvr.it/Qnddq7

Twitter октября 17, 15:33
Про браузеры http://dlvr.it/QndT1N

Twitter октября 17, 14:54
Прыгающий Робо-жук http://dlvr.it/QndGjW https://twitter.com/f1ashr/status/1052573591181582336/photo/1

Twitter октября 17, 14:54
Google Plus выкатывает красивые имена http://dlvr.it/QndGj2

Twitter октября 17, 14:54
Немецкие совестливые журналисты http://dlvr.it/QndGjD

Twitter октября 17, 09:27
Победа свободы над здравым смыслом http://dlvr.it/QnbjB5 https://twitter.com/f1ashr/status/1052491176593354752/photo/1

Twitter октября 17, 06:41
программа instagramliker обновлена 2018г http://dlvr.it/Qnb2DZ

Twitter октября 16, 07:50
CloudSearch http://dlvr.it/QnTLzB

Twitter октября 16, 07:50
Сидеть вредно. http://dlvr.it/QnTLzD

Twitter октября 16, 07:50
Вконтакте 7 лет http://dlvr.it/QnTLzH

Twitter октября 16, 07:50
Рейтинг авторитетности блогов http://dlvr.it/QnTLz2

Twitter октября 16, 07:50
Tech news http://dlvr.it/QnTLz5

Twitter октября 16, 07:13
Совет многоквартирного дома http://dlvr.it/QnTCHQ https://twitter.com/f1ashr/status/1052095075918872576/photo/1

Twitter октября 16, 07:13
Windows 10 и Новый мировой порядок http://dlvr.it/QnTCF0 https://twitter.com/f1ashr/status/1052095069317001216/photo/1

Twitter октября 16, 07:13
Украинские солдаты до сих пор не поняли с кем воюют http://dlvr.it/QnTC5Z https://twitter.com/f1ashr/status/1052095061586980864/photo/1

Twitter октября 16, 07:13
Продолжая тему браузеров http://dlvr.it/QnTC4k

Мой твиттер

Копирайт

Все мысли, высказанные в блоге, являются моим мнением и за это мнение меня никто не забанит! Кроме того, никто не имеет право копировать материалы блога без использования ctrl+C/V!

© Copyright 2008