Пример #1
0
def create_slack_websocket(data):
  global ws
  web_socket_url = data['url']
  try:
    ws = create_connection(web_socket_url)
    ws.sock.setblocking(0)
    w.hook_fd(ws.sock._sock.fileno(), 1, 0, 0, "slack_cb", "")
  except socket.error:
    return False
  return True
Пример #2
0
def init_socket():
    global sock
    kill_daemon()
    if sock is None:
        sock_path = '%s/signal.sock' % weechat.info_get("weechat_dir", "")
        try:
            os.unlink(sock_path)
        except OSError:
            if os.path.exists(sock_path):
                raise
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        sock.bind(sock_path)
        sock.listen(5)

        weechat.hook_fd(sock.fileno(), 1, 1, 0, 'receive', '')
Пример #3
0
def weecat_command_cb(data, buffer, args):
    global weecat_buffers, cmds_by_buffer, listen_hooks

    try:
        this_file = open(args)
    except IOError as e:
        weechat.prnt("", weechat.prefix("error") + "weecat: " + e.strerror)
        return weechat.WEECHAT_RC_ERROR

    filename = this_file.name

    if not args in listen_hooks:
        new_buffer = weechat.buffer_new(
                "wc: " + filename,
                "weecat_input_cb", "",
                "weecat_close_cb", ""
                )

        weechat.buffer_set(new_buffer, "title",
                "weecat: " + filename)

        weechat.hook_signal_send("logger_backlog",
                weechat.WEECHAT_HOOK_SIGNAL_POINTER, new_buffer)

        listen_hooks[filename] = weechat.hook_fd(this_file.fileno(), 1, 0, 0, "weecat_update_cb", new_buffer)

        weechat.buffer_set(new_buffer, "display", "1") # switch to it

        weecat_buffers.add(new_buffer)
        files_by_buffer[new_buffer] = this_file

    return weechat.WEECHAT_RC_OK
Пример #4
0
 def connect(self):
     self.create_buffer()
     self.disconnect()
     weechat.prnt(
         self.buffer, 'Connecting to %s:%s' %
         (self.get_option('host'), self.get_option('port')))
     try:
         hints = socket.getaddrinfo(self.get_option('host'),
                                    self.get_option('port'),
                                    socket.AF_UNSPEC, socket.SOCK_STREAM, 0,
                                    socket.AI_PASSIVE)
     except socket.error as e:
         weechat.prnt(self.buffer,
                      '%s%s' % (weechat.prefix('error'), e.args[1]))
     else:
         for res in hints:
             af, socktype, proto, canonname, sa = res
             try:
                 self.socket = socket.socket(af, socktype, proto)
                 self.socket.connect(sa)
             except socket.error:
                 self.socket = None
                 continue
             break
     if self.socket is None:
         weechat.prnt(self.buffer,
                      '%sCould not connect' % (weechat.prefix('error'), ))
     else:
         self.hook_fd = weechat.hook_fd(self.socket.fileno(), 1, 0, 0,
                                        'wee_ns_hook_fd_cb', '')
Пример #5
0
def urlserver_server_start():
    """Start mini HTTP server."""
    global urlserver, urlserver_settings
    if urlserver['socket']:
        weechat.prnt('', 'URL server already running')
        return
    port = 0
    try:
        port = int(urlserver_settings['http_port'])
    except:
        port = 0
    urlserver['socket'] = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    urlserver['socket'].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        urlserver['socket'].bind((urlserver_settings['http_hostname'] or
                                  socket.getfqdn(), port))
    except Exception as e:
        weechat.prnt('', '%sBind error: %s' % (weechat.prefix('error'), e))
        urlserver['socket'] = None
        urlserver_server_status()
        return
    urlserver['socket'].listen(5)
    urlserver['hook_fd'] = weechat.hook_fd(urlserver['socket'].fileno(),
                                           1, 0, 0,
                                           'urlserver_server_fd_cb', '')
    urlserver_server_status()
Пример #6
0
    def run(self):
        self.pid, fd = self.fork()

        self.hook_fd = weechat.hook_fd(fd, 1, 0, 0, "term_fd_cb", self.buffer)
        self.f = os.fdopen(fd, "w+b", 0)

        weechat.buffer_set(self.buffer, "display", "1") # switch to buffer
Пример #7
0
 def connect(self):
     self.create_buffer()
     self.disconnect()
     weechat.prnt(self.buffer,
                  'Connecting to %s:%s'
                  % (self.get_option('host'), self.get_option('port')))
     try:
         hints = socket.getaddrinfo(self.get_option('host'),
                                    self.get_option('port'),
                                    socket.AF_UNSPEC, socket.SOCK_STREAM,
                                    0, socket.AI_PASSIVE)
     except socket.error as e:
         weechat.prnt(self.buffer,
                      '%s%s' % (weechat.prefix('error'), e.args[1]))
     else:
         for res in hints:
             af, socktype, proto, canonname, sa = res
             try:
                 self.socket = socket.socket(af, socktype, proto)
                 self.socket.connect(sa)
             except socket.error:
                 self.socket = None
                 continue
             break
     if self.socket is None:
         weechat.prnt(self.buffer,
                      '%sCould not connect' % (weechat.prefix('error'),))
     else:
         self.hook_fd = weechat.hook_fd(self.socket.fileno(), 1, 0, 0,
                                        'wee_ns_hook_fd_cb', '')
Пример #8
0
def urlserver_server_start():
    """Start mini HTTP server."""
    global urlserver, urlserver_settings
    if urlserver['socket']:
        weechat.prnt('', 'URL server already running')
        return
    port = 0
    try:
        port = int(urlserver_settings['http_port'])
    except:
        port = 0
    urlserver['socket'] = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    urlserver['socket'].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        urlserver['socket'].bind((urlserver_settings['http_hostname']
                                  or socket.getfqdn(), port))
    except Exception as e:
        weechat.prnt('', '%sBind error: %s' % (weechat.prefix('error'), e))
        urlserver['socket'] = None
        urlserver_server_status()
        return
    urlserver['socket'].listen(5)
    urlserver['hook_fd'] = weechat.hook_fd(urlserver['socket'].fileno(), 1, 0,
                                           0, 'urlserver_server_fd_cb', '')
    urlserver_server_status()
