def _on_part(self, data):
     msg.log('%s left the workspace' % data['username'])
     user_id = str(data['user_id'])
     try:
         del self.workspace_info['users'][user_id]
     except Exception:
         print('Unable to delete user %s from user list' % (data))
Пример #2
0
def floobits_check_credentials():
    msg.debug('Print checking credentials.')
    if not (G.USERNAME and G.SECRET):
        if not utils.has_browser():
            msg.log('You need a Floobits account to use the Floobits plugin. Go to https://floobits.com to sign up.')
            return
        floobits_setup_credentials()
Пример #3
0
 def _on_part(self, data):
     msg.log(data['username'], ' left the workspace')
     user_id = str(data['user_id'])
     try:
         del self.workspace_info['users'][user_id]
     except Exception:
         msg.error('Unable to delete user %s from user list' % (data))
Пример #4
0
    def connect(self, conn=None):
        utils.cancel_timeout(self._reconnect_timeout)
        self._reconnect_timeout = None
        self.cleanup()
        host = self._host
        port = self._port

        self._empty_selects = 0

        # TODO: Horrible code here
        if self.proxy:
            if G.OUTBOUND_FILTERING:
                port = self.start_proxy(G.OUTBOUND_FILTER_PROXY_HOST,
                                        G.OUTBOUND_FILTER_PROXY_PORT)
            else:
                port = self.start_proxy(self.host, self.port)
        elif G.OUTBOUND_FILTERING:
            host = G.OUTBOUND_FILTER_PROXY_HOST
            port = G.OUTBOUND_FILTER_PROXY_PORT

        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.setblocking(False)
        if self._secure:
            with open(self._cert_path, 'wb') as cert_fd:
                cert_fd.write(cert.CA_CERT.encode('utf-8'))
        conn_msg = 'Connecting to %s:%s' % (self.host, self.port)
        if self.port != self._port or self.host != self._host:
            conn_msg += ' (proxying through %s:%s)' % (self._host, self._port)
        if host != self._host:
            conn_msg += ' (proxying through %s:%s)' % (host, port)
        msg.log(conn_msg)
        editor.status_message(conn_msg)
        self._connect(host, port)
Пример #5
0
    def connect(self, conn=None):
        utils.cancel_timeout(self._reconnect_timeout)
        self._reconnect_timeout = None
        self.cleanup()
        host = self._host
        port = self._port

        self._empty_selects = 0

        # TODO: Horrible code here
        if self.proxy:
            if G.OUTBOUND_FILTERING:
                port = self.start_proxy(G.OUTBOUND_FILTER_PROXY_HOST, G.OUTBOUND_FILTER_PROXY_PORT)
            else:
                port = self.start_proxy(self.host, self.port)
        elif G.OUTBOUND_FILTERING:
            host = G.OUTBOUND_FILTER_PROXY_HOST
            port = G.OUTBOUND_FILTER_PROXY_PORT

        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.setblocking(False)
        if self._secure:
            with open(self._cert_path, 'wb') as cert_fd:
                cert_fd.write(cert.CA_CERT.encode('utf-8'))
        conn_msg = 'Connecting to %s:%s' % (self.host, self.port)
        if self.port != self._port or self.host != self._host:
            conn_msg += ' (proxying through %s:%s)' % (self._host, self._port)
        if host != self._host:
            conn_msg += ' (proxying through %s:%s)' % (host, port)
        msg.log(conn_msg)
        editor.status_message(conn_msg)
        self._connect(host, port)
Пример #6
0
 def floobits_part_workspace(self):
     if not G.AGENT:
         return msg.warn(
             'Unable to leave workspace: You are not joined to a workspace.'
         )
     floobits_stop_everything()
     msg.log('You left the workspace.')
Пример #7
0
 def stop(self):
     self._retries = -1
     utils.cancel_timeout(self._reconnect_timeout)
     self._reconnect_timeout = None
     self.cleanup()
     self.emit('stop')
     msg.log('Disconnected.')
Пример #8
0
 def stop(self):
     self._retries = -1
     utils.cancel_timeout(self._reconnect_timeout)
     self._reconnect_timeout = None
     self.cleanup()
     self.emit('stop')
     msg.log('Disconnected.')
Пример #9
0
    def run(self, paths, current_file=False):
        if not self.is_enabled():
            return

        if paths is None and current_file:
            active_view = self.window.active_view()
            if active_view is None:
                msg.log(
                    'RemoveFromWorkspace: No active view found. Perhaps active tab is an image?'
                )
                return
            paths = [active_view.file_name()]

        if not hasattr(sublime, 'yes_no_cancel_dialog'):
            unlink = bool(
                sublime.ok_cancel_dialog(
                    'Delete? Select cancel to remove from the workspace without deleting.',
                    'Delete'))
        else:
            ret = sublime.yes_no_cancel_dialog(
                "What should I do with\n%s" % "\n".join(paths[:5]), "Delete!",
                "Just Remove from Workspace.")
            if ret == 0:
                return
            unlink = ret == 1

        for path in paths:
            G.AGENT.delete_buf(path, unlink)
