def add_privacy_record(self, buddy, type_, callback=None): """ Adds a buddy to your blocklist. buddy can be an OscarBuddy object or a string screenname. """ me = (yield None) name = common.get_bname(buddy) with self.ssi_edit(): if not self.find( lambda s: _lowerstrip(s.name) == _lowerstrip(name), type=type_): log.critical("adding " + name + " to your privacy list") buddy_ssi = item(name, 0, self.new_ssi_item_id(0), type_) buddy_errs = (yield self._add_ssi(buddy_ssi, me())) log.critical("ACK PRIVACY MOD!" + name) if not buddy_errs[0]: self.ssis[buddy_ssi] = buddy_ssi #self.o.buddies[name].setnotify('status', 'offline') else: callback.error() raise SSIException( "Error adding buddy to privacy list. " + ",".join([ssi_err_types[err] for err in buddy_errs])) else: callback.error() raise SSIException("Buddy already in that privacy list.") callback.success() self.ssis.root_group.notify()
def _add_to_group(self, group_ids, id_to_add, position): me = (yield None) try: groupclone = self.ssis[group_ids].clone() except KeyError: raise SSIException("Could not find SSI with group_id == %r", group_ids) groupclone.add_item_to_group(id_to_add, position) errors = (yield self._modify_ssi(groupclone, me())) if errors[0] == 0x0000: self.ssis[group_ids].add_item_to_group(id_to_add, position) else: raise SSIException( 'Error adding item to group: ' + ", ".join([ssi_err_types[err] for err in errors])) self.ssis.root_group.notify()
def remove_privacy_record(self, buddy, type_, callback=None): """ Remove the specified buddy from your block list. """ me = (yield None) name = _lowerstrip(common.get_bname(buddy)) buds_matching = self.find(name=name, type=type_) errors = [] if buds_matching: with self.ssi_edit(): log.critical("REMOVING PRIVACY RECORD FOR " + name) self._remove_ssi(buds_matching, me()) errors = (yield None) for err, ssi in zip(errors, buds_matching): if not err: del self.ssis[ssi] real_errors = filter(None, errors) if not buds_matching: log.critical( "Can't remove privacy record; no ssi in root group for %r (type = %r).", name, type_) if real_errors: callback.error() raise SSIException('Problem removing privacy ssi for %s.' % name + ",".join([ssi_err_types[err] for err in errors])) # On success, notify buddy listeners. callback.success() self.o.buddies[name].notify('blocked') self.ssis.root_group.notify()
def add_new_ssi(self, name, group_protocol_object=None, position=0, type_=None, authorization=False, callback=None): me = (yield None) if not isinstance(name, str): name = name.encode('utf-8') if group_protocol_object is not None: #adding a buddy: group_protocol_object = tuple_key(group_protocol_object) group_id = group_protocol_object[0] item_id = self.new_ssi_item_id(group_protocol_object[0]) if type_ is None: type_ = 0 else: #adding a group group_id = self.new_ssi_group_id() item_id = 0 if type_ is None: type_ = 1 #create ssi+ new_ssi = item(name, group_id, item_id, type_) if group_protocol_object is not None and authorization: new_ssi.tlvs[0x66] = "" with self.ssi_edit(): #needed until group mod is sent #send buddy to server errors = (yield self._add_ssi(new_ssi, me())) if not errors[0]: #update local buddylist self.ssis[new_ssi] = new_ssi ids = group_protocol_object or (0, 0) #buddy if adding to a group, else new group id_to_add = new_ssi.item_id if group_protocol_object \ else new_ssi.group_id self._add_to_group(ids, id_to_add, position) #end with block else: callback.error() if errors[0] != 0xE: raise SSIException( '%s: Error adding SSI %r to server list' % (",".join([ssi_err_types[err] for err in errors]), new_ssi)) try: log.info(','.join(g.name for g in self.ssis.root_group)) except: log.error('error repr-ing groups') self.ssis.root_group.notify() callback.success(new_ssi)
def rename_ssi(self, protocol_object, name): me = (yield None) new_ssi = self.ssis[protocol_object].clone() new_ssi.name = name.encode('utf-8') errors = (yield self._modify_ssi(new_ssi, me())) if errors[0]: raise SSIException("Error renaming object: " + ",".join([ssi_err_types[err] for err in errors])) else: ssiobj = self.ssis[protocol_object] ssiobj.name = name.encode('utf-8') self.ssis.get_group(protocol_object).set_ssi(ssiobj) self.ssis.root_group.notify()
def remove_buddy_ssi(self, ids, callback=None): me = (yield None) with self.ssi_edit(): #needed untill group mod is sent out buddy_clone = self.ssis[ids].clone() error = (yield self._remove_ssi(buddy_clone, me())) if not error[0]: self._remove_from_group(ids) #end with block del self.ssis[ids] callback.success() else: callback.error() raise SSIException( "Error removing object from list: " + ",".join([ssi_err_types[err] for err in error])) self.ssis.root_group.notify()
def alias_ssi(self, contact, name): me = (yield None) buddy, id = contact.buddy, contact.id new_ssi = self.ssis[id].clone() name = name.encode('utf-8') if name else None new_ssi.set_alias(name) # accepts None to delete errors = (yield self._modify_ssi(new_ssi, me())) if errors[0]: raise SSIException("Error setting alias: " + ",".join(ssi_err_types[err] for err in errors)) else: self.ssis[id].set_alias(name) self.ssis.root_group.notify()
def _remove_from_group(self, key): me = (yield None) group_id, item_id = tuple_key(key) log.info('removing (%d, %d)', group_id, item_id) #if it's a set of group ids we got, flip them, because then the #rest of the code is identical if not item_id: group_id, item_id = item_id, group_id group_clone = self.ssis[(group_id, 0)].clone() group_clone.remove_item_from_group(item_id) error = (yield self._modify_ssi(group_clone, me())) if not error[0]: self.ssis[(group_id, 0)].remove_item_from_group(item_id) else: raise SSIException('Error removing item from group: ' + ",".join([ssi_err_types[err] for err in error])) self.ssis.root_group.notify()
def get_privacy_ssi(self): # search for PDINFO ssi items PDINFO = 0x04 privacy_infos = [s for s in self.ssis.values() if s.type == PDINFO] # if there's no privacy entry if len(privacy_infos) == 0: # Add one, with "block list" enabled pinfo_ssi = item('', 0, self.new_ssi_item_id(0), PDINFO) elif len(privacy_infos) == 1: # there's already one--modify it to include "block list" pinfo_ssi = privacy_infos[0] else: log.critical("There was more than one privacy SSI:") log.critical(str(privacy_infos)) raise SSIException("There was more than one privacy SSI:") return pinfo_ssi
def add_modify(self, new_ssi): #, callback=None): ''' not to be used for things you need to hear back from! @param new_ssi: ''' me = (yield None) with self.ssi_edit(): if new_ssi in self.ssis: self._modify_ssi(new_ssi, me()) else: self._add_ssi(new_ssi, me()) errors = (yield None) if not errors[0]: self.ssis[new_ssi] = new_ssi # callback.success() else: # callback.error() raise SSIException("Error adding/modifying SSI: " + ",".join([ssi_err_types[err] for err in errors]))
def remove_group(self, group_protocol_object): me = (yield None) group_protocol_object = getattr(group_protocol_object, 'id', group_protocol_object) ssis_to_del = self.get_ssis_in_group(group_protocol_object) #[0]) log.info('Going to remove: %r', ssis_to_del) group_to_del = self.ssis[tuple_key(group_protocol_object)] groupclone = group_to_del.clone() groupclone.tlvs = {} ssis_to_del.append(groupclone) with self.ssi_edit(): #needed untill group mod is sent out self._remove_ssi(ssis_to_del, me()) errors = (yield None) for (ssi, error) in zip(ssis_to_del, errors): if not error and ssi in self.ssis: del self.ssis[ssi] if group_protocol_object not in self.ssis: self._remove_from_group(group_protocol_object) #end with block real_errors = filter(None, errors) if real_errors: raise SSIException("Error removing group from list: " + ",".join(ssi_err_types[err] for err in real_errors)) self.ssis.root_group.notify()
def move_ssi_to_position(self, item_ids, position, group_to_ids=None, callback=None): me = (yield None) # If we are passed numbers for groups, turn them into group tuples. item_ids = tuple_key(item_ids) if group_to_ids: group_to_ids = tuple_key(group_to_ids) if group_to_ids[1]: raise SSIException("Can't move items into something which is " "not a group.") if not item_ids[0]: #if group == root group raise AssertionError("Atttempted to move something in the " + "SSI root group (this is impossible, " + "since they don't have position).") elif not item_ids[1]: # moving a group group_from_ids = (0, 0) if group_to_ids and group_to_ids != (0, 0): raise SSIException("Can't move group into a group which is " "not the root group.") id_to_move = item_ids[0] else: # moving a buddy group_from_ids = (item_ids[0], 0) id_to_move = item_ids[1] if not group_to_ids or group_from_ids == group_to_ids: #move within group/move a group within root group groupclone = self.ssis[group_from_ids].clone() groupclone.move_item_to_position(id_to_move, position) errors = (yield self._modify_ssi(groupclone, me())) if not errors[0]: self.ssis[group_from_ids]. \ move_item_to_position(id_to_move, position) else: raise SSIException( 'Error moving item: ' + ",".join([ssi_err_types[err] for err in errors])) else: #moving between groups del id_to_move if not group_to_ids[0]: #if there is a group to go to, make sure it's not the root group raise AssertionError("atttempted to move something to the " + "SSI root group (this is impossible, " + "since they don't have position)") else: # valid from, valid to # do crazy delete/add/modify x2 here old_ssi = self.ssis[item_ids] new_ssi = old_ssi.clone() new_ssi.group_id = group_to_ids[0] new_ssi.item_id = self.new_ssi_item_id(group_to_ids[0]) with self.ssi_edit( ): #needed untill last group mod is sent out del_errors, action1, add_errors, action2 = \ (yield self._ssi_double_action( 0x0a, old_ssi, 0x08, new_ssi, me())) if action1 != 0x0a: del_errors, add_errors = add_errors, del_errors del_group_clone, add_group_clone = None, None if not del_errors[0]: del self.ssis[old_ssi] del_group_clone = self.ssis[(old_ssi.group_id, 0)].clone() del_group_clone.remove_item_from_group(old_ssi.item_id) if not add_errors[0]: self.ssis[new_ssi] = new_ssi add_group_clone = self.ssis[(new_ssi.group_id, 0)].clone() add_group_clone.add_item_to_group( new_ssi.item_id, position) mod_ssis = filter(None, [del_group_clone, add_group_clone]) self._modify_ssi(mod_ssis, me()) #end with block mod_errors = (yield None) del_mod_error = None add_mod_error = None if not del_errors[0]: del_mod_error = mod_errors[0] mod_errors = mod_errors[1:] if not del_mod_error: self.ssis[(old_ssi.group_id,0)] \ .remove_item_from_group(old_ssi.item_id) if not add_errors[0]: add_mod_error = mod_errors[0] if not add_mod_error: self.ssis[(new_ssi.group_id,0)] \ .add_item_to_group(new_ssi.item_id, position) # error handling errors = filter(None, (add_errors[0], del_errors[0], del_mod_error, add_mod_error)) if errors: err_string = '' if del_errors[0]: if err_string: err_string += ", " err_string += "deleting " + old_ssi.name + " in group " + \ self.ssis[(old_ssi.group_id,0)].name if del_mod_error: if err_string: err_string += ", " err_string += "removing " + old_ssi.name + " from group " + \ self.ssis[(old_ssi.group_id,0)].name + " list" if add_errors[0]: if err_string: err_string += ", " err_string += "adding " + old_ssi.name + " in group " + \ self.ssis[(new_ssi.group_id,0)].name if add_mod_error: if err_string: err_string += ", " err_string += "adding " + old_ssi.name + " to group " + \ self.ssis[(new_ssi.group_id,0)].name + " list" callback.error() raise SSIException("ERROR %s: %r" % (err_string, ",".join( [ssi_err_types[err] for err in errors]))) #from util import Timer #Timer(1, callback.success).start() callback.success((new_ssi.group_id, new_ssi.item_id)) self.ssis.root_group.notify()