Пример #9
0
 def create_slack_websocket(self, data):
     web_socket_url = data['url']
     try:
         self.ws = create_connection(web_socket_url)
         self.ws.sock.setblocking(0)
         self.ws_hook = w.hook_fd(self.ws.sock._sock.fileno(), 1, 0, 0, "slack_websocket_cb", self.identifier)
         return True
     except:
         return False
Пример #10
0
 def create_slack_websocket(self, data):
     web_socket_url = data['url']
     try:
         self.ws = create_connection(web_socket_url)
         self.ws.sock.setblocking(0)
         self.ws_hook = w.hook_fd(self.ws.sock._sock.fileno(), 1, 0, 0,
                                  "slack_websocket_cb", self.identifier)
         return True
     except:
         return False
Пример #11
0
def init_socket():
    global signald_socket
    global signald_hook
    signald_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    try:
        signald_socket.connect(options["socket"])
        # weechat really wants the last argument to be a string, but we really
        # want it to be bytes. so we end up having to do a bunch of gnarly
        # decoding and stuff in receive(). c'est la vie.
        signald_hook = weechat.hook_fd(signald_socket.fileno(), 1, 0, 0,
                                       'receive', '')
    except Exception:
        logger.exception("Failed to connect to signald socket")
Пример #12
0
 def setup_udp_listener(self):
     for key in ['udp_listen_ip', 'udp_listen_port', 'udp_listen_pass']:
         if self.state[key] and self.state[key] == '':
             return dlog("UDP listener disabled: missing '%s' setting" %
                         key)
     if self.udp_socket_open == True:
         self.udp_socket.close()
         self.udp_socket_open = False
     self.udp_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
     self.udp_socket.bind(
         (self.state['udp_listen_ip'], self.state['udp_listen_port']))
     self.udp_socket_open = True
     hook = weechat.hook_fd(self.udp_socket.fileno(), 1, 0, 0,
                            "shim_wcb_handle_udp_input", "")
     dlog("UDP listener started at [%s]:%s!" %
          (self.state['udp_listen_ip'], self.state['udp_listen_port']))
Пример #13
0
def create_stream(name, args = ""):
    global sock_fd_dict
    global proc_hooks
    global sock_hooks

    if proc_hooks.get(name):
        return "Stream has already been created, close it before trying to open a new one"

    #Check if buffer exists
    buffer = weechat.buffer_search("python", name)
    if buffer == "":
        buffer = weechat.buffer_new(name, "buffer_input_cb", name, "stream_close_cb", name)
        setup_buffer(buffer)

    if not sock_fd_dict.get(name):
        file_name = tempfile.gettempdir() + "/we_tw_" + name
        if os.path.exists(file_name):
            os.remove(file_name)

        server = socket.socket( socket.AF_UNIX, socket.SOCK_STREAM )
        server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server.bind(file_name)
        #Don't block, timeout if no data is present
        server.setblocking(0)
        server.listen(1)
        file_fd = server.fileno()
        sock_fd_dict[str(file_fd)] = name
        sock_fd_dict[name] = server
        sock_hooks[name] = weechat.hook_fd(file_fd, 1, 0, 0, "twitter_stream_cb", buffer)

    options = dict(screen_name = script_options['screen_name'], name = name,
            alt_rt_style = int(script_options['alt_rt_style']),
            home_replies = int(script_options['home_replies']),
            stream_args = args)

    proc_hooks[name] = weechat.hook_process("python3 " + SCRIPT_FILE_PATH + " " +
                script_options["oauth_token"] + " " + script_options["oauth_secret"] + " " +
                "stream " + file_name + ' "' + str(options) + '"',  0 , "my_process_cb", str([buffer,"Stream"]))
    return "Started stream"
Пример #14
0
def urlserver_server_start():
    """Start mini HTTP server."""
    global urlserver, urlserver_settings
    if urlserver["socket"]:
        weechat.prnt("", "URL server already running")
        return
    port = 0
    try:
        port = int(urlserver_settings["http_port"])
    except:
        port = 0
    urlserver["socket"] = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    urlserver["socket"].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        urlserver["socket"].bind((urlserver_settings["http_hostname"] or socket.getfqdn(), port))
    except Exception as e:
        weechat.prnt("", "%sBind error: %s" % (weechat.prefix("error"), e))
        urlserver["socket"] = None
        urlserver_server_status()
        return
    urlserver["socket"].listen(5)
    urlserver["hook_fd"] = weechat.hook_fd(urlserver["socket"].fileno(), 1, 0, 0, "urlserver_server_fd_cb", "")
    urlserver_server_status()
