main
sandyx 11 months ago
commit ee8246a0cc

@ -0,0 +1,55 @@
require 'fileutils'
class Database
def initialize(file)
@file = file
File.open(@file, 'w').write unless File.exist? @file
lines = File.readlines(@file) if File.exist? @file
FileUtils.touch(@file) unless File.exist? @file
lines.count = 0 unless File.exist? @file
@start = 0
@end = lines.count
end
def message(msg)
puts "#{@file}: #{msg}"
end
def get(key)
lines= File.readlines(@file)
eval('[' + lines.join() + ']').map { |hash|
hash[key]
}
end
def prepend(key, val)
lines = File.readlines(@file)
lines.insert(@start, "{:key => '#{key}', :value => '#{val}'},\n")
File.write(@file, lines.join)
end
def append(key, val)
message "added #{key} => #{val}"
lines = File.readlines(@file)
lines.insert(@end, "{:key => '#{key}', :value => '#{val}'},\n")
File.write(@file, lines.join)
end
def <<(hash)
lines = File.readlines(@file)
lines.insert(@end, "{:key => '#{hash[:key]}', :value => '#{hash[:value]}'},\n")
File.write(@file, lines.join)
end
def [](i)
lines = File.readlines(@file)
return eval('[' + lines.join() + ']')[i]
#return eval lines[i]
end
def []=(i, hash)
lines = File.readlines(@file)
lines.insert(i, "{:key => '#{hash[:key]}', :value => '#{hash[:value]}'},\n")
File.write(@file, lines.join)
end
end