Пример #10
0
    def run(self, paths, current_file=False):
        if not self.is_enabled():
            return

        if paths is None and current_file:
            active_view = self.window.active_view()
            if active_view is None:
                msg.log(
                    'AddToWorkspace: No active view found. Perhaps active tab is an image?'
                )
                return
            paths = [active_view.file_name()]

        notshared = []
        for path in paths:
            if utils.is_shared(path):
                G.AGENT.upload(path)
            else:
                notshared.append(path)

        if notshared:
            limit = 5
            sublime.error_message(
                "The following paths are not a child of\n\n%s\n\nand will not be shared for security reasons:\n\n%s%s."
                % (G.PROJECT_PATH, ",\n".join(notshared[:limit]),
                   len(notshared) > limit and ",\n..." or ""))
Пример #11
0
    def _uploader(self, paths_iter, cb, total_bytes, bytes_uploaded=0.0):
        reactor.tick()
        if len(self.proto) > 0:
            return utils.set_timeout(self._uploader, 10, paths_iter, cb,
                                     total_bytes, bytes_uploaded)

        bar_len = 20
        try:
            p = next(paths_iter)
            size = self._upload(p)
            bytes_uploaded += size
            try:
                percent = (bytes_uploaded / total_bytes)
            except ZeroDivisionError:
                percent = 0.5
            bar = '   |' + ('|' * int(bar_len * percent)) + (' ' * int(
                (1 - percent) * bar_len)) + '|'
            editor.status_message('Uploading... %2.2f%% %s' %
                                  (percent * 100, bar))
        except StopIteration:
            editor.status_message('Uploading... 100% ' + ('|' * bar_len) +
                                  '| complete')
            msg.log('All done uploading')
            return cb and cb()
        return utils.set_timeout(self._uploader, 50, paths_iter, cb,
                                 total_bytes, bytes_uploaded)
Пример #12
0
def floobits_check_credentials():
    msg.debug('Print checking credentials.')
    if utils.can_auth():
        return
    if not utils.has_browser():
        msg.log('You need a Floobits account to use the Floobits plugin. Go to https://floobits.com to sign up.')
        return
    yield VUI.create_or_link_account, None, G.DEFAULT_HOST, False
Пример #13
0
def floobits_toggle_highlights():
    G.SHOW_HIGHLIGHTS = not G.SHOW_HIGHLIGHTS
    if G.SHOW_HIGHLIGHTS:
        floobits_buf_enter()
        msg.log('Highlights enabled')
        return
    floobits_clear()
    msg.log('Highlights disabled')
Пример #14
0
def floobits_toggle_highlights():
    G.SHOW_HIGHLIGHTS = not G.SHOW_HIGHLIGHTS
    if G.SHOW_HIGHLIGHTS:
        floobits_buf_enter()
        msg.log('Highlights enabled')
        return
    floobits_clear()
    msg.log('Highlights disabled')
Пример #15
0
    def stop(self):
        for _conn in self._protos:
            _conn.stop()

        self._protos = []
        self._handlers = []
        msg.log('Reactor shut down.')
        editor.status_message('Disconnected.')
Пример #16
0
    def create_workspace(self, context, host, owner, name, api_args, dir_to_share):
        prompt = 'Workspace name: '

        api_args['name'] = name
        api_args['owner'] = owner

        while True:
            new_name = yield self.user_charfield, context, prompt, name
            name = new_name or name
            try:
                api_args['name'] = name
                r = api.create_workspace(host, api_args)
            except Exception as e:
                msg.error('Unable to create workspace ', str_e(e))
                editor.error_message('Unable to create workspace: %s' % str_e(e))
                return

            if r.code < 400:
                workspace_url = 'https://%s/%s/%s' % (host, owner, name)
                msg.log('Created workspace ', workspace_url)
                self.remote_connect(context, host, owner, name, dir_to_share, utils.JOIN_ACTION.UPLOAD)
                return

            msg.error('Unable to create workspace: ', r.body)

            if r.code not in (400, 402, 409):
                try:
                    r.body = r.body['detail']
                except Exception:
                    pass
                editor.error_message('Unable to create workspace: %s' % r.body)
                return

            if r.code == 402:
                try:
                    r.body = r.body['detail']
                except Exception:
                    pass

                yes = yield self.user_y_or_n, context, '%s Open billing settings?' % r.body, "Yes"
                if yes:
                    webbrowser.open('https://%s/%s/settings#billing' % (host, owner))
                return

            if r.code == 400:
                # TODO: strip leading dots/dashes/etc
                name = re.sub('[^A-Za-z0-9_\-\.]', '_', name)
                prompt = 'Workspace names may only contain [A-Za-z0-9_\-\.]. Choose another name: '
                continue

            yes = yield self.user_y_or_n, context, 'Workspace %s/%s already exists. Overwrite?' % (owner, name), 'Yes'
            if yes:
                # TODO: this doesn't set permissions on the workspace correctly
                self.remote_connect(context, host, owner, name, dir_to_share, utils.JOIN_ACTION.PROMPT)
                return

            prompt = 'Workspace %s/%s already exists. Choose new name: ' % (owner, name)
 def _on_delete_buf(self, data):
     path = utils.get_full_path(data['path'])
     try:
         utils.rm(path)
     except Exception:
         pass
     user_id = data.get('user_id')
     username = self.get_username_by_id(user_id)
     msg.log('%s deleted %s' % (username, path))