Пример #15
0
def buf_node_in(pssName, buf, args):

    global psses

    ctx = {}
    currentPss = None
    argv = ""
    argc = 0
    bufname = ""

    # parse cmd input
    # \todo remove consecutive whitespace
    argv = args.split(" ")
    argc = len(argv)

    # first we handle commands that are node independent

    # the connect command is the same for any context
    if argv[0] == "connect":

        host = "127.0.0.1"
        port = "8546"
        pssName = ""

        if argc < 2:
            wOut(PSS_BUFPFX_ERROR, [], "!!!",
                 "invalid command <TODO insert help text>")
        pssName = argv[1]

        if argc > 2:
            host = argv[2]

        if argc > 3:
            port = argv[3]

        if pssName in psses:
            existingBuf = weechat.buffer_search("python",
                                                "pss.node." + pssName)
            if existingBuf != "":
                wOut(
                    PSS_BUFPFX_DEBUG, [], "", "pss " + pssName +
                    " already exists, changing to that buffer")
                weechat.buffer_set(bufs[pssName], "display", "1")
                return weechat.WEECHAT_RC_OK

            if host == "":
                host = weechat.config_get_plugin(pssName + "_url", host)

            if port == "":
                port = weechat.config_get_plugin(pssName + "_port", port)

            wOut(PSS_BUFPFX_DEBUG, [], "",
                 "pss " + pssName + " already exists")
        else:
            psses[pssName] = pss.Pss(pssName, host, port)
            wOut(PSS_BUFPFX_OK, [], "+++", "added pss " + pssName)

        # regardless of if we have the node already, store the connection parameters for later for this node name
        weechat.config_set_plugin(pssName + "_url", host)
        weechat.config_set_plugin(pssName + "_port", port)

        # if we made it here we don't have a buffer for this node already
        # so create it and merge the node buffer with core so we can do the neat ctrl-x trick
        bufs[pssName] = weechat.buffer_new("pss.node." + pssName,
                                           "buf_node_in", pssName,
                                           "buf_node_close", pssName)
        weechat.buffer_set(bufs[pssName], "short_name", "pss." + pssName)
        weechat.buffer_set(bufs[pssName], "title",
                           "PSS '" + pssName + "' | not connected")
        weechat.buffer_merge(bufs[pssName], weechat.buffer_search_main())
        weechat.buffer_set(bufs[pssName], "display", "1")

        # now that we have the buffer up we have somewhere to write output relevant to this connection
        # we can proceed with connection in the pss instance
        wOut(PSS_BUFPFX_WARN, [bufs[pssName]], "0-> 0",
             "connecting to '" + pssName + "'")
        if not psses[pssName].connect():
            wOut(
                PSS_BUFPFX_ERROR, [bufs[pssName]], "0-x 0", "connect to '" +
                pssName + "' failed: " + psses[pssName].error()['description'])
            return weechat.WEECHAT_RC_ERROR
        wOut(PSS_BUFPFX_OK, [bufs[pssName]], "0---0",
             "connected to '" + pssName + "'")

        # \todo temporary solution, swarm gateway should be set explicitly or at least we need to be able to choose port
        hookSocks.append(
            weechat.hook_connect("", host, 8500, 0, 0, "", "sock_connect",
                                 pssName))

        # start processing inputs on the websocket
        hookFds[pssName] = weechat.hook_fd(psses[pssName].get_fd(), 1, 0, 0,
                                           "msgPipeRead", pssName)
        hookTimers.append(
            weechat.hook_timer(feedBoxPeriod, 0, 0, "processFeedBox", pssName))

        # set own nick for this node
        # \todo use configurable global default nick
        # \todo clean up messy pubkey slicing (should be binary format in pss obj)
        pubkey = psses[pssName].key[2:]
        selfs[pssName] = pss.PssContact(
            PSS_DEFAULT_NICK, psses[pssName].key,
            pss.publickey_to_account(pubkey.decode("hex")).encode("hex"),
            psses[pssName].key)
        wOut(PSS_BUFPFX_OK, [bufs[pssName]], pssName,
             "nick is " + selfs[pssName].nick)

        return weechat.WEECHAT_RC_OK

    # get the context we're getting the command in
    # if we are not in pss context,
    # the we assume that the first argument is the name of the node
    # /pss oc add someone key addr
    # becomes
    # /pss add someone key addr
    # and "oc" is set to pssName
    # \todo consider exception for connect-command
    ctx = buf_get_context(buf)
    wOut(PSS_BUFPFX_DEBUG, [], "",
         "ctx: " + repr(ctx['t']) + " n " + ctx['n'] + " h " + ctx['h'])
    shiftArg = False

    # t 0 means any non-pss buffer

    if ctx['t'] == 0 and argv[0] != "connect":
        pssName = argv[0]
        argv = argv[1:]
        argc -= 1
    else:
        pssName = ctx['n']

    wOut(PSS_BUFPFX_DEBUG, [], "!!!", "after ctx " + pssName)

    # see if we already have this node registered
    if not pssName in psses:
        wOut(PSS_BUFPFX_ERROR, [], "!!!",
             "unknown pss connection '" + pssName + "'")
        return weechat.WEECHAT_RC_ERROR
    currentPss = psses[pssName]

    # set configuation values
    if argv[0] == "set":
        if argc < 3:
            wOut(PSS_BUFPFX_ERROR, [], "!!!",
                 "insufficient number of arguments <TODO help output")
            return weechat.WEECHAT_RC_ERROR

        k = argv[1]
        v = argv[2]

        # for now we handle privkeys directly
        # we will read keystore jsons in near future instead, though
        if k == "pk":
            try:
                privkey = pss.clean_privkey(v)
            except:
                wOut(PSS_BUFPFX_ERROR, [], "!!!", "invalid key format")
                return weechat.WEECHAT_RC_ERROR
            try:
                currentPss.set_account_write(privkey.decode("hex"))
            except ValueError as e:
                wOut(PSS_BUFPFX_ERROR, [], "!!!",
                     "set account fail: " + str(e))
                return weechat.WEECHAT_RC_ERROR
        else:
            wOut(PSS_BUFPFX_ERROR, [], "!!!", "unknown config key")
            return weechat.WEECHAT_RC_ERROR

        wOut(PSS_BUFPFX_DEBUG, [], "!!!", "set pk to " + v + " for " + pssName)

        weechat.WEECHAT_RC_OK

    # add a recipient to the address books of plugin and node
    # \todo currently overwritten if same pubkey and different addr, should be possible to have both, maybe even one-shots special command with dark address where entry is deleted after message sent!!!
    elif argv[0] == "add":

        nick = ""
        key = ""
        addr = ""

        # input sanity check
        if argc < 3:
            wOut(PSS_BUFPFX_ERROR, [bufs[currentPssName]], "!!!",
                 "not enough arguments for add <TODO: help output>")
            return weechat.WEECHAT_RC_ERROR

        # puny human varnames
        nick = argv[1]
        key = argv[2]
        if argc == 4:
            addr = argv[3]
        else:
            addr = "0x"

        # backend add recipient call
        if not currentPss.add(nick, key, addr):
            wOut(PSS_BUFPFX_ERROR, [bufs[pssName]], "!!!",
                 "add contact error: " + currentPss.error()['description'])
            return weechat.WEECHAT_RC_ERROR

        # refresh the plugin memory map version of the recipient
        wOut(PSS_BUFPFX_DEBUG, [], "!!!",
             "added key " + key + " to nick " + nick)
        nicks[key] = currentPss.get_contact(nick)
        remotekeys[nick] = key

        # append recipient to file for reinstating across sessions
        storeFile.write(nick + "\t" + key + "\t" + addr + "\t" +
                        currentPss.key + "\n")

        # open the buffer if it doesn't exist
        buf_get(pssName, "chat", nick, True)

        wOut(
            PSS_BUFPFX_INFO, [bufs[pssName]], "!!!",
            "added contact '" + nicks[key].nick + "' to '" + pssName +
            "' (key: " + pss.label(key) + ", addr: " + pss.label(addr) + ")")

    # send a message to a recipient
    elif argv[0] == "send" or argv[0] == "msg":

        nick = ""
        msg = ""

        if argc < 2:
            wOut(PSS_BUFPFX_ERROR, [bufs[pssName]], "!!!",
                 "not enough arguments for send")
            return weechat.WEECHAT_RC_ERROR

        nick = argv[1]
        if argc > 2:
            msg = " ".join(argv[2:])

        # \todo handle hex address only
        if not currentPss.have_nick(nick):
            wOut(PSS_BUFPFX_ERROR, [bufs[pssName]], "!!!",
                 "invalid nick " + nick)
            return weechat.WEECHAT_RC_ERROR

        buf = buf_get(pssName, "chat", nick, True)
        # \todo remove the bufs dict, since we can use weechat method for getting it
        bufs[weechat.buffer_get_string(buf, "name")] = buf

        # if no message body we've just opened the chat window
        if msg != "":
            if not pss.is_message(msg):
                wOut(PSS_BUFPFX_DEBUG, [bufs[pssName]], "",
                     "invalid message " + msg)
                return weechat.WEECHAT_RC_ERROR
            return buf_in(pssName, buf, msg)

    # create/join existing chat room
    elif argv[0] == "join":

        room = ""

        if argc < 2:
            wOut(PSS_BUFPFX_ERROR, [bufs[pssName]], "!!!",
                 "not enough arguments for join")
            return weechat.WEECHAT_RC_ERROR

        room = argv[1]

        wOut(PSS_BUFPFX_DEBUG, [], "!!!", "in join " + pssName)
        buf = buf_get(pssName, "room", room, True)

    # invite works in context of chat rooms, and translates in swarm terms to
    # adding one separate feed encoded with the invited peer's key
    # room argument can be omitted if command is issued om channel to invite to
    # note feeds are currently unencrypted
    elif argv[0] == "invite":

        nick = ""
        roomname = ""

        if argc < 2:
            wOut(PSS_BUFPFX_ERROR, [bufs[pssName]], "!!!",
                 "not enough arguments for invite")

        # if missing channel argument get bufname command was issued in
        # and derive channel name from it if we can (fail if not)
        elif argc < 3:
            if ctx['t'] != PSS_BUFTYPE_ROOM:
                wOut(PSS_BUFPFX_ERROR, [bufs[pssName]], "!!!",
                     "unknown channel '" + ctx['t'] + "'")
                return weechat.WEECHAT_RC_ERROR
            roomname = ctx['h']

        else:
            roomname = argv[2]

        nick = argv[1]

        # check if room exists
        # if it does, perform invitation
        try:
            roombufname = buf_generate_name(pssName, "room", roomname)
            room = rooms[roombufname]
            pss_invite(pssName, nick, room)

            wOut(PSS_BUFPFX_DEBUG, [], "!!!",
                 "added " + nick + " to " + roomname)
            # if neither the previous fail, add the nick to the buffer
            roombuf = weechat.buffer_search("python", roombufname)
            buf_room_add(roombuf, nick)

        except KeyError as e:  # keyerror catches both try statements
            wOut(PSS_BUFPFX_ERROR, [buf], "!!!",
                 "Unknown room or nick: " + str(e))

    # output node key
    elif argv[0] == "key" or argv[0] == "pubkey":
        wOut(PSS_BUFPFX_INFO, [bufs[pssName]], pssName + ".key",
             currentPss.key)

    # output node base address
    elif argv[0] == "addr" or argv[0] == "address":
        wOut(PSS_BUFPFX_INFO, [bufs[pssName]], pssName + ".addr",
             currentPss.base)

    # set nick for pss node
    elif argv[0] == "nick":
        try:
            if len(argv) > 1:
                nick = pss.clean_nick(argv[1])
                selfs[pssName].nick = nick
            wOut(PSS_BUFPFX_INFO, [bufs[pssName]], pssName,
                 "nick is '" + selfs[pssName].nick + "'")
        except ValueError as e:
            wOut(PSS_BUFPFX_ERROR, [bufs[pssName]], "!!!",
                 "Invalid nick: " + argv[1])

    # stop connection
    # \todo also kill the subprocess
    # \todo ensure clean shutdown so conncet can be called over
    elif argv[0] == "stop":
        weechat.unhook(hookFds[pssName])
        wOut(PSS_BUFPFX_INFO, [bufs[pssName]], "!!!",
             "disconnected from " + pssName)
        currentPss.close()
        #del psses[currentPssName]

    # invalid input
    else:
        return weechat.WEECHAT_RC_ERROR

    # all good
    return weechat.WEECHAT_RC_OK