@ -0,0 +1,227 @@
#!/usr/bin/ruby
require 'socket'
require './database.rb'
ANSI_GREEN = "\e[32m"
ANSI_BLUE = "\e[34m"
ANSI_CLEAR = "\e[0m"
APPNAME = "#{ANSI_GREEN}APOCRYPHA#{ANSI_CLEAR}"
HTTP_GET = "GET"
HTTP_POST = "POST"
HTTP_QUERY = "QUERY"
HTTP_NIL = "NIL"
ROOT = ARGV[0]
PORT = ARGV[1]
db = Database.new('db.rb')
def message(msg)
puts "#{APPNAME}: #{msg}"
end
def error(msg)
puts "#{APPNAME}: #{msg}"
exit 1
end
#just to make the rest of the code look prettier
class String
def as_root
return "#{ROOT}/#{self}"
end
def tag(tag)
return "<#{tag}>#{self}</#{tag}>"
end
def tag_href(tag, href)
return "<#{tag} href=#{href}>#{self}</#{tag}>"
end
def tag_attrs(tag, attrs)
#this is kinda yucky
return "<#{tag} #{attrs.keys[0]}=\"#{attrs.values[0]}\">#{self}</#{tag}>"
end
end
def tmpl_not_found(data)
"<!DOCTYPE html><html><body><h>404 File not found: #{data}</h></body></html>"
end
def http_ok(data)
return "HTTP/1.1 200 OK\r\n\r\n #{data.join}" if data.class == Array
return "HTTP/1.1 200 OK\r\n\r\n #{data}" if data.class == String
message("could not :(")
end
def http_png(data)
return "HTTP/1.1 200 OK\r\nContent-Type: image/png\r\n\r\n #{data}" if data.class == String
message("could not :(")
end
def http_not_found(uri)
return "HTTP/1.1 404 Not Found\r\n\r\n #{tmpl_not_found(uri)}"
end
def init_database(db)
#get all files and check if theyre already in the database
keys = db.get(:key)
files = Dir.children(ROOT).filter {|x| x.end_with? ".pdf"}
not_files = files - keys
threads = []
mtx = Mutex.new
#if not make a thumbnail and add it
not_files.each do |file|
threads << Thread.new {
make_thumbnail "#{ROOT}/#{file}"
mtx.synchronize {
db.append(file, "#{File.basename(file, ".pdf")}.png")
}
}
end
threads.each { |t| t.join }
until threads.map {|t| t.alive?}.include? false
end unless threads.empty?
end
#generate html to send on requesting "/"
def gen_html(db)
keys = db.get(:key)
hrefs = db.get(:value)
key = 0
value = 1
content = keys.zip(hrefs).map { |x|
img_tag = "<img src=#{x[value]}>"
img_tag = img_tag.tag_href("a", x[key])
img_tag = img_tag.tag_attrs("div", {:class => "grid-item"})
}
content = content.join
content = content.tag_attrs("div", {:class => "grid-container"})
stylesheet = File.read("#{ROOT}/style.css")
stylesheet = stylesheet.tag("style")
head = stylesheet.tag("head")
body = content.tag("pre").tag("body")
html = (head + body).tag("html")
html = "<!DOCTYPE html>" + html
end
HANDLERS = {"/" => lambda { |cli| cli.puts http_ok gen_html(db)}}
DEFAULT = lambda { |cli, uri|
unless File.exist? "#{uri.as_root}"
message("could not open file: #{uri}")
cli.puts http_not_found uri
return
end
cli.puts http_ok File.read("#{uri.as_root}")
}
IMAGE_HANDLER = lambda { |cli, uri|
unless File.exist? "#{uri.as_root}"
message("could not open file: #{uri}")
cli.puts http_not_found uri
return
end
cli.puts File.read("#{uri.as_root}")
}
def make_thumbnail(file)
`convert -thumbnail "140x200" -background white -alpha remove -crop 178x178+0+0 "#{file}"[0] "#{ROOT}/#{File.basename(file, ".pdf")}.png"`
end
def get_file(cli, uri)
if HANDLERS[uri]
HANDLERS[uri].call(cli)
elsif uri.end_with? ".png"
IMAGE_HANDLER.call(cli, uri.split("/")[1])
#never wants the ico?
elsif uri.end_with? ".ico"
lambda { |cli, uri|
unless File.exist? uri.as_root
message "could not open file: #{uri}"
cli.puts http_not_found uri
return
end
cli.puts "HTTP/1.1 200 OK\r\nContent-Type: image/icon\r\n\r\n" + File.read(uri.as_root)
}.call(cli, uri.split("/")[1])
else
DEFAULT.call(cli, uri.split("/")[1])
end
end
def put_file(cli, uri, data)
"handle it"
end
class Request
attr_reader :method
attr_reader :data
attr_reader :uri
attr_reader :version
attr_reader :headers
def parse_request(str)
if @data[0].nil?
@method = HTTP_NIL
return
end
@method = @data[0].split(" ")[0]
@uri = @data[0].split(" ")[1]
@version = @data[0].split(" ")[2]
@headers = @data.map.drop(1) { |header|
{header.split(": ")[0] => header.split(": ")[1]}
}
end
def initialize(cli)
@data = [cli.gets]
parse_request(@data)
end
end
error("specify root folder") if ROOT.nil?
error("specify port") if PORT.nil?
message("starting server on port: #{PORT}")
init_database(db)
TCPServer.open("127.0.0.1", PORT) { |srv|
mutex = Mutex.new
loop do
Thread.start(srv.accept) { |cli|
mutex.synchronize do
h = Request.new(cli)
case h.method
when HTTP_GET
cli.puts get_file(cli, h.uri)
when HTTP_POST
message("unknown method: #{h.method}")
when HTTP_QUERY
cli.write Dir.children(ROOT).join("\n")
when HTTP_NIL
break
else
message("unknown method: #{h.method}")
end
cli.close
end
}
end
}

@ -0,0 +1,54 @@
#!/usr/bin/ruby
require 'net/http'
require 'socket'
PORT = 8081
HTTP_GET = "GET"
HTTP_POST = "POST"
HTTP_QUERY = "QUERY"
QDIR = ARGV[0]
class Request
attr_reader :method
attr_reader :data
attr_reader :uri
attr_reader :version
attr_reader :headers
def parse_request(str)
@method = @data[0].split(" ")[0]
@uri = @data[0].split(" ")[1]
@version = @data[0].split(" ")[2]
@headers = @data.map.drop(1) { |header|
{header.split(": ")[0] => header.split(": ")[1]}
}
end
def initialize(cli)
@data = [cli.gets]
parse_request(@data)
end
end
TCPServer.open("127.0.0.1", PORT) { |srv|
mutex = Mutex.new
loop do
Thread.start(srv.accept) { |cli|
mutex.synchronize do
h = Request.new(cli)
case h.method
when HTTP_QUERY
cli.write Dir.children(QDIR).join("\n")
else
cli.write("unknown method: #{h.method}")
end
cli.close
end
}
end
}
Loading…
Cancel
Save