def connect(self, cb=None):
     self.stop(False)
     self.empty_selects = 0
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     if self.secure:
         if ssl:
             cert_path = os.path.join(G.COLAB_DIR, 'startssl-ca.pem')
             with open(cert_path, 'wb') as cert_fd:
                 cert_fd.write(cert.CA_CERT.encode('utf-8'))
             self.sock = ssl.wrap_socket(self.sock, ca_certs=cert_path, cert_reqs=ssl.CERT_REQUIRED)
         else:
             msg.log('No SSL module found. Connection will not be encrypted.')
             if self.port == G.DEFAULT_PORT:
                 self.port = 3148  # plaintext port
     msg.debug('Connecting to %s:%s' % (self.host, self.port))
     try:
         self.sock.connect((self.host, self.port))
         if self.secure and ssl:
             self.sock.do_handshake()
     except socket.error as e:
         msg.error('Error connecting:', e)
         self.reconnect()
         return
     self.sock.setblocking(0)
     msg.debug('Connected!')
     self.reconnect_delay = G.INITIAL_RECONNECT_DELAY
     self.send_auth()
     if cb:
         cb()
Beispiel #2
0
 def redraw(self) :
   if self.sem_obj != None:
     self.thread_lock.acquire()
     try :
       try :
         self.sem_obj.P()
         try :
           shm_obj = self.shm_obj
           size = struct.unpack_from("i", shm_obj.read(4,4*0))[0]
           x = struct.unpack_from("i", shm_obj.read(4,4*1))[0]
           y = struct.unpack_from("i", shm_obj.read(4,4*2))[0]
           width = struct.unpack_from("i", shm_obj.read(4,4*3))[0]
           height = struct.unpack_from("i", shm_obj.read(4,4*4))[0]
           pixbufloader = gtk.gdk.PixbufLoader()
           pixbufloader.write(shm_obj.read(size,4*5))
           pixbufloader.close()                
           pixbuf = pixbufloader.get_pixbuf()
           
         finally :
           self.sem_obj.V()
           pass
         
         pixbuf.copy_area(0, 0, pixbuf.get_width(), pixbuf.get_height(), self.pixbuf, x, y)
         self.rectangle = (x,y,width,height)
         self.win.queue_draw_area(x,y, pixbuf.get_width(), pixbuf.get_height())
         
       except TypeError:
         msg.log("unexpected error:" + str(sys.exc_info()[0]))
         pass
     except :
       msg.log("unexpected general error:" + str(sys.exc_info()))
       pass                    
     finally:
       self.thread_lock.release()
       pass
Beispiel #3
0
def get_info(workspace_url, project_dir):
    repo_type = detect_type(project_dir)
    if not repo_type:
        return
    msg.debug('Detected ', repo_type, ' repo in ', project_dir)
    data = {
        'type': repo_type,
    }
    cmd = REPO_MAPPING[repo_type]['cmd']
    try:
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             cwd=project_dir)
        result = p.communicate()
        repo_url = result[0].decode('utf-8').strip()
        if repo_type == 'svn':
            repo_url = parse_svn_xml(repo_url)
        msg.log(repo_type, ' url is ', repo_url)
        if not repo_url:
            msg.error('Error getting ', repo_type, ' url:', result[1])
            return
    except Exception as e:
        msg.error('Error getting ', repo_type, ' url:', str_e(e))
        return

    data['url'] = repo_url
    return data
Beispiel #4
0
def send_error(description=None, exception=None):
    G.ERROR_COUNT += 1
    if G.ERRORS_SENT > G.MAX_ERROR_REPORTS:
        msg.warn('Already sent %s errors this session. Not sending any more.' %
                 G.ERRORS_SENT)
        return
    data = {
        'jsondump': {
            'error_count': G.ERROR_COUNT
        },
        'username': G.USERNAME,
        'dir': G.COLAB_DIR,
    }
    if G.AGENT:
        data['owner'] = G.AGENT.owner
        data['workspace'] = G.AGENT.workspace
    if description:
        data['description'] = description
    if exception:
        data['message'] = {
            'msg': str(exception),
            'stack': traceback.format_exc(exception)
        }
        msg.log('Floobits plugin error! Sending exception report: %s' %
                data['message'])
    try:
        api_url = 'https://%s/api/log' % (G.DEFAULT_HOST)
        r = api_request(api_url, data)
        G.ERRORS_SENT += 1
        return r
    except Exception as e:
        print(e)
 def on_auth(self):
     self.authed = True
     self.retries = G.MAX_RETRIES
     msg.log("Successfully joined room %s/%s" % (self.owner, self.room))
     if self._on_auth:
         self._on_auth(self)
         self._on_auth = None
Beispiel #6
0
def save_floorc_json(s):
    floorc_json = {}
    for k, v in s.items():
        floorc_json[k.lower()] = v
    msg.log('Writing ', floorc_json)
    with open(G.FLOORC_JSON_PATH, 'w') as fd:
        fd.write(json.dumps(floorc_json, indent=4, sort_keys=True))
Beispiel #7
0
def save_floorc_json(s):
    floorc_json = {}
    for k, v in s.items():
        floorc_json[k.lower()] = v
    msg.log('Writing %s' % floorc_json)
    with open(G.FLOORC_JSON_PATH, 'w') as fd:
        fd.write(json.dumps(floorc_json, indent=4, sort_keys=True))
Beispiel #8
0
    def __init__(self, parent, path):
        self.parent = parent
        self.size = 0
        self.children = []
        self.files = []
        self.ignores = {
            '/TOO_BIG/': []
        }
        self.path = utils.unfuck_path(path)

        try:
            paths = os.listdir(self.path)
        except OSError as e:
            if e.errno != errno.ENOTDIR:
                raise
            self.path = os.path.dirname(self.path)
            self.add_file(os.path.basename(path))
            return
        except Exception as e:
            msg.error('Error listing path %s: %s' % (path, unicode(e)))
            return

        msg.log('Initializing ignores for %s' % path)
        for ignore_file in IGNORE_FILES:
            try:
                self.load(ignore_file)
            except:
                pass

        for p in paths:
            self.add_file(p)
 def on_auth(self):
     self.authed = True
     self.retries = G.MAX_RETRIES
     msg.log('Successfully joined room %s/%s' % (self.owner, self.room))
     if self._on_auth:
         self._on_auth(self)
         self._on_auth = None
Beispiel #10
0
def save_floorc_json(s):
    floorc_json = {}
    for k, v in s.items():
        floorc_json[k.lower()] = v
    msg.log("Writing ", floorc_json)
    with open(G.FLOORC_JSON_PATH, "w") as fd:
        fd.write(json.dumps(floorc_json, indent=4, sort_keys=True, separators=(",", ": ")))
