| Server IP : 182.53.201.61 / Your IP : 216.73.217.175 Web Server : Apache/2.2.15 (Fedora) System : Linux km10.dyndns.org 2.6.31.5-127.fc12.i686.PAE #1 SMP Sat Nov 7 21:25:57 EST 2009 i686 User : apache ( 48) PHP Version : 5.3.3 Disable Function : NONE MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/share/doc/python-telepathy-0.15.11/examples/ |
Upload File : |
import dbus.glib
import sys
import dbus
import gobject
import socket
import os
import sys
import fcntl
import time
from dbus import PROPERTIES_IFACE
from telepathy.client import (Connection, Channel)
from telepathy.interfaces import (CONN_INTERFACE, CONNECTION_INTERFACE_REQUESTS, CHANNEL, CHANNEL_TYPE_FILE_TRANSFER)
from telepathy.constants import (CONNECTION_HANDLE_TYPE_CONTACT, CONNECTION_STATUS_CONNECTING,
CONNECTION_STATUS_CONNECTED, CONNECTION_STATUS_DISCONNECTED, SOCKET_ADDRESS_TYPE_UNIX,
SOCKET_ACCESS_CONTROL_LOCALHOST, FILE_TRANSFER_STATE_NONE, FILE_TRANSFER_STATE_PENDING, FILE_TRANSFER_STATE_ACCEPTED,
FILE_TRANSFER_STATE_OPEN, FILE_TRANSFER_STATE_COMPLETED, FILE_TRANSFER_STATE_CANCELLED)
from account import connection_from_file
loop = None
ft_states = ['none', 'pending', 'accepted', 'open', 'completed', 'cancelled']
class FTClient(object):
def __init__(self, account_file):
self.conn = connection_from_file(account_file, ready_handler=self.ready_cb)
self.conn[CONN_INTERFACE].connect_to_signal('StatusChanged',
self.status_changed_cb)
def run(self):
self.conn[CONN_INTERFACE].Connect()
loop = gobject.MainLoop()
try:
loop.run()
finally:
try:
self.conn[CONN_INTERFACE].Disconnect()
except:
pass
def status_changed_cb(self, state, reason):
if state == CONNECTION_STATUS_CONNECTING:
print 'connecting'
elif state == CONNECTION_STATUS_CONNECTED:
print 'connected'
elif state == CONNECTION_STATUS_DISCONNECTED:
print 'disconnected'
loop.quit()
def ready_cb(self, conn):
print "ready"
self.conn[CONNECTION_INTERFACE_REQUESTS].connect_to_signal('NewChannels',
self.new_channels_cb)
self.self_handle = self.conn[CONN_INTERFACE].GetSelfHandle()
self.self_id = self.conn[CONN_INTERFACE].InspectHandles(CONNECTION_HANDLE_TYPE_CONTACT,
[self.self_handle])[0]
print "I am %s" % self.self_id
if not self.is_ft_present():
print "FileTransfer is not implemented on this ConnectionManager"
sys.exit(1)
def is_ft_present(self):
# check if we can request FT channels
properties = self.conn[PROPERTIES_IFACE].GetAll(CONNECTION_INTERFACE_REQUESTS)
classes = properties['RequestableChannelClasses']
for fixed_prop, allowed_prop in classes:
if fixed_prop[CHANNEL + '.ChannelType'] == CHANNEL_TYPE_FILE_TRANSFER:
return True
return False
def new_channels_cb(self, channels):
for path, props in channels:
if props[CHANNEL + '.ChannelType'] == CHANNEL_TYPE_FILE_TRANSFER:
print "new FileTransfer channel"
self.ft_channel = Channel(self.conn.service_name, path)
self.ft_channel[CHANNEL_TYPE_FILE_TRANSFER].connect_to_signal('FileTransferStateChanged',
self.ft_state_changed_cb)
self.ft_channel[CHANNEL_TYPE_FILE_TRANSFER].connect_to_signal('TransferredBytesChanged',
self.ft_transferred_bytes_changed_cb)
self.ft_channel[CHANNEL_TYPE_FILE_TRANSFER].connect_to_signal('InitialOffsetDefined',
self.ft_initial_offset_defined_cb)
self.got_ft_channel()
self.file_name = props[CHANNEL_TYPE_FILE_TRANSFER + '.Filename']
self.file_size = props[CHANNEL_TYPE_FILE_TRANSFER + '.Size']
def ft_state_changed_cb(self, state, reason):
print "file transfer is now in state %s" % ft_states[state]
def ft_transferred_bytes_changed_cb(self, count):
per_cent = (float(count) / self.file_size) * 100
print "%.u%s transferred" % (per_cent, '%')
def ft_initial_offset_defined_cb(self, offset):
self.initial_offset = offset
class FTReceiverClient(FTClient):
def ready_cb(self, conn):
FTClient.ready_cb(self, conn)
print "waiting for file transfer offer"
def got_ft_channel(self):
print "accept FT"
self.sock_addr = self.ft_channel[CHANNEL_TYPE_FILE_TRANSFER].AcceptFile(
SOCKET_ADDRESS_TYPE_UNIX, SOCKET_ACCESS_CONTROL_LOCALHOST, "", 0,
byte_arrays=True)
def ft_state_changed_cb(self, state, reason):
FTClient.ft_state_changed_cb(self, state, reason)
if state == FILE_TRANSFER_STATE_OPEN:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(self.sock_addr)
path = self.create_output_path()
if self.initial_offset == 0:
out = file(path, 'w')
else:
out = file(path, 'a')
# Set non-blocking
fcntl.fcntl(out, fcntl.F_SETFL, os.O_NONBLOCK)
read = self.initial_offset
while read < self.file_size:
data = s.recv(self.file_size - read)
read += len(data)
out.write(data)
out.close()
print "received file: %s" % path
def create_output_path(self):
for i in range(30):
if i == 0:
name = self.file_name
else:
name = "%s.%d" % (self.file_name, i)
path = os.path.join('/tmp', name)
if not os.path.exists(path):
return path
class FTSenderClient(FTClient):
def __init__(self, account_file, contact, filename):
FTClient.__init__(self, account_file)
self.contact = contact
self.file_to_offer = filename
def ready_cb(self, conn):
FTClient.ready_cb(self, conn)
# Wait a bit so the other side is aware about us. If he's not,
# he'll automatically reject the XMPP connection.
time.sleep(3)
handle = self.conn.RequestHandles(CONNECTION_HANDLE_TYPE_CONTACT, [self.contact])[0]
file_name = os.path.basename(self.file_to_offer)
info = os.stat(self.file_to_offer)
size = info.st_size
# Request FT channel
self.conn[CONNECTION_INTERFACE_REQUESTS].CreateChannel({
CHANNEL + '.ChannelType': CHANNEL_TYPE_FILE_TRANSFER,
CHANNEL + '.TargetHandleType': CONNECTION_HANDLE_TYPE_CONTACT,
CHANNEL + '.TargetHandle': handle,
CHANNEL_TYPE_FILE_TRANSFER + '.ContentType': 'application/octet-stream',
CHANNEL_TYPE_FILE_TRANSFER + '.Filename': file_name,
CHANNEL_TYPE_FILE_TRANSFER + '.Size': size,
CHANNEL_TYPE_FILE_TRANSFER + '.Description': "I'm testing file transfer using Telepathy",
CHANNEL_TYPE_FILE_TRANSFER + '.InitialOffset': 0})
def got_ft_channel(self):
print "Offer %s to %s" % (self.file_to_offer, self.contact)
self.sock_addr = self.ft_channel[CHANNEL_TYPE_FILE_TRANSFER].ProvideFile(SOCKET_ADDRESS_TYPE_UNIX,
SOCKET_ACCESS_CONTROL_LOCALHOST, "", byte_arrays=True)
def ft_state_changed_cb(self, state, reason):
FTClient.ft_state_changed_cb(self, state, reason)
if state == FILE_TRANSFER_STATE_OPEN:
# receive file
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(self.sock_addr)
f = file(self.file_to_offer, 'r')
f.seek(self.initial_offset)
fcntl.fcntl(f, fcntl.F_SETFL, os.O_NONBLOCK)
s.send(f.read())
f.close()
def usage():
print "Usage:\n" \
"Send [file] to [contact]:\n" \
"\tpython %s [account-file] [contact] [file]\n" \
"Accept a file transfer from a contact:\n" \
"\tpython %s [account-file]\n" \
% (sys.argv[0], sys.argv[0])
if __name__ == '__main__':
args = sys.argv[1:]
if len(args) == 3:
account_file = args[0]
contact = args[1]
filename = args[2]
client = FTSenderClient(account_file, contact, filename)
elif len(args) == 1:
account_file = args[0]
client = FTReceiverClient(account_file)
else:
usage()
sys.exit(0)
client.run()