Пример #16
0
def connect(url, data):
    global xd
    # ping the server, to see if it's online
    ping = requests.get(urljoin(url, "api"))
    if ping.status_code == requests.codes.teapot and "decent" in ping.json():
        weechat.prnt(
            "", "weecent\tSuccessfully connected to Decent server %s." % url)
    elif ping.status_code in (requests.codes.ok, requests.codes.not_found):
        weechat.prnt(
            "", "weecent\t%s is not a valid Decent server, skipping." % url)
        del xd[url]
        return
    else:
        weechat.prnt("", "weecent\tCould not connect to %s, skipping." % url)
        del xd[url]
        return

    # login
    login_r = requests.post(urljoin(url, "api/login"), json=data)
    login_data = login_r.json()

    server_name = url.split("//")[1]
    if login_data["success"]:
        session_id = login_data["sessionID"]
        xd[url]["session_id"] = session_id

        channels_r = requests.get(urljoin(url, "api/channel-list"),
                                  {'sessionID': session_id})
        if channels_r.json()['success']:
            channels = channels_r.json()['channels']

            # create server buffer
            buffer_ = weechat.buffer_new(server_name, "server_input_cb", "",
                                         "server_close_cb", "")
            weechat.buffer_set(buffer_, "title", "Weecent testing!")
            weechat.buffer_set(buffer_, "localvar_set_no_log", "1")
            weechat.buffer_set(buffer_, "localvar_set_type", "server")
            weechat.buffer_set(buffer_, "localvar_set_url", url)
            weechat.buffer_set(buffer_, "localvar_set_server", server_name)
            xd[url]["buffer"] = buffer_

            # create channel buffers
            xd[url]["channels"] = {}
            for channel in channels:
                xd[url]["channels"][channel["id"]] = {"name": channel["name"]}

                # set up buffer
                buffer_ = weechat.buffer_new(channel["name"], "send_message",
                                             "", "channel_close_cb", "")
                weechat.buffer_set(buffer_, "title", "Weecent testing!")
                weechat.buffer_set(buffer_, "nicklist", "1")
                weechat.buffer_set(buffer_, "nicklist_display_groups", "0")
                weechat.buffer_set(buffer_, "localvar_set_no_log", "1")
                weechat.buffer_set(buffer_, "localvar_set_type", "channel")
                weechat.buffer_set(buffer_, "localvar_set_channel",
                                   json.dumps(channel))
                weechat.buffer_set(buffer_, "localvar_set_url", url)
                weechat.buffer_set(buffer_, "localvar_set_server", server_name)
                xd[url]["channels"][channel["id"]]["buffer"] = buffer_

                # get scrollback
                scrollback_r = requests.get(
                    urljoin(url,
                            "api/channel/%s/latest-messages" % channel["id"]))
                messages = scrollback_r.json()["messages"]
                for m in messages:
                    display_msg(buffer_, m, xd[url])

                # get users
                users_r = requests.get(urljoin(url, "api/user-list"))
                users = users_r.json()["users"]

                group = weechat.nicklist_add_group(
                    buffer_, "", "Users", "weechat.color.nicklist_group", 1)

                for u in users:
                    weechat.nicklist_add_nick(
                        buffer_, group, u["username"],
                        "default" if u["online"] else "lightgrey", "",
                        "lightgreen", 1)
        else:
            weechat.prnt("", "ono a bad happened")

        # create websocket
        if not "socket" in xd[url]:
            # wss or ws?
            use_secure = requests.get(urljoin(url,
                                              "api/should-use-secure")).json()
            protocol = "wss://" if use_secure["useSecure"] else "ws://"

            xd[url]['socket'] = websocket.create_connection(
                protocol + server_name, sslopt=sslopt_ca_certs)

            weechat.hook_fd(xd[url]['socket'].sock._sock.fileno(), 1, 0, 0,
                            "recv_cb", "")
            xd[url]['socket'].sock.setblocking(0)
    else:
        weechat.prnt("", "ono a bad happened")
