PageRenderTime 74ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/Server/IServV2/IPhone/Plugins/Content/AFP.IPhone.Content.Plugins.JournalInternet/Plugin.cs

https://bitbucket.org/fboltz/afpmobile
C# | 3180 lines | 2278 code | 446 blank | 456 comment | 372 complexity | 89b288cb6c243a771e0dbf16bfc6be8c MD5 | raw file
Possible License(s): Apache-2.0, MPL-2.0, LGPL-2.1, MIT, BSD-3-Clause, 0BSD, AGPL-3.0
  1. using AFP.IPhone.Application;
  2. using AFP.IPhone.Extensions;
  3. using AFP.IPhone.Storage;
  4. using AFP.IPhone.Processor.Plugins.JournalInternet.Documents;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Data;
  8. using System.Data.SqlClient;
  9. using System.Drawing;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Text.RegularExpressions;
  14. using System.Threading;
  15. using System.Xml;
  16. using System.Xml.Xsl;
  17. using System.Web.Services;
  18. using System.Globalization;
  19. #if SERVICE
  20. using AFP.IPhone.Plugins.GetCourseId;
  21. #endif
  22. namespace AFP.IPhone.Processor.Plugins.JournalInternet
  23. {
  24. class ExXmlTextWriter : XmlTextWriter
  25. {
  26. private StringWriter mvar_Writer;
  27. private ExXmlTextWriter(StringWriter w)
  28. : base(w)
  29. {
  30. mvar_Writer = w;
  31. // Indentation
  32. this.Formatting = Formatting.Indented;
  33. this.Indentation = 2;
  34. }
  35. public ExXmlTextWriter()
  36. : this(new StringWriter())
  37. {
  38. }
  39. public override string ToString()
  40. {
  41. return mvar_Writer.ToString();
  42. }
  43. }
  44. /// <summary>
  45. /// Class to handle JI AFP iPhone Content
  46. /// </summary>
  47. ///
  48. public class Plugin : ProcessorPluginBase
  49. {
  50. private const string _storagePhotosFormatName = "Photos";
  51. private const string _storageVideosFormatName = "Videos";
  52. private const string _storageDocumentFormatName = "Documents";
  53. private readonly List<SqlProcessor> _sqlProcessorList;
  54. private readonly List<SqlProcessor> _sqlProcessorList2;
  55. private readonly List<string> _dynamicTopicList;
  56. private XmlDocument _sites;
  57. private ProcessorServer.TTrace _levelTrace;
  58. private int _Version =1;
  59. private string _ImageActive ="true";
  60. private string _PreviewRole ="HighDef";
  61. private Boolean _UseUri = false;
  62. private System.Collections.Hashtable _Xslt;
  63. private static XmlWriter createXmlWriter()
  64. {
  65. return new ExXmlTextWriter();
  66. }
  67. public struct RatingEntry
  68. {
  69. public readonly string Lang;
  70. public readonly string NewsId;
  71. public readonly string TopicId;
  72. public RatingEntry(string topicId, string newsId, string lang)
  73. {
  74. Lang = lang;
  75. NewsId = newsId;
  76. TopicId = topicId;
  77. }
  78. }
  79. public struct HitEntry
  80. {
  81. public readonly string Lang;
  82. public readonly string NewsId;
  83. public readonly string TopicId;
  84. public readonly int Hits;
  85. public HitEntry(string topicId, string newsId, string lang, int hits)
  86. {
  87. Lang = lang;
  88. NewsId = newsId;
  89. TopicId = topicId;
  90. Hits = hits;
  91. }
  92. }
  93. public struct RatingEntryKey : IComparable<RatingEntryKey>
  94. {
  95. private readonly string _value;
  96. public RatingEntryKey(DateTime newsDate, DataRow row)
  97. {
  98. _value = string.Format("{0}{1}", (((double)row["averageRating"] * 1000) / (1 + (Math.Truncate(DateTime.Now.Subtract(newsDate).TotalDays) * 10))).ToString("0000"), ((int)row["votes"]).ToString("0000000000"));
  99. }
  100. public int CompareTo(RatingEntryKey other)
  101. {
  102. var cmp = other._value.CompareTo(_value);
  103. return (cmp == 0) ? -1 : cmp;
  104. }
  105. }
  106. private enum ComponentType
  107. {
  108. photo,
  109. video,
  110. text,
  111. unsupported
  112. }
  113. private enum MessageSection
  114. {
  115. Alimentation,
  116. Database,
  117. Processing
  118. }
  119. private enum NewsMediaFilter
  120. {
  121. all,
  122. photoOnly,
  123. videoOnly
  124. }
  125. private static Object GBLock = new Object();
  126. /// <summary>
  127. /// Creates a new instance of Plugin
  128. /// </summary>
  129. ///
  130. public Plugin()
  131. {
  132. // Initialisations
  133. _dynamicTopicList = new List<string>();
  134. _sqlProcessorList = new List<SqlProcessor>();
  135. _sites = new XmlDocument();
  136. _Xslt = new System.Collections.Hashtable();
  137. // Chargement sites
  138. _sites.LoadXml("<sites/>");
  139. // Initialisation des bases rating
  140. try
  141. {
  142. foreach (var connection in Configuration.GetAttribute("ratingConnection").Split('|'))
  143. {
  144. if (string.IsNullOrEmpty(connection) == false)
  145. _sqlProcessorList.Add(new SqlProcessor(connection));
  146. }
  147. foreach (var connection in Configuration.GetAttribute("alertConnection").Split('|'))
  148. {
  149. if (string.IsNullOrEmpty(connection) == false)
  150. _sqlProcessorList2.Add(new SqlProcessor(connection));
  151. }
  152. }
  153. catch (Exception e)
  154. {
  155. Process.Trace(e, System.Diagnostics.EventLogEntryType.Error);
  156. throw;
  157. }
  158. }
  159. /// <summary>
  160. /// Gets the plugin key name.
  161. /// </summary>
  162. ///
  163. public override string Key
  164. {
  165. get { return "JI"; }
  166. }
  167. /// <summary>
  168. /// Get or Set Leveltrace
  169. /// </summary>
  170. public override ProcessorServer.TTrace levelTrace
  171. {
  172. get
  173. {
  174. return _levelTrace;
  175. }
  176. set
  177. {
  178. _levelTrace = value;
  179. }
  180. }
  181. public override int Version
  182. {
  183. get
  184. {
  185. return _Version;
  186. }
  187. set
  188. {
  189. _Version = value;
  190. }
  191. }
  192. public override string ImageActive
  193. {
  194. get
  195. {
  196. return _ImageActive;
  197. }
  198. set
  199. {
  200. _ImageActive = value;
  201. }
  202. }
  203. public override bool UseUri
  204. {
  205. get
  206. {
  207. return _UseUri;
  208. }
  209. set
  210. {
  211. _UseUri = value;
  212. }
  213. }
  214. public override string PreviewRole
  215. {
  216. get
  217. {
  218. return _PreviewRole;
  219. }
  220. set
  221. {
  222. _PreviewRole = value;
  223. }
  224. }
  225. public override void MakeTopic(string topicId)
  226. {
  227. TopicImplementation topic;
  228. topic = TopicImplementation.Load(topicId);
  229. MakeTopic(topic, false, null);
  230. }
  231. /// <summary>
  232. /// Process the defined topics.
  233. /// </summary>
  234. /// <param name="content">The content configuration.</param>
  235. /// <param name="refresh">Flag for refreshing content.</param>
  236. ///
  237. public override void MakeTopics(XmlElement content, bool refresh, Boolean multiThread, int maxThreads)
  238. {
  239. var doneTopics = new List<ManualResetEvent>();
  240. //note : Traitement de tous les topics et subtopics du site
  241. try
  242. {
  243. foreach (XmlNode item in content.ChildNodes)
  244. {
  245. if (item is XmlElement)
  246. {
  247. if (item.HasChildNodes)
  248. MakeTopics((XmlElement)item, refresh, Boolean.Parse(item.GetAttributeValue("multiThread", multiThread.ToString())), maxThreads);
  249. // Traitement d'un topic
  250. if (item.Name.Equals("topic") || item.Name.Equals("subtopic"))
  251. {
  252. // dans le cadre du Touch il faut passer l'id et non l'item...
  253. var topic = new TopicImplementation((XmlElement)item);
  254. // note: Tout ce passe ici pour la synchro
  255. if (multiThread == false)
  256. {
  257. MakeTopic(topic, refresh, null);
  258. }
  259. else
  260. {
  261. if (topic.DynamicDelay.Equals(TimeSpan.Zero))
  262. {
  263. doneTopics.Add(new ManualResetEvent(false));
  264. ThreadPool.QueueUserWorkItem
  265. (
  266. MakeTopic, new object[]
  267. {
  268. topic,
  269. refresh,
  270. doneTopics[doneTopics.Count - 1]
  271. });
  272. // Limitation WaitAll à 64
  273. if (doneTopics.Count == maxThreads)
  274. {
  275. WaitHandle.WaitAll(doneTopics.ToArray());
  276. doneTopics.Clear();
  277. }
  278. }
  279. else if (_dynamicTopicList.Contains(topic.Id) == false)
  280. {
  281. var dynamicMakeTopicThread = new Thread(MakeTopicFromThread);
  282. dynamicMakeTopicThread.IsBackground = true;
  283. dynamicMakeTopicThread.Name = String.Format("MakeTopics:{0}", topic.Id);
  284. dynamicMakeTopicThread.Start(topic);
  285. _dynamicTopicList.Add(topic.Id);
  286. }
  287. }
  288. }
  289. }
  290. }
  291. }
  292. finally
  293. {
  294. // Attente fin de traitement de tous les topics d'un même niveau
  295. if (doneTopics.Count > 0)
  296. WaitHandle.WaitAll(doneTopics.ToArray());
  297. }
  298. }
  299. /// <summary>
  300. /// Rate a media.
  301. /// </summary>
  302. /// <param name="topicImplementation">Topic implementation.</param>
  303. /// <param name="newsId">Id of the owner news.</param>
  304. /// <param name="mediaId">Id of the media.</param>
  305. /// <param name="rate">Rate value.</param>
  306. ///
  307. public override string Rate(TopicImplementation topicImplementation, string productId, string newsId, string mediaId, float rate, string device)
  308. {
  309. //en cours
  310. double realRate = rate;
  311. int votes;
  312. // Vérification site
  313. if (_sites == null)
  314. new Rating(rate, "Invalid site value.", 1).ToString();
  315. lock (_sites)
  316. {
  317. // Récupération des votes
  318. GetRating(string.Format("SELECT SUM(votes) AS votes, SUM(rating) AS rating FROM Ratings2 WHERE mediaId='{0}' and productId='{1}' GROUP BY mediaId", mediaId, productId), ref realRate, out votes);
  319. // Vote
  320. foreach (var sqlProcessor in _sqlProcessorList)
  321. sqlProcessor.Add(new SqlMediaRateRequest(productId, topicImplementation.Id, newsId, mediaId, topicImplementation.Lang, rate, device));
  322. }
  323. return new Rating(rate, realRate, votes).ToString();
  324. }
  325. /// <summary>
  326. /// Rate a media.
  327. /// </summary>
  328. /// <param name="topicImplementation">Topic implementation</param>
  329. /// <param name="topicId">Id of the owner topic.</param>
  330. /// <param name="newsId">Id of the owner news.</param>
  331. /// <param name="rate">Rate value.</param>
  332. ///
  333. public override string Rate(TopicImplementation topicImplementation, string productId, string newsId, float rate, string device)
  334. {
  335. double realRate = rate;
  336. int votes;
  337. // Vérification site
  338. if (_sites == null)
  339. new Rating(rate, "Invalid site value.", 1).ToString();
  340. lock (_sites)
  341. {
  342. // Récupération des votes
  343. GetRating(string.Format("SELECT SUM(votes) AS votes, SUM(rating) AS rating FROM Ratings2 WHERE newsId='{0}' AND mediaId IS NULL AND producId='{1}' GROUP BY newsId", newsId, productId), ref realRate, out votes);
  344. // Vote
  345. foreach (var sqlProcessor in _sqlProcessorList)
  346. {
  347. sqlProcessor.Add(new SqlNewsRateRequest(productId, topicImplementation.Id, newsId, topicImplementation.Lang, rate, device));
  348. #if DEBUG && TRACE_REQUEST
  349. Process.Trace(string.Format(" productId {0} topicId {1} newsId {2} lang {3} rating {4} device {5} ", productId, topicImplementation.Id, newsId, topicImplementation.Lang, rate, device), System.Diagnostics.EventLogEntryType.Information);
  350. #endif
  351. }
  352. }
  353. return new Rating(rate, realRate, votes).ToString();
  354. }
  355. /// <summary>
  356. /// Appel via WCF pour connaitre le vote sur un article ou une photo
  357. /// </summary>
  358. /// <param name="productId"></param>
  359. /// <param name="topicId"></param>
  360. /// <param name="newsId"></param>
  361. /// <param name="mediaId"></param>
  362. /// <param name="lang"></param>
  363. /// <param name="rate"></param>
  364. /// <param name="vote"></param>
  365. public override void getRated(string productId, string topicId, string newsId, string mediaId, string lang, out double rate, out int vote)
  366. {
  367. if (_sites == null)
  368. throw new Exception("Invalid Site value");
  369. double realRate = 0;
  370. //int votes;
  371. if (string.IsNullOrEmpty(mediaId) == false)
  372. GetRating(string.Format("SELECT SUM(votes) AS votes, SUM(rating) AS rating FROM Ratings2 WHERE mediaId='{0}' and productId='{1}' GROUP BY mediaId", newsId, productId), ref realRate, out vote);
  373. else
  374. GetRating(string.Format("SELECT SUM(votes) AS votes, SUM(rating) AS rating FROM Ratings2 WHERE newsId='{0}' AND mediaId IS NULL AND productId='{1}' GROUP BY newsId", newsId, productId), ref realRate, out vote);
  375. rate = realRate;
  376. //return realRate;
  377. }
  378. //Encours GetMostViewed
  379. /// <summary>
  380. /// donne la liste des plus vus pour ce serveur...
  381. /// </summary>
  382. /// <param name="lstId"></param>
  383. /// <param name="productId"></param>
  384. /// <returns></returns>
  385. public override string GetMostViewed(string lstId, string productId, string topicId, TimeSpan MaxAge, int MaxEntries)
  386. {
  387. throw new NotImplementedException();
  388. }
  389. /// <summary>
  390. /// Donne la listes des medias les plus votés
  391. /// </summary>
  392. /// <param name="lstId"></param>
  393. /// <param name="productId"></param>
  394. /// <returns></returns>
  395. public override string GetHeartRatedList(string lstId, string productId, string topicId, TimeSpan MaxAge, int MaxEntries, string lang )
  396. {
  397. string sqlLang;
  398. if (string.IsNullOrEmpty(lang))
  399. {
  400. sqlLang = "";
  401. }
  402. else
  403. {
  404. sqlLang = string.Format(" AND [lang] = '{0}' ", lang);
  405. }
  406. string query = string.Format(
  407. "SELECT lang, topicId, newsId, MAX([rating]/[votes]) AS averageRating, SUM([votes]) AS votes " +
  408. "FROM [Ratings2] WHERE NOT [mediaId] IS NULL AND [dateUpdated] > CONVERT(datetime, '{0}', 120) " +
  409. "AND [productId]='{1}' {2} GROUP BY lang, topicId, newsId ORDER BY [averageRating] DESC, [votes] DESC",
  410. DateTime.UtcNow.Subtract(MaxAge).ToString("yyyy-MM-dd"), productId, sqlLang );
  411. //en cours
  412. #if DEBUG && TRACE_REQUEST
  413. Process.Trace(query, "GetHeartRatedList", System.Diagnostics.EventLogEntryType.Information);
  414. #endif
  415. return TopicBuildRated(query, topicId, MaxEntries, new StorageServer(), false);
  416. }
  417. /// <summary>
  418. /// Donne la liste les Articles les mieux votés
  419. /// </summary>
  420. /// <param name="lstId"></param>
  421. /// <param name="productId"></param>
  422. /// <returns></returns>
  423. public override string GetArticleRatedList(string lstId, string productId, string topicId, TimeSpan MaxAge, int MaxEntries, string lang )
  424. {
  425. #if DEBUG && DEBUGRATEDLIST
  426. System.Diagnostics.Debugger.Break();
  427. #endif
  428. string sqlLang ;
  429. if (string.IsNullOrEmpty(lang))
  430. {
  431. sqlLang = "";
  432. }
  433. else
  434. {
  435. sqlLang = string.Format(" AND [lang] = '{0}' ", lang);
  436. }
  437. string query = string.Format(
  438. "SELECT lang, topicId, newsId, MAX([rating]/[votes]) AS averageRating, SUM([votes]) AS votes " +
  439. "FROM [Ratings2] WHERE [mediaId] IS NULL AND [dateUpdated] > CONVERT(datetime, '{0}', 120) " +
  440. "AND [productId]='{1}' {2} GROUP BY lang, topicId, newsId ORDER BY [averageRating] DESC, [votes] DESC"
  441. , DateTime.UtcNow.Subtract(MaxAge).ToString("yyyy-MM-dd"), productId ,sqlLang );
  442. //en cours
  443. #if DEBUG && TRACE_REQUEST
  444. Process.Trace(query, "GetArticleRatedList", System.Diagnostics.EventLogEntryType.Information);
  445. #endif
  446. return TopicBuildRated(query, topicId, MaxEntries, new StorageServer(), false);
  447. }
  448. private void getDegMinSec(string value, ref int deg ,ref int min , ref int sec)
  449. {
  450. float Valeur = value.toFloat(0f) ;
  451. deg = (int) Math.Truncate(Valeur);
  452. Valeur = (Valeur - (float) deg ) * 60f;
  453. min = (int)Math.Truncate(Valeur);
  454. Valeur = (Valeur - (float)min) * 60f;
  455. sec = (int)Math.Truncate(Valeur);
  456. }
  457. public override string GetAroundMe(string latitude, string longitude, string range ,int MaxEntries, string lang )
  458. {
  459. //ttot
  460. // Determination de la plage
  461. /* int degLat = 0;
  462. int minLat = 0;
  463. int secLat = 0;
  464. int degLong = 0;
  465. int minLong = 0;
  466. int secLong = 0;
  467. */
  468. string sWhere = " where ";
  469. string sWhereLatitudeSup ="" ;
  470. string sWhereLatitudeInf ="" ;
  471. string sWhereLongitudeSup ="" ;
  472. string sWhereLongitudeInf ="" ;
  473. Decimal oLat = latitude.toDecimal(0m);
  474. Decimal oLong = longitude.toDecimal(0m);
  475. Sexagesimal sRange = new Sexagesimal (range, true);
  476. Decimal Valeur = range.toDecimal(0m) / 111.195m;
  477. Decimal latitudeBornesup ;
  478. Decimal latitudeBorneInf ;
  479. latitudeBornesup = oLat + Valeur ;
  480. if( latitudeBornesup > 90m)
  481. {
  482. // il faut découper
  483. sWhereLatitudeSup = string.Format(" latitude < 90 or ( latitude > {0:0.########} and latitude <90 and longitude >-180 and longitude <180) ", 90m - (latitudeBornesup - 90m));
  484. }
  485. else
  486. {
  487. sWhereLatitudeSup = string.Format(" latitude < {0:0.########} ", latitudeBornesup.ToString("G",CultureInfo.InvariantCulture) );
  488. }
  489. latitudeBorneInf = oLat - Valeur ;
  490. if ( latitudeBorneInf <-90m)
  491. {
  492. // il faut découper
  493. sWhereLatitudeInf = string.Format (" latitude > -90 or ( latitude < {1} and latitude >-90 and longitude >-180 and longitude <180) ", -90m +(latitudeBornesup -90m) );
  494. }
  495. else
  496. {
  497. sWhereLatitudeInf = string.Format(" latitude > {0:0.########}", latitudeBorneInf.ToString("G", CultureInfo.InvariantCulture));
  498. }
  499. Decimal longitudeBordSup ;
  500. Decimal longitudeBordInf;
  501. longitudeBordSup = oLong + Valeur ;
  502. longitudeBordInf = oLong - Valeur ;
  503. if( longitudeBordSup > 180m )
  504. {
  505. // on a dépasser le bord de la terre on tombe... ha non c'est rond.
  506. sWhereLongitudeSup = string.Format(" (longitude < {0:0.########} or (longitude > -180 and longitude < {1:0.########} ) ", longitudeBordSup.ToString("G", CultureInfo.InvariantCulture), -180m + (longitudeBordSup - 180m));
  507. }
  508. else
  509. {
  510. sWhereLongitudeSup = string.Format(" longitude < {0:0.########} ", longitudeBordSup.ToString("G", CultureInfo.InvariantCulture));
  511. }
  512. if(longitudeBordInf <-180m )
  513. {
  514. sWhereLongitudeSup = string.Format(" (longitude > {0:0.########} or (longitude > {1:0.########} and longitude < 180 ) ", longitudeBordSup.ToString("G", CultureInfo.InvariantCulture), 180m - (longitudeBordInf - 180m));
  515. }
  516. else
  517. {
  518. sWhereLongitudeInf = string.Format(" longitude > {0:0.########}", longitudeBordInf.ToString("G", CultureInfo.InvariantCulture));
  519. }
  520. sWhere = string.Format ("{4} {0} and {1} and {2} and {3}" , sWhereLatitudeInf , sWhereLatitudeSup , sWhereLongitudeInf ,sWhereLongitudeSup , sWhere );
  521. string query = string.Format(
  522. "SELECT * from Localization {0} ", sWhere );
  523. if (!string.IsNullOrEmpty(lang))
  524. {
  525. query = string.Format("{0} and lang='{1}'", query, lang);
  526. }
  527. #if DEBUG && TRACEAROUND
  528. Process.Trace(query, System.Diagnostics.EventLogEntryType.Information);
  529. #endif
  530. return TopicBuildAround(query,new StorageServer() , MaxEntries );
  531. }
  532. /// <summary>
  533. /// Trace viewed.
  534. /// </summary>
  535. /// <param name="topicImplementation"></param>
  536. /// <param name="productId"></param>
  537. /// <param name="newsId"></param>
  538. /// <param name="mediaId"></param>
  539. /// <param name="device"></param>
  540. public override void InsertViewed(TopicImplementation topicImplementation, string productId, string newsId, string mediaId, string device)
  541. {
  542. #if DEBUG && DEBUGINSERT
  543. System.Diagnostics.Debugger.Break();
  544. #endif
  545. // Insert viewed
  546. foreach (var sqlProcessor in _sqlProcessorList)
  547. sqlProcessor.Add(new SqlNewsViewed(productId, topicImplementation.Id, newsId, mediaId, topicImplementation.Lang, device));
  548. }
  549. private XslCompiledTransform GetXsltCT(string path)
  550. {
  551. lock (_Xslt)
  552. {
  553. if (!_Xslt.ContainsKey(path))
  554. {
  555. XslCompiledTransform newX = new XslCompiledTransform(System.Diagnostics.Debugger.IsAttached);
  556. newX.Load(path);
  557. _Xslt.Add(path, newX);
  558. }
  559. }
  560. return (XslCompiledTransform)_Xslt[path];
  561. }
  562. private string GetMediaName(string href, TopicImplementation topic)
  563. {
  564. var pattern = topic["mediaNamePattern"];
  565. var regEx = new Regex((string.IsNullOrEmpty(pattern)) ? "(.)*" : pattern);
  566. return regEx.Match(Path.GetFileNameWithoutExtension(href)).ToString();
  567. }
  568. public void GetRating(string query, ref double rate, out int votes)
  569. {
  570. // Valeur par défaut
  571. votes = 0;
  572. // Ajout du rating
  573. foreach (var processor in _sqlProcessorList)
  574. using (var sqlRatingReader = new SqlDataAdapter(query, processor.ConnectionString))
  575. {
  576. using (var sqlRatingTable = new DataTable())
  577. {
  578. try
  579. {
  580. sqlRatingReader.Fill(sqlRatingTable);
  581. }
  582. catch
  583. {
  584. continue;
  585. }
  586. if (sqlRatingTable.Rows.Count == 0)
  587. votes = 0;
  588. else
  589. {
  590. votes = ((int)sqlRatingTable.Rows[0]["votes"] + 1);
  591. rate = ((double)sqlRatingTable.Rows[0]["rating"] + rate) / votes;
  592. }
  593. break;
  594. }
  595. }
  596. }
  597. private void MakeTopic(object stateInfo)
  598. {
  599. MakeTopic((TopicImplementation)((object[])stateInfo)[0], (bool)((object[])stateInfo)[1], (ManualResetEvent)((object[])stateInfo)[2]);
  600. }
  601. private void MakeTopic(TopicImplementation topic, bool refresh, ManualResetEvent doneEvent)
  602. {
  603. var storage = new StorageServer();
  604. #if DBG_PERFORMANCE_TRACE
  605. var timer = new System.Diagnostics.Stopwatch();
  606. // Démarage compteur
  607. timer.Start();
  608. if (_levelTrace.TraceTimeMakeTopic == true )
  609. {
  610. Process.Trace(string.Format(" Start Processing {0} at {1}", topic.Id, DateTime.Now), System.Diagnostics.EventLogEntryType.Information);
  611. }
  612. #endif
  613. try
  614. {
  615. // Traitement des différents type de topic
  616. switch (topic.Type)
  617. {
  618. case TopicImplementation.TopicType.heart:
  619. case TopicImplementation.TopicType.rated:
  620. // Construction du topic et stockage
  621. // TO DO a reprendre et a tester...
  622. XmlDocument topicRated = new XmlDocument();
  623. topicRated.LoadXml(TopicBuildRated(topic, storage, refresh));
  624. using (var storageTopicFile = storage.Store(Constants._storageTopicFormatName, Key, string.Format("{0}.xml", topic.Id)))
  625. topicRated.Save(storageTopicFile);
  626. break;
  627. case TopicImplementation.TopicType.videorama:
  628. case TopicImplementation.TopicType.standard:
  629. // Récupération du fichier index NewsML
  630. NewsML index = TopicLoadDocument(topic, storage);
  631. #if DBG_PERFORMANCE_TRACE
  632. if (_levelTrace.TraceTimeMakeTopic == true)
  633. {
  634. Process.Trace(string.Format("TopicLoadDocument for topicId '{0}' processed after {1} seconds.", topic.Id, timer.ElapsedMilliseconds / 1000), System.Diagnostics.EventLogEntryType.SuccessAudit);
  635. }
  636. #endif
  637. // Transformation du document et stockage
  638. if (index != null)
  639. {
  640. String topicContent = TopicBuildStandard(index, topic, storage, topic.MaxEntries, refresh);
  641. #if DBG_PERFORMANCE_TRACE
  642. if (_levelTrace.TraceTimeMakeTopic == true)
  643. {
  644. Process.Trace(string.Format("TopicBuildStandard for topicId '{0}' processed after {1} seconds.", topic.Id, timer.ElapsedMilliseconds / 1000), System.Diagnostics.EventLogEntryType.SuccessAudit);
  645. }
  646. #endif
  647. if (String.IsNullOrEmpty(topicContent) == false)
  648. {
  649. Stream output = storage.Store(Constants._storageTopicFormatName, Key, string.Format("{0}.xml", topic.Id));
  650. if (output != null)
  651. {
  652. TextWriter wr = new StreamWriter(output, Encoding.UTF8);
  653. wr.Write(topicContent);
  654. wr.Flush();
  655. output.Close();
  656. }
  657. }
  658. }
  659. break;
  660. case TopicImplementation.TopicType.buildedvideorama:
  661. // Construction du topic et stockage
  662. var topicVideorama = TopicBuildVideorama(topic, storage, refresh);
  663. using (var storageTopicFile = storage.Store(Constants._storageTopicFormatName, Key, string.Format("{0}.xml", topic.Id)))
  664. topicVideorama.Save(storageTopicFile);
  665. break;
  666. /* case TopicImplementation.TopicType.magazin:
  667. case TopicImplementation.TopicType.diaporama:
  668. var indexd = TopicLoadDocument(topic, storage);
  669. if (indexd != null)
  670. {
  671. String topicContent = TopicBuildMagazin(indexd, topic, storage, topic.MaxEntries, refresh,"");
  672. #if DBG_PERFORMANCE_TRACE
  673. if (_levelTrace.TraceTimeMakeTopic == true)
  674. {
  675. Process.Trace(string.Format("TopicBuildStandard for topicId '{0}' processed after {1} seconds.", topic.Id, timer.ElapsedMilliseconds / 1000), System.Diagnostics.EventLogEntryType.SuccessAudit);
  676. }
  677. #endif
  678. if (String.IsNullOrEmpty(topicContent) == false)
  679. {
  680. Stream output = storage.Store(Constants._storageTopicFormatName, Key, string.Format("{0}.xml", topic.Id));
  681. if (output != null)
  682. {
  683. TextWriter wr = new StreamWriter(output, Encoding.UTF8);
  684. wr.Write(topicContent);
  685. wr.Flush();
  686. output.Close();
  687. }
  688. }
  689. }
  690. break;*/
  691. case TopicImplementation.TopicType.alert:
  692. //TODO implementer fonction alert
  693. break;
  694. case TopicImplementation.TopicType.diaporama:
  695. case TopicImplementation.TopicType.magazin:
  696. if (topic.IsSubTopic() == false)
  697. TopicLoadTableAndDoneTopics(topic, storage);
  698. else
  699. {
  700. // cas de l'update d'un topic spé Ipad de merde...
  701. NewsML index1 = TopicLoadDocument(topic, storage);
  702. // Transformation du document et stockage
  703. if (index1 != null)
  704. {
  705. String topicContent = TopicBuildStandard(index1, topic, storage, topic.MaxEntries, refresh);
  706. if (String.IsNullOrEmpty(topicContent) == false)
  707. {
  708. Stream output = storage.Store(Constants._storageTopicFormatName, Key, string.Format("{0}.xml", topic.Id));
  709. if (output != null)
  710. {
  711. TextWriter wr = new StreamWriter(output, Encoding.UTF8);
  712. wr.Write(topicContent);
  713. wr.Flush();
  714. output.Close();
  715. }
  716. }
  717. }
  718. }
  719. break;
  720. }
  721. }
  722. catch (ThreadAbortException)
  723. {
  724. }
  725. catch (Exception e)
  726. {
  727. Process.Trace(string.Format("Can't process topic {0}", topic.Id), e.ToString(), System.Diagnostics.EventLogEntryType.Error);
  728. this.Set("Topic process error", MessageSection.Processing.ToString(), System.Diagnostics.EventLogEntryType.Warning);
  729. }
  730. finally
  731. {
  732. #if DBG_PERFORMANCE_TRACE
  733. timer.Stop();
  734. if (_levelTrace.TraceTimeMakeTopic == true)
  735. {
  736. Process.Trace(string.Format("Topic '{0}' processed in {1} seconds.", topic.Id, timer.ElapsedMilliseconds / 1000), System.Diagnostics.EventLogEntryType.SuccessAudit);
  737. }
  738. #endif
  739. }
  740. // Attente fin des traitements
  741. if (doneEvent != null)
  742. doneEvent.Set();
  743. }
  744. private void MakeTopicFromThread(object state)
  745. {
  746. while (true)
  747. try
  748. {
  749. // Traitement
  750. MakeTopic((TopicImplementation)state, false, null);
  751. // Pause dynamique
  752. Thread.Sleep(((TopicImplementation)state).DynamicDelay);
  753. }
  754. catch (ThreadAbortException)
  755. {
  756. }
  757. }
  758. private void NewsBuildHtml(XmlElement extensions, XmlDocument news, TopicImplementation topic, string uno, StorageServer storage)
  759. {
  760. // Stockage et transformation de la news au format html
  761. if (String.IsNullOrEmpty((string)topic["htmlModel"]) == false)
  762. {
  763. using (var storageHtmlNews = storage.Store(Constants._storageNewsFormatName, Key, string.Format("{0}.htm", uno)))
  764. {
  765. XslCompiledTransform transform = GetXsltCT((string)topic["htmlModel"]);
  766. XsltArgumentList arguments = new XsltArgumentList();
  767. arguments.AddParam("NewsExtension", String.Empty, extensions);
  768. arguments.AddParam("Version", string.Empty, Version);
  769. arguments.AddParam("ImageActive", string.Empty, Convert.ToBoolean ( ImageActive )) ;
  770. transform.Transform(news, arguments, storageHtmlNews);
  771. }
  772. }
  773. }
  774. /// <summary>
  775. ///
  776. /// </summary>
  777. /// <param name="doc">Noeud ou on rajoute l'attribut</param>
  778. /// <param name="name">Nom de l'attribut</param>
  779. /// <param name="value">Valeur </param>
  780. /// <returns></returns>
  781. public XmlAttribute createAttribute(XmlDocument doc, String name, String value)
  782. {
  783. XmlAttribute attr = doc.CreateAttribute(name);
  784. attr.Value = value;
  785. return attr;
  786. }
  787. void appendXmlDateAttribute(XmlElement element, XmlDocument doc, String name, DateTime? dt)
  788. {
  789. if (dt != null && dt.HasValue)
  790. {
  791. String dtStr = XmlConvert.ToString(dt.Value, XmlDateTimeSerializationMode.RoundtripKind);
  792. element.Attributes.Append(createAttribute(doc, name, dtStr));
  793. }
  794. }
  795. private XmlElement NewsExtendDocument(XmlDocument news, List<Media> photoList, List<Media> documentsList, TopicImplementation topic, string uno, StorageServer storage, int XsltVersion)
  796. {
  797. XmlElement NewsExtension;
  798. Int16 pos = 0;
  799. Int16 previewB = 0;
  800. NewsExtension = news.CreateElement("NewsExtension");
  801. //NewsExtension.Attributes.Append(createAttribute(news, "id", topic.Id));
  802. if (topic.Id.Contains("__"))
  803. NewsExtension.Attributes.Append(createAttribute(news, "id", string.Format("{0:X}", topic.Id.Substring(topic.Id.IndexOf("__") + 2).MyGetHashCode())));
  804. else
  805. NewsExtension.Attributes.Append(createAttribute(news, "id", string.Format("{0:X}",topic.Id.MyGetHashCode())));
  806. //BUG le bon id commence par topic.Id.Substring(topic.Id.IndexOf("__")+2).MyGetHashCode()
  807. NewsExtension.Attributes.Append(createAttribute(news, "uno", uno));
  808. if (topic.UseBase64 == false)
  809. {
  810. NewsExtension.Attributes.Append(createAttribute(news, "DontUseDataUrl", "1"));
  811. }
  812. //NewsExtension.Attributes.Append(createAttribute(news, "Version", XsltVersion.ToString() ));
  813. // Traitement des dates
  814. if (XsltVersion == 1)
  815. {
  816. // on reste avec l'ancien traitement on ne sait jamais
  817. appendXmlDateAttribute(NewsExtension, news, "dateAndTime", news.DocumentElement.FindDate("/NewsML/NewsEnvelope/DateAndTime"));
  818. appendXmlDateAttribute(NewsExtension, news, "firstCreated", news.DocumentElement.FindDate("/NewsML/NewsItem/NewsManagement/FirstCreated"));
  819. appendXmlDateAttribute(NewsExtension, news, "thisRevisionCreated", news.DocumentElement.FindDate("/NewsML/NewsItem/NewsManagement/ThisRevisionCreated"));
  820. }
  821. else
  822. {
  823. NewsExtension.Attributes.Append(createAttribute(news, "dateAndTime", news.DocumentElement.FindDateToXmlUtcString("/NewsML/NewsEnvelope/DateAndTime")));
  824. NewsExtension.Attributes.Append(createAttribute(news, "firstCreated", news.DocumentElement.FindDateToXmlUtcString("/NewsML/NewsItem/NewsManagement/FirstCreated")));
  825. NewsExtension.Attributes.Append(createAttribute(news, "thisRevisionCreated", news.DocumentElement.FindDateToXmlUtcString("/NewsML/NewsItem/NewsManagement/ThisRevisionCreated")));
  826. }
  827. // Traitement des photos
  828. XmlElement ContainerNewsComponent = null ;
  829. string mediaCurrentId ="";
  830. Boolean newMediaId = false;
  831. foreach (Media media in photoList)
  832. {
  833. //XmlElement NewsComponent1 = news.CreateElement("NewsComponent");
  834. if (mediaCurrentId != media.Duid)
  835. {
  836. newMediaId = true;
  837. mediaCurrentId = media.Duid;
  838. }
  839. if (XsltVersion > 1 && newMediaId == true )
  840. {
  841. ContainerNewsComponent = news.CreateElement("NewsComponent");
  842. NewsExtension.AppendChild(ContainerNewsComponent);
  843. pos = 0; previewB = 0;
  844. newMediaId = false;
  845. }
  846. XmlElement NewsComponent;
  847. NewsComponent = news.CreateElement("NewsComponent");
  848. if (XsltVersion > 1)
  849. {
  850. ContainerNewsComponent.AppendChild(NewsComponent);
  851. }
  852. else
  853. {
  854. NewsExtension.AppendChild(NewsComponent);
  855. }
  856. //favori : Ici sont passées les Parametres...
  857. //NewsExtension.Attributes.Append(createAttribute(news, "uno", uno));
  858. if (XsltVersion == 1)
  859. {
  860. NewsComponent.Attributes.Append(createAttribute(news, "duid", media.Duid));
  861. NewsComponent.Attributes.Append(createAttribute(news, "hduid", string.Format("#{0}", media.Duid)));
  862. }
  863. else
  864. {
  865. if (pos == 0)
  866. {
  867. ContainerNewsComponent.Attributes.Append(createAttribute(news, "duid", media.Duid));
  868. ContainerNewsComponent.Attributes.Append(createAttribute(news, "huid", string.Format("#{0}", media.AbsoluteWebPath)));
  869. }
  870. pos += 1;
  871. }
  872. // insertion de la preview
  873. if (media.Role.Equals( _PreviewRole, StringComparison.InvariantCultureIgnoreCase ))
  874. {
  875. ContainerNewsComponent.Attributes.Append(createAttribute(news, "preview", string.Format("{0}", media.AbsoluteWebPath)));
  876. previewB += 1;
  877. }
  878. NewsComponent.Attributes.Append(createAttribute(news, "role", media.Role));
  879. // est-ce une video
  880. Boolean video= false;
  881. if (media.Role.ToLower() == "iformat" || media.Role.ToLower() == "video" || media.AbsoluteWebPath.EndsWith("mp4"))
  882. {
  883. NewsComponent.Attributes.Append(createAttribute(news, "video", "1"));
  884. video = true;
  885. }
  886. else
  887. {
  888. NewsComponent.Attributes.Append(createAttribute(news, "video", "0"));
  889. video = false;
  890. }
  891. if (topic.UseBase64 == true )
  892. {
  893. NewsComponent.Attributes.Append(createAttribute(news, "href", string.Format("{0}/{1}/{2}/{3}/{4}",
  894. topic.ProductServiceName,
  895. _storagePhotosFormatName,
  896. Key,
  897. Storage.StorageServer.GetHashFolder(media.Name),
  898. media.Name.UrlEncode()
  899. )
  900. ));
  901. }
  902. else
  903. {
  904. NewsComponent.Attributes.Append(createAttribute(news, "href", media.AbsoluteWebPath));
  905. }
  906. NewsComponent.Attributes.Append(createAttribute(news, "width", media.Width));
  907. NewsComponent.Attributes.Append(createAttribute(news, "height", media.Height));
  908. // Ecriture fichier encodé
  909. if (topic.UseBase64 && video == false)
  910. {
  911. if (storage.Exists(_storagePhotosFormatName, Key, media.Name))
  912. {
  913. using (var file = storage.Restore("Photos", Key, media.Name, true))
  914. {
  915. NewsComponent.InnerText = StorageServer.FileToBase64(file);
  916. }
  917. }
  918. }
  919. else
  920. {
  921. // NewsComponent.InnerText = media.AbsoluteWebPath;
  922. }
  923. }
  924. // on va maintenant prendre la liste des documents
  925. if (XsltVersion > 1)
  926. {
  927. XmlElement NewsComponent1 = news.CreateElement("NewsComponent");
  928. ((XmlElement)NewsComponent1).SetAttribute("role", "document");
  929. foreach (Media media in documentsList)
  930. {
  931. XmlElement docNewsComponent = news.CreateElement("NewsComponent");
  932. // NewsExtension.AppendChild(docNewsComponent);
  933. docNewsComponent.Attributes.Append(createAttribute(news, "duid", media.Duid));
  934. docNewsComponent.Attributes.Append(createAttribute(news, "role", "document"));
  935. docNewsComponent.Attributes.Append(createAttribute(news, "href", media.AbsoluteWebPath));
  936. NewsComponent1.AppendChild(docNewsComponent);
  937. }
  938. NewsExtension.AppendChild(NewsComponent1);
  939. }
  940. /* Process.Trace(" News Extension ",
  941. string.Format("version {0} ", XsltVersion),
  942. System.Diagnostics.EventLogEntryType.Information);
  943. */
  944. return NewsExtension;
  945. }
  946. private News NewsLoadDocument(NewsComponent newsComponent, TopicImplementation topic, StorageServer storage, DateTime dateReference)
  947. {
  948. return NewsLoadDocument(((NewsItemRef)newsComponent.Items[0]).NewsItem, topic, storage, dateReference);
  949. }
  950. private News NewsLoadDocument(String newsItemRef, TopicImplementation topic, StorageServer storage, DateTime dateReference)
  951. {
  952. String fileName = Path.GetFileName(newsItemRef);
  953. StorageFileInfo storedNewsInfo = storage.Info(Constants._storageNewsFormatName, Key, fileName);
  954. News news = new News(Path.GetFileNameWithoutExtension(fileName));
  955. Boolean srcNewsExists = false;
  956. String livraisonNewsPath = string.Empty;
  957. DateTime? ThisRevisionCreated;
  958. news.State = News.NewsState.New;
  959. try
  960. {
  961. // Recherche de la news
  962. foreach (var directoryName in topic.Folders)
  963. {
  964. livraisonNewsPath = Path.Combine(directoryName, newsItemRef);
  965. srcNewsExists = StorageServer.FileExists(livraisonNewsPath);
  966. if (srcNewsExists)
  967. {
  968. news.LastModificationDate = File.GetLastWriteTime(livraisonNewsPath);
  969. break;
  970. }
  971. }
  972. // Détermination de l'état de la news
  973. // News locale présente
  974. if (srcNewsExists)
  975. {
  976. // Ancienne news stockée existe ?
  977. using (var localNewsFile = StorageServer.FileOpen(livraisonNewsPath))
  978. {
  979. if (storedNewsInfo == null)
  980. {
  981. // Nouvelle news
  982. news.Document.Load(localNewsFile);
  983. news.Path = livraisonNewsPath;
  984. news.State = News.NewsState.New;
  985. #if SERVICE
  986. lock (GBLock)
  987. {
  988. AFP.IPhone.Plugins.GetCourseId.GetRefIdSoapClient Client = new AFP.IPhone.Plugins.GetCourseId.GetRefIdSoapClient();
  989. Client.ClientCredentials.Windows.AllowNtlm = true;
  990. news.Uid = Client.GetCourseId(topic.Id, news.Uno);
  991. };
  992. #endif
  993. }
  994. else
  995. {
  996. // La news a-t-elle été modifiée ? et la feuille de style a elle été modifiée?
  997. if (storedNewsInfo.LastModified >= news.LastModificationDate && topic.XsltDate <= storedNewsInfo.LastModified)
  998. {
  999. // La news est ancienne
  1000. news.Document.Load(storedNewsInfo.Path);
  1001. news.State = News.NewsState.Stored;
  1002. try
  1003. {
  1004. news.Uid = Convert.ToInt64(news.Document.SelectSingleNode("NewsML").Attributes["absoluteindex"].Value);
  1005. }
  1006. finally
  1007. {
  1008. }
  1009. }
  1010. else
  1011. {
  1012. // Nouvelle version de la news
  1013. news.Document.Load(localNewsFile);
  1014. news.Path = livraisonNewsPath;
  1015. #if SERVICE
  1016. lock (GBLock)
  1017. {
  1018. /*TO DO appel au service WEB !!! */
  1019. // TO DO a voir à factoriser le client
  1020. AFP.IPhone.Plugins.GetCourseId.GetRefIdSoapClient Client = new AFP.IPhone.Plugins.GetCourseId.GetRefIdSoapClient();
  1021. Client.ClientCredentials.Windows.AllowNtlm = true;
  1022. news.Uid = Client.GetCourseId(topic.Id, news.Uno);
  1023. };
  1024. #endif
  1025. news.State = News.NewsState.New;
  1026. }
  1027. }
  1028. }
  1029. // La news est ancienne
  1030. }
  1031. else
  1032. {
  1033. if (storedNewsInfo == null)
  1034. {
  1035. String Folders = "";
  1036. foreach (string cFolder in topic.Folders)
  1037. {
  1038. Folders = string.Format("{0} ; {1}", cFolder, Folders);
  1039. }
  1040. Process.Trace("Bug Store", string.Format("NO DOCUMENT FOUND {0}-{1}. Folder : {2}", topic.Id, newsItemRef, Folders), System.Diagnostics.EventLogEntryType.Information);
  1041. // La news n'est pas archivée
  1042. news.State = News.NewsState.Invalid;
  1043. }
  1044. else
  1045. {
  1046. //Process.Trace("Bug Store", string.Format("REUSE STORED DOCUMENT {0}-{1}", topic.Id, newsItemRef), System.Diagnostics.EventLogEntryType.Information);
  1047. // La news est archivée
  1048. if (topic.XsltDate <= storedNewsInfo.LastModified)
  1049. {
  1050. news.Document.Load(storedNewsInfo.Path);
  1051. try
  1052. {
  1053. news.Uid = Convert.ToInt64(news.Document.SelectSingleNode("NewsML").Attributes["absoluteindex"].Value);
  1054. }
  1055. finally
  1056. {
  1057. }
  1058. news.State = News.NewsState.Stored;
  1059. }
  1060. else
  1061. {
  1062. // la feuille de style a été modifiée on force le recalcul
  1063. news.Document.Load(storedNewsInfo.Path);
  1064. news.State = News.NewsState.New;
  1065. }
  1066. }
  1067. }
  1068. // Vérification date de validité et transformation éventuelle
  1069. if (news.State != News.NewsState.Invalid)
  1070. {
  1071. if (string.IsNullOrEmpty(topic.NewsXslt) == false)
  1072. {
  1073. using (var newsStream = new MemoryStream())
  1074. {
  1075. // Transformation de la news
  1076. GetXsltCT(topic.NewsXslt).Transform(news.Document, null, newsStream);
  1077. // Récupération
  1078. newsStream.Position = 0;
  1079. news.Document.Load(newsStream);
  1080. }
  1081. }
  1082. //ENCOURS si message alert on la prépare
  1083. if (topic.CanBeAlert)
  1084. {
  1085. // si le document comporte le flag alerte
  1086. // on le rajoute dans la base alerte...
  1087. // avec topicId siteIdn UrlDocument? on l'a ici?
  1088. //
  1089. TopicDeclaration topicDeclaration = new TopicDeclaration(topic.Topic);
  1090. AddAlert(topicDeclaration.Uno, news.Uno, news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/HeadLine"));
  1091. }
  1092. ThisRevisionCreated = news.Document.FindDate("/NewsML/NewsItem/NewsManagement/ThisRevisionCreated");
  1093. if (ThisRevisionCreated.HasValue == false)
  1094. ThisRevisionCreated = news.Document.FindDate("/NewsML/NewsItem/NewsManagement/FirstCreated");
  1095. // Vérification date de validité et transformation éventuelle
  1096. if (ThisRevisionCreated.Value > dateReference)
  1097. {
  1098. #if DEBUG
  1099. Process.Trace("Bug Delivery", string.Format("DOCUMENT IN FUTURE {0}-{1} Date:{2} --> {3}", topic.Id, newsItemRef, ThisRevisionCreated.Value, dateReference), System.Diagnostics.EventLogEntryType.Information);
  1100. #endif
  1101. }
  1102. else
  1103. {
  1104. if (topic.IsDaily == false)
  1105. {
  1106. if (dateReference.ToUniversalTime().Subtract(ThisRevisionCreated.Value).CompareTo(topic.MaxAge) > 0)
  1107. {
  1108. news.State = News.NewsState.Invalid;
  1109. }
  1110. }
  1111. }
  1112. }
  1113. else
  1114. {
  1115. }
  1116. }
  1117. catch (Exception e)
  1118. {
  1119. Process.Trace(string.Format("Can't load news document {0}", newsItemRef), e.ToString(), System.Diagnostics.EventLogEntryType.Error);
  1120. this.Set("News load error", MessageSection.Processing.ToString(), System.Diagnostics.EventLogEntryType.Warning);
  1121. // La news est invalide
  1122. news.State = News.NewsState.Invalid;
  1123. }
  1124. return news;
  1125. }
  1126. private News AnnounceLoadDocument(string Path, TopicImplementation topic, StorageServer storage, DateTime ThisRevisionCreated)
  1127. {
  1128. String FileName = System.IO.Path.GetFileName(Path);
  1129. String NewsItemRef = String.Format("{0}_{1}", topic.Id, FileName);
  1130. StorageFileInfo storedNewsInfo = storage.Info(Constants._storageNewsFormatName, Key, FileName);
  1131. News news = new News(NewsItemRef);
  1132. if (System.IO.File.Exists(Path))
  1133. {
  1134. // on a une annonce a faire !!
  1135. if (storedNewsInfo == null)
  1136. {
  1137. // first !!!
  1138. news.Document.Load(Path);
  1139. news.Path = Path;
  1140. news.State = News.NewsState.New;
  1141. }
  1142. else
  1143. {
  1144. // Stored
  1145. if (File.GetLastWriteTime(storedNewsInfo.Path) >= File.GetLastWriteTime(Path))
  1146. {
  1147. //
  1148. news.Document.Load(storedNewsInfo.Path);
  1149. news.State = News.NewsState.Stored;
  1150. }
  1151. else
  1152. {
  1153. // une mise à jour de l'annonce a été faite !
  1154. news.Document.Load(Path);
  1155. news.Path = Path;
  1156. news.State = News.NewsState.New;
  1157. }
  1158. }
  1159. // on applique eventuellement la XSLT !
  1160. if (string.IsNullOrEmpty(topic.NewsXslt) != true)
  1161. {
  1162. using (var newsStream = new MemoryStream())
  1163. {
  1164. // Transformation de la news
  1165. GetXsltCT(topic.NewsXslt).Transform(news.Document, null, newsStream);
  1166. // Récupération
  1167. newsStream.Position = 0;
  1168. news.Document.Load(newsStream);
  1169. }
  1170. }
  1171. news.LastModificationDate = ThisRevisionCreated;
  1172. news.Document.SelectSingleNode("/NewsML/NewsItem/NewsManagement/FirstCreated").SetDateToXmlUtcString(ThisRevisionCreated);
  1173. news.Document.SelectSingleNode("/NewsML/NewsItem/NewsManagement/ThisRevisionCreated").SetDateToXmlUtcString(ThisRevisionCreated);
  1174. // /NewsML/NewsItem/NewsManagement/FirstCreated
  1175. // /NewsML/NewsItem/NewsManagement/ThisRevisionCreated
  1176. }
  1177. else
  1178. {
  1179. if (storedNewsInfo != null)
  1180. {
  1181. // on supprimer le fichier reference... il faut supprimer du stockage
  1182. try
  1183. {
  1184. System.IO.File.Delete(storedNewsInfo.Path);
  1185. }
  1186. catch
  1187. {
  1188. ;
  1189. }
  1190. news.State = News.NewsState.Invalid;
  1191. }
  1192. }
  1193. return news;
  1194. }
  1195. // calcul des votes...
  1196. public void NewsWriteRating(string query, XmlWriter xmlTopic)
  1197. {
  1198. // Ajout du rating
  1199. if (_sqlProcessorList.Count > 0)
  1200. {
  1201. foreach (var processor in _sqlProcessorList)
  1202. using (var sqlRatingReader = new SqlDataAdapter(query, processor.ConnectionString))
  1203. {
  1204. using (var sqlRatingTable = new DataTable())
  1205. {
  1206. try
  1207. {
  1208. sqlRatingReader.Fill(sqlRatingTable);
  1209. }
  1210. catch
  1211. {
  1212. continue;
  1213. }
  1214. if (sqlRatingTable.Rows.Count == 0)
  1215. {
  1216. xmlTopic.WriteAttributeString("globalRate", "0");
  1217. xmlTopic.WriteAttributeString("numberOfVote", "0");
  1218. }
  1219. else
  1220. {
  1221. xmlTopic.WriteAttributeString("globalRate", Convert.ToString((double)sqlRatingTable.Rows[0]["rating"] / (int)sqlRatingTable.Rows[0]["votes"], System.Globalization.CultureInfo.InvariantCulture));
  1222. xmlTopic.WriteAttributeString("numberOfVote", Convert.ToString(sqlRatingTable.Rows[0]["votes"]));
  1223. }
  1224. break;
  1225. }
  1226. }
  1227. }
  1228. }
  1229. private void AddAlert(string topicUno, string newsId, string Headline)
  1230. {
  1231. // productId, topicId, newsId, mediaId, lang, hit,longitude, lattidute)
  1232. foreach (var sqlProcessor in _sqlProcessorList2)
  1233. {
  1234. sqlProcessor.Add(new SqlAlertServiceProduction(topicUno , newsId, Headline )) ;
  1235. }
  1236. }
  1237. private bool NewsWriteBySubject(News news, NewsML topicDocument, TopicImplementation topic, XmlWriter xmlTopic, StorageServer storage, NewsMediaFilter mediaFilter, int index, bool writeId, bool refresh, int nbHits, ref string rcatchLine)
  1238. {
  1239. // Traitement de la news
  1240. var mediaPhotoList = new List<Media>();
  1241. var processedComponent = new List<string>();
  1242. var firstComponent = true;
  1243. var textOnly = news.Document.SelectNodes("/NewsML/NewsItem/NewsComponent/NewsComponent/ContentItem/DataContent/p/a[@class='videoSet']").Count == 0 && news.Document.SelectNodes("/NewsML/NewsItem/NewsComponent/NewsComponent[@Duid]").Count == 0;
  1244. String FirstCreated = news.Document.FindDateToXmlUtcString("/NewsML/NewsItem/NewsManagement/FirstCreated");
  1245. String DatePublished = news.Document.FindDateToXmlUtcString("/NewsML/NewsItem/NewsManagement/ThisRevisionCreated");
  1246. if (string.IsNullOrEmpty(FirstCreated) || String.IsNullOrEmpty(DatePublished))
  1247. {
  1248. //TO do une log peut être?
  1249. Process.Trace(string.Format("Empty Date on {0} uno : {1} path : {2}", topic.Id, news.Uno, news.Path), System.Diagnostics.EventLogEntryType.Warning);
  1250. this.Set(string.Format("Empty Date on {0} uno : {1} path : {2}", topic.Id, news.Uno, news.Path), MessageSection.Processing.ToString(), System.Diagnostics.EventLogEntryType.Warning);
  1251. return false;
  1252. }
  1253. // Gestion d'un sujet
  1254. float latitude = 0;
  1255. float longitude = 0;
  1256. string city = "";
  1257. string country = "";
  1258. XmlNode selNode = null;
  1259. selNode = news.Document.SelectSingleNode("/NewsML/NewsItem/NewsComponent/DescriptiveMetadata/Location[@HowPresent='Origin']/Property[@FormalName='Latitude']");
  1260. if ( selNode != null )
  1261. latitude =float.Parse( selNode.GetAttributeValue("Value", "0"), CultureInfo.InvariantCulture) ;
  1262. selNode = news.Document.SelectSingleNode("/NewsML/NewsItem/NewsComponent/DescriptiveMetadata/Location[@HowPresent='Origin']/Property[@FormalName='Longitude']");
  1263. if (selNode != null)
  1264. longitude = float.Parse(selNode.GetAttributeValue("Value", "0"), CultureInfo.InvariantCulture) ;
  1265. selNode = news.Document.SelectSingleNode("/NewsML/NewsItem/NewsComponent/DescriptiveMetadata/Location[@HowPresent='Origin']/Property[@FormalName='City']");
  1266. if (selNode != null)
  1267. city = selNode.GetAttributeValue("City", "" ) ;
  1268. selNode = news.Document.SelectSingleNode("/NewsML/NewsItem/NewsComponent/DescriptiveMetadata/Location[@HowPresent='Origin']/Property[@FormalName='Country']");
  1269. if (selNode != null)
  1270. country = selNode.GetAttributeValue("Country", "");
  1271. // TO do enregistrement de la latitude longitude dans la base ;
  1272. AddDocumentInLocalizedDatabase(topic.ProductServiceName , topic.Id, news.Uno, "", topic.Lang ,latitude, longitude);
  1273. xmlTopic.WriteStartElement("Item");
  1274. {
  1275. // Xafp/Bag/Item
  1276. xmlTopic.WriteAttributeString("type", "multimedia");
  1277. xmlTopic.WriteAttributeString("uno", news.Uno);
  1278. xmlTopic.WriteAttributeString("parentId", topic.Id);
  1279. if (latitude != 0.0 )
  1280. xmlTopic.WriteAttributeString("latitude", latitude.ToString( new CultureInfo(""))) ;
  1281. if (longitude != 0.0)
  1282. xmlTopic.WriteAttributeString("longitude", longitude.ToString ( new CultureInfo("") ) );
  1283. if ( ! string.IsNullOrEmpty(city ))
  1284. xmlTopic.WriteAttributeString("city", city);
  1285. if (!string.IsNullOrEmpty(country ))
  1286. xmlTopic.WriteAttributeString("country",country );
  1287. string pPath ="";
  1288. if (_UseUri )// AbsolutePath or not
  1289. {
  1290. string WebFilePAth = string.Format("{0}/{1}/{2}/{3}.htm",
  1291. Constants._storageNewsFormatName,
  1292. Key,
  1293. AFP.IPhone.Storage.StorageServer.GetHashFolder(string.Format("{0}{1}", news.Uno, ".htm")),
  1294. news.Uno);
  1295. if (topic.UrlWebRacine.EndsWith ("/"))
  1296. pPath = string.Format(@"{0}{1}/{2}", topic.UrlWebRacine, topic.ProductServiceName, WebFilePAth);
  1297. else
  1298. pPath = string.Format(@"{0}/{1}/{2}", topic.UrlWebRacine, topic.ProductServiceName, WebFilePAth);
  1299. //pPath = pPath.Replace("//", "/");
  1300. xmlTopic.WriteAttributeString("href", pPath);
  1301. }
  1302. else
  1303. {
  1304. pPath = String.Format("{0}/{1}/{2}/{3}/{4}{5}",
  1305. topic.ProductServiceName,
  1306. Constants._storageNewsFormatName,
  1307. Key,
  1308. AFP.IPhone.Storage.StorageServer.GetHashFolder(string.Format("{0}{1}", news.Uno, ".htm")),
  1309. news.Uno,
  1310. ".htm");
  1311. xmlTopic.WriteAttributeString("href", pPath );
  1312. }
  1313. //Encours c'est ici qu'on va traiter les alertes
  1314. xmlTopic.WriteAttributeString("revision", news.Document.FindInnerText("/NewsML/NewsItem/Identification/NewsIdentifier/RevisionId"));
  1315. xmlTopic.WriteAttributeString("index", index.ToString());
  1316. xmlTopic.WriteAttributeString("absoluteindex", news.Uid.ToString());
  1317. if (nbHits != -1)
  1318. xmlTopic.WriteAttributeString("numberOfHits", nbHits.ToString());
  1319. // TopicId
  1320. if (writeId)
  1321. xmlTopic.WriteAttributeString("topicId", topic.Id);
  1322. // Ajout du rating
  1323. try
  1324. {
  1325. NewsWriteRating(string.Format("SELECT SUM(votes) AS votes, SUM(rating) AS rating FROM Ratings2 WHERE newsId='{0}' AND mediaId IS NULL GROUP BY newsId", news.Uno), xmlTopic);
  1326. }
  1327. catch (Exception e)
  1328. {
  1329. Process.Trace(string.Format("Can't get rating info for news {0} (source : {1})", news.Uno, topic.Id), e.ToString(), System.Diagnostics.EventLogEntryType.Warning);
  1330. this.Set("Rating access error", MessageSection.Database.ToString(), System.Diagnostics.EventLogEntryType.Warning);
  1331. }
  1332. // Gestion NewsLine
  1333. xmlTopic.WriteStartElement("NewsLines");
  1334. {
  1335. // Xafp/Bag/Item/NewsLines
  1336. xmlTopic.WriteElementString("HeadLine", news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/HeadLine"));
  1337. xmlTopic.WriteElementString("SubHeadLine", news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/SubHeadLine"));
  1338. xmlTopic.WriteElementString("SlugLine", news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/SlugLine"));
  1339. xmlTopic.WriteElementString("DateCreated", FirstCreated);
  1340. xmlTopic.WriteElementString("DatePublished", DatePublished);
  1341. xmlTopic.WriteElementString("DateLine", news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/DateLine"));
  1342. xmlTopic.WriteElementString("CopyRightLine", news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/CopyrightLine"));
  1343. }
  1344. xmlTopic.WriteEndElement();
  1345. // Xafp/Bag/Item/NewsLines
  1346. foreach (XmlElement element in news.Document.SelectNodes("/NewsML/NewsItem/NewsComponent/NewsComponent"))
  1347. {
  1348. XmlElement componentRelative = null;
  1349. ComponentType componentType;
  1350. string photoRef = null;
  1351. string headLine = "";
  1352. // Détermination du type de composante
  1353. if (element.SelectSingleNode("ContentItem/DataContent/p/a[@class='videoSet']") != null)
  1354. {
  1355. componentType = ComponentType.video;
  1356. photoRef = element.FindValue("ContentItem/DataContent/p/a[@class='videoSet']/a[@class='photo']/@href").Substring(1);
  1357. componentRelative = (XmlElement)news.Document.SelectSingleNode(string.Format("/NewsML/NewsItem/NewsComponent/NewsComponent[@Duid='{0}']", photoRef));
  1358. }
  1359. else if (element.HasAttribute("Duid"))
  1360. {
  1361. componentType = ComponentType.photo;
  1362. photoRef = element.GetAttribute("Duid");
  1363. componentRelative = element;
  1364. if (element.SelectSingleNode("NewsLines/HeadLine") != null)
  1365. headLine = element.SelectSingleNode("NewsLines/HeadLine").InnerText;
  1366. }
  1367. else
  1368. componentType = (textOnly) ? ComponentType.text : ComponentType.unsupported;
  1369. // Traitement des composantes supportées
  1370. switch (componentType)
  1371. {
  1372. case ComponentType.text:
  1373. // Traitement d'un bag
  1374. using (var xmlBag = createXmlWriter())
  1375. {
  1376. // Ecriture du bag
  1377. xmlBag.WriteStartElement("Bag");
  1378. {
  1379. // Xafp/Bag/Item/Bag
  1380. var titleLine = news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/NewsLine/NewsLineText[preceding-sibling::NewsLineType[@FormalName='MobileShortTitle']]");
  1381. var catchLine = news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/NewsLine/NewsLineText[preceding-sibling::NewsLineType[@FormalName='CatchLine']]");
  1382. //var OotherC = news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/NewsLine/NewsLineText[preceding-sibling::NewsLineType[@FormalName='CatchLine']]");
  1383. // TitleLine alternatif
  1384. if (String.IsNullOrEmpty(titleLine))
  1385. titleLine = news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/HeadLine");
  1386. // CatchLine alternatif
  1387. if (String.IsNullOrEmpty(catchLine))
  1388. catchLine = news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsComponent[1]/ContentItem/DataContent/p[1]");
  1389. rcatchLine = catchLine;
  1390. // Gestion TitleLine
  1391. if (!String.IsNullOrEmpty(titleLine))
  1392. {
  1393. xmlBag.WriteStartElement("Content");
  1394. {
  1395. // Xafp/Bag/Item/Bag/Content
  1396. xmlBag.WriteAttributeString("type", "Text");
  1397. xmlBag.WriteAttributeString("role", "Title");
  1398. xmlBag.WriteElementString("p", titleLine.ConvertWhitespacesToSingleSpaces().Trim());
  1399. }
  1400. xmlBag.WriteEndElement();
  1401. // Xafp/Bag/Item/Bag/Content
  1402. }
  1403. // Gestion CatchLine
  1404. if (!String.IsNullOrEmpty(catchLine))
  1405. {
  1406. xmlBag.WriteStartElement("Content");
  1407. {
  1408. // Xafp/Bag/Item/Bag/Content
  1409. xmlBag.WriteAttributeString("type", "Text");
  1410. xmlBag.WriteAttributeString("role", "News");
  1411. xmlBag.WriteElementString("p", catchLine.ConvertWhitespacesToSingleSpaces().Trim());
  1412. }
  1413. xmlBag.WriteEndElement();
  1414. // Xafp/Bag/Item/Bag/Content
  1415. }
  1416. }
  1417. xmlBag.WriteEndElement();
  1418. // Xafp/Bag/Item/Bag
  1419. //Ecriture du bag dans la news
  1420. xmlTopic.WriteRaw(xmlBag.ToString());
  1421. }
  1422. break;
  1423. case ComponentType.photo:
  1424. case ComponentType.video:
  1425. // Vérification de traitement déjà effectué (pb video liée à une photo)
  1426. if (!processedComponent.Contains(photoRef))
  1427. {
  1428. var photoName = GetMediaName(componentRelative.FindValue("NewsComponent/ContentItem/MediaType[@FormalName='Photo']/parent::*/@Href"), topic);
  1429. var provider = componentRelative.FindValue("AdministrativeMetadata/Provider/Party/@FormalName");
  1430. var creator = componentRelative.FindValue("AdministrativeMetadata/Creator/Party/@FormalName");
  1431. var bagDefined = false;
  1432. // Photo traitée
  1433. processedComponent.Add(photoRef);
  1434. // Traitement creator
  1435. if (string.IsNullOrEmpty(creator) && componentRelative.SelectNodes("AdministrativeMetadata/Provider/Party").Count > 1)
  1436. creator = componentRelative.FindValue("AdministrativeMetadata/Provider/Party[2]/@FormalName");
  1437. // Traitement d'un bag
  1438. using (var xmlBag = createXmlWriter())
  1439. {
  1440. // Ecriture du bag
  1441. xmlBag.WriteStartElement("Bag");
  1442. {
  1443. // Xafp/Bag/Item/Bag
  1444. // Ecriture du uno
  1445. xmlBag.WriteAttributeString("uno", photoName);
  1446. // Ajout du rating
  1447. try
  1448. {
  1449. NewsWriteRating(string.Format("SELECT SUM(votes) AS votes, SUM(rating) AS rating FROM Ratings2 WHERE mediaId='{0}' GROUP BY mediaId", photoName), xmlBag);
  1450. }
  1451. catch (Exception e)
  1452. {
  1453. Process.Trace(string.Format("Can't get rating info for media {0} (source : {1})", photoName, topic.Id), e.ToString(), System.Diagnostics.EventLogEntryType.Information);
  1454. this.Set("Rating access error", MessageSection.Database.ToString(), System.Diagnostics.EventLogEntryType.Warning);
  1455. }
  1456. // Traitement de la première composante
  1457. if (firstComponent)
  1458. {
  1459. var titleLine = news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/NewsLine/NewsLineText[preceding-sibling::NewsLineType[@FormalName='MobileShortTitle']]");
  1460. var catchLine = news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsLines/NewsLine/NewsLineText[preceding-sibling::NewsLineType[@FormalName='CatchLine']]");
  1461. // CatchLine alternatif
  1462. if (String.IsNullOrEmpty(catchLine))
  1463. catchLine = news.Document.FindInnerText("/NewsML/NewsItem/NewsComponent/NewsComponent[1]/ContentItem/DataContent/p[1]");
  1464. // Gestion TitleLine
  1465. if (!String.IsNullOrEmpty(titleLine))
  1466. {
  1467. xmlBag.WriteStartElement("Content");
  1468. {
  1469. // Xafp/Bag/Item/Bag/Content
  1470. xmlBag.WriteAttributeString("type", "Text");
  1471. xmlBag.WriteAttributeString("role", "Title");
  1472. xmlBag.WriteElementString("p", titleLine.ConvertWhitespacesToSingleSpaces().Trim());
  1473. }
  1474. xmlBag.WriteEndElement();
  1475. // Xafp/Bag/Item/Bag/Content
  1476. }
  1477. rcatchLine = catchLine;
  1478. // Gestion CatchLine
  1479. if (!String.IsNullOrEmpty(catchLine ))
  1480. {
  1481. xmlBag.WriteStartElement("Content");
  1482. {
  1483. // Xafp/Bag/Item/Bag/Content
  1484. xmlBag.WriteAttributeString("type", "Text");
  1485. xmlBag.WriteAttributeString("role", "News");
  1486. xmlBag.WriteElementString("p", catchLine.ConvertWhitespacesToSingleSpaces().Trim());
  1487. }
  1488. xmlBag.WriteEndElement();
  1489. // Xafp/Bag/Item/Bag/Content
  1490. }
  1491. }
  1492. // Gestion HeadLine (Rajout de fonctionnalité 02/2011)
  1493. if (!String.IsNullOrEmpty(headLine))
  1494. {
  1495. xmlBag.WriteStartElement("Content");
  1496. {
  1497. xmlBag.WriteAttributeString("type", "Text");
  1498. xmlBag.WriteAttributeString("role", "Headline");
  1499. xmlBag.WriteElementString("p", headLine.ConvertWhitespacesToSingleSpaces());
  1500. }
  1501. xmlBag.WriteEndElement();
  1502. }
  1503. // Gestion Caption
  1504. xmlBag.WriteStartElement("Content");
  1505. {
  1506. // Xafp/Bag/Item/Bag/Content
  1507. xmlBag.WriteAttributeString("type", "Text");
  1508. xmlBag.WriteAttributeString("role", "Caption");
  1509. xmlBag.WriteAttributeString("provider", provider);
  1510. xmlBag.WriteAttributeString("creator", creator);
  1511. // Caption ou HeadLine si vide
  1512. var documentCaption = componentRelative.FindInnerText("NewsComponent/Role[@FormalName='Caption']/following::DataContent");
  1513. if (string.IsNullOrEmpty(documentCaption))
  1514. xmlBag.WriteElementString("p", componentRelative.FindInnerText("NewsLines/HeadLine"));
  1515. else
  1516. xmlBag.WriteElementString("p", documentCaption);
  1517. }
  1518. xmlBag.WriteEndElement();
  1519. // Xafp/Bag/Item/Bag/Content
  1520. // Gestion des liens photos
  1521. if (!String.IsNullOrEmpty(photoRef))
  1522. foreach (XmlElement content in Configuration.SelectNodes("//contents/photo/content"))
  1523. foreach (var role in content.GetAttributeValue("source", content.GetAttribute("role")).Split(';'))
  1524. try
  1525. {
  1526. var media = (XmlElement)componentRelative.SelectSingleNode(string.Format("NewsComponent[Role[@FormalName='{0}']]", role));
  1527. // Role trouvé ?
  1528. if (media != null && media.FindValue("ContentItem/MediaType/@FormalName").Equals("Photo"))
  1529. {
  1530. String storageMediaName = string.Format("{0}-{1}.jpg", photoName, content.GetAttribute("role"));
  1531. var sourceState = News.NewsState.Invalid;
  1532. var mediaExists = false;
  1533. // Traitement nouveau média
  1534. if ((refresh && !string.IsNullOrEmpty(news.Path)) || news.State == News.NewsState.New)
  1535. {
  1536. mediaExists = StorageServer.FileExists(Path.Combine(Path.GetDirectoryName(news.Path), media.FindValue("ContentItem/@Href")));
  1537. // Source fichier ?
  1538. if (mediaExists)
  1539. sourceState = News.NewsState.New;
  1540. }
  1541. // Média depuis stockage si media pas trouvé ?
  1542. if (!mediaExists)
  1543. {
  1544. mediaExists = storage.Exists(_storagePhotosFormatName, Key, storageMediaName);
  1545. // Source stockage ?
  1546. if (mediaExists)
  1547. sourceState = News.NewsState.Stored;
  1548. else
  1549. if (topic.UseBase64) sourceState = News.NewsState.TemporayInvalid;
  1550. }
  1551. // Traitement du media
  1552. if (mediaExists)
  1553. {
  1554. var mediaWidth = 0;
  1555. var mediaHeight = 0;
  1556. // Transformations et stockage
  1557. switch (sourceState)
  1558. {
  1559. case News.NewsState.New:
  1560. var mediaPath = Path.Combine(Path.GetDirectoryName(news.Path), media.FindValue("ContentItem/@Href"));
  1561. try
  1562. {
  1563. // Traitements
  1564. using (Image photo = Transformations.Photo.Transform(mediaPath, content, role))
  1565. {
  1566. // Stockage du document
  1567. /*using (Stream storageMedia = storage.Store(_storagePhotosFormatName, Key, storageMediaName))
  1568. Transformations.Photo.Save(storageMedia, photo, content);
  1569. */
  1570. string StoragePath = "";
  1571. using (Stream storageMedia = storage.CreateStoreAndGetPath(_storagePhotosFormatName, Key, storageMediaName, out StoragePath))
  1572. Transformations.Photo.Save(storageMedia, photo, content);
  1573. // Récupération height et width
  1574. mediaHeight = photo.Height;
  1575. mediaWidth = photo.Width;
  1576. // Ajout de la photo à la liste pour extension
  1577. string AbsoluteWebPath = "";
  1578. AbsoluteWebPath = string.Format(@"{0}/{1}/{2}", topic.UrlWebRacine, topic.ProductServiceName, storage.Trunc(StoragePath));
  1579. // note : emplacement HD
  1580. mediaPhotoList.Add(
  1581. new Media(
  1582. photoRef,
  1583. content.GetAttribute("role"),
  1584. storageMediaName,
  1585. photo.Width.ToString(),
  1586. photo.Height.ToString(),
  1587. AbsoluteWebPath
  1588. )
  1589. );
  1590. }
  1591. }
  1592. catch (Exception e)
  1593. {
  1594. throw new Exception(string.Format("Photo {0} process error.", mediaPath), e);
  1595. }
  1596. break;
  1597. case News.NewsState.Stored:
  1598. using (Stream storageMedia = storage.Restore(_storagePhotosFormatName, Key, storageMediaName, true))
  1599. {
  1600. using (Image storageMediaImage = Image.FromStream(storageMedia))
  1601. {
  1602. string WebFilePAth = "";
  1603. // Récupération height et width
  1604. string AbsoluteWebPath = "";
  1605. mediaHeight = storageMediaImage.Height;
  1606. mediaWidth = storageMediaImage.Width;
  1607. if (topic.UseBase64 == false)
  1608. {
  1609. WebFilePAth = storage.GetStorageFilePath(_storagePhotosFormatName, Key, storageMediaName);
  1610. AbsoluteWebPath = string.Format(@"{0}/{1}/{2}", topic.UrlWebRacine, topic.ProductServiceName, WebFilePAth);
  1611. }
  1612. // Ajout de la photo à la liste pour extension
  1613. // note emplacement HD
  1614. mediaPhotoList.Add(
  1615. new Media
  1616. (
  1617. photoRef,
  1618. content.GetAttribute("role"),
  1619. storageMediaName,
  1620. storageMediaImage.Width.ToString(),
  1621. storageMediaImage.Height.ToString(),
  1622. AbsoluteWebPath
  1623. ));
  1624. }
  1625. }
  1626. break;
  1627. }
  1628. // Ecriture de l'élément Content
  1629. if (mediaFilter != NewsMediaFilter.videoOnly || componentType == ComponentType.video)
  1630. {
  1631. xmlBag.WriteStartElement("Content");
  1632. {
  1633. // Xafp/Bag/Item/Bag/Content
  1634. xmlBag.WriteAttributeString("type", "Photo");
  1635. xmlBag.WriteAttributeString("role", content.GetAttribute("role"));
  1636. /*
  1637. if (topic.UseBase64)
  1638. xmlBag.WriteAttributeString("href", String.Format("{0}/{1}/{2}", _storagePhotosFormatName, Key, storageMediaName.UrlEncode()));
  1639. else
  1640. {*/
  1641. //xmlBag.WriteAttributeString("href", string.Format(@"{0}\{1}\{2}\{3}\{4}", topic.ProductServiceName, _storagePhotosFormatName, Key, storage.GetHashFolder2(storageMediaName), storageMediaName));
  1642. // V .11 on passe en URL absolue pour les bags (cache à plein régime)
  1643. if (_UseUri)
  1644. {
  1645. string WebFilePAth = storage.GetStorageFilePath(_storagePhotosFormatName, Key, storageMediaName);
  1646. string AbsoluteWebPath = string.Format(@"{0}/{1}/{2}", topic.UrlWebRacine, topic.ProductServiceName, WebFilePAth);
  1647. xmlBag.WriteAttributeString("href", AbsoluteWebPath );
  1648. }
  1649. else
  1650. {
  1651. xmlBag.WriteAttributeString("href", string.Format(@"{0}\{1}\{2}\{3}\{4}", topic.ProductServiceName, _storagePhotosFormatName, Key, storage.GetHashFolder2(storageMediaName), storageMediaName));
  1652. }
  1653. /*
  1654. }
  1655. */
  1656. xmlBag.WriteAttributeString("height", mediaHeight.ToString());
  1657. xmlBag.WriteAttributeString("width", mediaWidth.ToString());
  1658. }
  1659. xmlBag.WriteEndElement();
  1660. // Xafp/Bag/Item/Bag/Content
  1661. // Ecriture du bag autorisée
  1662. bagDefined = true;
  1663. }
  1664. break;
  1665. }
  1666. // Media non trouvé
  1667. Process.Trace(string.Format("Can't find photo key {0} and id {1}.", Key, storageMediaName), System.Diagnostics.EventLogEntryType.FailureAudit);
  1668. }
  1669. }
  1670. catch (Exception e)
  1671. {
  1672. Process.Trace(string.Format("Can't process media {0} for role {1} in news {2} of topic {3} (source : {4})", photoName, role, news.Uno, topic.Id, topic.Id), e.ToString(), System.Diagnostics.EventLogEntryType.FailureAudit);
  1673. }
  1674. // Gestion des liens videos
  1675. foreach (XmlElement content in Configuration.SelectNodes("//contents/video/content"))
  1676. foreach (var title in content.GetAttributeValue("source", content.GetAttribute("role")).Split(';'))
  1677. {
  1678. var media = (XmlElement)element.SelectSingleNode(string.Format("ContentItem/DataContent/p/a[@class='videoSet']/a[@title='{0}']", title));
  1679. string StoragemediaPath = "";
  1680. // Traitement de la video
  1681. if (media != null)
  1682. {
  1683. var mediaName = Path.GetFileName(media.GetAttribute("href").Replace("/", @"\"));
  1684. var mediaExists = false;
  1685. // Traitement nouvelle vidéo
  1686. if (news.State == News.NewsState.New)
  1687. {
  1688. var mediaPath = Path.Combine(Path.GetDirectoryName(news.Path), media.GetAttribute("href").Replace("/", @"\"));
  1689. mediaExists = StorageServer.FileExists(mediaPath);
  1690. // Stockage de la vidéo
  1691. if (mediaExists)
  1692. StoragemediaPath = storage.Store(mediaPath, _storageVideosFormatName, Key, mediaName);
  1693. // TO Do se servir de StoragemediaPath
  1694. }
  1695. // Traitement du media
  1696. if ((news.State == News.NewsState.Stored || mediaExists))
  1697. // Ecriture de l'élément Content
  1698. if (mediaFilter != NewsMediaFilter.photoOnly && componentType == ComponentType.video)
  1699. {
  1700. xmlBag.WriteStartElement("Content");
  1701. {
  1702. // Xafp/Bag/Item/Bag/Content
  1703. xmlBag.WriteAttributeString("type", "Video");
  1704. xmlBag.WriteAttributeString("role", content.GetAttribute("role"));
  1705. xmlBag.WriteAttributeString("href", String.Format("{0}/{1}/{2}/{3}/{4}/{5}",
  1706. topic.UrlWebRacine,
  1707. topic.ProductServiceName,
  1708. _storageVideosFormatName,
  1709. Key,
  1710. StorageServer.GetHashFolder(mediaName),
  1711. mediaName.UrlEncode()
  1712. ));
  1713. }
  1714. xmlBag.WriteEndElement();
  1715. // Xafp/Bag/Item/Bag/Content
  1716. // Ecriture du bag autorisée
  1717. bagDefined = true;
  1718. }
  1719. else
  1720. Process.Trace(string.Format("Can't find video {0} in news {1} of topic {2} (source : {3})", media.GetAttribute("href"), news.Uno, topic.Id, topic.Id), System.Diagnostics.EventLogEntryType.FailureAudit);
  1721. break;
  1722. }
  1723. }
  1724. }
  1725. xmlBag.WriteEndElement();
  1726. // Xafp/Bag/Item/Bag
  1727. // Gestion du bag
  1728. if (bagDefined)
  1729. {
  1730. // Première composante traitée
  1731. firstComponent = false;
  1732. //Ecriture du bag dans la news
  1733. xmlTopic.WriteRaw(xmlBag.ToString());
  1734. }
  1735. }
  1736. }
  1737. break;
  1738. }
  1739. }
  1740. }
  1741. xmlTopic.WriteEndElement();
  1742. var mediaDocList = new List<Media>();
  1743. // Ajout de la photo à la liste pour extension
  1744. string DocWebPath;
  1745. string docmediaName = "";
  1746. foreach (XmlNode xCurDocuments in news.Document.SelectNodes("//a[@class='document']"))
  1747. {
  1748. // determination docmediaName ;
  1749. string href = "";
  1750. if (((XmlElement)xCurDocuments).HasAttribute("href"))
  1751. {
  1752. href = xCurDocuments.Attributes["href"].Value;
  1753. docmediaName = System.IO.Path.GetFileNameWithoutExtension(href);
  1754. DocWebPath = String.Format("{5}/{0}/{1}/{2}/{3}/{4}.htm",
  1755. topic.ProductServiceName,
  1756. "News",
  1757. Key,
  1758. StorageServer.GetHashFolder(href),
  1759. docmediaName.UrlEncode(),
  1760. topic.UrlWebRacine
  1761. );
  1762. //note: Lien vers la DOC ( **DOCUMENTATION**)
  1763. mediaDocList.Add(
  1764. new Media(
  1765. docmediaName,
  1766. "document",
  1767. docmediaName,
  1768. "", "",
  1769. DocWebPath
  1770. ));
  1771. } // si pas on oublie
  1772. }
  1773. // Xafp/Bag/Item
  1774. // Sauvegarde d'une nouvelle news dans le stockage
  1775. try
  1776. {
  1777. if (news.State == News.NewsState.New || refresh || topic.IsDaily == true)
  1778. {
  1779. // Traitement de la news en HTML
  1780. XmlElement xEtend;
  1781. xEtend = NewsExtendDocument(news.Document, mediaPhotoList, mediaDocList, topic, news.Uno, storage, _Version);
  1782. NewsBuildHtml(xEtend, news.Document, topic, news.Uno, storage);
  1783. #if DEBUG && TRACEINTER
  1784. try
  1785. {
  1786. StreamWriter writer = File.CreateText(string.Format("{0}.ext.xml", System.IO.Path.Combine(@"C:\Trace", news.Uno)));
  1787. writer.WriteLine(((XmlNode)xEtend).OuterXml);
  1788. writer.Close();
  1789. news.Document.Save(string.Format("{0}.xml", System.IO.Path.Combine(@"C:\Trace", news.Uno)));
  1790. Process.Trace(string.Format("version ", _Version.ToString () ), System.Diagnostics.EventLogEntryType.Warning);
  1791. }
  1792. catch (Exception e)
  1793. {
  1794. int a = 0;
  1795. Process.Trace(e, System.Diagnostics.EventLogEntryType.Warning);
  1796. }
  1797. #endif
  1798. // Stockage de la news d'origine
  1799. if (!string.IsNullOrEmpty(news.Path))
  1800. {
  1801. //Enregistrement du NewsML
  1802. storage.Store(news.Path, Constants._storageNewsFormatName, Key, string.Format("{0}.xml", news.Uno), news.LastModificationDate, news.Uid);
  1803. }
  1804. }
  1805. }
  1806. catch (Exception e)
  1807. {
  1808. Process.Trace(e, System.Diagnostics.EventLogEntryType.Warning);
  1809. this.Set(string.Format("Topic process error on {0}", topic.Id), MessageSection.Processing.ToString(), System.Diagnostics.EventLogEntryType.Warning);
  1810. }
  1811. return true;
  1812. }
  1813. private void AddDocumentInLocalizedDatabase(string productId, string topicId, string newsId, string mediaId, string lang, float latitude, float longitude)
  1814. {
  1815. // productId, topicId, newsId, mediaId, lang, hit,longitude, lattidute)
  1816. foreach (var sqlProcessor in _sqlProcessorList)
  1817. {
  1818. sqlProcessor.Add(new SqlLocation(productId, topicId, newsId, mediaId, lang, longitude, latitude));
  1819. }
  1820. }
  1821. private XmlDocument TopicMostViewed(TopicImplementation topic, StorageServer storage, bool refresh)
  1822. {
  1823. var documentTopic = new XmlDocument();
  1824. var nowDate = DateTime.Now.ToUniversalTime();
  1825. string productId = "";
  1826. var newsOrderedList = new SortedList<int, HitEntry>();
  1827. var topicCountByLang = new Dictionary<string, int>();
  1828. var query = (topic.Type == TopicImplementation.TopicType.mostviewed)
  1829. ?
  1830. string.Format("select Sum(hit) as hits , productId, topicId, newsId, lang from viewed where mediaid='' and productId='{0}' group by productid, topicid, newsid, hit, lang order by hits desc", productId)
  1831. :
  1832. string.Format("select Sum(hit) as hits , productId, topicId, newsId, lang from viewed where mediaid!='' and productId='{0}' group by productid, topicid, newsid, hit, lang order by hits desc", productId);
  1833. // Récupération des sujets
  1834. foreach (var processor in _sqlProcessorList)
  1835. using (var sqlRatingReader = new SqlDataAdapter(query, processor.ConnectionString))
  1836. {
  1837. using (var sqlRatingTable = new DataTable())
  1838. {
  1839. try
  1840. {
  1841. sqlRatingReader.Fill(sqlRatingTable);
  1842. }
  1843. catch
  1844. {
  1845. continue;
  1846. }
  1847. // Création document final
  1848. using (var xmlTopic = createXmlWriter())
  1849. {
  1850. // Création du document XAfp
  1851. xmlTopic.WriteStartElement("Xafp");
  1852. {
  1853. // Xafp
  1854. xmlTopic.WriteAttributeString("type", "collection");
  1855. xmlTopic.WriteAttributeString("id", topic.Id);
  1856. xmlTopic.WriteStartElement("Head");
  1857. {
  1858. // Xafp/Head
  1859. xmlTopic.WriteElementString("DateCreated", nowDate.ToXmlElementString());
  1860. xmlTopic.WriteElementString("DateUpdated", nowDate.ToXmlElementString());
  1861. xmlTopic.WriteElementString("NumberOfItems", string.Empty);
  1862. }
  1863. xmlTopic.WriteEndElement();
  1864. // Xafp/Head
  1865. xmlTopic.WriteStartElement("Bag");
  1866. {
  1867. // Xafp/Bag
  1868. foreach (DataRow row in sqlRatingTable.Rows)
  1869. {
  1870. try
  1871. {
  1872. var topicSource = TopicImplementation.Load((string)row["topicId"]);
  1873. var topicRated = TopicLoadDocument(topicSource, storage);
  1874. if (topicRated == null)
  1875. Process.Trace(string.Format("Can't load topic {0} for rated news {1}", row["topicId"], row["newsId"]), System.Diagnostics.EventLogEntryType.FailureAudit);
  1876. else
  1877. {
  1878. var news = NewsLoadDocument(string.Format("{0}.xml", row["newsId"]), topicSource, storage, DateTime.Now);
  1879. // Ecriture de la news
  1880. if (news == null)
  1881. Process.Trace(string.Format("Can't load rated news {0}.", row["newsId"]), System.Diagnostics.EventLogEntryType.FailureAudit);
  1882. else
  1883. newsOrderedList.Add((int)row["hits"], new HitEntry((string)row["topicId"], (string)row["newsId"], (string)row["lang"], (int)row["hits"]));
  1884. }
  1885. }
  1886. catch
  1887. {
  1888. }
  1889. }
  1890. foreach (var ratingEntry in newsOrderedList.Values)
  1891. {
  1892. var topicSource = TopicImplementation.Load(ratingEntry.TopicId);
  1893. var topicRated = TopicLoadDocument(topicSource, storage);
  1894. var news = NewsLoadDocument(string.Format("{0}.xml", ratingEntry.NewsId), topicSource, storage, DateTime.Now);
  1895. if (!topicCountByLang.ContainsKey(ratingEntry.Lang))
  1896. topicCountByLang.Add(ratingEntry.Lang, 0);
  1897. // Création du sujet
  1898. string tmv ="" ;
  1899. if (topicCountByLang[ratingEntry.Lang] <= topic.MaxEntries)
  1900. if (NewsWriteBySubject(news, topicRated, topicSource, xmlTopic, storage, NewsMediaFilter.all, topicCountByLang[ratingEntry.Lang], true, refresh, ratingEntry.Hits, ref tmv))
  1901. topicCountByLang[ratingEntry.Lang]++;
  1902. }
  1903. }
  1904. xmlTopic.WriteEndElement();
  1905. // Xafp/Bag
  1906. }
  1907. xmlTopic.WriteEndElement();
  1908. // Xafp
  1909. // Chargement du document
  1910. documentTopic.LoadXml(xmlTopic.ToString());
  1911. // Mise à jour du nombre de news
  1912. documentTopic.DocumentElement.SelectSingleNode("//Head/NumberOfItems").InnerText = topicCountByLang.Values.Sum().ToString();
  1913. }
  1914. break;
  1915. }
  1916. }
  1917. return documentTopic;
  1918. }
  1919. private string TopicBuildRated(TopicImplementation topic, StorageServer storage, bool refresh)
  1920. {
  1921. string productId = "";
  1922. string query = (topic.Type == TopicImplementation.TopicType.rated)
  1923. ?
  1924. string.Format("SELECT lang, topicId, newsId, MAX([rating]/[votes]) AS averageRating, SUM([votes]) AS votes FROM [Ratings2] WHERE [mediaId] IS NULL AND [dateUpdated] > CONVERT(datetime, '{0}', 120) AND [productId]='{1}' GROUP BY lang, topicId, newsId ORDER BY [averageRating] DESC, [votes] DESC", DateTime.Now.Subtract(topic.MaxAge).ToString("yyyy-MM-dd"), productId)
  1925. :
  1926. string.Format("SELECT lang, topicId, newsId, MAX([rating]/[votes]) AS averageRating, SUM([votes]) AS votes FROM [Ratings2] WHERE NOT [mediaId] IS NULL AND [dateUpdated] > CONVERT(datetime, '{0}', 120) AND [productId]='{1}' GROUP BY lang, topicId, newsId ORDER BY [averageRating] DESC, [votes] DESC", DateTime.Now.Subtract(topic.MaxAge).ToString("yyyy-MM-dd"), productId);
  1927. return TopicBuildRated(query, topic.Id, topic.MaxEntries, storage, refresh);
  1928. }
  1929. private string TopicBuildAround(string query, StorageServer storage , int MaxEntries)
  1930. {
  1931. var documentTopic = new XmlDocument();
  1932. var nowDate = DateTime.Now.ToUniversalTime();
  1933. var newsOrderedList = new List<News>();
  1934. var topicCountByLang = new Dictionary<string, int>();
  1935. int index =0 ;
  1936. // Récupération des sujets
  1937. foreach (var processor in _sqlProcessorList)
  1938. {
  1939. using (var sqlRatingReader = new SqlDataAdapter(query, processor.ConnectionString))
  1940. {
  1941. using (var sqlRatingTable = new DataTable())
  1942. {
  1943. try
  1944. {
  1945. sqlRatingReader.Fill(sqlRatingTable);
  1946. }
  1947. catch(Exception e )
  1948. {
  1949. #if DEBUG
  1950. Process.Trace(e, System.Diagnostics.EventLogEntryType.Error);
  1951. #endif
  1952. continue;
  1953. }
  1954. // Création document final
  1955. using (var xmlTopic = createXmlWriter())
  1956. {
  1957. // Création du document XAfp
  1958. xmlTopic.WriteStartElement("Xafp");
  1959. {
  1960. // Xafp
  1961. xmlTopic.WriteAttributeString("type", "collection");
  1962. xmlTopic.WriteAttributeString("id", "none" );
  1963. xmlTopic.WriteStartElement("Head");
  1964. {
  1965. // Xafp/Head
  1966. xmlTopic.WriteElementString("DateCreated", nowDate.ToXmlElementString());
  1967. xmlTopic.WriteElementString("DateUpdated", nowDate.ToXmlElementString());
  1968. xmlTopic.WriteElementString("NumberOfItems", string.Empty);
  1969. }
  1970. xmlTopic.WriteEndElement();
  1971. // Xafp/Head
  1972. xmlTopic.WriteStartElement("Bag");
  1973. {
  1974. // Xafp/Bag
  1975. foreach (DataRow row in sqlRatingTable.Rows)
  1976. {
  1977. try
  1978. {
  1979. var topicSource = TopicImplementation.Load((string)row["topicId"]);
  1980. var topicRated = TopicLoadDocument(topicSource, storage);
  1981. if (topicRated == null)
  1982. Process.Trace(string.Format("Can't load topic {0} for rated news {1}", row["topicId"], row["newsId"]), System.Diagnostics.EventLogEntryType.FailureAudit);
  1983. else
  1984. {
  1985. var news = NewsLoadDocument(string.Format("{0}.xml", row["newsId"]), topicSource, storage, DateTime.Now);
  1986. // Ecriture de la news
  1987. if (news == null)
  1988. Process.Trace(string.Format("Can't load rated news {0}.", row["newsId"]), System.Diagnostics.EventLogEntryType.FailureAudit);
  1989. else
  1990. {
  1991. index++;
  1992. string Tvc ="";
  1993. NewsWriteBySubject(news, topicRated, topicSource, xmlTopic, storage, NewsMediaFilter.all,index,true, false, -1, ref Tvc);
  1994. }
  1995. if (index > MaxEntries)
  1996. break;
  1997. }
  1998. }
  1999. catch
  2000. {
  2001. }
  2002. }
  2003. }
  2004. xmlTopic.WriteEndElement();
  2005. // Xafp/Bag
  2006. }
  2007. xmlTopic.WriteEndElement();
  2008. // Xafp
  2009. // Chargement du document
  2010. string res = xmlTopic.ToString();
  2011. #if DEBUG && DEBUGAROUND
  2012. Process.Trace(string.Format(" calcul et renvoit du document BuildAround query {0} : res {1} ", query , res), System.Diagnostics.EventLogEntryType.Error);
  2013. #endif
  2014. documentTopic.LoadXml(res);
  2015. // Mise à jour du nombre de news
  2016. documentTopic.DocumentElement.SelectSingleNode("//Head/NumberOfItems").InnerText = index.ToString();
  2017. }
  2018. break;
  2019. }
  2020. }
  2021. }
  2022. return documentTopic.OuterXml;
  2023. }
  2024. private string TopicBuildRated(string query, string topicId, int MaxEntries, StorageServer storage, bool refresh)
  2025. {
  2026. var documentTopic = new XmlDocument();
  2027. var nowDate = DateTime.Now.ToUniversalTime();
  2028. var newsOrderedList = new SortedList<RatingEntryKey, RatingEntry>();
  2029. var topicCountByLang = new Dictionary<string, int>();
  2030. // Récupération des sujets
  2031. #if DEBUG && TRACE_REQUEST
  2032. Process.Trace(string.Format("TopicBuildRated processor nb ProcessorList {0}", _sqlProcessorList.Count ), System.Diagnostics.EventLogEntryType.Error);
  2033. #endif
  2034. foreach (var processor in _sqlProcessorList)
  2035. {
  2036. #if DEBUG && TRACE_REQUEST
  2037. Process.Trace(string.Format("TopicBuildRated processor Processor {0}", processor.ConnectionString ), System.Diagnostics.EventLogEntryType.Error);
  2038. #endif
  2039. using (var sqlRatingReader = new SqlDataAdapter(query, processor.ConnectionString))
  2040. {
  2041. using (var sqlRatingTable = new DataTable())
  2042. {
  2043. try
  2044. {
  2045. sqlRatingReader.Fill(sqlRatingTable);
  2046. }
  2047. catch
  2048. {
  2049. #if DEBUG && TRACE_REQUEST
  2050. Process.Trace(string.Format("Can't Fill table {0} ", processor.ConnectionString), System.Diagnostics.EventLogEntryType.Error);
  2051. #endif
  2052. continue;
  2053. }
  2054. #if DEBUG && TRACE_REQUEST
  2055. Process.Trace(string.Format("Creation document {0} nombre releve {1} ", processor.ConnectionString, sqlRatingTable.Rows.Count), System.Diagnostics.EventLogEntryType.Error);
  2056. #endif
  2057. // Création document final
  2058. using (var xmlTopic = createXmlWriter())
  2059. {
  2060. // Création du document XAfp
  2061. xmlTopic.WriteStartElement("Xafp");
  2062. {
  2063. // Xafp
  2064. xmlTopic.WriteAttributeString("type", "collection");
  2065. xmlTopic.WriteAttributeString("id", topicId);
  2066. xmlTopic.WriteStartElement("Head");
  2067. {
  2068. // Xafp/Head
  2069. xmlTopic.WriteElementString("DateCreated", nowDate.ToXmlElementString());
  2070. xmlTopic.WriteElementString("DateUpdated", nowDate.ToXmlElementString());
  2071. xmlTopic.WriteElementString("NumberOfItems", string.Empty);
  2072. }
  2073. xmlTopic.WriteEndElement();
  2074. // Xafp/Head
  2075. xmlTopic.WriteStartElement("Bag");
  2076. {
  2077. // Xafp/Bag
  2078. foreach (DataRow row in sqlRatingTable.Rows)
  2079. {
  2080. try
  2081. {
  2082. var topicSource = TopicImplementation.Load((string)row["topicId"]);
  2083. var topicRated = TopicLoadDocument(topicSource, storage);
  2084. if (topicRated == null)
  2085. Process.Trace(string.Format("Can't load topic {0} for rated news {1}", row["topicId"], row["newsId"]), System.Diagnostics.EventLogEntryType.FailureAudit);
  2086. else
  2087. {
  2088. #if DEBUG && TRACE_REQUEST
  2089. Process.Trace(string.Format("NewsLoadDocument NewsDocument row[newsId] {0} (string)row[topicId] ", row["newsId"], (string)row["topicId"]), System.Diagnostics.EventLogEntryType.Warning);
  2090. #endif
  2091. var news = NewsLoadDocument(string.Format("{0}.xml", row["newsId"]), topicSource, storage, DateTime.Now);
  2092. #if DEBUG && TRACE_REQUEST
  2093. Process.Trace(string.Format("NewsLoadDocument NewsDocument {0} ", news.Document.OuterXml ), System.Diagnostics.EventLogEntryType.Warning);
  2094. #endif
  2095. // Ecriture de la news
  2096. if (news == null)
  2097. Process.Trace(string.Format("Can't load rated news {0}.", row["newsId"]), System.Diagnostics.EventLogEntryType.FailureAudit);
  2098. else
  2099. {
  2100. // if (news.State != News.NewsState.Invalid )
  2101. newsOrderedList.Add(new RatingEntryKey(news.Document.FindDate("/NewsML/NewsItem/NewsManagement/ThisRevisionCreated").Value, row), new RatingEntry((string)row["topicId"], (string)row["newsId"], (string)row["lang"]));
  2102. #if DEBUG && TRACE_REQUEST
  2103. /*else
  2104. {
  2105. Process.Trace(string.Format(" le document {0} est invalid ", row["newsId"]), System.Diagnostics.EventLogEntryType.Information);
  2106. }
  2107. * */
  2108. #endif
  2109. }
  2110. }
  2111. }
  2112. catch (Exception ErreuLoad)
  2113. {
  2114. #if DEBUG && TRACE_REQUEST
  2115. Process.Trace(string.Format("NewsLoadDocument Error {0} ",ErreuLoad.ToString() ), System.Diagnostics.EventLogEntryType.Information);
  2116. #endif
  2117. }
  2118. }
  2119. foreach (var ratingEntry in newsOrderedList.Values)
  2120. {
  2121. var topicSource = TopicImplementation.Load(ratingEntry.TopicId);
  2122. var topicRated = TopicLoadDocument(topicSource, storage);
  2123. var news = NewsLoadDocument(string.Format("{0}.xml", ratingEntry.NewsId), topicSource, storage, DateTime.Now);
  2124. if (!topicCountByLang.ContainsKey(ratingEntry.Lang))
  2125. topicCountByLang.Add(ratingEntry.Lang, 0);
  2126. // Création du sujet
  2127. string Tvc= "";
  2128. if (topicCountByLang[ratingEntry.Lang] <= MaxEntries)
  2129. if (NewsWriteBySubject(news, topicRated, topicSource, xmlTopic, storage, NewsMediaFilter.all, topicCountByLang[ratingEntry.Lang], true, refresh, -1, ref Tvc))
  2130. topicCountByLang[ratingEntry.Lang]++;
  2131. }
  2132. }
  2133. xmlTopic.WriteEndElement();
  2134. // Xafp/Bag
  2135. }
  2136. xmlTopic.WriteEndElement();
  2137. // Xafp
  2138. // Chargement du document
  2139. #if DEBUG && TRACE_REQUEST
  2140. Process.Trace(string.Format("Return TopicBuildRated xmlTopic ", xmlTopic.ToString()), System.Diagnostics.EventLogEntryType.Information);
  2141. #endif
  2142. documentTopic.LoadXml(xmlTopic.ToString());
  2143. // Mise à jour du nombre de news
  2144. documentTopic.DocumentElement.SelectSingleNode("//Head/NumberOfItems").InnerText = topicCountByLang.Values.Sum().ToString();
  2145. }
  2146. break;
  2147. }
  2148. }
  2149. }
  2150. #if DEBUG && TRACE_REQUEST
  2151. Process.Trace(string.Format("Return TopicBuildRated ", documentTopic.OuterXml), System.Diagnostics.EventLogEntryType.Error);
  2152. #endif
  2153. return documentTopic.OuterXml;
  2154. }
  2155. /// <summary>
  2156. /// magazin ou special diaporama (special Ipad)
  2157. /// </summary>
  2158. /// <param name="topicDocument"></param>
  2159. /// <param name="topic"></param>
  2160. /// <param name="storage"></param>
  2161. /// <param name="maxNews"></param>
  2162. /// <param name="refresh"></param>
  2163. /// <returns></returns>
  2164. private String TopicBuildMagazin(NewsML topicDocument, TopicImplementation topic, StorageServer storage, int maxNews, bool refresh, string idTopic, string catchLine)
  2165. {
  2166. String result = null;
  2167. // il faut extraire la premiere image...
  2168. #if DEBUG && TRACE_TIME_TOPIC
  2169. System.Diagnostics.Stopwatch timer =null;
  2170. if (_levelTrace.TraceTimeMakeTopic == true)
  2171. {
  2172. timer = new System.Diagnostics.Stopwatch();
  2173. timer.Start();
  2174. }
  2175. #endif
  2176. using (var xmlTopic = createXmlWriter())
  2177. {
  2178. var numberOfItems = 0;
  2179. var numberOfNews = 0;
  2180. DateTime ThisRevisionCreated =DateTime.UtcNow;
  2181. String sDateTimeRev;
  2182. sDateTimeRev = topicDocument.NewsItem.NewsManagement.ThisRevisionCreated;
  2183. if (string.IsNullOrEmpty(topic.Announces) == false)
  2184. {
  2185. if (System.IO.File.Exists(topic.Announces))
  2186. {
  2187. ThisRevisionCreated = DateTime.UtcNow.AddMinutes(1);
  2188. sDateTimeRev = ThisRevisionCreated.ToString().FromDateToXmlUTCString();
  2189. }
  2190. }
  2191. // Création du document XAfp
  2192. xmlTopic.WriteStartElement("Xafp");
  2193. {
  2194. // Xafp
  2195. xmlTopic.WriteAttributeString("type", "collection");
  2196. xmlTopic.WriteAttributeString("id", (string.IsNullOrEmpty(idTopic) ? topic.Id : idTopic));
  2197. xmlTopic.WriteAttributeString("newsItemId", topicDocument.NewsItem.Identification.NewsIdentifier.NewsItemId);
  2198. xmlTopic.WriteAttributeString("xml", "lang", "http://www.w3.org/XML/1998/namespace", topic.Lang.Split('_')[0]);
  2199. xmlTopic.WriteStartElement("Head");
  2200. {
  2201. // Xafp/Head
  2202. //xmlTopic.WriteElementString("Name", "__TEMPORAIRE__");
  2203. xmlTopic.WriteElementString("Name", topicDocument.NewsItem.Identification.NameLabel);
  2204. xmlTopic.WriteElementString("DateCreated", topicDocument.NewsItem.NewsManagement.FirstCreated);
  2205. xmlTopic.WriteElementString("DateUpdated", sDateTimeRev);
  2206. xmlTopic.WriteElementString("Source", topicDocument.NewsItem.Identification.NewsIdentifier.ProviderId);
  2207. xmlTopic.WriteElementString("NumberOfItems", "__NumberOfItems__");
  2208. // xmlTopic.WriteElementString("CatchLine", catchLine );
  2209. }
  2210. xmlTopic.WriteEndElement();
  2211. // Xafp/Head
  2212. xmlTopic.WriteStartElement("Bag");
  2213. {
  2214. Boolean removeIt = false;
  2215. NewsItemComponent newsItemComponent = topicDocument.NewsItem.NewsComponent;
  2216. if (string.IsNullOrEmpty(topic.Announces) == false)
  2217. {
  2218. // TO DO rajouter le document induit s'il existe...
  2219. NewsComponent newsComponent = newsItemComponent.NewsComponent[numberOfItems];
  2220. var news = AnnounceLoadDocument(topic.Announces, topic, storage, ThisRevisionCreated );
  2221. string tCatchLine ="";
  2222. if (NewsWriteBySubject(news, topicDocument, topic, xmlTopic, storage, NewsMediaFilter.all, numberOfNews++, false, refresh, -1, ref tCatchLine) == false)
  2223. {
  2224. topicDocument.NewsItem.NewsComponent.NewsComponent.Remove(newsComponent);
  2225. }
  2226. //numberOfItems++;
  2227. }
  2228. // Xafp/Bag
  2229. // Traitement des news
  2230. while (numberOfItems < topicDocument.NewsItem.NewsComponent.NewsComponent.Count && numberOfItems < maxNews)
  2231. {
  2232. NewsComponent newsComponent = newsItemComponent.NewsComponent[numberOfItems];
  2233. String newsItemRef = ((NewsItemRef)newsComponent.Items[0]).NewsItem;
  2234. #if DEBUG && TRACE_TIME_TOPIC
  2235. if (_levelTrace.TraceTimeMakeTopic == true)
  2236. {
  2237. Process.Trace(string.Format("********"), System.Diagnostics.EventLogEntryType.Information );
  2238. Process.Trace(string.Format("Start Load Component for topicId '{0}' newsItemRef {2} processed after {1} milliseconds.", topic.Id, timer.ElapsedMilliseconds, newsItemRef), System.Diagnostics.EventLogEntryType.SuccessAudit);
  2239. }
  2240. #endif
  2241. var news = NewsLoadDocument(newsComponent, topic, storage, topicDocument.NewsItem.NewsManagement.ThisRevisionCreated.FromXmlUTCStringToDate());
  2242. #if DEBUG && TRACE_TIME_TOPIC
  2243. if (_levelTrace.TraceTimeMakeTopic == true)
  2244. {
  2245. Process.Trace(string.Format("End load Component for topicId '{0}' newsItemRef{2} processed after {1} milliseconds.", topic.Id, timer.ElapsedMilliseconds, newsItemRef), System.Diagnostics.EventLogEntryType.SuccessAudit);
  2246. }
  2247. #endif
  2248. // Suppression du document newsml si invalide
  2249. string tC2 ="";
  2250. if (news.State == News.NewsState.Invalid)
  2251. {
  2252. removeIt = true;
  2253. // Process.Trace("RemoveTopic", String.Format("Invalid state:{0}-{1}", topic.Id, newsItemRef), System.Diagnostics.EventLogEntryType.Warning);
  2254. }
  2255. else if (NewsWriteBySubject(news, topicDocument, topic, xmlTopic, storage, NewsMediaFilter.all, numberOfNews++, false, refresh, -1, ref tC2) == false)
  2256. {
  2257. removeIt = true;
  2258. Process.Trace("RemoveTopic", String.Format("Can't save:{0}-{1}", topic.Id, newsItemRef), System.Diagnostics.EventLogEntryType.Warning);
  2259. }
  2260. else
  2261. {
  2262. numberOfItems++;
  2263. removeIt = false;
  2264. }
  2265. #if DEBUG && TRACE_TIME_TOPIC
  2266. if (_levelTrace.TraceTimeMakeTopic == true)
  2267. {
  2268. Process.Trace(string.Format("End NewsWriteBySubject for topicId '{0}' newsItemRef {2} processed after {1} milliseconds.", topic.Id, timer.ElapsedMilliseconds, newsItemRef), System.Diagnostics.EventLogEntryType.SuccessAudit);
  2269. }
  2270. #endif
  2271. if (removeIt)
  2272. {
  2273. topicDocument.NewsItem.NewsComponent.NewsComponent.Remove(newsComponent);
  2274. }
  2275. }
  2276. }
  2277. xmlTopic.WriteEndElement();
  2278. // Xafp/Bag
  2279. }
  2280. xmlTopic.WriteElementString("CatchLine", catchLine);
  2281. xmlTopic.WriteEndElement();
  2282. // Xafp
  2283. // Trace pour absence de document
  2284. if (numberOfItems == 0)
  2285. {
  2286. Process.Trace(string.Format("Empty topic error for topic id {0}", topic.Id), System.Diagnostics.EventLogEntryType.Information);
  2287. this.Set(string.Format("Empty topic error for topic id {0}", topic.Id), MessageSection.Alimentation.ToString(), System.Diagnostics.EventLogEntryType.Information);
  2288. }
  2289. #if DEBUG && TRACE_TIME_TOPIC
  2290. if (_levelTrace.TraceTimeMakeTopic == true)
  2291. {
  2292. timer.Stop();
  2293. Process.Trace(string.Format("End TopicBuildStandard for topicId '{0}' processed after {1} milliseconds.", topic.Id, timer.ElapsedMilliseconds), System.Diagnostics.EventLogEntryType.SuccessAudit);
  2294. }
  2295. #endif
  2296. // Chargement du document & Mise à jour du nombre de news
  2297. if (string.IsNullOrEmpty(topic.Announces) == false)
  2298. {
  2299. numberOfItems++;
  2300. }
  2301. result = xmlTopic.ToString().Replace("__NumberOfItems__", numberOfItems.ToString());
  2302. //result = result.Replace("__TEMPORAIRE__", );
  2303. }
  2304. return result;
  2305. }
  2306. //private XmlDocument TopicBuildStandard(NewsML topicDocument, TopicImplementation topic, StorageServer storage, int maxNews, bool refresh)
  2307. private String TopicBuildStandard(NewsML topicDocument, TopicImplementation topic, StorageServer storage, int maxNews, bool refresh)
  2308. {
  2309. String result = null;
  2310. #if DEBUG && TRACE_TIME_TOPIC
  2311. System.Diagnostics.Stopwatch timer =null;
  2312. if (_levelTrace.TraceTimeMakeTopic == true)
  2313. {
  2314. timer = new System.Diagnostics.Stopwatch();
  2315. timer.Start();
  2316. }
  2317. #endif
  2318. string catchLine="";
  2319. string otherC = "";
  2320. using (var xmlTopic = createXmlWriter())
  2321. {
  2322. var numberOfItems = 0;
  2323. var numberOfNews = 0;
  2324. DateTime ThisRevisionCreated = DateTime.UtcNow.AddMinutes(1);
  2325. // Création du document XAfp
  2326. xmlTopic.WriteStartElement("Xafp");
  2327. {
  2328. // Xafp
  2329. xmlTopic.WriteAttributeString("type", "collection");
  2330. xmlTopic.WriteAttributeString("id", topic.Id);
  2331. xmlTopic.WriteAttributeString("newsItemId", topicDocument.NewsItem.Identification.NewsIdentifier.NewsItemId);
  2332. xmlTopic.WriteAttributeString("xml", "lang", "http://www.w3.org/XML/1998/namespace", topic.Lang.Split('_')[0]);
  2333. xmlTopic.WriteStartElement("Head");
  2334. {
  2335. // Xafp/Head
  2336. xmlTopic.WriteElementString("Name", topicDocument.NewsItem.Identification.NameLabel);
  2337. xmlTopic.WriteElementString("DateCreated", topicDocument.NewsItem.NewsManagement.FirstCreated);
  2338. xmlTopic.WriteElementString("DateUpdated", topicDocument.NewsItem.NewsManagement.ThisRevisionCreated);
  2339. xmlTopic.WriteElementString("Source", topicDocument.NewsItem.Identification.NewsIdentifier.ProviderId);
  2340. xmlTopic.WriteElementString("NumberOfItems", "__NumberOfItems__");
  2341. }
  2342. xmlTopic.WriteEndElement();
  2343. // Xafp/Head
  2344. xmlTopic.WriteStartElement("Bag");
  2345. {
  2346. Boolean removeIt = false;
  2347. NewsItemComponent newsItemComponent = topicDocument.NewsItem.NewsComponent;
  2348. if (string.IsNullOrEmpty(topic.Announces) == false)
  2349. {
  2350. NewsComponent newsComponent = newsItemComponent.NewsComponent[numberOfItems];
  2351. var news = AnnounceLoadDocument(topic.Announces, topic, storage, ThisRevisionCreated);
  2352. string tA ="";
  2353. if (NewsWriteBySubject(news, topicDocument, topic, xmlTopic, storage, NewsMediaFilter.all, numberOfNews++, false, refresh, -1, ref tA) == false)
  2354. {
  2355. topicDocument.NewsItem.NewsComponent.NewsComponent.Remove(newsComponent);
  2356. }
  2357. }
  2358. // Xafp/Bag
  2359. // Traitement des news
  2360. while (numberOfItems < topicDocument.NewsItem.NewsComponent.NewsComponent.Count && numberOfItems < maxNews)
  2361. {
  2362. NewsComponent newsComponent = newsItemComponent.NewsComponent[numberOfItems];
  2363. try
  2364. {
  2365. String newsItemRef = ((NewsItemRef)newsComponent.Items[0]).NewsItem;
  2366. #if DEBUG && TRACE_TIME_TOPIC
  2367. if (_levelTrace.TraceTimeMakeTopic == true)
  2368. {
  2369. Process.Trace(string.Format("********"), System.Diagnostics.EventLogEntryType.Information );
  2370. Process.Trace(string.Format("Start Load Component for topicId '{0}' newsItemRef {2} processed after {1} milliseconds.", topic.Id, timer.ElapsedMilliseconds, newsItemRef), System.Diagnostics.EventLogEntryType.SuccessAudit);
  2371. }
  2372. #endif
  2373. News news = NewsLoadDocument(newsComponent, topic, storage, topicDocument.NewsItem.NewsManagement.ThisRevisionCreated.FromXmlUTCStringToDate());
  2374. #if DEBUG && TRACE_TIME_TOPIC
  2375. if (_levelTrace.TraceTimeMakeTopic == true)
  2376. {
  2377. Process.Trace(string.Format("End load Component for topicId '{0}' newsItemRef{2} processed after {1} milliseconds.", topic.Id, timer.ElapsedMilliseconds, newsItemRef), System.Diagnostics.EventLogEntryType.SuccessAudit);
  2378. }
  2379. #endif
  2380. // Suppression du document newsml si invalide
  2381. string tCatchLine="";
  2382. string tOtherC ="";
  2383. if (news.State == News.NewsState.Invalid)
  2384. {
  2385. removeIt = true;
  2386. // Process.Trace("RemoveTopic", String.Format("Invalid state:{0}-{1}", topic.Id, newsItemRef), System.Diagnostics.EventLogEntryType.Warning);
  2387. }
  2388. else if (NewsWriteBySubject(news, topicDocument, topic, xmlTopic, storage, NewsMediaFilter.all, numberOfNews++, false, refresh, -1, ref tCatchLine ) == false)
  2389. {
  2390. removeIt = true;
  2391. Process.Trace("RemoveTopic", String.Format("Can't save:{0}-{1}", topic.Id, newsItemRef), System.Diagnostics.EventLogEntryType.Warning);
  2392. }
  2393. else
  2394. {
  2395. numberOfItems++;
  2396. removeIt = false;
  2397. }
  2398. if (numberOfItems == 1)
  2399. {
  2400. catchLine = tCatchLine;
  2401. otherC = tOtherC;
  2402. }
  2403. #if DEBUG && TRACE_TIME_TOPIC
  2404. if (_levelTrace.TraceTimeMakeTopic == true)
  2405. {
  2406. Process.Trace(string.Format("End NewsWriteBySubject for topicId '{0}' newsItemRef {2} processed after {1} milliseconds.", topic.Id, timer.ElapsedMilliseconds, newsItemRef), System.Diagnostics.EventLogEntryType.SuccessAudit);
  2407. }
  2408. #endif
  2409. }
  2410. catch (Exception e)
  2411. {
  2412. Process.Trace(string.Format("Error topicId : {0} NameLabel : {1} Message : {2}", topic.Id, topicDocument.NewsItem.Identification.NameLabel, e.Message), System.Diagnostics.EventLogEntryType.Warning);
  2413. this.Set("Topic process error", MessageSection.Processing.ToString(), System.Diagnostics.EventLogEntryType.Warning);
  2414. removeIt = true;
  2415. }
  2416. if (removeIt)
  2417. {
  2418. try
  2419. {
  2420. topicDocument.NewsItem.NewsComponent.NewsComponent.Remove(newsComponent);
  2421. }
  2422. catch
  2423. { }
  2424. }
  2425. }
  2426. }
  2427. xmlTopic.WriteEndElement();
  2428. // Xafp/Bag
  2429. if (topic.MustShowCatchLine())
  2430. {
  2431. xmlTopic.WriteElementString("CatchLine", catchLine);
  2432. }
  2433. }
  2434. xmlTopic.WriteEndElement();
  2435. // Xafp
  2436. // Trace pour absence de document
  2437. if (numberOfItems == 0)
  2438. {
  2439. Process.Trace(string.Format("Empty topic error for topic id {0}", topic.Id), System.Diagnostics.EventLogEntryType.Information);
  2440. this.Set(string.Format("Empty topic error for topic id {0}", topic.Id), MessageSection.Alimentation.ToString(), System.Diagnostics.EventLogEntryType.Information);
  2441. }
  2442. #if DEBUG && TRACE_TIME_TOPIC
  2443. if (_levelTrace.TraceTimeMakeTopic == true)
  2444. {
  2445. timer.Stop();
  2446. Process.Trace(string.Format("End TopicBuildStandard for topicId '{0}' processed after {1} milliseconds.", topic.Id, timer.ElapsedMilliseconds), System.Diagnostics.EventLogEntryType.SuccessAudit);
  2447. }
  2448. #endif
  2449. // Chargement du document & Mise à jour du nombre de news
  2450. if (string.IsNullOrEmpty(topic.Announces) == false)
  2451. {
  2452. numberOfItems++;
  2453. }
  2454. result = xmlTopic.ToString().Replace("__NumberOfItems__", numberOfItems.ToString());
  2455. }
  2456. return result;
  2457. }
  2458. private XmlDocument TopicBuildVideorama(TopicImplementation topic, StorageServer storage, bool refresh)
  2459. {
  2460. var documentTopic = new XmlDocument();
  2461. string catchLine ="";
  2462. using (var xmlTopic = createXmlWriter())
  2463. {
  2464. var nowDate = DateTime.Now.ToUniversalTime();
  2465. var newsList = new List<SortedList<News, TopicImplementation>>();
  2466. var numberOfItems = 0;
  2467. // Création du document XAfp
  2468. xmlTopic.WriteStartElement("Xafp");
  2469. {
  2470. // Xafp
  2471. xmlTopic.WriteAttributeString("type", "collection");
  2472. xmlTopic.WriteAttributeString("id", topic.Id);
  2473. xmlTopic.WriteAttributeString("xml", "lang", "http://www.w3.org/XML/1998/namespace", topic.Lang.Split('_')[0]);
  2474. xmlTopic.WriteStartElement("Head");
  2475. {
  2476. // Xafp/Head
  2477. xmlTopic.WriteElementString("Name", topic["name"]);
  2478. xmlTopic.WriteElementString("DateCreated", nowDate.ToXmlElementString());
  2479. xmlTopic.WriteElementString("DateUpdated", nowDate.ToXmlElementString());
  2480. xmlTopic.WriteElementString("Source", topic["source"]);
  2481. xmlTopic.WriteElementString("NumberOfItems", string.Empty);
  2482. }
  2483. xmlTopic.WriteEndElement();
  2484. // Xafp/Head
  2485. xmlTopic.WriteStartElement("Bag");
  2486. {
  2487. // Xafp/Bag
  2488. // Traitement de tous les topics du topic parent
  2489. foreach (var referencedTopic in topic.Childs())
  2490. // Traitement des topic standard
  2491. if (referencedTopic.Type == TopicImplementation.TopicType.standard)
  2492. {
  2493. var topicDocument = TopicLoadDocument(referencedTopic, storage);
  2494. // Chargement des news
  2495. if (topicDocument != null)
  2496. {
  2497. // Nouveau sujet
  2498. newsList.Add(new SortedList<News, TopicImplementation>());
  2499. // Traitement des news
  2500. foreach (var newsComponent in topicDocument.NewsItem.NewsComponent.NewsComponent)
  2501. {
  2502. var news = NewsLoadDocument(newsComponent, referencedTopic, storage, topicDocument.NewsItem.NewsManagement.ThisRevisionCreated.FromXmlUTCStringToDate());
  2503. var exists = false;
  2504. // Selection et tri de la news en mode video only si contient au moins une vidéo
  2505. if (news.State != News.NewsState.Invalid && news.Document.SelectSingleNode("/NewsML/NewsItem/NewsComponent/NewsComponent/ContentItem/DataContent/p/a[@class='videoSet']") != null)
  2506. {
  2507. foreach (var newsInnerList in newsList)
  2508. exists |= newsInnerList.ContainsKey(news);
  2509. if (!exists)
  2510. newsList[newsList.Count - 1].Add(news, referencedTopic);
  2511. }
  2512. }
  2513. }
  2514. }
  2515. // Ecriture des news par ordre chronologique
  2516. foreach (var newsInnerList in newsList)
  2517. for (var i = 0; i < newsInnerList.Count; i++)
  2518. {
  2519. var news = newsInnerList.ElementAt(i).Key;
  2520. var topicImplementation = newsInnerList.ElementAt(i).Value;
  2521. var topicDocument = TopicLoadDocument(topicImplementation, storage);
  2522. // Ecriture de la news
  2523. string tcatchLine ="";
  2524. if (topicDocument != null && NewsWriteBySubject(news, topicDocument, topicImplementation, xmlTopic, storage, NewsMediaFilter.videoOnly, i, false, refresh, -1, ref tcatchLine ))
  2525. numberOfItems++;
  2526. if (numberOfItems == 1)
  2527. {
  2528. catchLine = tcatchLine;
  2529. }
  2530. }
  2531. }
  2532. xmlTopic.WriteEndElement();
  2533. // Xafp/Bag
  2534. if (topic.MustShowCatchLine())
  2535. {
  2536. xmlTopic.WriteElementString("CatchLine", catchLine);
  2537. }
  2538. }
  2539. xmlTopic.WriteEndElement();
  2540. // Xafp
  2541. // Trace pour absence de document
  2542. if (numberOfItems == 0)
  2543. {
  2544. Process.Trace(string.Format("Empty topic error for topic id {0}", topic.Id), System.Diagnostics.EventLogEntryType.Warning);
  2545. this.Set("Empty topic error", MessageSection.Alimentation.ToString(), System.Diagnostics.EventLogEntryType.Warning);
  2546. }
  2547. // Chargement du document
  2548. documentTopic.LoadXml(xmlTopic.ToString());
  2549. // Mise à jour du nombre de news
  2550. documentTopic.DocumentElement.SelectSingleNode("//Head/NumberOfItems").InnerText = numberOfItems.ToString();
  2551. }
  2552. return documentTopic;
  2553. }
  2554. private NewsML TopicLoadDocument(TopicImplementation topic, StorageServer storage)
  2555. {
  2556. NewsML indexNew = null;
  2557. DateTime IndexCompiledDateTime = DateTime.MinValue;
  2558. String topicFileNameAll = String.Format("{0}.all", topic.Id);
  2559. String topicFileNameRef = String.Format("{0}.ref", topic.Id);
  2560. // Création du fichier topic de référence
  2561. foreach (var file in topic.Files)
  2562. {
  2563. if (StorageServer.FileExists(file))
  2564. {
  2565. // Présence d'un fichier index ?
  2566. using (var topicFile = StorageServer.FileOpen(file))
  2567. {
  2568. // Ouverture du fichier en lecture avec attente de lock
  2569. if (indexNew == null)
  2570. {
  2571. indexNew = NewsML.Load(topicFile);
  2572. }
  2573. else
  2574. {
  2575. var indexConcat = NewsML.Load(topicFile);
  2576. // Consolidation avec index supplémentaire
  2577. indexNew.NewsItem.NewsComponent.NewsComponent = new List<NewsComponent>(indexNew.NewsItem.NewsComponent.NewsComponent.Union(indexConcat.NewsItem.NewsComponent.NewsComponent, new NewsComponentComparer()));
  2578. }
  2579. if (StorageServer.GetLastModifiedDate(file).CompareTo(IndexCompiledDateTime) > 0)
  2580. IndexCompiledDateTime = StorageServer.GetLastModifiedDate(file);
  2581. }
  2582. }
  2583. }
  2584. // Présence d'un fichier index ?
  2585. if (indexNew != null)
  2586. {
  2587. // Sauvegarde du document index concaténés
  2588. bool supportSeek;
  2589. var indexNewStream = new MemoryStream();
  2590. // En cours codage du daily
  2591. indexNew.Save(indexNewStream);
  2592. StorageFileInfo storedTopicInfo = null;
  2593. if (topic.IsDaily == false)
  2594. storedTopicInfo = storage.Info(Constants._storageTopicFormatName, Key, topicFileNameRef);
  2595. // si on est en daily on ne regarde pas ce qui était sauvegardé
  2596. // Nouveau dépot ?
  2597. // Process.Trace(string.Format("## id topic {0} CompiledDateTime {1} storedTopicInfo : path {3} Date Time {2} ", topic.Id, IndexCompiledDateTime, storedTopicInfo.LastModified , storedTopicInfo.Path ), System.Diagnostics.EventLogEntryType.Information);
  2598. //Ex Checksum
  2599. if (storedTopicInfo == null || (IndexCompiledDateTime.CompareTo(storedTopicInfo.LastModified) >= 0))
  2600. {
  2601. NewsML indexOld = null;
  2602. // Chargement de l'état précedent du topic
  2603. if (topic.IsDaily == false)
  2604. if (storage.Exists(Constants._storageTopicFormatName, Key, topicFileNameAll))
  2605. using (var indexOldStream = storage.Restore(Constants._storageTopicFormatName, Key, topicFileNameAll, true))
  2606. indexOld = NewsML.Load(indexOldStream);
  2607. // Consolidation si ancien index existe
  2608. if (indexOld != null)
  2609. indexNew.NewsItem.NewsComponent.NewsComponent = new List<NewsComponent>(
  2610. indexNew.NewsItem.NewsComponent.NewsComponent.Union(indexOld.NewsItem.NewsComponent.NewsComponent, new NewsComponentComparer()).Take(topic.MaxEntries)
  2611. );
  2612. // Sauvegarde du document de référence
  2613. storage.Store(indexNewStream, Constants._storageTopicFormatName, Key, topicFileNameRef, out supportSeek);
  2614. // Sauvegarde du document mergé
  2615. using (var storageFile = storage.Store(Constants._storageTopicFormatName, Key, topicFileNameAll))
  2616. indexNew.Save(storageFile);
  2617. }
  2618. // Restauration depuis le stockage
  2619. if (topic.IsDaily == false)
  2620. if (storage.Exists(Constants._storageTopicFormatName, Key, topicFileNameAll))
  2621. using (var indexOldStream = storage.Restore(Constants._storageTopicFormatName, Key, topicFileNameAll, true))
  2622. return NewsML.Load(indexOldStream);
  2623. return indexNew;
  2624. }
  2625. // Restauration depuis le stockage
  2626. if (storage.Exists(Constants._storageTopicFormatName, Key, topicFileNameAll))
  2627. using (var indexOldStream = storage.Restore(Constants._storageTopicFormatName, Key, topicFileNameAll, true))
  2628. return NewsML.Load(indexOldStream);
  2629. return null;
  2630. }
  2631. private NewsML TopicLoadTableAndDoneTopics(TopicImplementation topic, StorageServer storage)
  2632. {
  2633. NewsML indexNew = null;
  2634. DateTime IndexCompiledDateTime = DateTime.MinValue;
  2635. String topicFileNameAll = String.Format("{0}.all", topic.Id);
  2636. String topicFileNameRef = String.Format("{0}.ref", topic.Id);
  2637. string CatchLine = "";
  2638. string iop = "";
  2639. #if DEBUG && DEBUG_IPAD
  2640. Process.Trace(string.Format(" TopicLoadTableAndDoneTopics with topicID : {0}" , topic.Id) , System.Diagnostics.EventLogEntryType.Information);
  2641. #endif
  2642. // Création du fichier topic de référence
  2643. foreach (var file in topic.Files)
  2644. {
  2645. if (StorageServer.FileExists(file))
  2646. {
  2647. // Présence d'un fichier index ?
  2648. using (var topicFile = StorageServer.FileOpen(file))
  2649. {
  2650. // Ouverture du fichier en lecture avec attente de lock
  2651. if (indexNew == null)
  2652. {
  2653. indexNew = NewsML.Load(topicFile);
  2654. }
  2655. else
  2656. {
  2657. var indexConcat = NewsML.Load(topicFile);
  2658. // Consolidation avec index supplémentaire
  2659. indexNew.NewsItem.NewsComponent.NewsComponent = new List<NewsComponent>(indexNew.NewsItem.NewsComponent.NewsComponent.Union(indexConcat.NewsItem.NewsComponent.NewsComponent, new NewsComponentComparer()));
  2660. }
  2661. //BRUTDECOFFRAGE: Brut de coffrage si un jour on en a deux il faudra collectionner...
  2662. iop = System.IO.Path.GetDirectoryName(file);
  2663. if (StorageServer.GetLastModifiedDate(file).CompareTo(IndexCompiledDateTime) > 0)
  2664. IndexCompiledDateTime = StorageServer.GetLastModifiedDate(file);
  2665. }
  2666. }
  2667. }
  2668. // Présence d'un fichier index ?
  2669. if (indexNew != null)
  2670. {
  2671. // on a le news ML
  2672. #if DEBUG && DEBUG_IPAD
  2673. #if DEBUGMACHINE
  2674. System.Diagnostics.Debugger.Break();
  2675. #endif
  2676. Process.Trace(string.Format(" fichier Index trouvé "), System.Diagnostics.EventLogEntryType.Information);
  2677. #endif
  2678. foreach (NewsComponent topicpath in indexNew.NewsItem.NewsComponent.NewsComponent)
  2679. {
  2680. string topicID = topicpath.NewsLines.HeadLine;// ca ne va pas poser un souci?
  2681. try
  2682. {
  2683. //Determination du catchLine pour chaque subTopic
  2684. string FileName = ((NewsItemRef)(topicpath.Items[0])).NewsItem ;
  2685. CatchLine = "";
  2686. if (string.IsNullOrEmpty(iop) == false)
  2687. {
  2688. FileStream Fs = new FileStream(System.IO.Path.Combine(iop, FileName), FileMode.Open);
  2689. NewsML CatchLineUp = NewsML.Load(Fs);
  2690. //CatchLine = CatchLineUp.NewsItem.NewsComponent.NewsLines.NewsLine[""]
  2691. // il est parfois dans MobileShortTitle...
  2692. foreach (NewsLine Nl in CatchLineUp.NewsItem.NewsComponent.NewsLines.NewsLine)
  2693. {
  2694. if (string.IsNullOrEmpty(Nl.NewsLineText) == false)
  2695. {
  2696. CatchLine = Nl.NewsLineText;
  2697. break;
  2698. }
  2699. }
  2700. }
  2701. //string.Format("{0}__{1}", _ProductServiceName, _topic.GetAttribute("id"));
  2702. topicID = string.Format("{0}__{1}", topic.ProductServiceName, topicID);
  2703. TopicImplementation curtopic;
  2704. curtopic = TopicImplementation.Load(topicID);
  2705. NewsML indexd = TopicLoadDocument(curtopic, storage);
  2706. String topicContent = TopicBuildMagazin(indexd, curtopic, storage, topic.MaxEntries, true, topicID, CatchLine);
  2707. if (String.IsNullOrEmpty(topicContent) == false)
  2708. {
  2709. Stream output = storage.Store(Constants._storageTopicFormatName, Key, string.Format("{0}.xml", topicID));
  2710. if (output != null)
  2711. {
  2712. TextWriter wr = new StreamWriter(output, Encoding.UTF8);
  2713. wr.Write(topicContent);
  2714. wr.Flush();
  2715. output.Close();
  2716. }
  2717. }
  2718. }
  2719. catch (Exception ErrorTopic)
  2720. {
  2721. Process.Trace(string.Format(" Error with topic {0} {1}", topicID, ErrorTopic.Message), System.Diagnostics.EventLogEntryType.Error);
  2722. }
  2723. }
  2724. // on parcours tous les items et on fait un MakeTopic avec le headLine
  2725. }
  2726. return indexNew;
  2727. }
  2728. }
  2729. }