Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/anemone/page_store.rb
Views: 11766
require 'forwardable'12module Anemone3class PageStore4extend Forwardable56def_delegators :@storage, :keys, :values, :size, :each78def initialize(storage = {})9@storage = storage10end1112# We typically index the hash with a URI,13# but convert it to a String for easier retrieval14def [](index)15@storage[index.to_s]16end1718def []=(index, other)19@storage[index.to_s] = other20end2122def delete(key)23@storage.delete key.to_s24end2526def has_key?(key)27@storage.has_key? key.to_s28end2930def each_value31each { |key, value| yield value }32end3334def values35result = []36each { |key, value| result << value }37result38end3940def touch_key(key)41self[key] = Page.new(key)42end4344def touch_keys(keys)45@storage.merge! keys.inject({}) { |h, k| h[k.to_s] = Page.new(k); h }46end4748# Does this PageStore contain the specified URL?49# HTTP and HTTPS versions of a URL are considered to be the same page.50def has_page?(url)51schemes = %w(http https)52if schemes.include? url.scheme53u = url.dup54return schemes.any? { |s| u.scheme = s; has_key?(u) }55end5657has_key? url58end5960#61# Use a breadth-first search to calculate the single-source62# shortest paths from *root* to all pages in the PageStore63#64def shortest_paths!(root)65root = URI(root) if root.is_a?(String)66raise "Root node not found" if !has_key?(root)6768q = Queue.new6970q.enq root71root_page = self[root]72root_page.depth = 073root_page.visited = true74self[root] = root_page75while !q.empty?76page = self[q.deq]77page.links.each do |u|78begin79link = self[u]80next if link.nil? || !link.fetched? || link.visited8182q << u unless link.redirect?83link.visited = true84link.depth = page.depth + 185self[u] = link8687if link.redirect?88u = link.redirect_to89redo90end91end92end93end9495self96end9798#99# Removes all Pages from storage where redirect? is true100#101def uniq!102each_value { |page| delete page.url if page.redirect? }103self104end105106#107# If given a single URL (as a String or URI), returns an Array of Pages which link to that URL108# If given an Array of URLs, returns a Hash (URI => [Page, Page...]) of Pages linking to those URLs109#110def pages_linking_to(urls)111unless urls.is_a?(Array)112urls = [urls]113single = true114end115116urls.map! do |url|117unless url.is_a?(URI)118URI(url) rescue nil119else120url121end122end123urls.compact124125links = {}126urls.each { |url| links[url] = [] }127values.each do |page|128urls.each { |url| links[url] << page if page.links.include?(url) }129end130131if single and !links.empty?132return links[urls.first]133else134return links135end136end137138#139# If given a single URL (as a String or URI), returns an Array of URLs which link to that URL140# If given an Array of URLs, returns a Hash (URI => [URI, URI...]) of URLs linking to those URLs141#142def urls_linking_to(urls)143unless urls.is_a?(Array)144urls = [urls] unless urls.is_a?(Array)145single = true146end147148links = pages_linking_to(urls)149links.each { |url, pages| links[url] = pages.map{|p| p.url} }150151if single and !links.empty?152return links[urls.first]153else154return links155end156end157158end159end160161162