Beispiel #11
0
def send_error(description=None, exception=None):
    G.ERROR_COUNT += 1
    if G.ERRORS_SENT >= G.MAX_ERROR_REPORTS:
        msg.warn('Already sent %s errors this session. Not sending any more.' % G.ERRORS_SENT)
        return
    data = {
        'jsondump': {
            'error_count': G.ERROR_COUNT
        },
        'message': {},
        'dir': G.COLAB_DIR,
    }
    if G.AGENT:
        data['owner'] = G.AGENT.owner
        data['username'] = G.AGENT.username
        data['workspace'] = G.AGENT.workspace
    if exception:
        data['message'] = {
            'description': str(exception),
            'stack': traceback.format_exc(exception)
        }
    msg.log('Floobits plugin error! Sending exception report: %s' % data['message'])
    if description:
        data['message']['description'] = description
    try:
        # TODO: use G.AGENT.proto.host?
        api_url = 'https://%s/api/log' % (G.DEFAULT_HOST)
        r = api_request(G.DEFAULT_HOST, api_url, data)
        G.ERRORS_SENT += 1
        return r
    except Exception as e:
        print(e)
Beispiel #12
0
 def on_highlight(self, data):
     #     floobits.highlight(data['id'], region_key, data['username'], data['ranges'], data.get('ping', False))
     # buf_id, region_key, username, ranges, ping=False):
     ping = data.get("ping", False)
     if self.follow_mode:
         ping = True
     buf = self.FLOO_BUFS[data["id"]]
     view = self.get_view(data["id"])
     if not view:
         if not ping:
             return
         view = self.create_view(buf)
         if not view:
             return
     if ping:
         try:
             offset = data["ranges"][0][0]
         except IndexError as e:
             msg.debug("could not get offset from range %s" % e)
         else:
             msg.log("You have been summoned by %s" % (data.get("username", "an unknown user")))
             view.focus()
             view.set_cursor_position(offset)
     if G.SHOW_HIGHLIGHTS:
         view.highlight(data["ranges"], data["user_id"])
Beispiel #13
0
def send_error(description=None, exception=None):
    G.ERROR_COUNT += 1
    if G.ERRORS_SENT >= G.MAX_ERROR_REPORTS:
        msg.warn('Already sent ', G.ERRORS_SENT,
                 ' errors this session. Not sending any more.\n', description,
                 exception)
        return
    data = {
        'jsondump': {
            'error_count': G.ERROR_COUNT
        },
        'message': {},
        'dir': G.COLAB_DIR,
    }
    if G.AGENT:
        data['owner'] = getattr(G.AGENT, "owner", None)
        data['username'] = getattr(G.AGENT, "username", None)
        data['workspace'] = getattr(G.AGENT, "workspace", None)
    if exception:
        data['message'] = {
            'description': str(exception),
            'stack': traceback.format_exc(exception)
        }
    msg.log('Floobits plugin error! Sending exception report: ',
            data['message'])
    if description:
        data['message']['description'] = description
    try:
        # TODO: use G.AGENT.proto.host?
        api_url = 'https://%s/api/log' % (G.DEFAULT_HOST)
        r = api_request(G.DEFAULT_HOST, api_url, data)
        G.ERRORS_SENT += 1
        return r
    except Exception as e:
        print(e)
 def delete_buf(path):
     if not utils.is_shared(path):
         msg.error('Skipping deleting %s because it is not in shared path %s.' % (path, G.PROJECT_PATH))
         return
     if os.path.isdir(path):
         for dirpath, dirnames, filenames in os.walk(path):
             # TODO: rexamine this assumption
             # Don't care about hidden stuff
             dirnames[:] = [d for d in dirnames if d[0] != '.']
             for f in filenames:
                 f_path = os.path.join(dirpath, f)
                 if f[0] == '.':
                     msg.log('Not deleting buf for hidden file %s' % f_path)
                 else:
                     Listener.delete_buf(f_path)
         return
     buf_to_delete = None
     rel_path = utils.to_rel_path(path)
     for buf_id, buf in BUFS.items():
         if rel_path == buf['path']:
             buf_to_delete = buf
             break
     if buf_to_delete is None:
         msg.error('%s is not in this room' % path)
         return
     msg.log('deleting buffer ', rel_path)
     event = {
         'name': 'delete_buf',
         'id': buf_to_delete['id'],
     }
     Listener.agent.put(event)
Beispiel #15
0
def get_info(workspace_url, project_dir):
    repo_type = detect_type(project_dir)
    if not repo_type:
        return
    msg.debug('Detected ', repo_type, ' repo in ', project_dir)
    data = {
        'type': repo_type,
    }
    cmd = REPO_MAPPING[repo_type]['cmd']
    try:
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             cwd=project_dir)
        result = p.communicate()
        repo_url = result[0].decode('utf-8').strip()
        if repo_type == 'svn':
            repo_url = parse_svn_xml(repo_url)
        msg.log(repo_type, ' url is ', repo_url)
        if not repo_url:
            msg.error('Error getting ', repo_type, ' url:', result[1])
            return
    except Exception as e:
        msg.error('Error getting ', repo_type, ' url:', str_e(e))
        return

    data['url'] = repo_url
    return data
Beispiel #16
0
 def on_highlight(self, data):
     #     floobits.highlight(data['id'], region_key, data['username'], data['ranges'], data.get('ping', False))
     #buf_id, region_key, username, ranges, ping=False):
     ping = data.get('ping', False)
     if self.follow_mode:
         ping = True
     buf = self.FLOO_BUFS[data['id']]
     view = self.get_view(data['id'])
     if not view:
         if not ping:
             return
         view = self.create_view(buf)
         if not view:
             return
     if ping:
         try:
             offset = data['ranges'][0][0]
         except IndexError as e:
             msg.debug('could not get offset from range %s' % e)
         else:
             msg.log('You have been summoned by %s' % (data.get('username', 'an unknown user')))
             view.focus()
             view.set_cursor_position(offset)
     if G.SHOW_HIGHLIGHTS:
         view.highlight(data['ranges'], data['user_id'])
 def create_buf(path):
     # >>> (lambda x: lambda: x)(2)()
     # TODO: check if functools can do this in st2
     #  really_create_buf = lambda x: (lambda: Listener.create_buf(x))
     def really_create_buf(x):
         return (lambda: Listener.create_buf(x))
     if not utils.is_shared(path):
         msg.error('Skipping adding %s because it is not in shared path %s.' % (path, G.PROJECT_PATH))
         return
     if os.path.isdir(path):
         for dirpath, dirnames, filenames in os.walk(path):
             # Don't care about hidden stuff
             dirnames[:] = [d for d in dirnames if d[0] != '.']
             for f in filenames:
                 f_path = os.path.join(dirpath, f)
                 if f[0] == '.':
                     msg.log('Not creating buf for hidden file %s' % f_path)
                 else:
                     sublime.set_timeout(really_create_buf(f_path), 0)
         return
     try:
         buf_fd = open(path, 'rb')
         buf = buf_fd.read().decode('utf-8')
         rel_path = utils.to_rel_path(path)
         msg.log('creating buffer ', rel_path)
         event = {
             'name': 'create_buf',
             'buf': buf,
             'path': rel_path,
         }
         Listener.agent.put(event)
     except (IOError, OSError):
         msg.error('Failed to open %s.' % path)
     except Exception as e:
         msg.error('Failed to create buffer %s: %s' % (path, str(e)))
