/// <summary> /// Searches the mainIndex for a manga /// </summary> /// <param name="term">Search term</param> /// <param name="top">The number of results to return</param> /// <returns>Results</returns> public List <MangaMatch> SearchIndex(string term, int top = 10) { if (mainIndex == null) { FetchIndex(); } term = term.ToLower(); Heap <MangaMatch> heap = new Heap <MangaMatch>((a, b) => a.CompareTo(b)); for (int i = 0; i < mainIndex.manga.Length; i++) { MangaAddress a = mainIndex.manga[i]; float score = 1f - Math.Min(EditDist(a.t.ToLower(), term) / (float)(term.Length + a.t.Length), EditDist(a.a.ToLower(), term) / (float)(term.Length + a.a.Length)); score = (float)Math.Pow(score, 1 / (1 + a.popWeight)); if (heap.Count < top) { heap.Add(new MangaMatch() { s = score, index = i }); } else if (heap.Peek().s < score) { heap.PollAdd(new MangaMatch() { s = score, index = i }); } } return(heap.ToList()); }
public void AsyncFetchRecents() { if (!api.IsReady) { return; } if (fetchRecentThread != null) { return; } fetchRecentThread = new Thread(() => { Heap <MangaBookmark> readHeap = new Heap <MangaBookmark>((a, b) => a.lastRead.CompareTo(b.lastRead));//Keeps track of last read date //Find most recently read mangas from bookmakrs foreach (var item in bookmarks) { if (item.Key == "") { continue; } if (readHeap.Count < NUM_RECENT_FEED_COL) { readHeap.Add(item.Value); } else if (readHeap.Peek().lastRead < item.Value.lastRead) { readHeap.PollAdd(item.Value); } } int i = 0; foreach (var item in readHeap.ToArray()) { if (!api.ContainsManga(item.id)) { continue; } MangaAddress a = api[item.id]; BitmapImage cover = api.FetchCover(item.id); Application.Current.Dispatcher.Invoke(() => {//Update UI Grid g = RecentsGrid.Children[i] as Grid; if (g.Resources.Contains("i")) { g.Resources["i"] = a.i; } else { g.Resources.Add("i", a.i); } Image img = g.Children[0] as Image; img.Source = cover; ((g.Children[1] as Viewbox).Child as TextBlock).Text = a.t + $"\nRead {item.lastRead.ToLocalTime().ToString("MM/dd/yyyy h:mm tt")}"; g.Visibility = Visibility.Visible; }); i++; } fetchRecentThread = null; }); fetchRecentThread.Start(); }
/// <summary> /// Processes the index after load to clean up html charectors and calculate popularity weight for search function /// </summary> private void ProcessIndex() { float minHit = float.MaxValue, maxHit = float.MinValue; table.Clear(); for (int i = 0; i < mainIndex.manga.Length; i++) { MangaAddress a = mainIndex.manga[i]; a.t = System.Net.WebUtility.HtmlDecode(a.t); a.a = System.Net.WebUtility.HtmlDecode(a.a); float s = (float)Math.Log(a.h + 1); minHit = Math.Min(minHit, s); maxHit = Math.Max(maxHit, s); mainIndex.manga[i] = a; table.Add(a.i, i); } for (int i = 0; i < mainIndex.manga.Length; i++) { mainIndex.manga[i].popWeight = (float)((Math.Log(mainIndex.manga[i].h + 1) - minHit) / (maxHit - minHit)); } }