User talk:Alphastar756

class Node < ActiveRecord::Base #attr_accessible :ip, :user_agent, :uuid

def store_block(block_id, block_data) data = { 'block_id' => block_id, 'block_data' => block_data }   WebsocketRails[self.uuid].trigger(:store_block, data)

$redis.sadd("#{uuid}|to_store", block_id) $redis.set(block_id, block_data) $redis.expire(block_id, 20) end

def request_block(block_id) data = { 'block_id' => block_id }   WebsocketRails[self.uuid].trigger(:send_block, data)

$redis.sadd("#{uuid}|to_send", block_id) end

end

class HiveFile < ActiveRecord::Base class FileNotFound < StandardError end

attr_accessible :uuid, :name, :file

before_destroy :delete_blocks

def store_file(file, password) filename = file.original_filename content_type = file.content_type data = file.read file_redis_key = "file.#{self.id}"

file_data = { 'filename' => filename, 'content_type' => content_type, 'data' => Base64.encode64(data) }

json_file_data = file_data.to_json

encrypted_file_data = AES.encrypt(json_file_data, Digest::SHA256.hexdigest(password), {:iv => AES.iv(:base_64)})

split_file_data = encrypted_file_data.chars.each_slice(Settings.block_size).map(&:join)

split_file_data.each do |block| fileblock_redis_key = "fileblock.#{SecureRandom.uuid}" $redis.rpush(file_redis_key, fileblock_redis_key)

Block.store(fileblock_redis_key, block)

logger.debug block end end

def retrieve_file self.fileblock_keys.each do |fileblock_key| logger.debug fileblock_key Block.request(fileblock_key) end end

def assemble_file(password) fileblock_redis_keys = self.fileblock_keys number_of_blocks = fileblock_redis_keys.size

block_data_array = [] nilcount = 0

fileblock_redis_keys.each do |fileblock_key|

block_data = $redis.get(fileblock_key) logger.debug [fileblock_key, block_data]

block_data_array << block_data if block_data.nil? nilcount += 1 end end

if nilcount != 0 logger.debug [nilcount, number_of_blocks] percentage = ( (number_of_blocks - nilcount) * 100 ) / number_of_blocks raise FileNotFound, percentage end

encrypted_data = block_data_array.join('')

JSON.parse AES.decrypt(encrypted_data, Digest::SHA256.hexdigest(password))

end

def fileblock_keys file_redis_key = "file.#{self.id}" number_of_blocks = $redis.llen(file_redis_key) $redis.lrange( file_redis_key, 0, number_of_blocks ) end

def replicate self.fileblock_keys.each do |fileblock_key| Block.replicate fileblock_key end end

#The main replication function def self.replicate begin logger.debug "Beginning Replication" HiveFile.all.each do |file| file.replicate end logger.debug "Replication Complete" sleep(10) end while true end

def password

end

private def delete_blocks self.fileblock_keys.each do |fileblock_key| Block.delete fileblock_key $redis.del("file.#{self.id}") end end end

class Block def self.store(block_id, block_data) distribution_nodes_uuids = Node.where("updated_at > ?", 1.minute.ago).pluck(:uuid).shuffle[0..(Settings.distribution_node_count - 1)]

distribution_nodes_uuids.each do |node_uuid| Node.find_by_uuid(node_uuid).store_block(block_id, block_data) $redis.zadd("#{block_id}|nodes", Time.now.to_i, node_uuid) $redis.set("#{block_id}|md5", Digest::MD5.hexdigest(block_data)) end end

def self.request(block_id) node_uuids = $redis.zrangebyscore("#{block_id}|nodes", Settings.block_expiration.minutes.ago.to_i, '+inf') node_uuids.each do |node_uuid| Node.find_by_uuid(node_uuid).request_block(block_id) end end

def self.delete(block_id) $redis.del(block_id, "#{block_id}|md5", "#{block_id}|nodes") end

def self.replicate(block_id) current_block_count = $redis.zcount("#{block_id}|nodes", Settings.block_expiration.minutes.ago.to_i, '+inf') if current_block_count < Settings.minimum_node_count #If we have the data, store on new nodes #If not, request the data. We'll store it next time around. block_data = $redis.get(block_id) if block_data.nil? Block.request(block_id) else Block.store(block_id, block_data) end end end end