Beispiel #18
0
    def delete_buf(self, path):
        """deletes a path"""

        if not path:
            return

        path = utils.get_full_path(path)

        if not self.is_shared(path):
            msg.error("Skipping deleting %s because it is not in shared path %s." % (path, G.PROJECT_PATH))
            return

        if os.path.isdir(path):
            for dirpath, dirnames, filenames in os.walk(path):
                # Don't care about hidden stuff
                dirnames[:] = [d for d in dirnames if d[0] != "."]
                for f in filenames:
                    f_path = os.path.join(dirpath, f)
                    if f[0] == ".":
                        msg.log("Not deleting buf for hidden file %s" % f_path)
                    else:
                        self.delete_buf(f_path)
            return
        buf_to_delete = None
        rel_path = utils.to_rel_path(path)
        for buf_id, buf in self.FLOO_BUFS.items():
            if rel_path == buf["path"]:
                buf_to_delete = buf
                break
        if buf_to_delete is None:
            msg.error("%s is not in this room" % path)
            return
        msg.log("deleting buffer ", rel_path)
        event = {"name": "delete_buf", "id": buf_to_delete["id"]}
        self.agent.put(event)
Beispiel #19
0
 def delete_buf(path):
     if not utils.is_shared(path):
         msg.error('Skipping deleting %s because it is not in shared path %s.' % (path, G.PROJECT_PATH))
         return
     if os.path.isdir(path):
         for dirpath, dirnames, filenames in os.walk(path):
             # TODO: rexamine this assumption
             # Don't care about hidden stuff
             dirnames[:] = [d for d in dirnames if d[0] != '.']
             for f in filenames:
                 f_path = os.path.join(dirpath, f)
                 if f[0] == '.':
                     msg.log('Not deleting buf for hidden file %s' % f_path)
                 else:
                     Listener.delete_buf(f_path)
         return
     buf_to_delete = None
     rel_path = utils.to_rel_path(path)
     for buf_id, buf in BUFS.items():
         if rel_path == buf['path']:
             buf_to_delete = buf
             break
     if buf_to_delete is None:
         msg.error('%s is not in this room' % path)
         return
     msg.log('deleting buffer ', rel_path)
     event = {
         'name': 'delete_buf',
         'id': buf_to_delete['id'],
     }
     Listener.agent.put(event)
Beispiel #20
0
 def update_view(self, buf, view=None):
     msg.debug('updating view for buf %s' % buf['id'])
     view = view or self.get_view(buf['id'])
     if not view:
         msg.log('view for buf %s not found. not updating' % buf['id'])
         return
     self.MODIFIED_EVENTS.put(1)
     view.set_text(buf['buf'])
    def stop(self):
        for _conn in self._protos:
            _conn.stop()

        self._protos = []
        self._handlers = []
        msg.log("Disconnected.")
        editor.status_message("Disconnected.")
Beispiel #22
0
    def stop(self):
        for _conn in self._protos:
            _conn.stop()

        self._protos = []
        self._handlers = []
        msg.log('Disconnected.')
        editor.status_message('Disconnected.')
Beispiel #23
0
 def update_view(self, buf, view=None):
     msg.debug("updating view for buf %s" % buf["id"])
     view = view or self.get_view(buf["id"])
     if not view:
         msg.log("view for buf %s not found. not updating" % buf["id"])
         return
     self.MODIFIED_EVENTS.put(1)
     view.set_text(buf["buf"])
Beispiel #24
0
 def update_view(self, buf, view=None):
     msg.debug('updating view for buf %s' % buf['id'])
     view = view or self.get_view(buf['id'])
     if not view:
         msg.log('view for buf %s not found. not updating' % buf['id'])
         return
     self.MODIFIED_EVENTS.put(1)
     view.set_text(buf['buf'])
Beispiel #25
0
 def on_delete_buf(self, data):
     # TODO: somehow tell the user about this. maybe delete on disk too?
     del self.FLOO_BUFS[data['id']]
     path = utils.get_full_path(data['path'])
     if not G.DELETE_LOCAL_FILES:
         msg.log('Not deleting %s because delete_local_files is disabled' % path)
         return
     utils.rm(path)
     msg.warn('deleted %s because %s told me to.' % (path, data.get('username', 'the internet')))
Beispiel #26
0
 def stop(self):
     msg.log('Disconnecting from room %s/%s' % (self.owner, self.room))
     try:
         self.retries = -1
         self.sock.shutdown(2)
         self.sock.close()
     except Exception:
         pass
     msg.log('Disconnected.')
Beispiel #27
0
 def on_delete_buf(self, data):
     # TODO: somehow tell the user about this. maybe delete on disk too?
     del self.FLOO_BUFS[data["id"]]
     path = utils.get_full_path(data["path"])
     if not G.DELETE_LOCAL_FILES:
         msg.log("Not deleting %s because delete_local_files is disabled" % path)
         return
     utils.rm(path)
     msg.warn("deleted %s because %s told me to." % (path, data.get("username", "the internet")))
 def stop(self):
     msg.log('Disconnecting from room %s/%s' % (self.owner, self.room))
     try:
         self.retries = -1
         self.sock.shutdown(2)
         self.sock.close()
     except Exception:
         pass
     msg.log('Disconnected.')
