Пример #1
0
        public void TestDifference()
        {
            var mapCli = new NewsMap
                {
                    channelIds = new[] {1, 3},
                    records = new[]
                        {
                            new NewsMapRecord(new DateTime(2013, 12, 2), 141),
                            new NewsMapRecord(new DateTime(2013, 12, 3), 102),
                            new NewsMapRecord(new DateTime(2013, 12, 4), 151),
                            new NewsMapRecord(new DateTime(2013, 12, 5), 151),
                            new NewsMapRecord(new DateTime(2013, 12, 6), 150),
                        }
                };
            var mapSrv = MakeTestMap();
            NewsMap mapDiff = null;
            try
            {
                mapDiff = mapCli.MakeMapOfLackedNews(mapSrv);
            }
            catch (Exception ex)
            {
                Assert.Fail("Failed to make NewsMap diff: {0}", ex);
            }

            Assert.AreEqual(5, mapDiff.channelIds[0], "lacked channels");
            Assert.AreEqual(3, mapDiff.records.Length, "records lacked - count is OK");
        }
Пример #2
0
        public static NewsMap LoadFromFile(string path)
        {
            if (!File.Exists(path)) return null;
            var doc = new XmlDocument();
            try
            {
                doc.Load(path);
            }
            catch (Exception ex)
            {
                Logger.Error("NewsMap.LoadFromFile() error: ", ex);
                return null;
            }

            if (doc.DocumentElement == null) return null;

            var map = new NewsMap();
            var records = new List<NewsMapRecord>();
            map.channelIds = doc.DocumentElement.GetAttributeString("channels").ToIntArrayUniform();
            foreach (XmlElement node in doc.DocumentElement)
            {
                DateTime date;
                if (!DateTime.TryParseExact(node.GetAttributeString("date"), "ddMMyyyy",
                                            CultureProvider.Common, DateTimeStyles.None, out date)) continue;
                var count = node.GetAttributeString("records", "0").ToIntSafe() ?? 0;
                records.Add(new NewsMapRecord { date = date, recordsCount = count });
            }
            map.records = records.ToArray();
            return map;
        }
Пример #3
0
        public NewsMap GetNewsMap(int accountId)
        {
            var map = new NewsMap
            {
                channelIds = new int[0],
                records = new NewsMapRecord[0]
            };

            if (!channelsByAccount.ContainsKey(accountId))
                return map;

            map.channelIds = channelsByAccount[accountId];

            // посчитать количество записей на дату
            var records = new Dictionary<DateTime, NewsMapRecord>();
            foreach (var chan in map.channelIds)
            {
                var list = newsByChannel[chan];
                foreach (var news in list)
                {
                    var date = news.Time.Date;
                    if (!records.ContainsKey(date))
                        records.Add(date, new NewsMapRecord(date, 1));
                    else
                        records[date] = new NewsMapRecord(date, records[date].recordsCount + 1);
                }
            }
            map.records = records.Values.OrderBy(r => r.date).ToArray();
            return map;
        }
Пример #4
0
        public bool AreSame(NewsMap map)
        {
            if (map.channelIds.Length != channelIds.Length ||
                map.records.Length != records.Length) return false;
            if (!map.channelIds.SequenceEqual(channelIds)) return false;
            if (!map.records.SequenceEqual(records)) return false;

            return true;
        }
Пример #5
0
        public NewsMap MakeMapOfLackedNews(NewsMap serverMap)
        {
            var resulted = new NewsMap
            {
                channelIds = serverMap.channelIds.Where(channelId => !channelIds.Any(id => id == channelId)).ToArray(),
                records    = (from record in serverMap.records let existRec = records.FirstOrDefault(r => r.date == record.date)
                                                                              where existRec.recordsCount < record.recordsCount select record).ToArray()
            };

            return(resulted);
        }
Пример #6
0
        private NewsCache()
        {
            syncCompletedEvent = new ManualResetEventSlim(false);
            mapPath = NewsLocalStorage.newsPath + "\\news_map.xml";
            NewsLocalStorage.Instance.EnsureNewsPath();

            // подкачать карту новостей (канал - дата - количество новостей)
            map = NewsMap.LoadFromFile(mapPath) ?? new NewsMap
                {
                    channelIds = new int[0],
                    records = new NewsMapRecord[0]
                };
        }
Пример #7
0
        public bool AreSame(NewsMap map)
        {
            if (map.channelIds.Length != channelIds.Length ||
                map.records.Length != records.Length)
            {
                return(false);
            }
            if (!map.channelIds.SequenceEqual(channelIds))
            {
                return(false);
            }
            if (!map.records.SequenceEqual(records))
            {
                return(false);
            }

            return(true);
        }