Пример #17
0
class weeNSServer :
    def __init__(self) :
        global weeNS_server_opt, weeNS_config_file, weeNS_config_server_section
        self.buffer = None
        self.hook_fd = None
        self.socket = None
        self.netbuffer = ''
        self.chats = []
        self.contacts = {}
        self.options = {
            'host'     : weechat.config_new_option(weeNS_config_file, weeNS_config_server_section,
                                                   'host', 'string', 'Server Host (default: ns-server.epita.fr)', '', 0, 0,
                                                   'ns-server.epita.fr', 'ns-server.epita.fr', 0, '', '', '', '', '', ''),
            'port'     : weechat.config_new_option(weeNS_config_file, weeNS_config_server_section,
                                                   'port', 'string', 'Server Port (default: 4242)', '', 0, 0,
                                                   '4242', '4242', 0, '', '', '', '', '', ''),
            'login'    : weechat.config_new_option(weeNS_config_file, weeNS_config_server_section,
                                                   'login', 'string', 'User login (ie: login_x)', '', 0, 0,
                                                   'login_x', 'login_x', 0, '', '', '', '', '', ''),
            'password' : weechat.config_new_option(weeNS_config_file, weeNS_config_server_section,
                                                   'password', 'string', 'User password (ie: your SOCKS password)', '', 0, 0,
                                                   'xxxxxx', 'xxxxxx', 0, '', '', '', '', '', ''),
            'location' : weechat.config_new_option(weeNS_config_file, weeNS_config_server_section,
                                                   'location', 'string', 'User location (ie: at home)', '', 0, 0,
                                                   '-', '-', 0, '', '', '', '', '', ''),
            'data'     : weechat.config_new_option(weeNS_config_file, weeNS_config_server_section,
                                                   'data', 'string', 'User data (ie: j\'aime les chips)', '', 0, 0,
                                                   '-', '-', 0, '', '', '', '', '', ''),
            'contacts' : weechat.config_new_option(weeNS_config_file, weeNS_config_server_section,
                                                   'contacts', 'string', 'Comma separated login list (ie: sb,rn)', '', 0, 0,
                                                   '', '', 0, '', '', '', '', '', '')}

    def getOption(self, opt_name) :
        return weechat.config_string(self.options[opt_name])

    def getChatByRecipient(self, login = None, fd = None, create = False) :
        for chat in self.chats :
            if (fd is not None and chat.fd == fd) or (chat.login == login and chat.fd == fd) :
                return chat
        if create is True :
            return weeNSChat(self, login, fd)
        return None

    def getChatByBuffer(self, buffer) :
        for chat in self.chats :
            if chat.buffer == buffer :
                return chat
        return server

    def createBuffer(self) :
        if self.buffer == None :
            self.buffer = weechat.buffer_new('Netsoul', 'weeNS_buffer_input_cb', '', 'weeNS_buffer_close_cb', '')
            weechat.buffer_set(self.buffer, "nicklist", "1")
            weechat.buffer_set(self.buffer, "nicklist_display_groups", "1")
            weechat.buffer_set(self.buffer, "display", "auto")

    def connect(self) :
        self.createBuffer()
        self.disconnect()
        weechat.prnt(self.buffer, 'Connecting to %s:%s' % (self.getOption('host'), self.getOption('port')))
        for res in socket.getaddrinfo(self.getOption('host'), self.getOption('port'), socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE) :
            af, socktype, proto, canonname, sa = res
            try :
                self.socket = socket.socket(af, socktype, proto)
                self.socket.connect(sa)
            except socket.error, msg:
                self.socket = None
                continue
            break
        if self.socket is None :
            weechat.prnt(self.buffer, 'Could not connect')
        self.hook_fd = weechat.hook_fd(self.socket.fileno(), 1, 0, 0, 'weeNS_hook_fd_cb', '')
Пример #18
0
    def connect(self):
        """ Connect """
        if not self.connect_webex():
            return False

        if not self.buffer:
            bufname = f"{SCRIPT_NAME}.{self.domain}"
            self.buffer = weechat.buffer_search("python", bufname)
            if not self.buffer:
                self.buffer = weechat.buffer_new(bufname,
                                                 "webex_buffer_input_cb", "",
                                                 "webex_buffer_close_cb", "")
            if self.buffer:
                weechat.buffer_set(self.buffer, "short_name", SCRIPT_NAME)
                weechat.buffer_set(self.buffer, "input_multiline", "1")
                weechat.buffer_set(self.buffer, "localvar_set_type", "server")
                weechat.buffer_set(self.buffer, "localvar_set_server",
                                   self.domain)
                weechat.buffer_set(self.buffer, "display", "auto")

        self.prnt(f"Bienvenue {self.buddy.name}")

        # Join rooms that are in config
        rooms_to_join = self.get_config_value("autojoin_rooms")
        if rooms_to_join:
            for room_name in rooms_to_join.split(','):
                room = self.search_room(room_name, use_cache=True)
                if room:
                    self.chats.append(
                        Chat(self, room.title, room.id, "channel", auto=False))

        # Join direct chats that are in config
        directs_to_join = self.get_config_value("autojoin_directs")
        if directs_to_join:
            for email in directs_to_join.split(','):
                if '@' not in email:
                    email = f"{email}@{self.domain}"
                buddy = Buddy(self.get_person(email))
                if buddy:
                    if buddy.domain == self.domain:
                        buf_name = buddy.name
                    else:
                        buf_name = buddy.email
                    self.chats.append(
                        Chat(self, buf_name, buddy.id, "private", auto=False))

        # Autojoin last rooms
        autojoin_last = self.get_config_int_value("autojoin_last")
        if autojoin_last > 0:
            rooms = self.list_rooms(type=None, max=autojoin_last)
            if rooms:
                for room in rooms:
                    if room.type == 'group':
                        self.chats.append(
                            Chat(self,
                                 room.title,
                                 room.id,
                                 "channel",
                                 auto=False))
                    else:
                        person = self.get_person_from_id(room.id)
                        if person:
                            buddy = Buddy(self.get_person_from_id(room.id))
                            if buddy.domain == self.domain:
                                buf_name = buddy.name
                            else:
                                buf_name = buddy.email
                            self.chats.append(
                                Chat(self,
                                     buf_name,
                                     buddy.id,
                                     "private",
                                     auto=False))

        # SOCKET
        # We bind on 127.0.0.1:{port/8080}
        # So we need a proxy pass (like nginx or apache)
        # to forward the request to this socket
        if not self.sock:
            self.prnt("Starting socket")
            try:
                port = self.get_config_int_value("port")
                self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.sock.bind(("127.0.0.1", port))
                self.sock.listen(5)
                self.prnt(f"Socket listening on {self.sock.getsockname()}")
            except Exception as e:
                self.prnt(f"Error while creating the HTTP server: {e}")
                self.disconnect()
                self.sock = None

        # WEECHAT HOOK
        if not self.hook:
            try:
                self.hook = weechat.hook_fd(self.sock.fileno(), 1, 0, 0,
                                            "socket_cb", "")
            except Exception as e:
                self.prnt(f"Error while creating the weechat hook: {e}")
                self.disconnect()
                self.hook = None

        # WEBEX HOOKBUSTER / Websocket proxy
        self.start_websocket(force=False)

        return True
