#coding: UTF-8 import os import socket import ConfigParser from ccnet.packet import to_request_id, to_update_id from ccnet.packet import request_to_packet, update_to_packet from ccnet.packet import write_packet from ccnet.errors import NetworkError from .utils import make_socket_closeonexec def parse_response(body): '''Parse the content of the response The struct of response data: - first 3 bytes is the - from the 4th byte to the first occurrence of '\n' is the . If the 4th byte is '\n', then there is no - from the first occurrence of '\n' to the end is the ''' code = body[:3] if body[3] == '\n': code_msg = '' content = body[4:] else: pos = body.index('\n') code_msg = body[4:pos] content = body[pos + 1:] return code, code_msg, content def parse_update(body): '''The structure of an update is the same with a response''' code = body[:3] if body[3] == '\n': code_msg = '' content = body[4:] else: pos = body.index('\n') code_msg = body[4:pos] content = body[pos + 1:] return code, code_msg, content class Client(object): '''Base ccnet client class''' def __init__(self, config_dir): if not isinstance(config_dir, unicode): config_dir = config_dir.decode('UTF-8') config_dir = os.path.expanduser(config_dir) config_file = os.path.join(config_dir, u'ccnet.conf') if not os.path.exists(config_file): raise RuntimeError(u'%s does not exits' % config_file) self.config_dir = config_dir self.config_file = config_file self.config = None self.port = None self.peer_id = None self.peer_name = None self.parse_config() self._connfd = None self._req_id = 1000 def __del__(self): '''Destructor of the client class. We close the socket here, if connetced to daemon ''' if self.is_connected(): try: self._connfd.close() except: pass def parse_config(self): self.config = ConfigParser.ConfigParser() self.config.read(self.config_file) self.port = self.config.getint('Client', 'PORT') self.peer_id = self.config.get('General', 'ID') self.peer_name = self.config.get('General', 'NAME') def connect_daemon(self): self._connfd = socket.socket() self._connfd.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) try: self._connfd.connect(('127.0.0.1', self.port)) except: raise NetworkError("Can't connect to daemon") make_socket_closeonexec(self._connfd.fileno()) def is_connected(self): return self._connfd != None def send_request(self, id, req): id = to_request_id(id) pkt = request_to_packet(id, req) write_packet(self._connfd, pkt) def send_update(self, id, code, code_msg, content=''): id = to_update_id(id) pkt = update_to_packet(id, code, code_msg, content) write_packet(self._connfd, pkt) def get_request_id(self): self._req_id += 1 return self._req_id