Last active
August 29, 2015 14:14
-
-
Save townie/d29f7c120f44d89445ea to your computer and use it in GitHub Desktop.
Neo4j google drive items hierachy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ChildOf | |
include Neo4j::ActiveRel | |
from_class GoogleDriveItem | |
to_class GoogleDriveItem | |
type 'child_of' | |
property :since, type: Integer | |
validates_presence_of :since | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class GoogleDriveItem | |
include Neo4j::ActiveNode | |
include Backupify::LoggerSupport | |
property :document_id, constraint: :unique | |
property :service_id, default: "foo1" | |
property :document_type, default: "foo2" | |
property :folder_ids, default: {"foo12324" =>"bar"} | |
property :title, default: "foo7" | |
property :size, default: "foo235678" | |
serialize :access_control_list | |
serialize :folder_ids | |
index :document_id | |
has_many :out, :parents, model_class: GoogleDriveItem, rel_class: ChildOf | |
def set_parent(parent, since) | |
ChildOf.create(from_node: self, to_node: parent, since: since) | |
end | |
def children(time=Time.now.to_i) | |
time.to_datetime.to_i unless time.is_a?(Integer) | |
candidates = query_as(:parent).match('parent<-[rel:child_of]-(child)').where("rel.since < #{time}").pluck(:rel) | |
rels = candidates.inject({}) do |hash,rel| | |
doc_id = rel.from_node.document_id | |
if hash.has_key?(doc_id) && (rel.since > hash[doc_id].since) | |
hash[doc_id] = rel | |
else | |
hash[doc_id] = rel | |
end | |
hash | |
end | |
rels.values.map(&:from_node) | |
end | |
def insert_into_graph | |
node = fetch_node_with_document_id | |
if node.nil? | |
self.save | |
node = self | |
else | |
node = transfer_attr(node,self) | |
end | |
parents = locate_parent_object(node) | |
parents.each do |parent| | |
node.set_parent(parent, Time.now.to_i) | |
end | |
node | |
end | |
def hierarchy(time=Time.now.to_i) | |
time = time.to_datetime.to_i unless time.is_a?(Integer) | |
h = children(time).inject({}) do |hash,child| | |
hash[child.title] = child.hierarchy(time) | |
hash | |
end | |
if h.empty? | |
document_id | |
else | |
h | |
end | |
end | |
private | |
def label_from_mime(node) | |
node.add_label(node.document_type) | |
end | |
def transfer_attr(to_node,from_node) | |
attrs = to_node.attributes.keys | |
attrs.each do |attr| | |
to_node[attr] = from_node[attr] | |
end | |
to_node.save | |
to_node | |
end | |
def fetch_node_with_document_id | |
GoogleDriveItem.find_by(:document_id => self.document_id) | |
end | |
def locate_parent_object(node) | |
parent_ids = node.folder_ids.try(:keys) | |
# returns only in case of my_drive | |
return [] if node.is_my_drive? | |
parents = parent_ids.map do |pid| | |
begin | |
GoogleDriveItem.find_by(:document_id => pid) | |
rescue => e | |
logger.log_exception(e) | |
end | |
end | |
parents.compact! | |
if parents.empty? | |
parents = create_dummy_parent(parent_ids) | |
end | |
parents | |
end | |
def create_dummy_parent(parent_ids) | |
parent_ids.map do |pid| | |
GoogleDriveItem.create(:document_id => pid) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment