def _input_mouseDoubleClickEvent(self, event): cursor = self.widgets.input.textCursor() if cursor.position() == 0: log_debug("doing nothing") event.ignore() else: QTextEdit.mouseDoubleClickEvent(self.widgets.input, event)
def remove_account(self): #get current item: w = self.widgets item = w.accounts.currentItem() #get the index (ugh.. this is tedious) itemindex = w.accounts.indexOfTopLevelItem(item) if itemindex == -1: log_err("couldn't get index!") return account = self.account_items[item] #remove the item from the widget: w.accounts.takeTopLevelItem(itemindex) #find the account in our global config list index = -1 for i in xrange(0, len(self.config.accounts)): a = self.config.accounts[i] if str(a["name"]) == str(account["name"]) and str(a["improto"]) == str(account["improto"]): index = i break else: pass if index >= 0: log_debug("index:", index) self.config.accounts.pop(index) #finally, remove it from the mapping self.account_items.pop(item)
def addTab(self, widget, *args): log_debug("%x: adding %x" % (id(self), id(widget))) self.tab_ids.add(id(widget)) if not self.count(): self.resize(widget.size()) QTabWidget.addTab(self, widget, *args) self.setCurrentWidget(widget)
def autoconnect(self): log_info("autoconnecting..") #auto-connect all accounts in our config.. if self.config and self.config.do_autoconnect: config = self.config for a in config.accounts: log_debug("found account: %s/%s" % (a["name"], a["improto"])) if not a.get("autoconnect", False): continue #create positional arguments: user, password, improto = a.get("name"), a.get("password"), a.get("improto") if not (user and password and improto): continue improto = getattr(yobotproto, improto, -1) if improto == -1: continue args = (user, password, improto) kwargs = {} if a.get("use_proxy", False): while True: if not (a.get("proxy_address") and a.get("proxy_type")): break kwargs["proxy_host"] = a["proxy_address"] kwargs["proxy_type"] = a["proxy_type"].lower() kwargs["proxy_port"] = int(a["proxy_port"]) if a["proxy_port"] else None kwargs["proxy_username"] = a.get("proxy_username", None) kwargs["proxy_password"] = a.get("proxy_password", None) break self.connect(*args, **kwargs)
def encode(self): if not self.user or not self.passw or not self.improto or not self.id: raise TypeError("missing parameters") info = yobot_mkacctinfo() info.user = self.user info.password = self.passw info.acctid = self.id info.improto = self.improto if self._proxy_host: proxy_info_xml = "<foo><proxy_info proxy_host='%s' " % (self._proxy_host) if self._proxy_port: proxy_info_xml += "proxy_port='%s' " % (str(self._proxy_port)) if self._proxy_username: proxy_info_xml += "proxy_username='******' " % (self._proxy_username) if self._proxy_password: proxy_info_xml += "proxy_password='******' " % (self._proxy_password) if self._proxy_type in ("socks4", "socks5", "http"): proxy_info_xml += "proxy_type='%d' " % ( getattr(yobotproto, "PURPLE_PROXY_" + self._proxy_type.upper())) else: log_warn("unknown proxy type", self._proxy_type) proxy_info_xml = "" if proxy_info_xml: proxy_info_xml += "/></foo>" info.attr_xml = proxy_info_xml log_debug(proxy_info_xml) else: log_debug("proxy info is null?") ptr = yobot_protoclient_mkacct_encode(info, None, YOBOT_PROTOCLIENT_TO_BUF) return ptr
def __init__(self, backend): """The backend should be iterable and indexable. The backend itself must contain list of blist objects which should also be iterable and indexable. Additionally, each item should have a status, status_message, and name attribute """ self.IDSTR="hi" super(AccountModel, self).__init__() #self.backend = backend self.backend = yobot_interfaces.component_registry.get_component("account-store") if not self.backend: raise Exception("couldn't find account store") #try to register account model: model = yobot_interfaces.component_registry.get_component("account-model") if model: return model else: yobot_interfaces.component_registry.register_component("account-model", self) self.acctRoot = backend self.blist = None #tie up some functions.. self.backend.beginAdd = self.beginAccountAdd self.backend.beginRemove = self.beginAccountRemove self.backend.beginChildAdd = self.beginBuddyAdd self.backend.beginChildRemove = self.beginBuddyRemove self.backend.endAdd = self.endInsertRows self.backend.endRemove = self.endRemoveRows self.backend.dataChanged = self.statusChange self.backend.firstChildInserted = self._firstChange log_debug( "AccountModel: init done") def _logchanged(childindex, parentindex): log_err("called")
def gotMsg(self, msg_obj): #get time.. w = self.widgets fmt = _ChatText.defaultFmt colon_ish = ":" #determine format... if (msg_obj.yprotoflags & yobotproto.YOBOT_BACKLOG or msg_obj.prplmsgflags & yobotproto.PURPLE_MESSAGE_DELAYED): fmt = _ChatText.archFmt elif msg_obj.yprotoflags & yobotproto.PURPLE_MESSAGE_SYSTEM: fmt = _ChatText.errFmt elif strip_html_regexp.sub("", msg_obj.txt).startswith("/me "): fmt = _ChatText.emoteFmt colon_ish = "**" who = msg_obj.who if not who and msg_obj.prplmsgflags & yobotproto.PURPLE_MESSAGE_SYSTEM: who = "SYSTEM MESSAGE" whocolor = "darkblue" if msg_obj.prplmsgflags & yobotproto.PURPLE_MESSAGE_SEND else "darkred" whostyle = "color:%s;font-weight:bold;text-decoration:none;" % (whocolor,) msg_str = (("""<a href='YOBOT_INTERNAL/%s' style='%s'>""" % (who, whostyle)) + ("(%s) " % (msg_obj.timeFmt,) if w.actionTimestamps.isChecked() else "") + ("%s</a>%s " % (msg_obj.who,colon_ish))) formatted = process_input(msg_obj.txt, self.use_relsize) log_debug("BEFORE", formatted) formatted = insert_smileys(formatted, self.account.improto, ":smileys/smileys", 24, 24) log_debug(formatted) msg_str += formatted msg_str = unicode(msg_str, "utf-8") self.chat_text.append(msg_str, fmt)
def fill_from(self, account_dict): w = self.widgets w.username.setText(account_dict.get("name", "")) w.password.setText(account_dict.get("password", "")) #get protocol constant improto_constant = getattr(yobotproto, str(account_dict.get("improto"))) log_debug("improto_constant", improto_constant) #find it in the combobox i = w.improto.findData(QVariant(improto_constant)) if i >= 0: w.improto.setCurrentIndex(i) else: log_warn("couldn't find improto_constant", improto_constant) if account_dict.get("use_proxy", False) and account_dict.get("proxy_params", False): w.use_proxy.setChecked(True) pp = account_dict["proxy_params"] proxy_type_index = w.improto.findText(pp.get("proxy_type", "").upper()) if proxy_type_index >= 0: w.proxy_type.setCurrentIndex(proxy_type_index) w.proxy_address.setText(pp.get("proxy_address")) w.proxy_port.setText(pp.get("proxy_port")) w.proxy_username.setText(pp.get("proxy_username", "")) w.proxy_password.setText(pp.get("proxy_password", "")) else: w.use_proxy.setChecked(False)
def addAcct(self, acct): #add an account and request an ID.. if acct in self._all_accounts: log_warn( "request already completed or pending.. not adding") return self.pending_accounts.put(acct) self.yobot_server.sendCommand(yobotproto.YOBOT_CMD_ACCT_ID_REQUEST,0) log_debug( "send account connect command for account %s" % (acct, ))
def navigate(self, next = True): log_debug("") currentIndex = self.qsw.currentIndex() if next: #navigate to next.. if currentIndex-1 < self.qsw.count() and currentIndex >= 0: self.qsw.setCurrentIndex(currentIndex+1) else: if currentIndex-1 > 0: self.qsw.setCurrentIndex(currentIndex-1)
def sendAccountEvent(self, event, id,severity=yobotproto.YOBOT_INFO, txt=None): "Convenicne function to send an event related to an account" log_debug("begin") evt = yobotclass.YobotEvent() evt.objid = id evt.objtype = yobotproto.YOBOT_PURPLE_ACCOUNT evt.severity = severity evt.txt = txt evt.event = event self.sendSegment(evt) log_debug( "done")
def __init__(self, account, txt, refid=0): if not txt: log_warn("no text") txt = "" log_debug(txt) self.refid = refid self._initvars() self.acct = account self.options.append(("Ok", lambda: None, yobotproto.YOBOT_ACTIONTYPE_OK)) self._prettyformat(txt)
def widgetformatter(widget, font, color, klass="QWidget", extra=""): stylesheet = ((klass + "{" ) + ("font-weight:bold;" if font.bold() else "") + ("font-style:italic;" if font.italic() else "") + ("text-decoration:underline;" if font.underline() else "") + ("font-size:%dpt;" % (font.pointSize(),)) + ("font-family:%s;" % (font.family(),)) + ("color:%s;" % (color.name())) + (extra + "}") ) log_debug(stylesheet) widget.setStyleSheet(stylesheet)
def gotmsg(self, msg): """This should be overridden by the GUI""" log_debug( msg) if msg.yprotoflags & yobotproto.YOBOT_MSG_TYPE_CHAT: #find room... for room in self.rooms: if room.name == msg.name: room.gotmsg(msg) elif msg.yprotoflags & yobotproto.YOBOT_MSG_ATTENTION: log_info( msg.name, "Has buzzed you!!") elif msg.yprotoflags & yobotproto.YOBOT_MSG_TYPE_IM: pass
def _getBuddy(self, name): buddy = None if name in self.blist: #get buddy object buddy = self.blist.get(name) else: buddy = YBuddy(self.blist, name) self.blist.add(buddy) #log_warn("len is", len(self.blist)) if len(self.blist) == 1: #new buddy just added log_debug("calling firstChildInserted") self.svc.accounts.firstChildInserted(self.index) return buddy
def _encode_pycls(self,pycls): """ Calls the object's .encode() method and returns a python string version """ log_debug( pycls) ptr = pycls.encode() if not ptr: return plen = yobotproto.yobot_protoclient_getsegsize(ptr) if not plen or plen > yobotproto.YOBOT_MAX_COMMSIZE: return None #error return yobotproto.cdata(ptr,plen)
def delAcct(self, id=None,userproto=None): """Deletes an account indexed by ID or (user,proto) pair. If the account exists, it will return the data portion of the entry. This will also delete the account from the connected protocol instances.. Raises KeyError if something doesn't exist""" (acct, data) = None, None if id: log_debug("looking up ID") #get account from ID and remove from other dict: res = self._ids.pop(id) if res == RESERVED_ID: log_debug("Reserved ID") return None acct, data = res self._accounts.pop((acct.user,acct.improto)) elif userproto: log_debug("looking up userproto") res = self._accounts.pop((userproto)) assert res acct, data = res self._ids.pop(acct.id) else: log_err("oops.. neither id or userproto was specified") raise TypeError, "Must provide a (user,proto) or ID as a key" for conn in data: self._connections[conn].remove(acct.id) log_debug("done")
def accept(self): #validate input.. #load the variables first.. w = self.widgets name, password = w.username.text(), w.password.text() improto = yobotops.imprototostr(w.improto.itemData(w.improto.currentIndex()).toPyObject()) log_debug("improto is", improto) use_proxy = w.use_proxy.isChecked() proxy_username, proxy_password, proxy_address, proxy_port = ( w.proxy_username.text(), w.proxy_password.text(), w.proxy_address.text(), w.proxy_port.text()) proxy_type = w.proxy_type.currentText() autoconnect = w.autoconnect.isChecked() err = False while not err: if not name or not password: err = "username and password required" break if use_proxy: if not proxy_address or not proxy_port: err = "proxy requested but no port:address specified" break if (proxy_password and not proxy_username) or ( proxy_username and not proxy_password): err = "username and password must be specified together" break break if err: QErrorMessage(self).showMessage(err) return a = { "name":str(name), "password":str(password), "improto":str(improto), "autoconnect":bool(autoconnect), "use_proxy":bool(use_proxy), "proxy_params": { "proxy_type":str(proxy_type), "proxy_address":str(proxy_address), "proxy_port":str(proxy_port), "proxy_username":str(proxy_username), "proxy_password":str(proxy_password), } } QDialog.accept(self) self.values = a
def acctExists(self, ybacct): """uses the user,proto index Returns [MATCH_TYPE, ] """ ret = [NO_MATCH, None] acct_match = self.byUserProto(ybacct.user,ybacct.improto) if not acct_match: #no match at all log_debug( "NO MATCH.. returning", ret) return ret ret[0] |= USERPROTO_MATCH ret[1] = acct_match if acct_match[0].passw == ybacct.passw: ret[0] |= PASSWORD_MATCH return ret
def buddyEvent(self, obj, proto): #find account... log_info( "id: ", obj.evt.objid) acct = self.accounts.getAccount(obj.evt.objid) if not acct: log_warn( "Couldn't find account!") log_debug(acct) name, data = getNameAndData(obj) if name == "*": name = None if obj.evt.event == yobotproto.YOBOT_EVENT_BUDDY_GOT_ICON: acct.gotBuddyIcon(name, data) else: acct.gotBuddyStatus(name, obj.evt.event, data)
def unregisterClient(self, proto): """ Hook for connectionLost(). Removes the CID (if any) and its associated protocol instance from the table of clients """ log_debug( "UNREGISTERING: ", proto.cid) #first remove it from the accounts list: acct_refs = self.accounts.getConnectionData(proto) if acct_refs: acct_refs = acct_refs.copy() for acctid in acct_refs: self.accounts.delConnection(proto, id = acctid) #finally, remove the client.. need to find a better way for this try: self.accounts._connections.pop(proto) except KeyError, e: log_warn( e, "don't care")
def sendMsg(self): w = self.widgets if not w.input.toPlainText(): log_debug("empty input") return if self._send_html: txt = unicode(w.input.toHtml().toUtf8(), "utf-8") txt = simplify_css(txt.encode("utf-8")) else: txt = unicode(w.input.toPlainText().toUtf8(), "utf-8") if not txt: return log_warn(txt) w.input.clear() chat = True if self.type == CHAT else False self.account.sendmsg(self.target, str(txt), chat=chat)
def load_settings(self): w = self.widgets if not self.config: log_warn("config object not available! bailing") return #for font.. appearance = self.config.globals.setdefault("appearance", {}) family = appearance.get("font_family", None) size = appearance.get("font_size", None) color = appearance.get("font_color", None) if family: self.font.setFamily(family) if size: self.font.setPointSize(size) if color: self.color.setNamedColor(color) bold = appearance.get("font_bold", False) italic = appearance.get("font_italic", False) underline = appearance.get("font_underline", False) html_relsize = appearance.get("use_html_relsize", False) show_joinpart = appearance.get("show_joinpart", False) self.font.setBold(bold) self.font.setItalic(italic) self.font.setUnderline(underline) w.html_relsize.setChecked(html_relsize) w.show_joinpart.setChecked(show_joinpart) self.change_formatting() #for the agent... agent = self.config.globals.get("agent_address", None) if agent: w.agent_address.setText(agent) self.change_agent() #for accounts: for a in self.config.accounts: log_warn("got account", a) if a.get("name", None) and a.get("improto", None): #get name and icon name, icon = getProtoIconAndName(getattr(yobotproto, a["improto"], "")) log_debug(icon, name) i = QTreeWidgetItem((a["name"], name)) i.setIcon(1, icon) i.setData(0, ITEM_PLACEHOLDER_ROLE, a) self.account_items[i] = a self.widgets.accounts.addTopLevelItem(i)
def encode(self): if self.cmd is None or self.acctid is None: raise TypeError("need command and ID") dlen = 0 if self.data and isinstance(self.data,str): dlen = len(self.data) + 1 info = yobot_cmdinfo() info.command = self.cmd info.acctid = self.acctid info.data = self.data info.len = dlen info.commflags = self.commflags info.reference = self.reference ptr = yobot_protoclient_cmd_encode(info, None, YOBOT_PROTOCLIENT_TO_BUF) log_debug( "encoding done") return ptr
def handle_request(self, obj, proto): """Mainly for buddy auth requests but can also possibly be used for other stuff""" evt = obj.evt acct = self.accounts.getAccount(obj.evt.objid) if evt.event == yobotproto.YOBOT_EVENT_USER_ADDREQ: req = BuddyAuthorize(self, evt.txt, acct) self.uihooks.gotRequest(req) elif evt.event == yobotproto.YOBOT_EVENT_PURPLE_REQUEST_GENERIC: req = YCRequest(self, obj.evt, acct) log_warn(req) self.uihooks.gotRequest(req) elif evt.event in (yobotproto.YOBOT_EVENT_PURPLE_NOTICE_GENERIC, yobotproto.YOBOT_EVENT_AGENT_NOTICE_GENERIC): #get the text.. req = SimpleNotice(acct, obj.evt.txt, obj.evt.reference) self.uihooks.gotRequest(req) elif evt.event == yobotproto.YOBOT_EVENT_PURPLE_REQUEST_GENERIC_CLOSED: log_debug("closed") #get request id.. refid = obj.evt.reference self.uihooks.delRequest(acct, refid)
def purple_request_responder(self, obj, proto): """What we do here is simple.. look at the commflags for a "YOBOT_RESPONSE", and if so, relay the segment to the client""" #first get the type... if obj.commflags & yobotproto.YOBOT_RESPONSE_END: self.requests.pop(obj.reference, None) log_debug("request done.. removing..") return if not obj.commflags & yobotproto.YOBOT_RESPONSE: log_err("how the hell did this get here..") return client = self.requests.get(obj.reference, None) if not client: log_err("couldn't get client!") return #check that the client is associated with the account ID still (this is #a really paranoid provision, for e.g. a new client which has taken the #old id of the previous client....) #if not self.verifyObj(obj, client): # raise UnauthorizedTransmission() #finally.. relay.. log_debug(obj.evt) client.sendPrefixed(obj.raw)
def dropEvent(self, event): log_debug("") m = event.mimeData() s = event.source() if "action" in m.formats() and m.data("action") == "window_drag": event.acceptProposedAction() log_debug("Got drop request for window") if not getattr(s, "current_widget", None): log_debug("Not a valid object for dropping:", s) return widget = s.current_widget if id(widget) in self.tabwidget.tab_ids: log_info("drop requested, but widget %r already exists" % (widget)) return widget.addToContainer(self)
def addAcct(self,reqhandler): acct = reqhandler.newacct res_type, acct_data = self.acctExists(acct) if res_type & (USERPROTO_MATCH|PASSWORD_MATCH): log_debug( "FULL MATCH") #account exists, notify of existing ID reqhandler.handle_exists(acct_data) elif res_type & USERPROTO_MATCH: log_debug( "USERPROTO MATCH") if acct_data[0].loggedin: reqhandler.handle_authfail(acct_data) else: reqhandler.handle_authwait(acct_data) #wait until an account has been authenticated elif res_type == NO_MATCH: log_debug( "NO MATCH!!!") #Add to both our indices acct_data = self._accounts[acct.user,acct.improto] = [acct, set()] self._ids[acct.id] = acct_data reqhandler.handle_added(acct_data)
def rm_account(self, cbresult): log_debug( "rm_account...") #tell the client we've timed out if self.timedOut: log_debug( "sending event..") self.proto.sendAccountEvent(yobotproto.YOBOT_EVENT_LOGIN_TIMEOUT, self.newacct.id,severity=yobotproto.YOBOT_WARN, txt="Yobot Server did not get a response from purple") log_debug( "Sent event") #tell purple to forget about our account log_debug( "telling purple to remove the account...") self.prpl.sendCommand(yobotproto.YOBOT_CMD_ACCT_REMOVE,self.newacct.id) log_debug( "done") try: log_debug( "deleting account from relay...") self.acct_mgr.delAcct(id=self.newacct.id) log_debug( "done") except Exception,e: log_warn( err)
#!/usr/bin/env python config = None import yobot_interfaces import sys import yobotops from debuglog import log_debug, log_err, log_warn, log_crit, log_info try: import json except Exception, e: log_debug("Couldn't load json module: ", str(e)) import simplejson json = simplejson class ConfigLoadError(Exception): pass class ConfigSaveError(Exception): pass class acctlist(list): def append(self, obj): for a in self: if a["name"] == obj["name"] and a["improto"] == obj["improto"]: return list.append(self, obj) class RingBuffer(list): def __init__(self, limit, l=list()): if l: #filter out duplicates...