#!/usr/bin/env python

# xrflib.py
#
# Copyright Rob Cakebread 2001
# Released under the GNU Public License (See freenet:KSK@gpl.txt)
#

# Python system stuff
import os, sys, string, time, threading
#win32 removed socket :~(
# Custom stuff:
#win32 :
#from xmlrpclib import *
from prefs import *

if sys.platform == 'win32':
    xmlrpc = 0
else:
    xmlrpc = 1

TRANSFERRING=0
DONE=1
FAILED=2

class getKey(threading.Thread):
    def __init__(self, parent, server, port, key, filename, htl, dir):
        threading.Thread.__init__(self)
        self.setDaemon(1)
        self.server=server
        self.port=port
        self.key=key
        self.dir = dir
        #win32
        self.filename=('%s\%s' % (dir, filename))
        #self.filename=('%s/%s' % (dir, filename))
        self.htl=string.atoi(htl)
        self.verbose = 1
        self.setName(key)
        self.row = parent

    def run(self):
        if xmlrpc:
            self.xmlrpc()
        else:
            self.noXmlrpc()

    def noXmlrpc(self):
        #win32
        freenetdir = '\Freenet'
        hops = self.htl
        verbose =1
        filename = self.filename
        key = self.key
        #win32
        fileout = ("\Snarfzilla\%s" % filename)
        print fileout
        finsert = (r"c:\Freenet\Frequest")
        cmd = ('"%s" -h %s %s %s' % (finsert, hops, key, fileout))
        #cmd = ('"%s" -h %s %s' % (finsert, hops, key))
        print cmd
        i, o, result = os.popen3(cmd)
        l = o.readline()
        good = 0
        filesize = 0
        ttlFileSize = 0
        while l:
            l = result.readline()
            d = string.find(l, 'State') # This will show PREPARED, REQUESTING, DONE etc.
            if d != -1:
                l = string.replace(l, 'State "', '')
                l = string.replace(l, '" reached.', '')
                l = string.replace(l, 'PREPARED', 'Prepared...')
                l = string.replace(l, 'REQUESTING', 'Requesting...')
                l = string.replace(l, 'TRANSFERING', 'Transfering...')
                l = string.replace(l, 'DONE', 'Done.')
                good = 1 # If we don't get any 'State' messages, we have some sort of Java server error
            d = string.find(l, 'bytes started') # This is the file size
            if d != -1:
                ttlFileSize = string.split(l, ' ')[2]
                Status = 'Snarfing'
                filesize = 0
                self.row.UpdateRow(self.key, Status, filesize, ttlFileSize)

            d = string.find(l, ' bytes transfered.')
            if d != -1:
                filesize = string.split(l, ' ')[0]
                self.row.UpdateRow(self.key, Status, filesize, ttlFileSize)

            #d = string.find(l, 'waiting another') # This means the search started, konked out and was re-started
            #if d != -1:
                #print l

        if not good or ttlFileSize == 0:    # This means we received no "State" messages at all, something went very bad.
            Status = 'Fail'
        else:
            Status = 'Done'
        if filesize == 0:
            ttlFileSize = -1
        else:
            filesize = ttlFileSize
        self.row.UpdateRow(self.key, Status, filesize, ttlFileSize)


    '''
    # This is the *nix noXmlrpc:

    def noXmlrpc(self):
        freenetdir = '/home/rob/freenet'
        hops = self.htl
        verbose =1
        filename = self.filename
        key = self.key
        fileout = ("/home/rob/dev/snarfzilla/%s" % filename)
        result = os.popen("%s/freenet_request -h %s '%s' '%s' 2>&1" % (freenetdir, hops, key, fileout))
        l = result.readline()
        print l
        good = 0
        filesize = 0
        ttlFileSize = 0
        while l:
            l = result.readline()
            d = string.find(l, 'State "') # This will show PREPARED, REQUESTING, DONE etc.
            if d != -1:
                l = string.replace(l, 'State "', '')
                l = string.replace(l, '" reached.', '')
                l = string.replace(l, 'PREPARED', 'Prepared...')
                l = string.replace(l, 'REQUESTING', 'Requesting...')
                l = string.replace(l, 'TRANSFERING', 'Transfering...')
                l = string.replace(l, 'DONE', 'Done.')
                good = 1 # If we don't get any 'State' messages, we have some sort of Java server error
            d = string.find(l, 'bytes started') # This is the file size
            if d != -1:
                ttlFileSize = string.split(l, ' ')[2]
                Status = 'Snarfing'
                filesize = 0
                self.row.UpdateRow(self.key, Status, filesize, ttlFileSize)

            d = string.find(l, ' bytes transfered.')
            if d != -1:
                filesize = string.split(l, ' ')[0]
                self.row.UpdateRow(self.key, Status, filesize, ttlFileSize)

            d = string.find(l, 'waiting another') # This means the search started, konked out and was re-started
            if d != -1:
                print l

        if not good or ttlFileSize == 0:    # This means we received no "State" messages at all, something went very bad.
            Status = 'Fail'
        else:
            Status = 'Done'
        if filesize == 0:
            ttlFileSize = -1
        else:
            filesize = ttlFileSize
        self.row.UpdateRow(self.key, Status, filesize, ttlFileSize)
        '''

    def xmlrpc(self):
        self.file = open(self.filename, "wb")
        client = Server('http://%s:%s/' % (self.server, self.port))
        try:
            id = client.streaming.getPort()
        except:
            if debug == '1':
                print sys.exc_type, sys.exc_value
            print 'Error- Is XML-RPC enabled in your Freenet config file and is Freenet running?'
            print ('server:%s port:%s\n' % (self.server, self.port))
            self.row.UpdateRow(self.key, 'Error', 0, -1)
            sys.exit(0)
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.connect((self.server, id))
        client.streaming.startRequest(id, self.key, self.htl)
        status=client.streaming.getStatus(id)
        ttlFileSize = client.streaming.getFileSize(id)
        filesize = 0
        sizeCounter = 0
        try:
            while 1:
                if status==FAILED:
                    self.row.UpdateRow(self.key, 'Failed', filesize, ttlFileSize)
                    status = 'Failed'
                    try:
                        os.unlink(self.filename)
                    except os.error, value:
                        print "Couldn't delete file:", value[0], value[1]
                    break
                try:
                    chunk=s.recv(1024)
                except:
                    if debug == '1':
                        print "Couldn't chunk=s.recv(1024)"
                if not chunk: # End of file
                    break
                filesize = filesize + len(chunk)
                sizeCounter = sizeCounter + 1
                if sizeCounter >= 10:  #Print size every 10k
                    self.row.UpdateRow(self.key, 'Snarfing', filesize, ttlFileSize)
                    sizeCounter = 0
                self.file.write(chunk)
                #self.row.UpdateRow(self.key, 'Requesting', filesize, ttlFileSize)
            Status = 'Done'
        except:
            status=client.streaming.getStatus(id)
            if status==DONE:
                Status = 'Done'
                self.file.close()
            else:
                if debug == '1':
                    print sys.exc_type, sys.exc_value
                Status = 'Fail'
                try:
                    os.unlink(self.filename)
                except os.error, value:
                    print value[0], value[1]
        self.row.UpdateRow(self.key, Status, filesize, ttlFileSize)