Beispiel #29
0
    def recurse(self, root):
        try:
            paths = os.listdir(self.path)
        except OSError as e:
            if e.errno != errno.ENOTDIR:
                msg.error('Error listing path ', self.path, ': ', str_e(e))
            return
        except Exception as e:
            msg.error('Error listing path ', self.path, ': ', str_e(e))
            return

        msg.debug('Initializing ignores for ', self.path)
        for ignore_file in IGNORE_FILES:
            try:
                self.load(ignore_file)
            except Exception:
                pass

        for p in paths:
            if p == '.' or p == '..':
                continue
            if p in BLACKLIST:
                msg.log('Ignoring blacklisted file ', p)
                continue
            p_path = os.path.join(self.path, p)
            try:
                s = os.stat(p_path)
            except Exception as e:
                msg.error('Error stat()ing path ', p_path, ': ', str_e(e))
                continue

            if stat.S_ISREG(s.st_mode) and p in HIDDEN_WHITELIST:
                # Don't count these whitelisted files in size
                self.files.append(p_path)
                continue

            is_dir = stat.S_ISDIR(s.st_mode)
            if root.is_ignored(p_path, is_dir, True):
                continue

            if is_dir:
                ig = Ignore(p_path, self)
                self.children[p] = ig
                ig.recurse(root)
                self.total_size += ig.total_size
                continue

            if stat.S_ISREG(s.st_mode):
                if s.st_size > (MAX_FILE_SIZE):
                    self.ignores['/TOO_BIG/'].append(p)
                    msg.log(
                        self.is_ignored_message(p_path, p, '/TOO_BIG/', False))
                else:
                    self.size += s.st_size
                    self.total_size += s.st_size
                    self.files.append(p_path)
Beispiel #30
0
 def stop(self):
     msg.log("Disconnecting from room %s/%s" % (self.owner, self.room))
     try:
         self.retries = -1
         self.sock.shutdown(2)
         self.sock.close()
     except Exception:
         return False
     msg.log("Disconnected.")
     return True
Beispiel #31
0
    def recurse(self, root):
        try:
            paths = os.listdir(self.path)
        except OSError as e:
            if e.errno != errno.ENOTDIR:
                msg.error('Error listing path ', self.path, ': ', str_e(e))
            return
        except Exception as e:
            msg.error('Error listing path ', self.path, ': ', str_e(e))
            return

        msg.debug('Initializing ignores for ', self.path)
        for ignore_file in IGNORE_FILES:
            try:
                self.load(ignore_file)
            except Exception:
                pass

        for p in paths:
            if p == '.' or p == '..':
                continue
            if p in BLACKLIST:
                msg.log('Ignoring blacklisted file ', p)
                continue
            p_path = os.path.join(self.path, p)
            try:
                s = os.stat(p_path)
            except Exception as e:
                msg.error('Error stat()ing path ', p_path, ': ', str_e(e))
                continue

            if stat.S_ISREG(s.st_mode) and p in HIDDEN_WHITELIST:
                # Don't count these whitelisted files in size
                self.files.append(p_path)
                continue

            is_dir = stat.S_ISDIR(s.st_mode)
            if root.is_ignored(p_path, is_dir, True):
                continue

            if is_dir:
                ig = Ignore(p_path, self)
                self.children[p] = ig
                ig.recurse(root)
                self.total_size += ig.total_size
                continue

            if stat.S_ISREG(s.st_mode):
                if s.st_size > (MAX_FILE_SIZE):
                    self.ignores['/TOO_BIG/'].append(p)
                    msg.log(self.is_ignored_message(p_path, p, '/TOO_BIG/', False))
                else:
                    self.size += s.st_size
                    self.total_size += s.st_size
                    self.files.append(p_path)
 def on_emacs_delete_buf(self, req):
     buf = self.get_buf_by_path(req['path'])
     if not buf:
         msg.debug('No buffer for path %s' % req['path'])
         return
     msg.log('deleting buffer ', buf['path'])
     event = {
         'name': 'delete_buf',
         'id': buf['id'],
     }
     self.agent.put(event)
Beispiel #33
0
    def create_buf(path, always_add=False):
        if not utils.is_shared(path):
            msg.error(
                'Skipping adding %s because it is not in shared path %s.' %
                (path, G.PROJECT_PATH))
            return
        if os.path.isdir(path):
            command = 'git ls-files %s' % path
            try:
                p = subprocess.Popen(command,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE,
                                     shell=True,
                                     cwd=path)
                stdoutdata, stderrdata = p.communicate()
                if p.returncode == 0:
                    for git_path in stdoutdata.split('\n'):
                        git_path = git_path.strip()
                        if not git_path:
                            continue
                        add_path = os.path.join(path, git_path)
                        msg.debug('adding %s' % add_path)
                        utils.set_timeout(Listener.create_buf, 0, add_path)
                    return
            except Exception as e:
                msg.debug("Couldn't run %s. This is probably OK. Error: %s" %
                          (command, str(e)))

            for dirpath, dirnames, filenames in os.walk(path):
                # Don't care about hidden stuff
                dirnames[:] = [d for d in dirnames if d[0] != '.']
                for f in filenames:
                    f_path = os.path.join(dirpath, f)
                    if f[0] == '.':
                        msg.log('Not creating buf for hidden file %s' % f_path)
                    else:
                        utils.set_timeout(Listener.create_buf, 0, f_path)
            return
        try:
            buf_fd = open(path, 'rb')
            buf = buf_fd.read().decode('utf-8')
            rel_path = utils.to_rel_path(path)
            msg.log('creating buffer ', rel_path)
            event = {
                'name': 'create_buf',
                'buf': buf,
                'path': rel_path,
            }
            Listener.agent.put(event)
        except (IOError, OSError):
            msg.error('Failed to open %s.' % path)
        except Exception as e:
            msg.error('Failed to create buffer %s: %s' % (path, str(e)))