Пример #18
0
 def _on_delete_buf(self, data):
     path = utils.get_full_path(data['path'])
     try:
         utils.rm(path)
     except Exception:
         pass
     user_id = data.get('user_id')
     username = self.get_username_by_id(user_id)
     msg.log('%s deleted %s' % (username, path))
    def start_proxy(self):
        if G.PROXY_PORT:
            self._port = int(G.PROXY_PORT)
            msg.log("SSL proxy in debug mode: Port is set to %s", self._port)
            return
        args = ("python", "-m", "floo.proxy", self.host, str(self.port), str(int(self.secure)))

        self._proc = proxy.ProxyProtocol()
        self._port = self._proc.connect(args)
Пример #20
0
    def start_proxy(self):
        if G.PROXY_PORT:
            self._port = int(G.PROXY_PORT)
            msg.log('SSL proxy in debug mode: Port is set to %s' % self._port)
            return
        args = ('python', '-m', 'floo.proxy', '--host=%s' % self.host, '--port=%s' % str(self.port), '--ssl=%s' % str(bool(self.secure)))

        self._proc = proxy.ProxyProtocol()
        self._port = self._proc.connect(args)
Пример #21
0
    def create_workspace(self, context, host, owner, name, api_args, dir_to_share):
        prompt = 'Workspace name: '

        api_args['name'] = name
        api_args['owner'] = owner

        while True:
            new_name = yield self.user_charfield, context, prompt, name
            name = new_name or name
            try:
                api_args['name'] = name
                r = api.create_workspace(host, api_args)
            except Exception as e:
                msg.error('Unable to create workspace ', str_e(e))
                editor.error_message('Unable to create workspace: %s' % str_e(e))
                return

            if r.code < 400:
                workspace_url = 'https://%s/%s/%s' % (host, owner, name)
                msg.log('Created workspace ', workspace_url)
                self.remote_connect(context, host, owner, name, dir_to_share, utils.JOIN_ACTION.UPLOAD)
                return

            msg.error('Unable to create workspace: ', r.body)

            if r.code not in (400, 402, 409):
                try:
                    r.body = r.body['detail']
                except Exception:
                    pass
                editor.error_message('Unable to create workspace: %s' % r.body)
                return

            if r.code == 402:
                try:
                    r.body = r.body['detail']
                except Exception:
                    pass

                yes = yield self.user_y_or_n, context, '%s Open billing settings?' % r.body, "Yes"
                if yes:
                    webbrowser.open('https://%s/%s/settings#billing' % (host, owner))
                return

            if r.code == 400:
                # TODO: strip leading dots/dashes/etc
                name = re.sub('[^A-Za-z0-9_\-\.]', '_', name)
                prompt = 'Workspace names may only contain [A-Za-z0-9_\-\.]. Choose another name: '
                continue

            yes = yield self.user_y_or_n, context, 'Workspace %s/%s already exists. Overwrite?' % (owner, name), 'Yes'
            if yes:
                # TODO: this doesn't set permissions on the workspace correctly
                self.remote_connect(context, host, owner, name, dir_to_share, utils.JOIN_ACTION.PROMPT)
                return

            prompt = 'Workspace %s/%s already exists. Choose new name: ' % (owner, name)
