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


Кто я?

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

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

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

Topbot at FeedsBurner

Облако тэгов

Мои Твиты

Twitter декабря 7, 13:11
Механический медведь для Америки - Погружение во Тьму http://dlvr.it/Qt3hCf https://twitter.com/f1ashr/status/1071029327888736256/photo/1

Twitter декабря 6, 07:49
@coinhive_com Are you paying or not? Are you stopping your service?

Twitter декабря 1, 15:49
Международная система единиц СИ http://dlvr.it/QsZWxP https://twitter.com/f1ashr/status/1068894908939784192/photo/1

Twitter ноября 30, 15:47
Пользователи умудрились поломать гео-локацию в Инстаграм http://dlvr.it/QsVQn0

Twitter ноября 30, 15:47
Популярные блогеры и посты за 2017 год http://dlvr.it/QsVQmn https://twitter.com/f1ashr/status/1068532024984498176/photo/1

Twitter ноября 30, 15:47
Разбор сериала Медичи: Повелители Флоренции http://dlvr.it/QsVQmf https://twitter.com/f1ashr/status/1068532019930353664/photo/1

Twitter ноября 29, 15:45
Обновлен робот instagram для лайков http://dlvr.it/QsPrh2

Twitter ноября 29, 15:45
Skype and Baidu links http://dlvr.it/QsPrht

Twitter ноября 29, 15:45
О смене дизайна Вконтакте http://dlvr.it/QsPrgT

Twitter ноября 23, 13:18
Статистика просмотров Телеграма http://dlvr.it/Qrwybs

Twitter ноября 20, 11:54
По-тихому закрылся http://taaasty.com http://dlvr.it/QrgcJf

Twitter ноября 15, 21:21
Разное - сетевое http://dlvr.it/QrLfbH

Twitter ноября 12, 08:54
@lopp @coinhive_com Beware, that coinhive doesnt process payouts for last month and no reply from them.

Twitter ноября 6, 08:26
@MultiFollow_com @coinhive_com The same, cant get payment since Oct 29

Twitter октября 29, 18:13
Вконтакте закрыла гео-поиск http://dlvr.it/QptcDZ

Twitter октября 29, 17:48
RT @t30p: Моя Борьба (Mein Kampf) - Мыслить №112 https://youtu.be/eq3r3n3jAkY с помощью @YouTube

Twitter октября 23, 17:57
8-й час в России http://dlvr.it/QpG99N https://twitter.com/f1ashr/status/1054793845546790912/photo/1

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

Мой твиттер

Копирайт

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

© Copyright 2008