Source code for jsonwspclient.jsonwsputils

# -*- coding: utf-8 -*-
"""
==============================================
Jsonwsputils :mod:`jsonwspclient.jsonwsputils`
==============================================

"""
from __future__ import with_statement, absolute_import, print_function
import io
import os
import re
import sys
import types
import logging
from six import string_types, integer_types
if sys.version_info[0] == 2:
    def make_method(funct, instance, cls):
        """Make method"""
        return types.MethodType(funct, instance, cls)
elif sys.version_info[0] >= 3:
[docs] def make_method(funct, instance, _cls): """Make method""" return types.MethodType(funct, instance)
has_attachments = re.compile(r'(?i)^cid:(.+)$').match _get_multipart = re.compile(r'(?i)multipart/(?P<multipart>[^; ]+)').search _get_boundary = re.compile(r'(?i)boundary=(?P<boundary>[^; ]+)').search _get_charset = re.compile( r'(?i)charset\s*=\s*(?P<charset>[-_.a-zA-Z0-9]+)').search log = logging.getLogger('jsonwspclient')
[docs]def get_fileitem(path, data='data', name='name', mode='rb'): """get fileitem.""" path = os.path.abspath(path) return { name: os.path.basename(path), data: open(path, mode), }
[docs]def get_multipart(headers): """return multipart.""" multipart = _get_multipart(headers.get('Content-type', '')) if multipart: return multipart.group(1) return None
[docs]def get_boundary(headers): """return boundary.""" boundary = _get_boundary(headers.get('Content-type', '')) if boundary: return boundary.group(1) return None
[docs]def get_charset(headers): """return charset.""" charset = _get_charset(headers.get('Content-type', '')) if charset: return charset.group(1) return None
[docs]def check_attachment(items): """check_attachment.""" res = {} if not isinstance(items, list): items = [items] for item in items: for value in item.values(): if not isinstance(value, string_types): continue isatt = has_attachments(value) if isatt: res.update({isatt.group(1): item}) return res
[docs]def fix_attachment(val, attachment_map): """Fix attachment.""" if hasattr(val, 'read'): while True: cid = 'file{}'.format(attachment_map['cid_seq']) attachment_map['cid_seq'] += 1 if cid not in attachment_map['files']: break attachment_map['files'][cid] = val return 'cid:%s' % cid if (isinstance(val, string_types) and val and val[0] == '@' and os.path.isfile(val[1:])): cid = os.path.normpath(val[1:]) if cid not in attachment_map: attachment_map['files'][cid] = open(cid, 'rb') return 'cid:%s' % cid
[docs]def walk_args_dict(kwargs, attachment_map): """Walk args.""" for key, value in kwargs.items(): if isinstance(value, tuple): kwargs[key] = list(value) if isinstance(value, list): for idx, lvalue in enumerate(value): if isinstance(lvalue, dict): walk_args_dict(lvalue, attachment_map) else: attachment_ref = fix_attachment(lvalue, attachment_map) if attachment_ref is not None: value[idx] = attachment_ref elif isinstance(value, dict): walk_args_dict(value, attachment_map) else: attachment_ref = fix_attachment(value, attachment_map) if attachment_ref is not None: kwargs[key] = attachment_ref
[docs]class Observer(object): """Observer for events.""" def __init__(self, events): self._events = events
[docs] def add(self, name, funct): """add event.""" if not (name, funct, ) in self._events: self._events.append((name, funct,))
[docs] def remove(self, name, funct): """remove event.""" if (name, funct, ) in self._events: self._events.remove((name, funct,))
[docs] def trigger(self, event, **kwargs): """Trigger.""" for name, funct in self._events: if event.startswith(name) or name == '*': funct(event, **kwargs)
[docs]class FileWithCallBack(object): """FileWithCallBack.""" def __init__(self, path, callback, mode='rb', size=0): self._read_bytes = 0 self._write_bytes = 0 if hasattr(path, 'read'): self._file = path else: self._file = io.open(path, mode) try: self.seek(0, os.SEEK_END) self._total = self.tell() or size self.seek(0) except Exception: self._total = size self._callback = callback self._callback( 'file.init', fobj=self._file, value=0, max_value=self._total)
[docs] def close(self): """Close.""" try: self._callback('file.close', fobj=self._file, value=self._write_bytes, max_value=self._total) self._file.close() self._callback('file.closed', fobj=self._file, value=self._write_bytes, max_value=self._total) except IOError: pass
def __getattr__(self, name): return getattr(self._file, name) def __len__(self): return self._total def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self.close()
[docs] def write(self, data): """write.""" self._file.write(data) self._write_bytes += len(data) self._callback('file.write', fobj=self._file, value=self._write_bytes, max_value=self._total)
[docs] def read(self, size): """read.""" data = self._file.read(size) self._read_bytes += len(data or '') self._callback('file.read', fobj=self._file, value=self._read_bytes, max_value=self._total) return data