Пример #22
0
def floobits_check_credentials():
    msg.debug('Print checking credentials.')
    if not (G.USERNAME and G.SECRET):
        if not utils.has_browser():
            msg.log(
                'You need a Floobits account to use the Floobits plugin. Go to https://floobits.com to sign up.'
            )
            return
        floobits_setup_credentials()
 def on_done(owner):
     msg.log('Colab dir: %s, Username: %s, Workspace: %s/%s' % (G.COLAB_DIR, username, owner[0], workspace_name))
     self.window.run_command('floobits_create_workspace', {
         'workspace_name': workspace_name,
         'dir_to_share': dir_to_share,
         'upload': file_to_share or dir_to_share,
         'api_args': self.api_args,
         'owner': owner[0],
         'host': host,
     })
    def on_input(self, workspace_name, dir_to_share=None):
        if dir_to_share:
            self.dir_to_share = dir_to_share
        if workspace_name == '':
            return self.run(dir_to_share=self.dir_to_share)
        try:
            self.api_args['name'] = workspace_name
            self.api_args['owner'] = self.owner
            msg.debug(str(self.api_args))
            r = api.create_workspace(self.host, self.api_args)
        except Exception as e:
            msg.error('Unable to create workspace: %s' % str_e(e))
            return sublime.error_message('Unable to create workspace: %s' % str_e(e))

        workspace_url = 'https://%s/%s/%s' % (self.host, self.owner, workspace_name)
        msg.log('Created workspace %s' % workspace_url)

        if r.code < 400:
            utils.add_workspace_to_persistent_json(self.owner, workspace_name, workspace_url, self.dir_to_share)
            return self.window.run_command('floobits_join_workspace', {
                'workspace_url': workspace_url,
                'upload': dir_to_share
            })

        msg.error('Unable to create workspace: %s' % r.body)
        if r.code not in [400, 402, 409]:
            try:
                r.body = r.body['detail']
            except Exception:
                pass
            return sublime.error_message('Unable to create workspace: %s' % r.body)

        kwargs = {
            'dir_to_share': self.dir_to_share,
            'workspace_name': workspace_name,
            'api_args': self.api_args,
            'owner': self.owner,
            'upload': self.upload,
            'host': self.host,
        }
        if r.code == 400:
            kwargs['workspace_name'] = re.sub('[^A-Za-z0-9_\-\.]', '-', workspace_name)
            kwargs['prompt'] = 'Invalid name. Workspace names must match the regex [A-Za-z0-9_\-\.]. Choose another name:'
        elif r.code == 402:
            try:
                r.body = r.body['detail']
            except Exception:
                pass
            if sublime.ok_cancel_dialog('%s' % r.body, 'Open billing settings'):
                webbrowser.open('https://%s/%s/settings#billing' % (self.host, self.owner))
            return
        else:
            kwargs['prompt'] = 'Workspace %s/%s already exists. Choose another name:' % (self.owner, workspace_name)

        return self.window.run_command('floobits_create_workspace', kwargs)
Пример #25
0
    def floobits_info(self):
        kwargs = {
            'cs': bool(int(vim.eval('has("clientserver")'))),
            'mode': (using_feedkeys and 'feedkeys') or 'client-server',
            'servername': vim.eval('v:servername'),
            'ticker_errors': ticker_errors,
            'updatetime': vim.eval('&l:updatetime'),
            'version': G.__PLUGIN_VERSION__,
        }

        msg.log(FLOOBITS_INFO.format(**kwargs))
Пример #26
0
    def floobits_info(self):
        kwargs = {
            'cs': bool(int(vim.eval('has("clientserver")'))),
            'mode': (using_feedkeys and 'feedkeys') or 'client-server',
            'servername': vim.eval('v:servername'),
            'ticker_errors': ticker_errors,
            'updatetime': vim.eval('&l:updatetime'),
            'version': G.__PLUGIN_VERSION__,
        }

        msg.log(FLOOBITS_INFO.format(**kwargs))
Пример #27
0
    def reconnect(self):
        if self._reconnect_timeout:
            return
        self.cleanup()
        self._reconnect_delay = min(10000, int(1.5 * self._reconnect_delay))

        if self._retries > 0:
            msg.log('Floobits: Reconnecting in %sms' % self._reconnect_delay)
            self._reconnect_timeout = utils.set_timeout(self.connect, self._reconnect_delay)
        elif self._retries == 0:
            editor.error_message('Floobits Error! Too many reconnect failures. Giving up.')
        self._retries -= 1
Пример #28
0
 def stop_handler(self, handler):
     try:
         handler.proto.stop()
     except Exception as e:
         msg.warn('Error stopping connection: %s' % str_e(e))
     self._handlers.remove(handler)
     self._protos.remove(handler.proto)
     if hasattr(handler, 'listener_factory'):
         return handler.listener_factory.stop()
     if not self._handlers and not self._protos:
         msg.log('All handlers stopped. Stopping reactor.')
         self.stop()
Пример #29
0
def floobits_complete_signup():
    msg.debug('Completing signup.')
    if not utils.has_browser():
        msg.log('You need a modern browser to complete the sign up. Go to https://floobits.com to sign up.')
        return
    floorc = utils.load_floorc()
    username = floorc.get('USERNAME')
    secret = floorc.get('SECRET')
    msg.debug('Completing sign up with %s %s' % (username, secret))
    if not (username and secret):
        return msg.error('You don\'t seem to have a Floobits account of any sort.')
    webbrowser.open('https://%s/%s/pinocchio/%s' % (G.DEFAULT_HOST, username, secret))
Пример #30
0
 def on_done(owner):
     msg.log('Colab dir: %s, Username: %s, Workspace: %s/%s' %
             (G.COLAB_DIR, username, owner[0], workspace_name))
     self.window.run_command(
         'floobits_create_workspace', {
             'workspace_name': workspace_name,
             'dir_to_share': dir_to_share,
             'upload': file_to_share or dir_to_share,
             'api_args': self.api_args,
             'owner': owner[0],
             'host': host,
         })
Пример #31
0
 def stop_handler(self, handler):
     try:
         handler.proto.stop()
     except Exception as e:
         msg.warn('Error stopping connection: %s' % str(e))
     self._handlers.remove(handler)
     self._protos.remove(handler.proto)
     if hasattr(handler, 'listener_factory'):
         return handler.listener_factory.stop()
     if not self._handlers and not self._protos:
         msg.log('All handlers stopped. Stopping reactor.')
         self.stop()