Beispiel #34
0
def get_git_excludesfile():
    global_ignore = None
    try:
        p = subprocess.Popen(['git', 'config -z --get core.excludesfile'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        result = p.communicate()
        global_ignore = result[0]
        if not global_ignore:
            return
        global_ignore = os.path.realpath(os.path.expanduser(str(global_ignore)))
        msg.log('git core.excludesfile is ', global_ignore)
    except Exception as e:
        msg.error('Error getting git core.excludesfile:', str_e(e))
    return global_ignore
Beispiel #35
0
def get_git_excludesfile():
    global_ignore = None
    try:
        p = subprocess.Popen(['git', 'config -z --get core.excludesfile'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        result = p.communicate()
        global_ignore = result[0]
        if not global_ignore:
            return
        global_ignore = os.path.realpath(os.path.expanduser(global_ignore.decode('utf-8')))
        msg.log('git core.excludesfile is ', global_ignore)
    except Exception as e:
        msg.error('Error getting git core.excludesfile:', str_e(e))
    return global_ignore
Beispiel #36
0
 def msg_log(self, _type, _dir="-->", data=None, err=""):
     if self.is_debug_msg(_type):
         data = {} if data is None else data
         msg.log(
             self.addr,
             _type,
             _dir,
             name=self.name,
             data=data,
             err=err,
             pg=self.pg,
             tag=self._conn_tag
         )
Beispiel #37
0
    def _is_ignored(self, rel_path, is_dir, log):
        base_path, file_name = os.path.split(rel_path)

        if not is_dir and file_name in HIDDEN_WHITELIST:
            return False

        for ignore_file, patterns in self.ignores.items():
            for pattern in patterns:
                orig_pattern = pattern
                negate = False
                match = False
                if pattern[0] in NEGATE_PREFIXES:
                    negate = True
                    pattern = pattern[1:]

                if not pattern:
                    continue

                if pattern[0] == '/':
                    match = fnmatch.fnmatch(rel_path, pattern[1:])
                else:
                    if len(pattern) > 0 and pattern[-1] == '/':
                        if is_dir:
                            pattern = pattern[:-1]
                    if file_name == pattern:
                        match = True
                    elif base_path == pattern or (pattern[-1] == '/' and
                                                  base_path == pattern[:-1]):
                        match = True
                    elif fnmatch.fnmatch(file_name, pattern):
                        match = True
                    elif fnmatch.fnmatch(rel_path, pattern):
                        match = True
                if match:
                    if log:
                        msg.log(
                            self.is_ignored_message(rel_path, orig_pattern,
                                                    ignore_file, negate))
                    if negate:
                        return False
                    return True

        split = rel_path.split("/", 1)
        if len(split) != 2:
            return False
        name, new_path = split
        ig = self.children.get(name)
        if ig:
            return ig._is_ignored(new_path, is_dir, log)
        return False
 def stop(self, log=True):
     if log:
         msg.log('Disconnecting from room %s/%s' % (self.owner, self.room))
     sublime.cancel_timeout(self.reconnect_timeout)
     self.reconnect_timeout = None
     try:
         self.retries = -1
         self.sock.shutdown(2)
         self.sock.close()
     except Exception:
         return False
     if log:
         msg.log('Disconnected.')
     return True
Beispiel #39
0
    def on_room_info(self, data):
        # Success! Reset counter
        self.room_info = data
        self.perms = data["perms"]

        if "patch" not in data["perms"]:
            msg.log("We don't have patch permission. Setting buffers to read-only")

        utils.mkdir(G.PROJECT_PATH)

        floo_json = {
            "url": utils.to_room_url(
                {
                    "host": self.agent.host,
                    "owner": self.agent.owner,
                    "port": self.agent.port,
                    "room": self.agent.room,
                    "secure": self.agent.secure,
                }
            )
        }
        with open(os.path.join(G.PROJECT_PATH, ".floo"), "w") as floo_fd:
            floo_fd.write(json.dumps(floo_json, indent=4, sort_keys=True))

        for buf_id, buf in data["bufs"].iteritems():
            buf_id = int(buf_id)  # json keys must be strings
            buf_path = utils.get_full_path(buf["path"])
            new_dir = os.path.dirname(buf_path)
            utils.mkdir(new_dir)
            self.FLOO_BUFS[buf_id] = buf
            try:
                buf_fd = open(buf_path, "r")
                buf_buf = buf_fd.read().decode("utf-8")
                md5 = hashlib.md5(buf_buf.encode("utf-8")).hexdigest()
                if md5 == buf["md5"]:
                    msg.debug("md5 sums match. not getting buffer")
                    buf["buf"] = buf_buf
                else:
                    raise Exception("different md5")
            except Exception:
                try:
                    open(buf_path, "a").close()
                except Exception as e:
                    msg.debug("couldn't touch file: %s becuase %s" % (buf_path, e))
                self.agent.send_get_buf(buf_id)

        msg.debug(G.PROJECT_PATH)

        self.agent.on_auth()
Beispiel #40
0
def proxy_api_request(url, data, method):
    args = ['python', '-m', 'floo.proxy', '--url', url]
    if data:
        args += ["--data", json.dumps(data)]
    if method:
        args += ["--method", method]
    msg.log('Running %s (%s)' % (' '.join(args), G.PLUGIN_PATH))
    proc = subprocess.Popen(args, cwd=G.PLUGIN_PATH, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    (stdout, stderr) = proc.communicate()
    if stderr:
        raise IOError(stderr)

    if proc.poll() != 0:
        raise IOError(stdout)
    r = APIResponse(stdout)
    return r
Beispiel #41
0
def proxy_api_request(host, url, data, method):
    args = ["python", "-m", "floo.proxy", "--host", host, "--url", url]
    if data:
        args += ["--data", json.dumps(data)]
    if method:
        args += ["--method", method]
    msg.log("Running ", " ".join(args), " (", G.PLUGIN_PATH, ")")
    proc = subprocess.Popen(args, cwd=G.PLUGIN_PATH, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    (stdout, stderr) = proc.communicate()
    if stderr:
        raise IOError(stderr)

    if proc.poll() != 0:
        raise IOError(stdout)
    r = APIResponse(stdout)
    return r
Beispiel #42
0
def proxy_api_request(host, url, data, method):
    args = ['python', '-m', 'floo.proxy', '--host', host, '--url', url]
    if data:
        args += ["--data", json.dumps(data)]
    if method:
        args += ["--method", method]
    msg.log('Running ', ' '.join(args), ' (', G.PLUGIN_PATH, ')')
    proc = subprocess.Popen(args, cwd=G.PLUGIN_PATH, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    (stdout, stderr) = proc.communicate()
    if stderr:
        raise IOError(stderr)

    if proc.poll() != 0:
        raise IOError(stdout)
    r = APIResponse(stdout)
    return r
Beispiel #43
0
    def on_room_info(self, data):
        # Success! Reset counter
        self.room_info = data
        self.perms = data['perms']

        if 'patch' not in data['perms']:
            msg.log('We don\'t have patch permission. Setting buffers to read-only')

        utils.mkdir(G.PROJECT_PATH)

        floo_json = {
            'url': utils.to_room_url({
                'host': self.agent.host,
                'owner': self.agent.owner,
                'port': self.agent.port,
                'room': self.agent.room,
                'secure': self.agent.secure,
            })
        }
        with open(os.path.join(G.PROJECT_PATH, '.floo'), 'w') as floo_fd:
            floo_fd.write(json.dumps(floo_json, indent=4, sort_keys=True))

        for buf_id, buf in data['bufs'].iteritems():
            buf_id = int(buf_id)  # json keys must be strings
            buf_path = utils.get_full_path(buf['path'])
            new_dir = os.path.dirname(buf_path)
            utils.mkdir(new_dir)
            self.FLOO_BUFS[buf_id] = buf
            try:
                buf_fd = open(buf_path, 'r')
                buf_buf = buf_fd.read().decode('utf-8')
                md5 = hashlib.md5(buf_buf.encode('utf-8')).hexdigest()
                if md5 == buf['md5']:
                    msg.debug('md5 sums match. not getting buffer')
                    buf['buf'] = buf_buf
                else:
                    raise Exception('different md5')
            except Exception:
                try:
                    open(buf_path, "a").close()
                except Exception as e:
                    msg.debug("couldn't touch file: %s becuase %s" % (buf_path, e))
                self.agent.send_get_buf(buf_id)

        msg.debug(G.PROJECT_PATH)

        self.agent.on_auth()
Beispiel #44
0
    def _is_ignored(self, rel_path, is_dir, log):
        base_path, file_name = os.path.split(rel_path)

        if not is_dir and file_name in HIDDEN_WHITELIST:
            return False

        for ignore_file, patterns in self.ignores.items():
            for pattern in patterns:
                orig_pattern = pattern
                negate = False
                match = False
                if pattern[0] in NEGATE_PREFIXES:
                    negate = True
                    pattern = pattern[1:]

                if not pattern:
                    continue

                if pattern[0] == '/':
                    match = fnmatch.fnmatch(rel_path, pattern[1:])
                else:
                    if len(pattern) > 0 and pattern[-1] == '/':
                        if is_dir:
                            pattern = pattern[:-1]
                    if file_name == pattern:
                        match = True
                    elif base_path == pattern or (pattern[-1] == '/' and base_path == pattern[:-1]):
                        match = True
                    elif fnmatch.fnmatch(file_name, pattern):
                        match = True
                    elif fnmatch.fnmatch(rel_path, pattern):
                        match = True
                if match:
                    if log:
                        msg.log(self.is_ignored_message(rel_path, orig_pattern, ignore_file, negate))
                    if negate:
                        return False
                    return True

        split = rel_path.split("/", 1)
        if len(split) != 2:
            return False
        name, new_path = split
        ig = self.children.get(name)
        if ig:
            return ig._is_ignored(new_path, is_dir, log)
        return False
Beispiel #45
0
    def create_buf(path, always_add=False):
        if not utils.is_shared(path):
            msg.error('Skipping adding %s because it is not in shared path %s.' % (path, G.PROJECT_PATH))
            return
        if os.path.isdir(path):
            command = 'git ls-files %s' % path
            try:
                p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=path)
                stdoutdata, stderrdata = p.communicate()
                if p.returncode == 0:
                    for git_path in stdoutdata.split('\n'):
                        git_path = git_path.strip()
                        if not git_path:
                            continue
                        add_path = os.path.join(path, git_path)
                        msg.debug('adding %s' % add_path)
                        utils.set_timeout(Listener.create_buf, 0, add_path)
                    return
            except Exception as e:
                msg.debug("Couldn't run %s. This is probably OK. Error: %s" % (command, str(e)))

            for dirpath, dirnames, filenames in os.walk(path):
                # Don't care about hidden stuff
                dirnames[:] = [d for d in dirnames if d[0] != '.']
                for f in filenames:
                    f_path = os.path.join(dirpath, f)
                    if f[0] == '.':
                        msg.log('Not creating buf for hidden file %s' % f_path)
                    else:
                        utils.set_timeout(Listener.create_buf, 0, f_path)
            return
        try:
            buf_fd = open(path, 'rb')
            buf = buf_fd.read().decode('utf-8')
            rel_path = utils.to_rel_path(path)
            msg.log('creating buffer ', rel_path)
            event = {
                'name': 'create_buf',
                'buf': buf,
                'path': rel_path,
            }
            Listener.agent.put(event)
        except (IOError, OSError):
            msg.error('Failed to open %s.' % path)
        except Exception as e:
            msg.error('Failed to create buffer %s: %s' % (path, str(e)))
Beispiel #46
0
def send_error(description=None, exception=None):
    G.ERROR_COUNT += 1
    data = {
        'jsondump': {
            'error_count': G.ERROR_COUNT
        },
        'message': {},
        'dir': G.COLAB_DIR,
    }
    stack = ''
    if G.AGENT:
        data['owner'] = getattr(G.AGENT, "owner", None)
        data['username'] = getattr(G.AGENT, "username", None)
        data['workspace'] = getattr(G.AGENT, "workspace", None)
    if exception:
        exc_info = sys.exc_info()
        try:
            stack = traceback.format_exception(*exc_info)
        except Exception:
            if exc_info[0] is None:
                stack = 'No sys.exc_info()'
            else:
                stack = "Python is rtardd"
        try:
            description = str(exception)
        except Exception:
            description = "Python is rtadd"

        data['message'] = {
            'description': description,
            'stack': stack
        }
    msg.log('Floobits plugin error! Sending exception report: ', data['message'])
    if description:
        data['message']['description'] = description
    if G.ERRORS_SENT >= G.MAX_ERROR_REPORTS:
        msg.warn('Already sent ', G.ERRORS_SENT, ' errors this session. Not sending any more.\n', description, exception, stack)
        return
    try:
        # TODO: use G.AGENT.proto.host?
        api_url = 'https://%s/api/log' % (G.DEFAULT_HOST)
        r = api_request(G.DEFAULT_HOST, api_url, data)
        G.ERRORS_SENT += 1
        return r
    except Exception as e:
        print(e)
Beispiel #47
0
 def reconnect(self):
     try:
         self.sock.close()
     except Exception:
         pass
     self.room_info = {}
     self.net_buf = ''
     self.sock = None
     self.authed = False
     self.reconnect_delay *= 1.5
     if self.reconnect_delay > 10000:
         self.reconnect_delay = 10000
     if self.retries > 0:
         msg.log('Floobits: Reconnecting in %sms' % self.reconnect_delay)
         sublime.set_timeout(self.connect, int(self.reconnect_delay))
     elif self.retries == 0:
         msg.error(
             'Floobits Error! Too many reconnect failures. Giving up.')
     self.retries -= 1
Beispiel #48
0
 def __init__(self, current, buf):
     self.buf = buf
     self.current = current
     self.previous = buf['buf']
     if buf['encoding'] == 'base64':
         self.md5_before = hashlib.md5(self.previous).hexdigest()
         self.md5_after = hashlib.md5(self.current).hexdigest()
     else:
         try:
             self.md5_before = hashlib.md5(self.previous.encode('utf-8')).hexdigest()
         except Exception as e:
             # Horrible fallback if for some reason encoding doesn't agree with actual object
             self.md5_before = hashlib.md5(self.previous).hexdigest()
             msg.log('Error calculating md5_before for ', str(self), ': ', str_e(e))
         try:
             self.md5_after = hashlib.md5(self.current.encode('utf-8')).hexdigest()
         except Exception as e:
             # Horrible fallback if for some reason encoding doesn't agree with actual object
             self.md5_after = hashlib.md5(self.current).hexdigest()
             msg.log('Error calculating md5_after for ', str(self), ': ', str_e(e))
Beispiel #49
0
    def create_buf(self, path):
        if 'create_buf' not in self.perms:
            msg.error("Skipping %s. You don't have permission to create buffers in this room." % path)
            return
        if not self.is_shared(path):
            msg.error('Skipping adding %s because it is not in shared path %s.' % (path, G.PROJECT_PATH))
            return
        if os.path.isdir(path):
            for dirpath, dirnames, filenames in os.walk(path):
                # Don't care about hidden stuff
                dirnames[:] = [d for d in dirnames if d[0] != '.']
                for f in filenames:
                    f_path = os.path.join(dirpath, f)
                    if f[0] == '.':
                        msg.log('Not creating buf for hidden file %s' % f_path)
                    if f in self.ignored_names:
                        # TODO: prompt instead of being lame
                        msg.log('Not creating buf for ignored file %s' % f_path)
                    else:
                        sublime.set_timeout(self.create_buf, 0, f_path)
            return

        if self.get_buf_by_path(path):
            msg.debug('Buf %s already exists in room. Skipping adding.' % path)
            return

        try:
            buf_fd = open(path, 'rb')
            buf = buf_fd.read().decode('utf-8')
            rel_path = utils.to_rel_path(path)
            msg.debug('creating buffer ', rel_path)
            event = {
                'name': 'create_buf',
                'buf': buf,
                'path': rel_path,
            }
            self.agent.put(event)
        except (IOError, OSError):
            msg.error('Failed to open %s.' % path)
        except Exception as e:
            msg.error('Failed to create buffer %s: %s' % (path, str(e)))
Beispiel #50
0
 def connect(self):
     self.empty_selects = 0
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     if self.secure:
         if ssl:
             cert_path = os.path.join(G.COLAB_DIR, 'startssl-ca.pem')
             with open(cert_path, 'wb') as cert_fd:
                 cert_fd.write(cert.CA_CERT.encode('utf-8'))
             self.sock = ssl.wrap_socket(self.sock,
                                         ca_certs=cert_path,
                                         cert_reqs=ssl.CERT_REQUIRED)
         else:
             msg.log(
                 'No SSL module found. Connection will not be encrypted.')
             if self.port == G.DEFAULT_PORT:
                 self.port = 3148  # plaintext port
     msg.log('Connecting to %s:%s' % (self.host, self.port))
     try:
         self.sock.settimeout(30)  # Seconds before timing out connecting
         self.sock.connect((self.host, self.port))
         if self.secure and ssl:
             self.sock.do_handshake()
     except socket.error as e:
         msg.error('Error connecting:', e)
         self.reconnect()
         return
     self.sock.setblocking(False)
     msg.log('Connected!')
     self.reconnect_delay = G.INITIAL_RECONNECT_DELAY
     utils.set_timeout(self.select, 0)
     self.auth()
Beispiel #51
0
 def add_file(self, p):
     p_path = os.path.join(self.path, p)
     if p[0] == '.' and p not in HIDDEN_WHITELIST:
         msg.log('Ignoring hidden path %s' % p_path)
         return
     is_ignored = self.is_ignored(p_path)
     if is_ignored:
         msg.log(is_ignored)
         return
     try:
         s = os.stat(p_path)
     except Exception as e:
         msg.error('Error stat()ing path %s: %s' % (p_path, unicode(e)))
         return
     if stat.S_ISDIR(s.st_mode):
         ig = Ignore(self, p_path)
         self.children.append(ig)
         self.size += ig.size
         return
     elif stat.S_ISREG(s.st_mode):
         if s.st_size > (MAX_FILE_SIZE):
             self.ignores['/TOO_BIG/'].append(p)
             msg.log(self.is_ignored_message(p_path, p, '/TOO_BIG/'))
         else:
             self.size += s.st_size
             self.files.append(p)
Beispiel #52
0
def got_msg(sock, client_obj, byte_data):
    message = msg.extract_message(sock, client_obj, byte_data);
    if (message != None):
        mid = message.mid;
        params = message.params;
        np = len(params);

        msg.log(message);
        
        callback.process_message(message);

        return;

        if (verify_params(mid, _MID.RECV_CLIENT_REGISTER_USER_PASS, np)):
            print("username: %s, password: %s" % (params[0], params[1]));
            db.add_user_account(params[0], params[1]);

        elif (verify_params(mid, _MID.RELAY_TEST, np)):
            msg.send(sock, client_obj, msg.build(_MID.RELAY_TEST, client_obj.id, client_obj.ip, client_obj.c_tcp_port, client_obj.c_udp_port));

        elif (verify_params(mid, _MID.SEND_CLIENT_ID, np)):
            pass;

        elif (verify_params(mid, _MID.RECV_CLIENT_BINDED_UDP_PORT, np)):
            client_obj.c_udp_port = params[0];

        elif (verify_params(mid, _MID.RECV_UDP_PEER_BIND_PORT_SUCCESS, np)):
            client_obj.joined_game.received_udp_bind_port(client_obj.game_client, params[0], params[1], params[2]);

        elif (verify_params(mid, _MID.RECV_UDP_PEER_BIND_PORT_FAILED, np)):
            client_obj.joined_game.received_udp_bind_port(client_obj.game_client, params[0], params[1], -1);

        elif (verify_params(mid, _MID.RECV_PEER_CONNECT_SUCCESS, np)):
            client_obj.joined_game.received_connect_success(client_obj.game_client, params[0], params[1]);

        elif (verify_params(mid, _MID.BEGIN_RELAY_TEST, np)):
            msg.send(sock, client_obj, msg.build(_MID.RELAY_TEST, client_obj.id, client_obj.ip, client_obj.c_tcp_port, client_obj.c_udp_port));
    else:
        print("received msg (raw: %s, len: %d) has an unknown MID" % (byte_data, byte_data.__len__()));
Beispiel #53
0
    def _is_ignored(self, rel_path, is_dir, log):
        base_path, file_name = os.path.split(rel_path)

        for ignore_file, patterns in self.ignores.items():
            for pattern in patterns:
                orig_pattern = pattern
                exclude = False
                match = False
                if pattern[0] == "!":
                    exclude = True
                    pattern = pattern[1:]

                if pattern[0] == '/':
                    match = fnmatch.fnmatch(rel_path, pattern[1:])
                else:
                    if len(pattern) > 0 and pattern[-1] == '/':
                        if is_dir:
                            pattern = pattern[:-1]
                    if fnmatch.fnmatch(file_name, pattern):
                        match = True
                    elif fnmatch.fnmatch(rel_path, pattern):
                        match = True
                if match:
                    if log:
                        msg.log(
                            self.is_ignored_message(rel_path, orig_pattern,
                                                    ignore_file, exclude))
                    if exclude:
                        return False
                    return True

        split = rel_path.split("/", 1)
        if len(split) != 2:
            return False
        name, new_path = split
        ig = self.children.get(name)
        if ig:
            return ig._is_ignored(new_path, is_dir, log)
        return False
    def on_post_save(self, view):
        def cleanup():
            del self.between_save_events[view.buffer_id()]
        if view == G.CHAT_VIEW or view.file_name() == G.CHAT_VIEW_PATH:
            return cleanup()
        else:
            print(G.CHAT_VIEW_PATH, "not", view.file_name())
        event = None
        buf = get_buf(view)
        name = utils.to_rel_path(view.file_name())
        old_name = self.between_save_events[view.buffer_id()]

        if buf is None:
            if utils.is_shared(view.file_name()):
                msg.log('new buffer ', name, view.file_name())
                event = {
                    'name': 'create_buf',
                    'buf': get_text(view),
                    'path': name
                }
        elif name != old_name:
            if utils.is_shared(view.file_name()):
                msg.log('renamed buffer {0} to {1}'.format(old_name, name))
                event = {
                    'name': 'rename_buf',
                    'id': buf['id'],
                    'path': name
                }
            else:
                msg.log('deleting buffer from shared: {0}'.format(name))
                event = {
                    'name': 'delete_buf',
                    'id': buf['id'],
                }

        if event and Listener.agent:
            Listener.agent.put(event)

        cleanup()
Beispiel #55
0
 def on_connect(self):
     msg.log('Connection established.')
     self.proto.proxy = self.proxy
Beispiel #56
0
 def on_connect(self):
     msg.log('Connection established.')
     reactor.reactor.connect(FlooConn(self), G.DEFAULT_HOST, G.DEFAULT_PORT, True)
Beispiel #57
0
    def protocol(self, req):
        self.buf += req.decode('utf-8')
        msg.debug('buf: %s' % self.buf)
        while True:
            before, sep, after = self.buf.partition('\n')
            if not sep:
                break
            try:
                data = json.loads(before)
            except Exception as e:
                msg.error('Unable to parse json: %s' % str(e))
                msg.error('Data: %s' % before)
                raise e
            name = data.get('name')
            if name == 'patch':
                # TODO: we should do this in a separate thread
                Listener.apply_patch(data)
            elif name == 'get_buf':
                buf_id = data['id']
                listener.BUFS[buf_id] = data
                view = listener.get_view(buf_id)
                if view:
                    Listener.update_view(data, view)
                else:
                    listener.save_buf(data)
            elif name == 'create_buf':
                listener.BUFS[data['id']] = data
                listener.save_buf(data)
            elif name == 'rename_buf':
                new = utils.get_full_path(data['path'])
                old = utils.get_full_path(data['old_path'])
                new_dir = os.path.split(new)[0]
                if new_dir:
                    utils.mkdir(new_dir)
                os.rename(old, new)
                view = listener.get_view(data['id'])
                if view:
                    view.retarget(new)
            elif name == 'delete_buf':
                path = utils.get_full_path(data['path'])
                try:
                    utils.rm(path)
                except Exception:
                    pass
                listener.delete_buf(data['id'])
            elif name == 'room_info':
                # Success! Reset counter
                self.retries = G.MAX_RETRIES
                self.room_info = data
                G.PERMS = data['perms']

                if 'patch' not in data['perms']:
                    msg.log(
                        'We don\'t have patch permission. Setting buffers to read-only'
                    )

                project_json = {'folders': [{'path': G.PROJECT_PATH}]}

                utils.mkdir(G.PROJECT_PATH)
                with open(os.path.join(G.PROJECT_PATH, '.sublime-project'),
                          'wb') as project_fd:
                    project_fd.write(
                        json.dumps(project_json, indent=4,
                                   sort_keys=True).encode('utf-8'))

                floo_json = {
                    'url':
                    utils.to_room_url({
                        'host': self.host,
                        'owner': self.owner,
                        'port': self.port,
                        'room': self.room,
                        'secure': self.secure,
                    })
                }
                with open(os.path.join(G.PROJECT_PATH, '.floo'),
                          'w') as floo_fd:
                    floo_fd.write(
                        json.dumps(floo_json, indent=4, sort_keys=True))

                for buf_id, buf in data['bufs'].items():
                    buf_id = int(buf_id)  # json keys must be strings
                    buf_path = utils.get_full_path(buf['path'])
                    new_dir = os.path.dirname(buf_path)
                    utils.mkdir(new_dir)
                    listener.BUFS[buf_id] = buf
                    try:
                        buf_fd = open(buf_path, 'rb')
                        buf_buf = buf_fd.read().decode('utf-8')
                        md5 = hashlib.md5(buf_buf.encode('utf-8')).hexdigest()
                        if md5 == buf['md5']:
                            msg.debug('md5 sums match. not getting buffer')
                            buf['buf'] = buf_buf
                        else:
                            msg.debug(
                                'md5 for %s should be %s but is %s. getting buffer'
                                % (buf['path'], buf['md5'], md5))
                            raise Exception('different md5')
                    except Exception as e:
                        msg.debug('Error calculating md5:', e)
                        Listener.get_buf(buf_id)

                self.authed = True
                G.CONNECTED = True
                msg.log('Successfully joined room %s/%s' %
                        (self.owner, self.room))
                if self.on_connect:
                    self.on_connect(self)
                    self.on_connect = None
            elif name == 'join':
                msg.log('%s joined the room' % data['username'])
                self.room_info['users'][data['user_id']] = data['username']
            elif name == 'part':
                msg.log('%s left the room' % data['username'])
                try:
                    del self.room_info['users'][data['user_id']]
                except Exception as e:
                    print('Unable to delete user %s from user list' % (data))
                region_key = 'floobits-highlight-%s' % (data['user_id'])
                for window in sublime.windows():
                    for view in window.views():
                        view.erase_regions(region_key)
            elif name == 'highlight':
                region_key = 'floobits-highlight-%s' % (data['user_id'])
                Listener.highlight(data['id'], region_key, data['username'],
                                   data['ranges'], data.get('ping', False))
            elif name == 'error':
                message = 'Floobits: Error! Message: %s' % str(data.get('msg'))
                msg.error(message)
            elif name == 'disconnect':
                message = 'Floobits: Disconnected! Reason: %s' % str(
                    data.get('reason'))
                msg.error(message)
                sublime.error_message(message)
                self.stop()
            elif name == 'msg':
                self.on_msg(data)
            else:
                msg.debug('unknown name!', name, 'data:', data)
            self.buf = after