Пример #19
0
def pss_handle(pssName, buf, args):

	# context is only used for acvie nodes
	ctx = EventContext()

	# parse cmd input 
	# \todo remove consecutive whitespace
	argv = args.split(" ")
	argc = len(argv)

	# first we handle commands that are node independent	

	# the connect command is the same for any context
	# \todo rollback on connect fail
	if argv[0] == "connect":

		host = "127.0.0.1"
		port = "8546"
	
		if argc < 2:
			wOut(PSS_BUFPFX_ERROR, [], "!!!", "invalid command <TODO insert help text>")
		ctx.set_node(argv[1])

		if argc > 2:
			host = argv[2]	
		
		if argc > 3:
			port = argv[3]	

		if cache.have_node_name(ctx.get_node()):	
			existingBuf = weechat.buffer_search("python", "pss.node." + ctx.get_node())
			if existingBuf != "":
				wOut(PSS_BUFPFX_DEBUG, [], "", "pss " + ctx.get_node() + " already exists, changing to that buffer")
				weechat.buffer_set(bufs[ctx.get_node()], "display", "1")
				return weechat.WEECHAT_RC_OK

			if host == "":
				host = weechat.config_get_plugin(ctx.get_node() + "_url", host)

			if port == "":
				port = weechat.config_get_plugin(ctx.get_node() + "_port", port)
	
			wOut(PSS_BUFPFX_DEBUG, [], "", "pss " + ctx.get_node() + " already exists")

		# regardless of if we have the node already, store the connection parameters for later for this node name	
		weechat.config_set_plugin(ctx.get_node() + "_url", host)
		weechat.config_set_plugin(ctx.get_node() + "_port", port)

	
		# if we made it here we don't have a buffer for this node already
		# so create it and merge the node buffer with core so we can do the neat ctrl-x trick
		bufs[ctx.get_node()] = weechat.buffer_new("pss.node." + ctx.get_node(), "buf_node_in", ctx.get_node(), "buf_close", ctx.get_node())
		weechat.buffer_set(bufs[ctx.get_node()], "short_name", "pss."+ ctx.get_node())
		weechat.buffer_set(bufs[ctx.get_node()], "title", "PSS '" + ctx.get_node() + "' | not connected")
		weechat.buffer_merge(bufs[ctx.get_node()], weechat.buffer_search_main())
		weechat.buffer_set(bufs[ctx.get_node()], "display", "1")


		# now that we have the buffer up we have somewhere to write output relevant to this connection
		# we can proceed with connection in the pss instance
		wOut(
			PSS_BUFPFX_WARN,
			[bufs[ctx.get_node()]],
			"0-> 0",
			"connecting to '" + ctx.get_node() + "'"
		)
	
		pssnode = pss.Pss(ctx.get_node(), host, port)

		if not pssnode.connect():
			wOut(PSS_BUFPFX_ERROR, [bufs[ctx.get_node()]], "-1-x 0", "connect to '" + ctx.get_node() + "' failed: " + cache.get_pss(ctx.get_node()).error()['description'])
			return weechat.WEECHAT_RC_ERROR

		wOut(PSS_BUFPFX_OK, [bufs[ctx.get_node()]], "0---0", "connected to '" + ctx.get_node() + "'")

		_tmp_chat_queue_hash[ctx.get_node()] = ""
		cache.add_node(pssnode)

		wOut(PSS_BUFPFX_OK, [], "+++", "added pss " + ctx.get_node())

		
		# save what we've accomplished so far in the context, to be passed to the hook
		ctx.parse_buffer(bufs[ctx.get_node()])
		ctx.set_pss(cache.get_pss(ctx.get_node()))
		ctx.set_bzz(cache.get_active_bzz())
		# \todo temporary solution, swarm gateway should be set explicitly or at least we need to be able to choose port
		ctxid = ctxstore.put(ctx)
		hookSocks.append(weechat.hook_connect("", host, 8500, 0, 0, "", "pss_connect", ctxid))
		


		# start processing inputs on the websocket
		hookFds[ctx.get_node()] = weechat.hook_fd(cache.get_pss(ctx.get_node()).get_fd(), 1, 0, 0, "msgPipeRead", ctx.get_node())
		hookTimers.append(weechat.hook_timer(PSS_FEEDBOX_PERIOD, 0, 0, "processFeedOutQueue", ctx.get_node()))

		# set own nick for this node
		# \todo use configurable global default nick
		# \todo clean up messy pubkey slicing (should be binary format in pss obj)
		cache.set_nodeself(ctx.get_node(), PSS_DEFAULT_NICK)
		
		return weechat.WEECHAT_RC_OK


	# get the context we're getting the command in
	# if we are not in pss context, 
	# the we assume that the first argument is the name of the node
	# /pss oc add someone key addr
	# becomes
	# /pss add someone key addr
	# and "oc" is set to pssName
	# \todo consider exception for connect-command

	ctx.parse_buffer(buf)
	if ctx.is_root():
		ctx.set_node(argv[0])
		argv = argv[1:]
		argc -= 1

	try:
		ctx.set_pss(cache.get_pss(ctx.get_node()))
		ctx.set_bzz(cache.get_active_bzz())
	except:
		wOut(
			PSS_BUFPFX_ERROR,
			[],
			"!!!",
			"unknown pss connection '" + ctx.get_node() + "'"
		)
		return weechat.WEECHAT_RC_ERROR


	# set configuation values
	if argv[0] == "set":
		if argc < 3:
			wOut(PSS_BUFPFX_ERROR, [], "!!!", "insufficient number of arguments <TODO help output")
			return weechat.WEECHAT_RC_ERROR

		k = argv[1]
		v = argv[2]

		# for now we handle privkeys directly
		# we will read keystore jsons in near future instead, though
		if k == "pk":
			try:
				privkey = pss.clean_privkey(v)
			except:
				wOut(PSS_BUFPFX_ERROR, [], "!!!", "invalid key format")
				return weechat.WEECHAT_RC_ERROR
			try:
				pssnode = cache.get_pss(ctx.get_node())
				pssnode.set_account_write(privkey.decode("hex"))
				cache.update_node_contact_feed(pssnode)
			except KeyError as e:
				pass
			except ValueError as e:
				wOut(PSS_BUFPFX_ERROR, [], "!!!", "set account fail: " + str(e))
				return weechat.WEECHAT_RC_ERROR
		else:
			wOut(PSS_BUFPFX_ERROR, [], "!!!", "unknown config key")
			return weechat.WEECHAT_RC_ERROR
					
		wOut(PSS_BUFPFX_DEBUG, [], "!!!", "set pk to " + v + " for " + ctx.get_node())

		weechat.WEECHAT_RC_OK	
	


	# add a recipient to the address books of plugin and node
	# \todo currently overwritten if same pubkey and different addr, should be possible to have both, maybe even one-shots special command with dark address where entry is deleted after message sent!!!
	elif argv[0] == "add":

		nick = ""
		pubkeyhx = ""
		overlayhx = ""

		# input sanity check
		if argc < 3:
			wOut(
				PSS_BUFPFX_ERROR,
				[ctx.get_buffer()],
				"!!!",
				"not enough arguments for add <TODO: help output>"
			)
			return weechat.WEECHAT_RC_ERROR

		# puny human varnames
		nick = argv[1]
		pubkeyhx = argv[2]
		if argc == 4:
			overlayhx = argv[3]
		else:
			overlayhx = "0x"
		
		# backend add recipient call	
		pubkey = pss.clean_pubkey(pubkeyhx).decode("hex")
		overlay = pss.clean_overlay(overlayhx).decode("hex")
		try:
			newcontact = pss.PssContact(nick, ctx.get_pss().get_public_key())
			newcontact.set_public_key(pubkey)
			newcontact.set_overlay(overlay)
			ctx.get_pss().add(newcontact)
			cache.add_contact(newcontact, True)
		except Exception as e:
			wOut(
				PSS_BUFPFX_ERROR,
				[ctx.get_buffer()],
				"!!!",
				"add contact error: " + repr(e)
			)
			return weechat.WEECHAT_RC_ERROR

		ctx.reset(PSS_BUFTYPE_CHAT, ctx.get_node(), nick)

		# refresh the plugin memory map version of the recipient
		wOut(
			PSS_BUFPFX_DEBUG,
			[],
			"!!!",
			"added key " + pubkeyhx + " to nick " + nick + " node " + ctx.get_node()
		)

		# retrieve the buffer (create if it doesn't exist)
		buf_get(ctx, True)	
		wOut(
			PSS_BUFPFX_INFO,
			[ctx.get_buffer()],
			"!!!",
			"added contact '" + ctx.get_name() + "' to '" + ctx.get_node() + "' (key: " + pss.label(pubkeyhx) + ", addr: " + pss.label(overlayhx) + ")"
		)


	# send a message to a recipient
	elif argv[0] == "send" or argv[0] == "msg":

		nick = ""
		msg = ""

		# verify input
		if argc < 2:
			wOut(
				PSS_BUFPFX_ERROR,
				[ctx.get_buffer()],
				"!!!",
				"not enough arguments for send"
			)
			return weechat.WEECHAT_RC_ERROR

		nick = pss.clean_nick(argv[1])
		if argc > 2:
			msg = " ".join(argv[2:])

		# check that the contact is known in the cache
		contact = None
		try:
			contact = cache.get_contact_by_nick(nick)
		except:
			wOut(
				PSS_BUFPFX_ERROR,
				[ctx.get_buffer()],
				"!!!",
				"invalid nick " + nick
			)
			return weechat.WEECHAT_RC_ERROR

		ctx.reset(PSS_BUFTYPE_CHAT, ctx.get_node(), nick)
		buf = buf_get(ctx, True)

		# if no message body we've just opened the chat window
		if msg != "":
			if not pss.is_message(msg):
				wOut(
					PSS_BUFPFX_DEBUG,
					[ctx.get_buffer()],
					"",
					"invalid message " + msg
				)
				return weechat.WEECHAT_RC_ERROR

			return buf_in(ctx.get_node(), buf, msg)


	# create/join existing chat room
	# \todo broken 
	elif argv[0] == "join":

		room = ""

		if argc < 2:
			wOut(
				PSS_BUFPFX_ERROR,
				[ctx.get_buffer()],
				"!!!",
				"not enough arguments for join"
			)
			return weechat.WEECHAT_RC_ERROR

		room = argv[1]
		ctx.reset(PSS_BUFTYPE_ROOM, ctx.get_node(), room)

		if not ctx.get_name() in _tmp_room_queue_hash:
			_tmp_room_queue_hash[ctx.get_name()] = pss.zerohsh

		# start buffer for room
		buf_get(ctx, True)


	# invite works in context of chat rooms, and translates in swarm terms to
	# adding one separate feed encoded with the invited peer's key
	# room argument can be omitted if command is issued om channel to invite to
	# note feeds are currently unencrypted
	# \todo broken
	elif argv[0] == "invite":

		nick = ""
		roomname = ""

		if argc < 2:
			wOut(
				PSS_BUFPFX_ERROR,
				[ctx.get_buffer()],
				"!!!",
				"not enough arguments for invite"
			)

		# if missing channel argument get bufname command was issued in
		# and derive channel name from it if we can (fail if not)
		elif argc < 3:
			if not ctx.is_room():
				wOut(
					PSS_BUFPFX_ERROR,
					[ctx.get_buffer()],
					"!!!",
					"unknown channel '" + ctx.get_name() + "'"
				)
				return weechat.WEECHAT_RC_ERROR
	
		else:
			ctx.set_name(argv[2])

		nick = pss.clean_nick(argv[1])

		# check if room exists
		# if it does, perform invitation
		try:
			#roombufname = buf_generate_name(pssName, "room", roomname)
			roombufname = ctx.to_buffer_name()
			room = cache.get_room(ctx.get_name()) #roombufname)
			pss_invite(pssName, nick, room)
			wOut(
				PSS_BUFPFX_DEBUG,
				[],
				"!!!",
				"added " + nick + " to " + ctx.get_name()
			)
			# if neither the previous fail, add the nick to the buffer
			roombuf = weechat.buffer_search("python", roombufname)
			buf_room_add(roombuf, nick)

		except KeyError as e: # keyerror catches both try statements
			wOut(
				PSS_BUFPFX_ERROR,
				[ctx.get_buffer()],
				"!!!",
				"Unknown room or nick: " + str(e)
			)


	# output node key
	elif argv[0] == "key" or argv[0] == "pubkey":
		wOut(
			PSS_BUFPFX_INFO,
			[ctx.get_buffer()],
			ctx.get_node() + ".key",
			ctx.get_pss().get_public_key().encode("hex")
		)


	# output node base address
	elif argv[0] == "addr" or argv[0] == "address":
		wOut(
			PSS_BUFPFX_INFO,
			[ctx.get_buffer()],
			ctx.get_node() + ".addr",
			ctx.get_pss().get_overlay().encode("hex")
		)


	# set nick for pss node
	elif argv[0] == "nick":
		try:
			if len(argv) > 1:
				nick = pss.clean_nick(argv[1])
				cache.set_nodeself(ctx.get_node(), nick)
			wOut(
				PSS_BUFPFX_INFO,
				[ctx.get_buffer()],
				ctx.get_node(),
				"nick is '" + cache.get_nodeself(ctx.get_node()) + "'"
			)
		except ValueError as e:
			wOut(
				PSS_BUFPFX_ERROR,
				[ctx.get_buffer()],
				"!!!",
				"Invalid nick: " + argv[1]
			)
			
	# stop connection
	# \todo also kill the subprocess 
	# \todo ensure clean shutdown so conncet can be called over
	elif argv[0] == "stop":
		weechat.unhook(hookFds[ctx.get_node()])
		wOut(
			PSS_BUFPFX_INFO,
			[ctx.get_buffer()],
			"!!!",
			"disconnected from " + ctx.get_node()
		)
		cache.close_node(ctx.get_node())


	# invalid input
	else:
		return weechat.WEECHAT_RC_ERROR

	
	# all good
	return weechat.WEECHAT_RC_OK