home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.6)
-
- from __future__ import with_statement
- from threading import RLock
- from util.callbacks import callsback
- from traceback import print_exc
- from util.threads import threaded
- from util.primitives.error_handling import traceguard
- from util.primitives.funcs import do, readonly
- from util.primitives.mapping import Storage
- from util.primitives.synchronization import lock
- from digsby_chatlogs.interfaces import IAliasProvider
- import traceback
- import os.path as os
- import wx
- import cPickle
- import stat
- from os.path import isfile, join as pathjoin, exists as pathexists
- from cStringIO import StringIO
- from util import Timer
- import stdpaths
- from path import path
- from util.observe import Observable, ObservableProperty as oproperty
- from common.actions import ObservableActionMeta, action
- from common import profile
- from PIL import Image
- from time import time
- from gui.toolbox import calllimit
- from logging import getLogger
- log = getLogger('Buddy')
- info = log.info
- from common.buddyicon import _rate_limited_icon_get
-
- class FileTransferException(Exception):
- pass
-
- ICON_HASH_FILE = 'iconhashes.dat'
-
- def load_hashes():
- global hashes, cache_path, hashes
- hashes = { }
- wx.GetApp().PreShutdown.append(write_hashes)
- cache_path = pathjoin(stdpaths.userlocaldata, 'cache')
- if not pathexists(cache_path):
- os.makedirs(cache_path)
- elif pathexists(cache_path):
- hash_filename = pathjoin(cache_path, ICON_HASH_FILE)
- None if not pathexists(hash_filename) else None<EXCEPTION MATCH>Exception
-
- hash_lock = RLock()
-
- def buddy_icon_key(buddy):
- return buddy.service
-
-
- def write_hashes():
- if 'hashes' not in globals():
- load_hashes()
-
- log.info('writing icon hashes')
- hash_lock.__enter__()
-
- try:
-
- try:
- f = _[1]
- cPickle.dump(hashes, f)
- finally:
- pass
-
- except Exception:
- hash_lock.__exit__
- hash_lock.__exit__
- hash_lock
- log.critical('error writing icon hashes')
- print_exc()
- except:
- hash_lock.__exit__
- finally:
- pass
-
-
- write_hashes = calllimit(5)(write_hashes)
-
- def icon_path_for(buddy):
- if 'cache_path' not in globals():
- load_hashes()
-
- bname = buddy.name
- if isinstance(bname, bytes):
- bname = bname.decode('fuzzy utf8').encode('filesys')
- elif isinstance(bname, unicode):
- bname = bname.encode('filesys')
-
- return pathjoin(cache_path, buddy_icon_key(buddy), '%s_ICON.dat' % bname).decode('filesys')
-
-
- def get_disk_icon_hash(buddy):
- if 'hashes' not in globals():
- load_hashes()
-
- protoname = buddy_icon_key(buddy)
-
- try:
- protohashes = hashes[protoname]
- except KeyError:
- return None
-
- return protohashes.get(buddy.name, None)
-
-
- def get_cached_icon(buddy):
- if 'hashes' not in globals():
- load_hashes()
-
- icon_path = icon_path_for(buddy)
- if not isfile(icon_path):
- return (None, None)
-
- try:
- icon_file = open(icon_path, 'rb')
- data = icon_file.read()
- except Exception:
- isfile(icon_path)
- isfile(icon_path)
- print_exc()
- return (None, None)
-
- icon_file.close()
- if buddy.name not in hashes.setdefault(buddy_icon_key(buddy), { }):
- return (None, None)
- hash = hashes[buddy_icon_key(buddy)][buddy.name]
- if len(data) == 0:
- return ('empty', hash)
-
- try:
- img = Image.open(StringIO(data))
- except Exception:
- len(data) == 0
- len(data) == 0
- buddy.name not in hashes.setdefault(buddy_icon_key(buddy), { })
- log.critical('%s was not an icon, removing it', icon_path)
-
- try:
- os.remove(icon_path)
- except Exception:
- isfile(icon_path)
- isfile(icon_path)
- log.critical('could not remove nonimage icon %s', icon_path)
- except:
- isfile(icon_path)
-
- return (None, None)
- isfile(icon_path)
-
- img.path = unicode(icon_path) + unicode(time())
- return (img, hash)
-
-
- def save_cached_icon(buddy, imgdata, imghash):
- full_path = icon_path_for(buddy)
- (dir, file) = os.path.split(full_path)
- if not pathexists(dir):
-
- try:
- os.makedirs(dir)
- except Exception:
- traceback.print_exc()
- except:
- None<EXCEPTION MATCH>Exception
-
-
- None<EXCEPTION MATCH>Exception
-
- try:
-
- try:
- f = _[1]
- f.write(imgdata)
- finally:
- pass
-
- except Exception:
- traceback.print_exc()
-
- hash_lock.__enter__()
-
- try:
- hashes.setdefault(buddy_icon_key(buddy), { })[buddy.name] = imghash
- finally:
- pass
-
-
-
- def get_bname(b):
-
- try:
- return b.name
- except AttributeError:
- return str(b)
-
-
- available_fix = {
- 'online': 'available',
- 'normal': 'available' }
-
- def get_status_orb(contact):
- st = contact.status.lower()
- st = available_fix.get(st, st)
- if st == 'unknown':
- pass
- elif contact.mobile:
- st = 'mobile'
- elif not contact.online:
- st = 'offline'
- elif st == 'idle' or contact.idle:
- st = 'idle'
- elif contact.away:
- st = 'away'
-
- return st
-
-
- def get_log_size(buddy):
- return get_log_size_tup(buddy.name, buddy.service)
-
-
- def get_log_size_tup(name, service):
- return profile.logger.logsize_for_nameservice(name, service)
-
-
- class LogSizeDict(dict):
-
- def __init__(self):
- dict.__init__(self)
- self.needed = dict()
- self.triggered = False
-
-
- def __missing__(self, key, initialize = True):
- if initialize:
- self.needed[key] = []
-
- self.__setitem__(key, 0)
- if not self.triggered:
- self.triggered = True
- self.trigger()
-
- return 0
-
- __missing__ = lock(__missing__)
-
- def trigger(self):
- Timer(0.1, self.do_disk_access, success = self.update).start()
-
-
- def do_disk_access(self):
- self._lock.__enter__()
-
- try:
- needed = self.needed
- self.needed = dict()
- finally:
- pass
-
- retval = dict()
- for key in needed:
- retval[key] = get_log_size_tup(*key)
-
- log.info('getting %d log sizes: %r', len(needed), needed)
- return (retval, needed)
-
- do_disk_access = threaded(do_disk_access)
-
- def update(self, d):
- self._lock.__enter__()
-
- try:
- (newvals, retrieved) = d
- for key in newvals:
- self.needed.pop(key, None)
-
- if not self.needed:
- self.triggered = False
- else:
- self.trigger()
- finally:
- pass
-
-
- try:
- retval = dict.update(self, newvals)
- except Exception:
- self._lock.__exit__
- self._lock.__exit__
- self._lock
- raise
- except:
- self._lock.__exit__
- else:
- for val in retrieved.values():
- for buddy in val:
- traceguard.__enter__()
-
- try:
- buddy.notify('log_size')
- finally:
- pass
-
-
-
- return retval
- return None
-
-
-
- def notify_get(self, key, buddy):
- if key in self.needed:
- self.needed[key].append(buddy)
- return self[key]
- if key not in self:
- self.needed[key] = [
- buddy]
- return self.__missing__(key, initialize = False)
- return self[key]
-
- notify_get = lock(notify_get)
-
- def __getitem__(self, key):
- return dict.__getitem__(self, key)
-
- __getitem__ = lock(__getitem__)
-
- def __setitem__(self, key, value):
- return dict.__setitem__(self, key, value)
-
- __setitem__ = lock(__setitem__)
-
-
- class Buddy(Observable):
- __metaclass__ = ObservableActionMeta
- _icon_requests = 0
- _get_image_min_once = False
-
- def __init__(self, name, protocol):
- Observable.__init__(self)
- self.add_observer(self.store_remote_alias, 'remote_alias')
- self.name = name
- self.protocol = protocol
- self._notify_dirty = True
- self.entering = self.leaving = False
- (do,)((lambda .0: for s in .0:
- setattr(self, s, None))([
- 'icon_bitmap']))
- self.icon_hash = self.get_icon_hash()
- self._getting_image = False
- self._cached_hash = None
- self.icon_disabled = False
-
- try:
- register = profile.account_manager.buddywatcher.register
- except AttributeError:
- log.debug('No buddy watcher to register with')
- return None
-
- register(self)
-
-
- def store_remote_alias(self, obj, attr, old, new):
- if attr is None or attr == 'remote_alias':
- IAliasProvider(profile()).set_alias(self.name, self.service, protocol = self.protocol.service, alias = self.alias)
-
-
-
- def raise_proto_impl_err(self, prop = ''):
- raise NotImplementedError('%s has not implemented a required property %s' % (getattr(self, '__class__', str(self)), prop))
-
-
- def __repr__(self):
- return '<%s %s>' % (self.__class__.__name__, self.name)
-
- nice_name = readonly('name')
-
- def online(self):
- self.raise_proto_impl_err('online')
-
- online = property(online)
-
- def mobile(self):
- self.raise_proto_impl_err('mobile')
-
- mobile = property(mobile)
-
- def status_message(self):
- self.raise_proto_impl_err('status_message')
-
- status_message = property(status_message)
-
- def stripped_msg(self):
- if not self.status_message:
- pass
- return u''
-
- stripped_msg = property(stripped_msg)
-
- def idle(self):
- self.raise_proto_impl_err('idle')
-
- idle = property(idle)
-
- def away(self):
- self.raise_proto_impl_err('away')
-
- away = property(away)
-
- def blocked(self):
- self.raise_proto_impl_err('blocked')
-
- blocked = property(blocked)
-
- def _set_isbot(self, isbot):
- caps = caps
- import common
- if isbot:
- self.caps.add(caps.BOT)
- else:
- self.caps.discard(caps.BOT)
-
-
- def isbot(self):
- caps = caps
- import common
- return caps.BOT in self.caps
-
- isbot = property(isbot)
- bot = isbot
-
- def service(self):
- return self.protocol.name
-
- service = property(service)
-
- def serviceicon(self):
- skin = skin
- import gui
- return skin.get('serviceicons.%s' % self.service)
-
- serviceicon = property(serviceicon)
-
- def pending_auth(self):
- return False
-
- pending_auth = property(pending_auth)
-
- def sms(self):
- return False
-
- sms = property(sms)
-
- def get_caps(self):
- caps = caps
- import common
- if self.sms:
- return set([
- caps.SMS])
- buddy_caps = set(self.protocol.caps)
- if not self.online:
- buddy_caps.discard(caps.FILES)
- buddy_caps.discard(caps.VIDEO)
-
- return buddy_caps
-
- caps = property(get_caps)
-
- def imwin_mode(self, mode):
- begin_conversation = begin_conversation
- import gui.imwin
- begin_conversation(self, mode = mode)
-
-
- def chat(self):
- self.imwin_mode('im')
-
- chat = action((lambda self: 'IM' in self.caps))(chat)
-
- def buddy_info(self):
- self.imwin_mode('info')
-
- buddy_info = action((lambda self: 'INFO' in self.caps))(buddy_info)
-
- def send_email(self):
- self.imwin_mode('email')
-
- send_email = action((lambda self: 'EMAIL' in self.caps))(send_email)
-
- def send_sms(self):
- self.imwin_mode('sms')
-
- send_sms = action((lambda self: 'SMS' in self.caps))(send_sms)
-
- def idstr(self):
- return '/'.join([
- self.protocol.name,
- self.protocol.username,
- self.name])
-
-
- def alias(self):
- a = profile.get_contact_info(self, 'alias')
- if a:
- return a
- a = getattr(self, 'local_alias', None)
- if a:
- return a
- a = getattr(self, 'remote_alias', None)
- if a:
- return a
- return self.name
-
- alias = property(alias)
-
- def local_alias(self):
- return profile.blist.get_contact_info(self, 'alias')
-
- local_alias = property(local_alias)
-
- def block(self, set_blocked = True, callback = None):
- self.raise_proto_impl_err('block')
-
- block = action((lambda self: if self.blocked:
- NoneTrue))(callsback(block))
-
- def equals_chat_buddy(self, chat_buddy):
- return self == chat_buddy
-
-
- def unblock(self, callback = None):
- self.raise_proto_impl_err('unblock')
-
- unblock = action((lambda self: if self.blocked:
- True))(callsback(unblock))
-
- def send_file(self, filepath = None):
- if filepath is None:
- Hub = Hub
- import hub
- filepath = Hub.getInstance().get_file('Sending file to %s' % self.name)
-
- if filepath:
- finfo = fileinfo(filepath)
- if finfo.size:
- if self.online:
- xfer = self.protocol.send_file(self, finfo)
- profile.xfers.insert(0, xfer)
-
- else:
- Hub = Hub
- import hub
- Hub.getInstance().on_error(FileTransferException('%s is an empty file' % finfo.name))
-
-
- send_file = action((lambda self: if self.online:
- pass'FILES' in self.caps))(send_file)
-
- def send_folder(self, dirpath = None):
- Hub = Hub
- import hub
- if dirpath is None:
- dirpath = Hub.getInstance().get_dir('Choose a directory to send to %s.' % self.name)
-
- if dirpath:
- finfo = fileinfo(dirpath)
- if len(finfo.files) == 0:
- Hub.getInstance().on_error(ValueError('No files in that directory.'))
- elif finfo.size == 0:
- Hub.getInstance().on_error(ValueError('There are zero bytes in that directory.'))
- else:
- self.protocol.send_file(self, finfo)
-
-
-
- def remove(self, protocol_obj):
- self.protocol.remove_buddy(protocol_obj)
-
- remove = action()(remove)
-
- def icon_path(self):
- return path(icon_path_for(self))
-
- icon_path = property(icon_path)
-
- def num_online(self):
- return int(self.online)
-
- num_online = property(num_online)
-
- def notify(self, attr = None, *a, **k):
- self._notify_dirty = True
- profile.blist.buddy_changed(self, attr)
- return Observable.notify(self, attr, *a, **k)
-
-
- def cache_path(self):
- proto = self.protocol
- return pathjoin(proto.name, self.name) + '.dat'
-
- cache_path = property(cache_path)
-
- def info_key(self):
- return self.name + '_' + self.service
-
- info_key = property(info_key)
- email_hint = property((lambda self: self.protocol.email_hint(self)))
-
- def history(self):
- return profile.logger.history_for_safe(self.protocol, self)
-
- history = property(history)
-
- def icon(self):
- if self.icon_disabled:
- return None
- nh = self.icon_hash
- if self.icon_bitmap is not None and self.icon_bitmap is not -1:
- if not (self._getting_image) and nh is not None and nh != self._cached_hash:
- self._getting_image = True
- _rate_limited_icon_get(self)
-
- elif (nh or self._get_image_min_once) and not (self._getting_image):
- self._getting_image = True
- _rate_limited_icon_get(self)
-
- if self.icon_bitmap is not None and self.icon_bitmap is not -1:
- if isinstance(self.icon_bitmap, str) and self.icon_bitmap == 'empty':
- return None
- return self.icon_bitmap
- self.icon_bitmap is not -1
- return None
-
- icon = property(icon)
-
- def cache_icon(self, icon_data, icon_hash):
- self.icon_bitmap = None
- self._cached_hash = None
- self._getting_image = False
- save_cached_icon(self, icon_data, icon_hash)
- wx.CallAfter(write_hashes)
- self.notify('icon')
-
-
- def get_icon_hash(self):
- return get_disk_icon_hash(self)
-
-
- def log_size(self):
- return profile.log_sizes.notify_get((self.name, self.service), self)
-
- log_size = property(log_size)
-
- def increase_log_size(self, num_bytes):
- profile.log_sizes[(self.name, self.service)] += num_bytes
- self.notify('log_size')
-
-
- def __eq__(self, b):
- s = object()
- if getattr(b, 'name', s) == self.name:
- pass
- return getattr(b, 'protocol') is self.protocol
-
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
-
- def __hash__(self):
- return hash(self.info_key)
-
- status_notifies = { }
-
- def _set_status(self, status):
- status = {
- 'online': 'available' }.get(status, status)
- self.setnotifyif('status', status)
-
- status_orb = oproperty((lambda self: get_status_orb(self)), observe = 'status')
-
- def sightly_status(self):
- return self.status.title()
-
- sightly_status = property(sightly_status)
-
- def pretty_profile(self):
- return u''
-
- pretty_profile = property(pretty_profile)
-
- def buddy_icon(self):
- get_buddy_icon = get_buddy_icon
- import gui.buddylist.renderers
- return get_buddy_icon(self, 32, False)
-
- buddy_icon = property(buddy_icon)
-
- def view_past_chats(self, fromacct = None):
- if fromacct is None:
- fromacct = self.protocol
-
- buddypath = profile.logger.pathfor(fromacct, self)
- PastBrowser = PastBrowser
- import gui.pastbrowser
- PastBrowser.MakeOrShowAndSelect(buddypath)
-
-
-
- def fileinfo(filepath):
- filestats = os.stat(filepath)
- s = Storage(size = os.path.getsize(filepath), modtime = filestats[stat.ST_MTIME], ctime = filestats[stat.ST_CTIME], name = os.path.split(filepath)[1], path = path(filepath))
- return s
-
-