/src/SSCMS.Core/Utils/Serialization/Components/ContentIe.cs

https://github.com/siteserver/cms · C# · 484 lines · 427 code · 53 blank · 4 comment · 35 complexity · abe1f93fcb71afb354ae1eec1916a5ed MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using SSCMS.Core.Utils.Serialization.Atom.Atom.Core;
  8. using SSCMS.Core.Utils.Serialization.Atom.Atom.Core.Collections;
  9. using SSCMS.Models;
  10. using SSCMS.Services;
  11. using SSCMS.Utils;
  12. namespace SSCMS.Core.Utils.Serialization.Components
  13. {
  14. internal class ContentIe
  15. {
  16. private readonly IPathManager _pathManager;
  17. private readonly IDatabaseManager _databaseManager;
  18. private readonly CacheUtils _caching;
  19. private readonly Site _site;
  20. private readonly string _siteContentDirectoryPath;
  21. public ContentIe(IPathManager pathManager, IDatabaseManager databaseManager, CacheUtils caching, Site site, string siteContentDirectoryPath)
  22. {
  23. _pathManager = pathManager;
  24. _databaseManager = databaseManager;
  25. _caching = caching;
  26. _siteContentDirectoryPath = siteContentDirectoryPath;
  27. _site = site;
  28. }
  29. public async Task ImportContentsAsync(string filePath, bool isOverride, Channel channel, int taxis, int importStart, int importCount, bool isChecked, int checkedLevel, int adminId, string guid)
  30. {
  31. if (!FileUtils.IsFileExists(filePath)) return;
  32. var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath));
  33. await ImportContentsAsync(feed.Entries, channel, taxis, importStart, importCount, false, isChecked, checkedLevel, isOverride, adminId, guid);
  34. }
  35. public async Task<List<int>> ImportContentsAsync(string filePath, bool isOverride, Channel channel, int taxis, bool isChecked, int checkedLevel, int adminId, int userId, int sourceId)
  36. {
  37. if (!FileUtils.IsFileExists(filePath)) return null;
  38. var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath));
  39. return await ImportContentsAsync(feed.Entries, channel, taxis, false, isChecked, checkedLevel, isOverride, adminId, userId, sourceId);
  40. }
  41. public async Task ImportContentsAsync(AtomEntryCollection entries, Channel channel, int taxis, bool isOverride, int adminId, string guid)
  42. {
  43. await ImportContentsAsync(entries, channel, taxis, 0, 0, true, true, 0, isOverride, adminId, guid);
  44. }
  45. // 内部消化掉错误
  46. private async Task ImportContentsAsync(AtomEntryCollection entries, Channel channel, int taxis, int importStart, int importCount, bool isCheckedBySettings, bool isChecked, int checkedLevel, bool isOverride, int adminId, string guid)
  47. {
  48. if (importStart > 1 || importCount > 0)
  49. {
  50. var theEntries = new AtomEntryCollection();
  51. if (importStart == 0)
  52. {
  53. importStart = 1;
  54. }
  55. if (importCount == 0)
  56. {
  57. importCount = entries.Count;
  58. }
  59. var firstIndex = entries.Count - importStart - importCount + 1;
  60. if (firstIndex <= 0)
  61. {
  62. firstIndex = 0;
  63. }
  64. var addCount = 0;
  65. for (var i = 0; i < entries.Count; i++)
  66. {
  67. if (addCount >= importCount) break;
  68. if (i >= firstIndex)
  69. {
  70. theEntries.Add(entries[i]);
  71. addCount++;
  72. }
  73. }
  74. entries = theEntries;
  75. }
  76. var contents = new List<Content>();
  77. foreach (AtomEntry entry in entries)
  78. {
  79. try
  80. {
  81. taxis++;
  82. var groupNames = AtomUtility.GetDcElementContent(entry.AdditionalElements, new List<string>{ nameof(Content.GroupNames), "GroupNameCollection", "ContentGroupNameCollection" });
  83. var tagNames = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, new List<string> { nameof(Content.TagNames), "Tags" }));
  84. if (isCheckedBySettings)
  85. {
  86. isChecked = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements,
  87. new List<string> { nameof(Content.Checked), "IsChecked"}));
  88. checkedLevel = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.CheckedLevel)));
  89. }
  90. var hits = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.Hits)));
  91. var hitsByDay = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.HitsByDay)));
  92. var hitsByWeek = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.HitsByWeek)));
  93. var hitsByMonth = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.HitsByMonth)));
  94. var lastHitsDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.LastHitsDate));
  95. var downloads = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.Downloads)));
  96. var title = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.Title));
  97. var isTop = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements,
  98. new List<string> {nameof(Content.Top), "IsTop"}));
  99. var isRecommend = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements,
  100. new List<string> {nameof(Content.Recommend), "IsRecommend"}));
  101. var isHot = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements,
  102. new List<string> {nameof(Content.Hot), "IsHot"}));
  103. var isColor = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements,
  104. new List<string> {nameof(Content.Color), "IsColor"}));
  105. var linkUrl = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.LinkUrl)));
  106. var addDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.AddDate));
  107. var body = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements,
  108. new List<string> { nameof(Content.Body), "Content" }));
  109. var topTaxis = 0;
  110. if (isTop)
  111. {
  112. topTaxis = taxis - 1;
  113. taxis = await _databaseManager.ContentRepository.GetMaxTaxisAsync(_site, channel, true) + 1;
  114. }
  115. var dict = new Dictionary<string, object>();
  116. var attributes = AtomUtility.GetDcElementNameValueCollection(entry.AdditionalElements);
  117. foreach (string attributeName in attributes.Keys)
  118. {
  119. dict[attributeName] = AtomUtility.Decrypt(attributes[attributeName]);
  120. }
  121. var content = new Content();
  122. content.LoadDict(dict);
  123. content.SiteId = _site.Id;
  124. content.ChannelId = channel.Id;
  125. content.AddDate = TranslateUtils.ToDateTime(addDate);
  126. content.AdminId = adminId;
  127. content.LastEditAdminId = adminId;
  128. content.GroupNames = ListUtils.GetStringList(groupNames);
  129. content.TagNames = ListUtils.GetStringList(tagNames);
  130. content.Checked = isChecked;
  131. content.CheckedLevel = checkedLevel;
  132. content.Hits = hits;
  133. content.HitsByDay = hitsByDay;
  134. content.HitsByWeek = hitsByWeek;
  135. content.HitsByMonth = hitsByMonth;
  136. content.LastHitsDate = TranslateUtils.ToDateTime(lastHitsDate);
  137. content.Downloads = downloads;
  138. content.Title = AtomUtility.Decrypt(title);
  139. content.Top = isTop;
  140. content.Recommend = isRecommend;
  141. content.Hot = isHot;
  142. content.Color = isColor;
  143. content.LinkUrl = linkUrl;
  144. content.Body = body;
  145. var isInsert = false;
  146. if (isOverride)
  147. {
  148. var existsIDs = await _databaseManager.ContentRepository.GetContentIdsBySameTitleAsync(_site, channel, content.Title);
  149. if (existsIDs.Count > 0)
  150. {
  151. foreach (var id in existsIDs)
  152. {
  153. content.Id = id;
  154. contents.Add(content);
  155. }
  156. }
  157. else
  158. {
  159. isInsert = true;
  160. }
  161. }
  162. else
  163. {
  164. isInsert = true;
  165. }
  166. if (isInsert)
  167. {
  168. content.Taxis = taxis;
  169. contents.Add(content);
  170. if (!string.IsNullOrEmpty(tagNames))
  171. {
  172. foreach (var tagName in ListUtils.GetStringList(tagNames))
  173. {
  174. await _databaseManager.ContentTagRepository.InsertAsync(_site.Id, tagName);
  175. }
  176. }
  177. }
  178. if (isTop)
  179. {
  180. taxis = topTaxis;
  181. }
  182. }
  183. catch(Exception ex)
  184. {
  185. await _databaseManager.ErrorLogRepository.AddErrorLogAsync(ex, "导入内容");
  186. }
  187. }
  188. foreach (var content in contents)
  189. {
  190. _caching.SetProcess(guid, $"导入内容: {content.Title}");
  191. if (content.Id > 0)
  192. {
  193. await _databaseManager.ContentRepository.UpdateAsync(_site, channel, content);
  194. }
  195. else
  196. {
  197. await _databaseManager.ContentRepository.InsertWithTaxisAsync(_site, channel, content, content.Taxis);
  198. }
  199. }
  200. }
  201. private async Task<List<int>> ImportContentsAsync(AtomEntryCollection entries, Channel channel, int taxis, bool isCheckedBySettings, bool isChecked, int checkedLevel, bool isOverride, int adminId, int userId, int sourceId)
  202. {
  203. var contents = new List<Content>();
  204. foreach (AtomEntry entry in entries)
  205. {
  206. try
  207. {
  208. taxis++;
  209. var groupNameCollection = AtomUtility.GetDcElementContent(entry.AdditionalElements, new List<string> { nameof(Content.GroupNames), "GroupNameCollection", "ContentGroupNameCollection" });
  210. if (isCheckedBySettings)
  211. {
  212. isChecked = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, new List<string>{nameof(Content.Checked), "IsChecked" }));
  213. checkedLevel = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.CheckedLevel)));
  214. }
  215. var hits = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.Hits)));
  216. var hitsByDay = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.HitsByDay)));
  217. var hitsByWeek = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.HitsByWeek)));
  218. var hitsByMonth = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.HitsByMonth)));
  219. var lastHitsDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.LastHitsDate));
  220. var downloads = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.Downloads)));
  221. var title = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.Title));
  222. var isTop = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, new List<string> { nameof(Content.Top), "IsTop" }));
  223. var isRecommend = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, new List<string> { nameof(Content.Recommend), "IsRecommend" }));
  224. var isHot = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, new List<string> { nameof(Content.Hot), "IsHot" }));
  225. var isColor = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, new List<string> { nameof(Content.Color), "IsColor" }));
  226. var linkUrl = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.LinkUrl)));
  227. var addDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(Content.AddDate));
  228. var topTaxis = 0;
  229. if (isTop)
  230. {
  231. topTaxis = taxis - 1;
  232. taxis = await _databaseManager.ContentRepository.GetMaxTaxisAsync(_site, channel, true) + 1;
  233. }
  234. var tags = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, new List<string> { nameof(Content.TagNames), "Tags" }));
  235. var contentInfo = new Content
  236. {
  237. SiteId = _site.Id,
  238. ChannelId = channel.Id,
  239. AdminId = adminId,
  240. LastEditAdminId = adminId,
  241. UserId = userId,
  242. SourceId = sourceId,
  243. AddDate = TranslateUtils.ToDateTime(addDate),
  244. GroupNames = ListUtils.GetStringList(groupNameCollection),
  245. TagNames = ListUtils.GetStringList(tags),
  246. Checked = isChecked,
  247. CheckedLevel = checkedLevel,
  248. Hits = hits,
  249. HitsByDay = hitsByDay,
  250. HitsByWeek = hitsByWeek,
  251. HitsByMonth = hitsByMonth,
  252. LastHitsDate = TranslateUtils.ToDateTime(lastHitsDate),
  253. Downloads = downloads,
  254. Title = AtomUtility.Decrypt(title),
  255. Top = isTop,
  256. Recommend = isRecommend,
  257. Hot = isHot,
  258. Color = isColor,
  259. LinkUrl = linkUrl
  260. };
  261. var attributes = AtomUtility.GetDcElementNameValueCollection(entry.AdditionalElements);
  262. foreach (string attributeName in attributes.Keys)
  263. {
  264. if (!contentInfo.ContainsKey(StringUtils.ToLower(attributeName)))
  265. {
  266. contentInfo.Set(attributeName, AtomUtility.Decrypt(attributes[attributeName]));
  267. }
  268. }
  269. var isInsert = false;
  270. if (isOverride)
  271. {
  272. var existsIDs = await _databaseManager.ContentRepository.GetContentIdsBySameTitleAsync(_site, channel, contentInfo.Title);
  273. if (existsIDs.Count > 0)
  274. {
  275. foreach (var id in existsIDs)
  276. {
  277. contentInfo.Id = id;
  278. contents.Add(contentInfo);
  279. }
  280. }
  281. else
  282. {
  283. isInsert = true;
  284. }
  285. }
  286. else
  287. {
  288. isInsert = true;
  289. }
  290. if (isInsert)
  291. {
  292. contentInfo.Taxis = taxis;
  293. contents.Add(contentInfo);
  294. if (!string.IsNullOrEmpty(tags))
  295. {
  296. foreach (var tagName in ListUtils.GetStringList(tags))
  297. {
  298. await _databaseManager.ContentTagRepository.InsertAsync(_site.Id, tagName);
  299. }
  300. }
  301. }
  302. if (isTop)
  303. {
  304. taxis = topTaxis;
  305. }
  306. }
  307. catch
  308. {
  309. // ignored
  310. }
  311. }
  312. var contentIdList = new List<int>();
  313. foreach (var content in contents)
  314. {
  315. if (content.Id > 0)
  316. {
  317. await _databaseManager.ContentRepository.UpdateAsync(_site, channel, content);
  318. }
  319. else
  320. {
  321. contentIdList.Add(await _databaseManager.ContentRepository.InsertWithTaxisAsync(_site, channel, content, content.Taxis));
  322. }
  323. }
  324. return contentIdList;
  325. }
  326. public async Task<bool> ExportContentsAsync(Site site, int channelId, List<int> contentIdList, bool isPeriods, string dateFrom, string dateTo, bool? checkedState)
  327. {
  328. var filePath = _siteContentDirectoryPath + PathUtils.SeparatorChar + "contents.xml";
  329. var channelInfo = await _databaseManager.ChannelRepository.GetAsync(channelId);
  330. var feed = AtomUtility.GetEmptyFeed();
  331. if (contentIdList == null)
  332. {
  333. contentIdList = await _databaseManager.ContentRepository.GetContentIdsAsync(site, channelInfo, isPeriods, dateFrom, dateTo, checkedState);
  334. }
  335. if (!contentIdList.Any()) return false;
  336. var collection = new NameValueCollection();
  337. foreach (var contentId in contentIdList)
  338. {
  339. var contentInfo = await _databaseManager.ContentRepository.GetAsync(site, channelInfo, contentId);
  340. try
  341. {
  342. await _pathManager.PutImagePathsAsync(site, contentInfo, collection);
  343. }
  344. catch
  345. {
  346. // ignored
  347. }
  348. var entry = ExportContentInfo(contentInfo);
  349. feed.Entries.Add(entry);
  350. }
  351. feed.Save(filePath);
  352. foreach (string imageUrl in collection.Keys)
  353. {
  354. var sourceFilePath = collection[imageUrl];
  355. var destFilePath = _pathManager.ParsePath(_siteContentDirectoryPath, imageUrl);
  356. DirectoryUtils.CreateDirectoryIfNotExists(destFilePath);
  357. FileUtils.MoveFile(sourceFilePath, destFilePath, true);
  358. }
  359. return true;
  360. }
  361. public async Task<bool> ExportContentsAsync(Site site, List<Content> contentInfoList)
  362. {
  363. var filePath = _siteContentDirectoryPath + PathUtils.SeparatorChar + "contents.xml";
  364. var feed = AtomUtility.GetEmptyFeed();
  365. var collection = new NameValueCollection();
  366. foreach (var contentInfo in contentInfoList)
  367. {
  368. try
  369. {
  370. await _pathManager.PutImagePathsAsync(site, contentInfo, collection);
  371. }
  372. catch
  373. {
  374. // ignored
  375. }
  376. var entry = ExportContentInfo(contentInfo);
  377. feed.Entries.Add(entry);
  378. }
  379. feed.Save(filePath);
  380. foreach (string imageUrl in collection.Keys)
  381. {
  382. var sourceFilePath = collection[imageUrl];
  383. var destFilePath = _pathManager.ParsePath(_siteContentDirectoryPath, imageUrl);
  384. DirectoryUtils.CreateDirectoryIfNotExists(destFilePath);
  385. FileUtils.MoveFile(sourceFilePath, destFilePath, true);
  386. }
  387. return true;
  388. }
  389. public AtomEntry ExportContentInfo(Content content)
  390. {
  391. var entry = AtomUtility.GetEmptyEntry();
  392. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.Id), content.Id.ToString());
  393. AtomUtility.AddDcElement(entry.AdditionalElements, new List<string>{ nameof(Content.ChannelId), "NodeId" }, content.ChannelId.ToString());
  394. AtomUtility.AddDcElement(entry.AdditionalElements, new List<string> { nameof(Content.SiteId), "PublishmentSystemId" }, content.SiteId.ToString());
  395. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.Taxis), content.Taxis.ToString());
  396. AtomUtility.AddDcElement(entry.AdditionalElements, new List<string>{ nameof(Content.GroupNames), "GroupNameCollection", "ContentGroupNameCollection" }, ListUtils.ToString(content.GroupNames));
  397. AtomUtility.AddDcElement(entry.AdditionalElements, new List<string> { nameof(Content.TagNames), "Tags" }, AtomUtility.Encrypt(ListUtils.ToString(content.TagNames)));
  398. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.SourceId), content.SourceId.ToString());
  399. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.ReferenceId), content.ReferenceId.ToString());
  400. AtomUtility.AddDcElement(entry.AdditionalElements, new List<string> { nameof(Content.Checked), "IsChecked" }, content.Checked.ToString());
  401. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.CheckedLevel), content.CheckedLevel.ToString());
  402. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.Hits), content.Hits.ToString());
  403. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.HitsByDay), content.HitsByDay.ToString());
  404. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.HitsByWeek), content.HitsByWeek.ToString());
  405. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.HitsByMonth), content.HitsByMonth.ToString());
  406. if (content.LastHitsDate.HasValue)
  407. {
  408. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.LastHitsDate), content.LastHitsDate.Value.ToString(CultureInfo.InvariantCulture));
  409. }
  410. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.Downloads), content.Downloads.ToString());
  411. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.Title), AtomUtility.Encrypt(content.Title));
  412. AtomUtility.AddDcElement(entry.AdditionalElements, new List<string> { nameof(Content.Top), "IsTop" }, content.Top.ToString());
  413. AtomUtility.AddDcElement(entry.AdditionalElements, new List<string> { nameof(Content.Recommend), "IsRecommend" }, content.Recommend.ToString());
  414. AtomUtility.AddDcElement(entry.AdditionalElements, new List<string> { nameof(Content.Hot), "IsHot" }, content.Hot.ToString());
  415. AtomUtility.AddDcElement(entry.AdditionalElements, new List<string> { nameof(Content.Color), "IsColor" }, content.Color.ToString());
  416. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.LinkUrl), AtomUtility.Encrypt(content.LinkUrl));
  417. if (content.AddDate.HasValue)
  418. {
  419. AtomUtility.AddDcElement(entry.AdditionalElements, nameof(Content.AddDate), content.AddDate.Value.ToString(CultureInfo.InvariantCulture));
  420. }
  421. foreach (var attributeName in content.ToDictionary().Keys)
  422. {
  423. if (!ListUtils.ContainsIgnoreCase(ColumnsManager.MetadataAttributes.Value, attributeName))
  424. {
  425. AtomUtility.AddDcElement(entry.AdditionalElements, attributeName, AtomUtility.Encrypt(content.Get<string>(attributeName)));
  426. }
  427. }
  428. return entry;
  429. }
  430. }
  431. }