Example #1
0
class CloudDropbox(Wrapper):
    """ Wraps a Dropbox connection client.
    """
    wrapper_type = 'Dropbox connection'
    required_secret_attr = 'secret'
    required_secret_label = 'an OAuth 2 access token'

    def __init__(self, *args, **kwargs):
        super(CloudDropbox, self).__init__(*args, **kwargs)
        self._impl = None  # type: DropboxClient

# ################################################################################################################################

    def _init_impl(self):

        with self.update_lock:

            # Create a pool of at most that many connections
            session = create_session(50)

            scope = as_list(self.config.default_scope, ',')

            config = {
                'session': session,
                'user_agent': self.config.user_agent,
                'oauth2_access_token': self.server.decrypt(self.config.secret),
                'oauth2_access_token_expiration': int(self.config.oauth2_access_token_expiration or 0),
                'scope': scope,
                'max_retries_on_error': int(self.config.max_retries_on_error or 0),
                'max_retries_on_rate_limit': int(self.config.max_retries_on_rate_limit or 0),
                'timeout': int(self.config.timeout),
                'headers': parse_extra_into_dict(self.config.http_headers),
            }

            # Create the actual connection object
            self._impl = DropboxClient(**config)

            # Confirm the connection was established
            self.ping()

            # We can assume we are connected now
            self.is_connected = True

# ################################################################################################################################

    def _delete(self):
        if self._impl:
            self._impl.close()

# ################################################################################################################################

    def _ping(self):
        self._impl.check_user()
Example #2
0
class CacheFile(object):
    def __init__(self, config, path=tempfile.gettempdir()):
        super(CacheFile, self).__init__()
        self.config = config

        # we do not use the agent name in the file.  this
        # would prevent multiple different agents from
        # accessing/updating the same cache file.

        self.cache_file_name = '%s_%s_%s.pickle' % \
                                (config.teamcity.project_name,
                                 config.teamcity.config_name,
                                 config.teamcity.branch_name)

        self.local_file = None
        self.local_file_fp = None
        self.local_file_open_state = FileModes.CLOSED

        self.path = path

        self.ftp = None
        self.ftp_username = None
        self.ftp_password = None
        self.ftp_address = None
        self.ftp_path = None
        self.ftp_display = None

        self.dropbox = None

        temp_folder = tempfile.gettempdir()
        self.local_file = os.path.join(temp_folder, self.cache_file_name)

        if self.path.startswith('ftp://'):
            # open the FTP connection
            if not self._connect_to_ftp():
                print 'Warning: FTP cache folder could not be accessed: "%s"' % self.path
                print 'Warning: Defaulting to local file: "%s"' % self.local_file
            else:
                self.reset()

        elif self.path.startswith('dropbox:'):
            self.dropbox = Dropbox(self.path)
            if not self.dropbox.available():
                print 'Warning: Dropbox could not be accessed: "%s"' % self.path
                print 'Warning: Defaulting to local file: "%s"' % self.local_file
                self.dropbox = None

        else:
            if not os.path.exists(self.path):
                # make sure the full path to the cache folder exists
                try:
                    os.makedirs(self.path)
                except:
                    pass

            if not os.path.exists(self.path):
                print 'Error: Cache folder does not exist: "%s"' % self.path
                sys.exit(1)

            self.local_file = os.path.join(self.path, self.cache_file_name)

    def __del__(self):
        if self.ftp:
            self.ftp.close()
            if os.path.exists(self.local_file):
                os.remove(self.local_file)

    def reset(self):
        if os.path.exists(self.local_file):
            os.remove(self.local_file)

    def open(self, mode=FileModes.READ_ONLY):
        if mode not in [FileModes.READ_ONLY, FileModes.WRITE_ONLY]:
            return None

        self.local_file_open_state = mode
        self.local_file_fp = None

        if self.ftp:
            if not os.path.exists(self.local_file):
                if not self._retrieve_pickle_file():
                    return None

            try:
                self.local_file_fp = open(
                    self.local_file,
                    'rb' if mode == FileModes.READ_ONLY else 'wb')
            except:
                self.local_file_fp = None

        elif self.dropbox:
            self.local_file_fp = self.dropbox.open(self.cache_file_name, mode)

        else:
            try:
                self.local_file_fp = open(
                    self.local_file,
                    'rb' if mode == FileModes.READ_ONLY else 'wb')
            except:
                self.local_file_fp = None

        return self.local_file_fp

    def close(self):
        if self.ftp:
            if (not os.path.exists(
                    self.local_file)) or (not self.local_file_fp):
                return

            try:
                self.local_file_fp.close()
            except:
                pass
            self.local_file_fp = None

            if self.local_file_open_state == FileModes.WRITE_ONLY:
                # upload the (presumably) updated cache file
                if not self._store_pickle_file():
                    print 'Error: Could not store cache file to FTP'
                    sys.exit(1)
                else:
                    self.reset()

        elif self.dropbox:
            self.dropbox.close()
            self.local_file_fp = None

        else:
            try:
                self.local_file_fp.close()
            except:
                pass
            self.local_file_fp = None

    def _retrieve_pickle_file(self):
        if self.ftp:
            files = []
            self.ftp.retrlines('NLST', files.append)
            if self.cache_file_name in files:
                try:
                    self.ftp.retrbinary('RETR %s' % self.cache_file_name,
                                        open(self.local_file, 'wb').write)
                except:
                    return False

        return True

    def _store_pickle_file(self):
        if self.ftp:
            with open(self.local_file, 'rb') as local_file_input:
                try:
                    self.ftp.storbinary('STOR %s' % self.cache_file_name,
                                        local_file_input)
                except:
                    return False

        return True

    def _connect_to_ftp(self):
        result = re.search(r'^ftp:\/\/([\da-z]+):([^\@]+)\@([^\/\s]+)\/(.+)$',
                           self.path)
        if not result:
            return False

        self.ftp_username = result.group(1)
        self.ftp_password = result.group(2)
        self.ftp_address = result.group(3)
        self.ftp_path = result.group(4)

        # take the username/password info out of any displayed value
        self.ftp_display = 'ftp://%s/%s' % (self.ftp_address, self.ftp_path)

        try:
            self.ftp = FTP(self.ftp_address)
        except:
            self.ftp = None
            return False

        try:
            self.ftp.login(self.ftp_username, self.ftp_password)
        except:
            self.ftp.close()
            self.ftp = None
            return False

        #print self.ftp.getwelcome()

        try:
            self.ftp.cwd(self.ftp_path)
        except:
            self.ftp.close()
            self.ftp = None
            return False

        return True

    def __str__(self):
        if self.ftp:
            return '%s/%s' % (self.ftp_display, self.cache_file_name)
        if self.dropbox:
            return str(self.dropbox)
        return os.path.join(os.path.abspath(self.path), self.cache_file_name)