Пример #32
0
    def on_input(self, workspace_name, dir_to_share=None):
        if dir_to_share:
            self.dir_to_share = dir_to_share
        if workspace_name == '':
            return self.run(dir_to_share=self.dir_to_share)
        try:
            self.api_args['name'] = workspace_name
            self.api_args['owner'] = self.owner
            msg.debug(str(self.api_args))
            r = api.create_workspace(self.api_args)
        except Exception as e:
            msg.error('Unable to create workspace: %s' % unicode(e))
            return sublime.error_message('Unable to create workspace: %s' % unicode(e))

        workspace_url = 'https://%s/%s/%s/' % (G.DEFAULT_HOST, self.owner, workspace_name)
        msg.log('Created workspace %s' % workspace_url)

        if r.code < 400:
            utils.add_workspace_to_persistent_json(self.owner, workspace_name, workspace_url, self.dir_to_share)
            return self.window.run_command('floobits_join_workspace', {
                'workspace_url': workspace_url,
                'agent_conn_kwargs': {
                    'get_bufs': False
                }
            })

        msg.error('Unable to create workspace: %s' % r.body)
        if r.code not in [400, 402, 409]:
            try:
                r.body = r.body['detail']
            except Exception:
                pass
            return sublime.error_message('Unable to create workspace: %s' % r.body)

        kwargs = {
            'dir_to_share': self.dir_to_share,
            'workspace_name': workspace_name,
            'api_args': self.api_args,
            'owner': self.owner,
        }
        if r.code == 400:
            kwargs['workspace_name'] = re.sub('[^A-Za-z0-9_\-\.]', '-', workspace_name)
            kwargs['prompt'] = 'Invalid name. Workspace names must match the regex [A-Za-z0-9_\-\.]. Choose another name:'
        elif r.code == 402:
            try:
                r.body = r.body['detail']
            except Exception:
                pass
            return sublime.error_message('%s' % r.body)
        else:
            kwargs['prompt'] = 'Workspace %s/%s already exists. Choose another name:' % (self.owner, workspace_name)

        return self.window.run_command('floobits_create_workspace', kwargs)
Пример #33
0
 def _on_saved(self, data):
     buf_id = data['id']
     buf = self.bufs.get(buf_id)
     if not buf:
         return
     if G.MIRRORED_SAVES:
         view = self.get_view(data['id'])
         if view:
             self.save_view(view)
         elif 'buf' in buf:
             utils.save_buf(buf)
     username = self.get_username_by_id(data['user_id'])
     msg.log('%s saved buffer %s' % (username, buf['path']))
 def _on_saved(self, data):
     buf_id = data['id']
     buf = self.bufs.get(buf_id)
     if not buf:
         return
     if G.MIRRORED_SAVES:
         view = self.get_view(data['id'])
         if view:
             self.save_view(view)
         elif 'buf' in buf:
             utils.save_buf(buf)
     username = self.get_username_by_id(data['user_id'])
     msg.log('%s saved buffer %s' % (username, buf['path']))
Пример #35
0
    def create_workspace(self, context, host, owner, name, api_args, dir_to_share):
        prompt = "Workspace name: "

        api_args["name"] = name
        api_args["owner"] = owner

        while True:
            new_name = yield self.user_charfield, context, prompt, name
            name = new_name or name
            try:
                api_args["name"] = name
                r = api.create_workspace(host, api_args)
            except Exception as e:
                msg.error("Unable to create workspace ", str_e(e))
                editor.error_message("Unable to create workspace: %s" % str_e(e))
                return

            if r.code < 400:
                workspace_url = "https://%s/%s/%s" % (host, owner, name)
                msg.log("Created workspace ", workspace_url)
                self.remote_connect(context, host, owner, name, dir_to_share, utils.JOIN_ACTION.UPLOAD)
                return

            msg.error("Unable to create workspace: ", r.body)

            if r.code not in (400, 402, 409):
                try:
                    r.body = r.body["detail"]
                except Exception:
                    pass
                editor.error_message("Unable to create workspace: %s" % r.body)
                return

            if r.code == 402:
                try:
                    r.body = r.body["detail"]
                except Exception:
                    pass

                yes = yield self.user_y_or_n, context, "%s Open billing settings?" % r.body, "Yes"
                if yes:
                    webbrowser.open("https://%s/%s/settings#billing" % (host, owner))
                return

            if r.code == 400:
                # TODO: strip leading dots/dashes/etc
                name = re.sub("[^A-Za-z0-9_\-\.]", "_", name)
                prompt = "Workspace names may only contain [A-Za-z0-9_\-\.]. Choose another name: "
                continue

            prompt = "Workspace %s/%s already exists. Choose another name: " % (owner, name)
