#!/usr/bin/env python # I, Danny Milosavljevic, hereby release this file into the public domain. import errno import time import os import socket import ssl import zlib import struct import getpass import hashlib import exceptions import base64 import webserver import sys class FileMetadata(object): def __init__(self, ID, is_directory, name, parent_inode, size, time, description, dummy_2, dummy_3, CRC, dummy_4, file_type, *args): self.ID = int(ID) self.B_directory = is_directory != "0" self.name = name self.parent_inode_ID = int(parent_inode) self.size = int(size) self.time = int(time) self.description = base64.decodestring(description) if description != "" else "" self.dummy_2 = int(dummy_2) self.dummy_3 = int(dummy_3) if dummy_3 != "" else None self.CRC = CRC self.dummy_4 = dummy_4 self.file_type = file_type # "png"|"unknown". self.parent = None self.children = [] #for name in dir(self): # print name, getattr(self, name) def __repr__(self): d = self.__dict__.copy() del d["parent"] return "FileMetadata(%r)" % d username = os.environ["USER"] password_hash = hashlib.sha1() password_hash.update(getpass.getpass("Password for user %r: " % username)) command_prefix = "%s\n%s\n" % (username, password_hash.hexdigest()) connection = None def reconnect(): global connection connection = socket.socket() connection.connect(("whiskey.megashares.com", 2939)) connection = ssl.wrap_socket(connection) #connection.send(command_prefix + "refresh\n") return connection file_list = None # global public def receive_file_list(): global file_list prefix = connection.recv(1) if prefix == "e": # error. print >>sys.stderr, "OOPS", "e" + connection.recv(1000) # FIXME. return data = connection.recv(100000) data = prefix + data assert(data.startswith("filelist\n")) #ilelist #2113 52 command_response, number_response, data_response = data.split("\n", 2) expected_size = struct.unpack(">I", data_response[0 : 4])[0] file_list = zlib.decompress(data_response[4 : ]) assert(len(file_list) == expected_size) file_list = [FileMetadata(*line.split("\t")) for line in file_list.split("\n") if line != ""] file_list = dict([(item.ID, item) for item in file_list]) # root node: file_list[0] = FileMetadata("0", "1", "", "0", "0", "0", "", "0", "0", "CRC", "0", "unknown") for item in file_list.values(): item.parent = file_list[item.parent_inode_ID] file_list[item.parent_inode_ID].children.append(item) file_list[0].parent = None file_list[0].children.remove(file_list[0]) return file_list def execute(command_args): s = "%s%s\n\n\n" % (command_prefix, "\n".join(command_args)) #print s reconnect() global connection connection.send(s) def update_file_list(): global file_list execute(["refresh"]) receive_file_list() update_file_list() #execute("ready") def check_status(): while True: status = connection.recv(4) if status != "": break if status == "done" or status == "read": # "done"|"ready" return status + connection.recv(1000) raise exceptions.Exception("bad bad status %r" % status) # FIXME def makedir(parent_ID, name): execute(["makedir", "%d\t%s" % (parent_ID, name)]) check_status() def movedir(ID, new_parent_ID, new_name): execute(["movedir", "%d\t%d\t%s" % (ID, new_parent_ID, new_name)]) check_status() def movefile(ID, new_parent_ID, new_name): execute(["movefile", "%d\t%d\t%s" % (ID, new_parent_ID, new_name)]) check_status() def deldir(ID): execute(["deldir", "%d" % ID]) check_status() def delfile(ID): execute(["delfile", "%d" % ID]) check_status() def downloadfile(ID): execute(["downloadfile", "%d" % ID]) response = check_status().split("\n") assert(response[0] == "ready") URL = response[1] return URL #port = int(response[1]) # port #return ("38.107.110.54", port) # FIXME def uploadurl(parent_ID, URLs): execute(["uploadurl", "\t".join(["%d" % parent_ID] + URLs)]) response = check_status().split("\n") print response def uploadfile(input_file, name, mime_type, parent_path): # mime_type = "unknown" is OK. # parent_path = "foo/bar" checksum = hashlib.md5() old_position = input_file.tell() while True: data = input_file.read(16384) if data == "": # EOF break checksum.update(data) size = input_file.tell() - old_position input_file.seek(old_position) # TODO web server with that file on a port. #port = 7 # FIXME #MD5\t<name>\t<type>\t<dummy>\t<zero>\t<dummy>\t<size>\t<dummy>\n\n\n", len=133) at ssl/qsslso # FIXME: is parent_ID position OK? dummy_1 = "" dummy_2 = "" zero_1 = "0" execute(["uploadfile", "\t".join([checksum.hexdigest(), name, mime_type, dummy_1, zero_1, dummy_2, str(size), parent_path])]) """ready 46576 218 None""" # whiskey.megashares.com response = check_status().split("\n") assert(response[0] == "ready") port = int(response[1]) socket_1 = socket.socket() socket_1.connect(("whiskey.megashares.com", port)) server = webserver.OneFileServer(input_file, socket_1) #, "ready", port]) MD5_prefix = checksum.hexdigest()[ : 7] not_CRC = "0" # 2e125f0 # FIXME ID = 0 # ??? # 2438490 # 2438820 d41d8cd #connection.send("done\n%d %d" % (ID, MD5_prefix)) #f = File(2212885) #print f.read(100, 0) #host, port = downloadfile(2212885) #import socket #c = socket.socket() #c.connect((host, port)) #c.send("GET file HTTP/1.1\x0D\x0AHost: %s:%d\x0D\x0AContent-Range: 0-*\x0D\x0Acontent-length: 0\x0D\x0A\x0D\x0A" % (host, port)) ##c.send("GET file HTTP/1.1\x0D\x0AHost: whiskey.megashares.com\x0D\x0AContent-Range: 0-*\x0D\x0Acontent-length: 0\x0D\x0A\x0D\x0A") #print c.recv(1000) #uploadurl(0, ["http://www.scratchpost.org/patch/22-meta-mime.patch"]) #print file_list[0].children[0] if __name__ == "__main__": import StringIO print uploadfile(StringIO.StringIO("foo"), "foo", "text/plain", "manga")