Пример #8
0
        public static NewsMap LoadFromFile(string path)
        {
            if (!File.Exists(path))
            {
                return(null);
            }
            var doc = new XmlDocument();

            try
            {
                doc.Load(path);
            }
            catch (Exception ex)
            {
                Logger.Error("NewsMap.LoadFromFile() error: ", ex);
                return(null);
            }

            if (doc.DocumentElement == null)
            {
                return(null);
            }

            var map     = new NewsMap();
            var records = new List <NewsMapRecord>();

            map.channelIds = doc.DocumentElement.GetAttributeString("channels").ToIntArrayUniform();
            foreach (XmlElement node in doc.DocumentElement)
            {
                DateTime date;
                if (!DateTime.TryParseExact(node.GetAttributeString("date"), "ddMMyyyy",
                                            CultureProvider.Common, DateTimeStyles.None, out date))
                {
                    continue;
                }
                var count = node.GetAttributeString("records", "0").ToIntSafe() ?? 0;
                records.Add(new NewsMapRecord {
                    date = date, recordsCount = count
                });
            }
            map.records = records.ToArray();
            return(map);
        }
Пример #9
0
        private void ActualizeSync(object accountIdObj)
        {
            var totalNews = 0;
            try
            {
                if (isTerminating) return;
                var accountId = (int)accountIdObj;
                if (accountId == 0)
                {
                    var accountData = AccountStatus.Instance.AccountData;
                    if (accountData != null)
                        accountId = accountData.ID;
                    if (accountId == 0) return;
                }

                // получить от сервера карту новостей
                NewsMap serverNewsMap = null;
                try
                {
                    using (var proxy = new NewsStorageProxy(TerminalBindings.BindingNewsStorage))
                    {
                        serverNewsMap = proxy.GetNewsMap(accountId);
                    }
                }
                catch (Exception ex)
                {
                    Logger.ErrorFormat("NewsCache({0}) - ошибка получения карты новостей: {1}",
                        accountId, ex);
                }
                if (serverNewsMap == null) return;
                if (isTerminating) return;

                // сформировать список каналов / дат, на которые нужно подкачать новости
                var lackMap = map.MakeMapOfLackedNews(serverNewsMap);
                if (lackMap.records.Length == 0 || serverNewsMap.channelIds.Length == 0)
                    return;

                // подкачать новости по указанным каналам за указанные даты
                var numFailsLeft = StopAskingServerAfterFails + 1;
                using (var proxy = new NewsStorageProxy(TerminalBindings.BindingNewsStorage))
                    foreach (var rec in lackMap.records)
                    {
                        if (isTerminating) break;

                        try
                        {
                            var news = proxy.GetNews(accountId, rec.date, serverNewsMap.channelIds);
                            if (news == null || news.Count == 0) continue;
                            totalNews += news.Count;
                            // обновить кеш новостей
                            NewsLocalStorage.Instance.UpdateNews(news);
                        }
                        catch (Exception ex)
                        {
                            numFailsLeft--;
                            if (numFailsLeft == 0) break;
                            Logger.Error("Ошибка в NewsCache.ActualizeSync()", ex);
                        }
                    }

                // сохранить кешированные новости
                NewsLocalStorage.Instance.SaveNewsInFiles();
                // обновить карту новостей
                map = NewsLocalStorage.Instance.MakeNewsMap(); //serverNewsMap;
                map.SaveInFile(mapPath);
            }
            finally
            {
                syncCompletedEvent.Set();
            }
            if (actualizationCompleted != null && !isTerminating)
                actualizationCompleted(totalNews);
        }
Пример #10
0
 public NewsMap MakeMapOfLackedNews(NewsMap serverMap)
 {
     var resulted = new NewsMap
         {
             channelIds = serverMap.channelIds.Where(channelId => !channelIds.Any(id => id == channelId)).ToArray(),
             records = (from record in serverMap.records let existRec = records.FirstOrDefault(r => r.date == record.date)
                        where existRec.recordsCount < record.recordsCount select record).ToArray()
         };
     return resulted;
 }
Пример #11
0
        public NewsMap GetNewsMap(int accountId)
        {
            var channels = GetChannelsByAccount(accountId);
            if (channels == null)
                return null;

            var map = new NewsMap
                {
                    channelIds = channels.ToArray()
                };
            // сформировать записи - дата - количество новостей по указанным каналам
            // запрос вида
            // select DateNews, COUNT(*) as Count from NEWS where Channel = 1 group by DateNews order by DateNews
            try
            {
                using (var cn = new SqlConnection(connectionString))
                {
                    cn.Open();
                    DbCommand cmd = cn.CreateCommand();
                    cmd.Connection = cn;
                    cmd.CommandText = string.Format("select DateNews, COUNT(*) as Count" +
                        " from NEWS where Channel in ({0}) group by DateNews order by DateNews",
                        string.Join(",", channels));

                    using (var dr = cmd.ExecuteReader())
                    {
                        var recordsList = new List<NewsMapRecord>();
                        while (dr.Read())
                        {
                            recordsList.Add(new NewsMapRecord((DateTime)dr["DateNews"], (int)dr["Count"]));
                        }
                        map.records = recordsList.ToArray();
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Error("DbNewsStorage.GetNewsMap: возникла ошибка ", ex);
                return null;
            }

            return map;
        }