Light12306/TrainInfomationProviderService/StationInfo/SameStationManager.cs
2015-10-21 12:40:04 +08:00

159 lines
3.9 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms.VisualStyles;
using FSLib.Network.Http;
using Newtonsoft.Json;
namespace TrainInfomationProviderService.StationInfo
{
using TrainInfomationProviderService.Web;
class SameStationManager
{
public static Dictionary<string, HashSet<string>> SameStationMap { get; private set; }
private static Timer _timer;
internal static string _cacheUrl;
internal static string _blackHashesUrl;
public static void Init()
{
_cacheUrl = PathUtility.Combine(RunTimeContext.DataStorageRoot, "samestation.json");
_blackHashesUrl = PathUtility.Combine(RunTimeContext.DataStorageRoot, "blocksamestation.json");
SameStationMap = new Dictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
LoadCache();
if (StationManager.Instance.Storage != null)
{
AutoRefreshFromSource();
}
}
static void LoadCache()
{
if (!File.Exists(_cacheUrl)) return;
var list = JsonConvert.DeserializeObject<List<HashSet<string>>>(File.ReadAllText(_cacheUrl));
foreach (var hashSet in list)
{
foreach (var s in hashSet)
{
SameStationMap.AddOrUpdate(s, hashSet);
}
}
}
static void Grabber()
{
try
{
GrabberFromWeb();
}
catch (Exception)
{
}
_timer.Change(new TimeSpan(0, 30, 0), Timeout.InfiniteTimeSpan);
}
internal static void Save()
{
lock (_cacheUrl)
{
File.WriteAllText(_cacheUrl, JsonConvert.SerializeObject(SameStationMap.Values.Distinct().ToArray()));
}
}
internal static void AutoRefreshFromSource()
{
var map = SameStationMap;
if (map == null)
return;
var count = map.Count;
var stations = StationManager.Instance.Storage.StationNameMap.Values.OrderByDescending(s => s.Name.Length).ToList();
var blockStations = File.Exists(_blackHashesUrl) ? JsonConvert.DeserializeObject<Dictionary<string, HashSet<string>>>(File.ReadAllText(_blackHashesUrl)) : new Dictionary<string, HashSet<string>>();
while (stations.Count > 0)
{
var st = stations.Last();
stations.RemoveAt(stations.Count - 1);
HashSet<string> collection = null;
var blackList = blockStations.GetValue(st.Code);
for (var i = stations.Count - 1; i >= 0; i--)
{
if (stations[i].Name.IndexOf(st.Name) != 0 || blackList?.Contains(stations[i].Code) == true)
continue;
(collection ?? (collection = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { st.Code })).Add(stations[i].Code);
stations.RemoveAt(i);
i--;
}
if (collection != null && collection.Count > 1)
{
var curSet = collection.Select(map.GetValue).FirstOrDefault(s => s != null) ?? new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var s1 in collection)
{
curSet.SafeAdd(s1);
}
foreach (var s in collection)
{
map.AddOrUpdate(s, curSet);
}
}
}
if (SameStationMap.Count != count)
{
//有变化
Save();
}
}
private static string _url = "http://service.fishlee.net/ss.json";
static bool GrabberFromWeb()
{
var ctx = new HttpWebClient().Create<string>(HttpMethod.Get, _url).Send();
if (!ctx.IsValid())
return false;
//缓存
File.WriteAllText(_cacheUrl, ctx.Result);
var list = JsonConvert.DeserializeObject<List<HashSet<string>>>(File.ReadAllText(_cacheUrl));
var map = SameStationMap;
var count = SameStationMap.Count;
foreach (var hashSet in list)
{
var curSet = hashSet.Select(map.GetValue).FirstOrDefault(s => s != null) ?? new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var s1 in hashSet)
{
curSet.SafeAdd(s1);
}
foreach (var s in hashSet)
{
map.AddOrUpdate(s, curSet);
}
}
if (SameStationMap.Count != count)
{
//有变化
Save();
}
return true;
}
}
}