Пример #36
0
    def connect(self, args):
        self._proc = proc = subprocess.Popen(args, cwd=G.PLUGIN_PATH, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        line = proc.stdout.readline().decode('utf-8')
        self.fd = proc.stdout.fileno()
        fl = fcntl.fcntl(self.fd, fcntl.F_GETFL)
        fcntl.fcntl(self.fd, fcntl.F_SETFL, fl | os.O_NONBLOCK | os.O_ASYNC)

        msg.log("Read line from Floobits SSL proxy: %s" % line)
        match = re.search('Now listening on <(\d+)>', line)
        if not match:
            raise Exception("Couldn't find port in line from proxy: %s" % line)
        self._port = int(match.group(1))
        self.reactor._protos.append(self)
        return self._port
Пример #37
0
    def reconnect(self):
        if self._reconnect_timeout:
            return
        self.cleanup()
        self._reconnect_delay = min(10000, int(1.5 * self._reconnect_delay))

        if self._retries > 0:
            msg.log('Floobits: Reconnecting in %sms' % self._reconnect_delay)
            self._reconnect_timeout = utils.set_timeout(self.connect, self._reconnect_delay)
        elif self._retries == 0:
            editor.error_message('Floobits Error! Too many reconnect failures. Giving up.')

        # Only use proxy.floobits.com if we're trying to connect to floobits.com
        G.OUTBOUND_FILTERING = self.host == 'floobits.com' and self._retries % 4 == 0
        self._retries -= 1
Пример #38
0
 def _on_saved(self, data):
     buf_id = data['id']
     buf = self.bufs.get(buf_id)
     if not buf:
         return
     on_view_load = self.on_load.get(buf_id)
     if on_view_load:
         del on_view_load['patch']
     view = self.get_view(data['id'])
     if view:
         self.save_view(view)
     elif 'buf' in buf:
         utils.save_buf(buf)
     username = self.get_username_by_id(data['user_id'])
     msg.log('%s saved buffer %s' % (username, buf['path']))
Пример #39
0
 def _on_saved(self, data):
     buf_id = data['id']
     buf = self.bufs.get(buf_id)
     if not buf:
         return
     on_view_load = self.on_load.get(buf_id)
     if on_view_load:
         del on_view_load['patch']
     view = self.get_view(data['id'])
     if view:
         self.save_view(view)
     elif 'buf' in buf:
         utils.save_buf(buf)
     username = self.get_username_by_id(data['user_id'])
     msg.log('%s saved buffer %s' % (username, buf['path']))
Пример #40
0
def floobits_complete_signup():
    msg.debug('Completing signup.')
    if not utils.has_browser():
        msg.log(
            'You need a modern browser to complete the sign up. Go to https://floobits.com to sign up.'
        )
        return
    floorc = utils.load_floorc()
    username = floorc.get('USERNAME')
    secret = floorc.get('SECRET')
    msg.debug('Completing sign up with %s %s' % (username, secret))
    if not (username and secret):
        return msg.error(
            'You don\'t seem to have a Floobits account of any sort.')
    webbrowser.open('https://%s/%s/pinocchio/%s' %
                    (G.DEFAULT_HOST, username, secret))
Пример #41
0
 def _on_perms(self, data):
     action = data['action']
     user_id = str(data['user_id'])
     user = self.workspace_info['users'].get(user_id)
     if user is None:
         msg.log('No user for id ', user_id, '. Not handling perms event')
         return
     perms = set(user['perms'])
     if action == 'add':
         perms |= set(data['perms'])
     elif action == 'remove':
         perms -= set(data['perms'])
     else:
         return
     user['perms'] = list(perms)
     if user_id == self.workspace_info['user_id']:
         G.PERMS = perms
 def _on_perms(self, data):
     action = data['action']
     user_id = str(data['user_id'])
     user = self.workspace_info['users'].get(user_id)
     if user is None:
         msg.log('No user for id %s. Not handling perms event' % user_id)
         return
     perms = set(user['perms'])
     if action == 'add':
         perms |= set(data['perms'])
     elif action == 'remove':
         perms -= set(data['perms'])
     else:
         return
     user['perms'] = list(perms)
     if user_id == self.workspace_info['user_id']:
         G.PERMS = perms
Пример #43
0
    def reconnect(self):
        if self._reconnect_timeout:
            return
        self.cleanup()
        self._reconnect_delay = min(10000, int(1.5 * self._reconnect_delay))

        if self._retries > 0:
            msg.log('Floobits: Reconnecting in %sms' % self._reconnect_delay)
            self._reconnect_timeout = utils.set_timeout(
                self.connect, self._reconnect_delay)
        elif self._retries == 0:
            editor.error_message(
                'Floobits Error! Too many reconnect failures. Giving up.')

        # Only use proxy.floobits.com if we're trying to connect to floobits.com
        G.OUTBOUND_FILTERING = self.host == 'floobits.com' and self._retries % 4 == 0
        self._retries -= 1
Пример #44
0
    def connect(self, args):
        msg.debug('Running proxy with args %s in %s' % (args, G.PLUGIN_PATH))
        self._proc = proc = subprocess.Popen(args,
                                             cwd=G.PLUGIN_PATH,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.STDOUT)
        line = proc.stdout.readline().decode('utf-8')
        self.fd = proc.stdout.fileno()
        fl = fcntl.fcntl(self.fd, fcntl.F_GETFL)
        fcntl.fcntl(self.fd, fcntl.F_SETFL, fl | os.O_NONBLOCK | os.O_ASYNC)

        msg.log("Read line from Floobits SSL proxy: %s" % line)
        match = re.search('Now listening on <(\d+)>', line)
        if not match:
            raise Exception("Couldn't find port in line from proxy: %s" % line)
        self._port = int(match.group(1))
        self.reactor._protos.append(self)
        return self._port
    def _uploader(self, paths_iter, cb, total_bytes, bytes_uploaded=0.0):
        reactor.tick()
        if len(self.proto) > 0:
            return utils.set_timeout(self._uploader, 10, paths_iter, cb, total_bytes, bytes_uploaded)

        bar_len = 20
        try:
            p = next(paths_iter)
            size = self._upload(p)
            bytes_uploaded += size
            try:
                percent = (bytes_uploaded / total_bytes)
            except ZeroDivisionError:
                percent = 0.5
            bar = '   |' + ('|' * int(bar_len * percent)) + (' ' * int((1 - percent) * bar_len)) + '|'
            editor.status_message('Uploading... %2.2f%% %s' % (percent * 100, bar))
        except StopIteration:
            editor.status_message('Uploading... 100% ' + ('|' * bar_len) + '| complete')
            msg.log('All done uploading')
            return cb and cb()
        return utils.set_timeout(self._uploader, 50, paths_iter, cb, total_bytes, bytes_uploaded)
Пример #46
0
 def _on_delete_buf(self, data):
     buf_id = data['id']
     try:
         buf = self.bufs.get(buf_id)
         if buf:
             del self.paths_to_ids[buf['path']]
             del self.bufs[buf_id]
     except KeyError:
         msg.debug('KeyError deleting buf id ', buf_id)
     # TODO: if data['unlink'] == True, add to ignore?
     action = 'removed'
     path = utils.get_full_path(data['path'])
     if data.get('unlink', False):
         action = 'deleted'
         try:
             utils.rm(path)
         except Exception as e:
             msg.debug('Error deleting ', path, ': ', str_e(e))
     user_id = data.get('user_id')
     username = self.get_username_by_id(user_id)
     msg.log(username, ' ', action, ' ', path)
Пример #47
0
    def run(self, paths, current_file=False):
        if not self.is_enabled():
            return

        if paths is None and current_file:
            active_view = self.window.active_view()
            if active_view is None:
                msg.log('RemoveFromWorkspace: No active view found. Perhaps active tab is an image?')
                return
            paths = [active_view.file_name()]

        if not hasattr(sublime, 'yes_no_cancel_dialog'):
            unlink = bool(sublime.ok_cancel_dialog('Delete? Select cancel to remove from the workspace without deleting.', 'Delete'))
        else:
            ret = sublime.yes_no_cancel_dialog("What should I do with\n%s" % "\n".join(paths[:5]), "Delete!", "Just Remove from Workspace.")
            if ret == 0:
                return
            unlink = ret == 1

        for path in paths:
            G.AGENT.delete_buf(path, unlink)
Пример #48
0
 def _on_delete_buf(self, data):
     buf_id = data['id']
     try:
         buf = self.bufs.get(buf_id)
         if buf:
             del self.paths_to_ids[buf['path']]
             del self.bufs[buf_id]
     except KeyError:
         msg.debug('KeyError deleting buf id ', buf_id)
     # TODO: if data['unlink'] == True, add to ignore?
     action = 'removed'
     path = utils.get_full_path(data['path'])
     if data.get('unlink', False):
         action = 'deleted'
         try:
             utils.rm(path)
         except Exception as e:
             msg.debug('Error deleting ', path, ': ', str_e(e))
     user_id = data.get('user_id')
     username = self.get_username_by_id(user_id)
     msg.log(username, ' ', action, ' ', path)
Пример #49
0
    def connect(self, conn=None):
        utils.cancel_timeout(self._reconnect_timeout)
        self._reconnect_timeout = None
        self.cleanup()

        self._empty_selects = 0

        if self.proxy:
            self.start_proxy()

        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.setblocking(False)
        if self._secure:
            with open(self._cert_path, 'wb') as cert_fd:
                cert_fd.write(cert.CA_CERT.encode('utf-8'))
        conn_msg = 'Connecting to %s:%s' % (self.host, self.port)
        if self.port != self._port or self.host != self._host:
            conn_msg += ' (proxying through %s:%s)' % (self._host, self._port)
        msg.log(conn_msg)
        editor.status_message(conn_msg)
        self._connect()
Пример #50
0
    def connect(self, conn=None):
        utils.cancel_timeout(self._reconnect_timeout)
        self._reconnect_timeout = None
        self.cleanup()

        self._empty_selects = 0

        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.setblocking(False)
        if self.secure:
            if ssl:
                with open(self._cert_path, 'wb') as cert_fd:
                    cert_fd.write(cert.CA_CERT.encode('utf-8'))
            else:
                msg.log('No SSL module found. Connection will not be encrypted.')
                self.secure = False
                if self.port == G.DEFAULT_PORT:
                    self.port = 3148  # plaintext port
        conn_msg = 'Connecting to %s:%s' % (self.host, self.port)
        msg.log(conn_msg)
        editor.status_message(conn_msg)
        self._connect()
Пример #51
0
    def run(self, paths, current_file=False):
        if not self.is_enabled():
            return

        if paths is None and current_file:
            active_view = self.window.active_view()
            if active_view is None:
                msg.log('AddToWorkspace: No active view found. Perhaps active tab is an image?')
                return
            paths = [active_view.file_name()]

        notshared = []
        for path in paths:
            if utils.is_shared(path):
                G.AGENT.upload(path)
            else:
                notshared.append(path)

        if notshared:
            limit = 5
            sublime.error_message("The following paths are not a child of\n\n%s\n\nand will not be shared for security reasons:\n\n%s%s." %
                                  (G.PROJECT_PATH, ",\n".join(notshared[:limit]), len(notshared) > limit and ",\n..." or ""))
Пример #52
0
    def _upload(self, path, text=None):
        size = 0
        try:
            if text:
                # TODO: possible encoding issues with python 3
                buf = text
            else:
                with open(path, 'rb') as buf_fd:
                    buf = buf_fd.read()
            size = len(buf)
            encoding = 'utf8'
            rel_path = utils.to_rel_path(path)
            existing_buf = self.get_buf_by_path(path)
            if existing_buf:
                buf_md5 = hashlib.md5(buf).hexdigest()
                if existing_buf['md5'] == buf_md5:
                    msg.log('%s already exists and has the same md5. Skipping.' % path)
                    return size
                msg.log('Setting buffer ', rel_path)

                try:
                    buf = buf.decode('utf-8')
                except Exception:
                    buf = base64.b64encode(buf).decode('utf-8')
                    encoding = 'base64'

                existing_buf['buf'] = buf
                existing_buf['encoding'] = encoding
                existing_buf['md5'] = buf_md5

                self.send({
                    'name': 'set_buf',
                    'id': existing_buf['id'],
                    'buf': buf,
                    'md5': buf_md5,
                    'encoding': encoding,
                })
                return size

            try:
                buf = buf.decode('utf-8')
            except Exception:
                buf = base64.b64encode(buf).decode('utf-8')
                encoding = 'base64'

            msg.log('Creating buffer ', rel_path)
            event = {
                'name': 'create_buf',
                'buf': buf,
                'path': rel_path,
                'encoding': encoding,
            }
            self.send(event)
        except (IOError, OSError):
            msg.error('Failed to open %s.' % path)
        except Exception as e:
            msg.error('Failed to create buffer %s: %s' % (path, unicode(e)))
        return size
Пример #53
0
    def connect(self, conn=None):
        utils.cancel_timeout(self._reconnect_timeout)
        self._reconnect_timeout = None
        self.cleanup()

        self._empty_selects = 0

        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.setblocking(False)
        if self.secure:
            if ssl:
                with open(self._cert_path, 'wb') as cert_fd:
                    cert_fd.write(cert.CA_CERT.encode('utf-8'))
            else:
                msg.log(
                    'No SSL module found. Connection will not be encrypted.')
                self.secure = False
                if self.port == G.DEFAULT_PORT:
                    self.port = 3148  # plaintext port
        conn_msg = 'Connecting to %s:%s' % (self.host, self.port)
        msg.log(conn_msg)
        editor.status_message(conn_msg)
        self._connect()
Пример #54
0
    def _rate_limited_upload(self, paths_iter, total_bytes, bytes_uploaded=0.0, upload_func=None):
        reactor.tick()
        upload_func = upload_func or (lambda x: self._upload(utils.get_full_path(x)))
        if len(self.proto) > 0:
            self.upload_timeout = utils.set_timeout(self._rate_limited_upload, 10, paths_iter, total_bytes, bytes_uploaded, upload_func)
            return

        bar_len = 20
        try:
            p = next(paths_iter)
            size = upload_func(p)
            bytes_uploaded += size
            try:
                percent = (bytes_uploaded / total_bytes)
            except ZeroDivisionError:
                percent = 0.5
            bar = '   |' + ('|' * int(bar_len * percent)) + (' ' * int((1 - percent) * bar_len)) + '|'
            editor.status_message('Uploading... %2.2f%% %s' % (percent * 100, bar))
        except StopIteration:
            editor.status_message('Uploading... 100% ' + ('|' * bar_len) + '| complete')
            msg.log('All done uploading')
            return
        self.upload_timeout = utils.set_timeout(self._rate_limited_upload, 50, paths_iter, total_bytes, bytes_uploaded, upload_func)
Пример #55
0
 def run(self):
     G.FOLLOW_MODE = False
     G.FOLLOW_USERS.clear()
     G.SPLIT_MODE = False
     msg.log('Follow mode disabled')
     G.AGENT.update_status_msg('Stopped following changes.')