Tech.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Configuration;
using Bitrix.DataLayer;
using Bitrix.IBlock;
using Bitrix.Services;
using Bitrix.Services.Syndication;
using Bitrix.Services.Text;
namespace Bitrix.Demo
{
public class RssFeedSettings
{
private string url;
private int iblockId;
private int agentPeriod;
private int elementActivePeriod;
private string defaultAuthorName;
private bool onlyPreview;
private string[] automaticTags;
public string DefaultAuthorName
{
get { return defaultAuthorName; }
set { defaultAuthorName = value; }
}
public string Url
{
get { return url; }
set { url = value; }
}
public int IBlockId
{
get { return iblockId; }
set { iblockId = value; }
}
public int AgentPeriod
{
get { return agentPeriod; }
set { agentPeriod = value; }
}
public int ElementActivePeriod
{
get { return elementActivePeriod; }
set { elementActivePeriod = value; }
}
public bool OnlyPreview
{
get { return onlyPreview; }
set { onlyPreview = value; }
}
public string[] AutomaticTags
{
get { return automaticTags; }
set { automaticTags = value; }
}
public RssFeedSettings(string url, int iblockId, string defaultAuthorName)
{
this.url = url;
this.defaultAuthorName = defaultAuthorName;
this.iblockId = iblockId;
this.agentPeriod = 10;
this.elementActivePeriod = 0;
this.onlyPreview = false;
}
}
public class TechnologyItem
{
private string code;
private int id;
private List<TechnologyItem> childs;
private TechnologyItem defaultChild;
private int storageTime;
public string Code
{
get { return code; }
}
public int Id
{
get { return id; }
}
public TechnologyItem DefaultChild
{
get { return defaultChild; }
set { defaultChild = value; }
}
public int StorageTime
{
get { return storageTime; }
set { storageTime = value; }
}
public List<TechnologyItem> Childs
{
get { return childs ?? (childs = new List<TechnologyItem>()); }
}
public TechnologyItem(int id, string code, int storageTime)
: this(id, code)
{
this.storageTime = storageTime;
}
public TechnologyItem(int id, string code)
{
this.id = id;
this.code = code;
}
}
public static class Aggregator
{
static List<TechnologyItem> technoloryTree = null;
public static void LoadRssItems(RssFeedSettings settings)
{
BXRss20Feed feed = BXRss20Feed.CreateByUrl(settings.Url, 1000 * 20);
if (feed == null || feed.Channels.Count < 1)
return;
foreach (BXRss20ChannelItem item in feed.Channels[0].Items)
{
string guid = GetItemGuid(item);
if (BXStringUtility.IsNullOrTrimEmpty(item.Title) || BXStringUtility.IsNullOrTrimEmpty(item.Description) ||
BXStringUtility.IsNullOrTrimEmpty(item.Link) || guid == null)
continue;
if (settings.AutomaticTags != null)
foreach (string tag in settings.AutomaticTags)
item.Categories.Add(new BXRss20Category(tag));
var technologySections = GetSections(item);
if (technologySections.Count < 1)
continue;
BXIBlockElement element = GetElement(guid, item.Link, settings.IBlockId);
if (element == null)
{
string preview = GetPreview(item.Description, 400);
if (BXStringUtility.IsNullOrTrimEmpty(preview))
continue;
try
{
element = new BXIBlockElement();
element.Name = item.Title;
element.PreviewTextType = BXTextType.Text;
element.DetailTextType = BXTextType.Html;
element.IBlockId = settings.IBlockId;
element.XmlId = guid;
element.PreviewText = preview;
//Сохраняем орининальную дату
if (item.PubDate.HasValue)
element.ActiveFromDate = item.PubDate.Value;
//Если для записей подписки указано время жизни
if (settings.ElementActivePeriod > 0)
element.ActiveToDate = DateTime.Now.AddDays(settings.ElementActivePeriod);
if (!settings.OnlyPreview)
element.DetailText = item.Description;
element.Sections.AddRange(technologySections);
string tags = "";
foreach (var tag in item.Categories)
{
if (!String.IsNullOrEmpty(tags))
tags += ", ";
tags += tag.Name;
}
element.Tags = tags;
element.CustomPublicValues["AUTHOR_NAME"] = GetAuthorName(item, settings.DefaultAuthorName);
element.CustomPublicValues["SOURCE_URL"] = item.Link;
element.CustomPublicValues["COMMENTS_URL"] = BXStringUtility.IsNullOrTrimEmpty(item.Comments) ? item.Link : item.Comments;
element.Save();
}
catch (Exception ex)
{
BXLogService.LogAll(ex, BXLogMessageType.Error, String.Format("Aggregator. Ошибка сохранения элемента.({0}) ", item.Link));
}
}
}
}
public static RssFeedSettings GetSettings(BXIBlockElement iblockElement)
{
RssFeedSettings settings = null;
if (iblockElement == null)
return settings;
string url = iblockElement.CustomPublicValues.GetString("SOURCE_URL");
string defaultAuthorName = iblockElement.CustomPublicValues.GetString("AUTHOR_NAME");
int iblockId;
if (!BXStringUtility.IsNullOrTrimEmpty(url) && !BXStringUtility.IsNullOrTrimEmpty(defaultAuthorName) && int.TryParse(WebConfigurationManager.AppSettings["TechnologyIBlockId"], out iblockId))
{
settings = new RssFeedSettings(url, iblockId, defaultAuthorName);
settings.AgentPeriod = iblockElement.CustomPublicValues.GetInt32("PERIOD", 10);
settings.ElementActivePeriod = iblockElement.CustomPublicValues.GetInt32("STORAGE_TIME", 0);
settings.OnlyPreview = iblockElement.CustomPublicValues.GetBoolean("PREVIEW_ONLY", false);
string tags = iblockElement.CustomPublicValues.GetString("TAGS");
if (tags != null && !BXStringUtility.IsNullOrTrimEmpty(tags))
settings.AutomaticTags = tags.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
}
return settings;
}
public static void ClearTechnologyTreeCache()
{
technoloryTree = null;
}
public static void InitTechnologyTree()
{
technoloryTree = new List<TechnologyItem>();
int iblockId;
if (!int.TryParse(WebConfigurationManager.AppSettings["TechnologyIBlockId"], out iblockId))
return;
BXIBlockSectionCollection sections = BXIBlockSection.GetList(
new BXFilter(
new BXFilterItem(BXIBlockSection.Fields.IBlock.ID, BXSqlFilterOperators.Equal, iblockId),
new BXFilterItem(BXIBlockSection.Fields.ActiveGlobal, BXSqlFilterOperators.Equal, "Y"),
new BXFilterItem(BXIBlockSection.Fields.DepthLevel, BXSqlFilterOperators.LessOrEqual, 2)
),
new BXOrderBy(new BXOrderByPair(BXIBlockSection.Fields.LeftMargin, BXOrderByDirection.Asc)),
null,
null,
BXTextEncoder.EmptyTextEncoder
);
TechnologyItem previousSection = null;
foreach (BXIBlockSection section in sections)
{
string code = GetTechnologyItemsTag(section);
int storageTime = section.CustomPublicValues.GetInt32("STORAGE_TIME", 0);
if (section.DepthLevel == 1)
{
previousSection = new TechnologyItem(section.Id, code, storageTime);
technoloryTree.Add(previousSection);
}
else if (section.DepthLevel == 2 && previousSection != null)
{
TechnologyItem child = new TechnologyItem(section.Id, code, storageTime);
if (code == null)
previousSection.DefaultChild = child;
previousSection.Childs.Add(child);
}
}
}
private static string GetTechnologyItemsTag(BXIBlockSection section)
{
if (section == null || BXStringUtility.IsNullOrTrimEmpty(section.XmlId))
return null;
StringBuilder result = new StringBuilder();
string[] tags = section.XmlId.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
foreach (string tag in tags)
{
result.Append('{');
result.Append(tag.Trim());
result.Append('}');
}
return result.ToString().ToUpper();
}
private static BXIBlockElement GetElement(string guid, string url, int iblockId)
{
BXIBlockElementCollection elements = BXIBlockElement.GetList(
new BXFilter(
new BXFilterItem(BXIBlockElement.Fields.IBlock.ID, BXSqlFilterOperators.Equal, iblockId),
new BXFilterItem(BXIBlockElement.Fields.XmlId, BXSqlFilterOperators.Equal, guid)
),
null
);
//Если элементов с таким xmlId несколько, сравним их адреса
if (elements.Count > 1)
{
BXIBlockElement trueElement = null;
foreach (var element in elements)
{
if (element.CustomValues != null && String.Equals(element.CustomPublicValues.GetString("SOURCE_URL"), url, StringComparison.OrdinalIgnoreCase))
{
trueElement = element;
break;
}
}
return trueElement ?? elements[0];
}
else if (elements.Count == 1)
return elements[0];
else
return null;
}
private static string GetPreview(string originalText, int maxLength)
{
string preview = BXStringUtility.StripOffSimpleTags(originalText);
preview = HttpUtility.HtmlDecode(preview);
preview = preview.Trim(' ', '\n', '\t', '\r');
if (maxLength > 0 && preview.Length > maxLength)
preview = preview.Substring(0, maxLength) + " ...";
return preview;
}
private static BXIBlockElement.BXInfoBlockElementSectionCollection GetSections(BXRss20ChannelItem rssItem)
{
BXIBlockElement.BXInfoBlockElementSectionCollection result = new BXIBlockElement.BXInfoBlockElementSectionCollection();
if (technoloryTree == null)
InitTechnologyTree();
List<TechnologyItem> rootSections = GetSection(rssItem, technoloryTree, false);
foreach (TechnologyItem rootSection in rootSections)
{
List<TechnologyItem> childSections = GetSection(rssItem, rootSection.Childs, false);
if (childSections.Count > 0)
{
result.Add(childSections[0].Id);
}
else if (rootSection.DefaultChild != null && !(rootSection.DefaultChild.StorageTime > 0 && rssItem.PubDate.HasValue && rssItem.PubDate.Value <= DateTime.Now.AddDays(-rootSection.DefaultChild.StorageTime)))
{
//если никуда не попал, значит в дефолтовую категорию
result.Add(rootSection.DefaultChild.Id);
}
}
return result;
}
private static List<TechnologyItem> GetSection(BXRss20ChannelItem rssItem, IEnumerable<TechnologyItem> sections, bool onlyFirst)
{
List<TechnologyItem> result = new List<TechnologyItem>();
foreach (var category in rssItem.Categories)
{
if (BXStringUtility.IsNullOrTrimEmpty(category.Name))
continue;
string categoryName = String.Concat("{", category.Name.ToUpper().Trim(), "}");
foreach (TechnologyItem item in sections)
{
//если дата записи меньше, чем время хранения в разделе, то не добавляем такой элемент
if (item.StorageTime > 0 && rssItem.PubDate.HasValue && rssItem.PubDate.Value <= DateTime.Now.AddDays(-item.StorageTime))
continue;
if (item.Code != null && item.Code.IndexOf(categoryName) != -1 && !result.Contains(item))
{
result.Add(item);
if (onlyFirst)
return result;
}
}
}
return result;
}
private static string GetItemGuid(BXRss20ChannelItem item)
{
string guid = null;
if (item.Guid != null && !BXStringUtility.IsNullOrTrimEmpty(item.Guid.Guid))
guid = item.Guid.Guid;
else if (!BXStringUtility.IsNullOrTrimEmpty(item.Link))
guid = item.Link;
return guid;
}
private static string GetAuthorName(BXRss20ChannelItem item, string defaultName)
{
foreach (var tag in new[] { "dc:creator", "lj:poster" })
{
var names = item.ElementExtensions.FindByName(tag);
if (names.Length > 0 && !BXStringUtility.IsNullOrTrimEmpty(names[0].InnerXml))
return names[0].InnerXml;
}
if (!BXStringUtility.IsNullOrTrimEmpty(item.Author))
return item.Author;
return defaultName;
}
}
}
Страница
5 - 5 из 6
Начало
|
Пред.
|
2
3
4
5
6
|
След. |
Конец
Список новостей