This is the s3upload.py file, might be easier than posing extracts

-- 
You received this message because you are subscribed to the Google Groups 
"weewx-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/weewx-user/80298daf-c899-40ae-930d-5bf8c362c781%40googlegroups.com.
#
#    Copyright (c) 2009-2020 Mike Revitt <[email protected]>
#
#    See the file LICENSE.txt for your full rights.
#
"""For uploading files to a remove server via S3"""

import logging
import os
import sys
import time
import boto3

from    weewx.reportengine  import ReportGenerator
from    six.moves           import cPickle

log = logging.getLogger(__name__)

# =============================================================================
#                    Class S3UploadGenerator
# =============================================================================
class S3UploadGenerator(ReportGenerator):
    
    """Class for managing the "AWS generator".

    This will copy everything in the public_html subdirectory to a webserver."""
    
    def run(self):
        import user.s3upload

        # determine how much logging is desired
        log_success = to_bool(search_up(self.skin_dict, 'log_success', True))

        t1 = time.time()
        try:
            S3_upload = user.s3upload.S3Upload(bucket=self.skin_dict['S3_BUCKET'],
                                            profile=self.skin_dict['AWS_Profile'],
                                            html_root=self.config_dict['StdReport']['HTML_ROOT'],
                                            remote_root=self.skin_dict['S3_ROOT'],
                                            name=self.skin_dict['REPORT_NAME'])
        except KeyError:
            syslog.syslog(syslog.LOG_DEBUG,
                          "S3UploadGenerator: AWS upload not requested. Skipped.")
            return

        try:
            n = S3_upload.run()
        except (socket.timeout, socket.gaierror, ftplib.all_errors, IOError) as e:
            (cl, unused_ob, unused_tr) = sys.exc_info()
            syslog.syslog(syslog.LOG_ERR, "S3UploadGenerator: "
                                          "Caught exception %s: %s" % (cl, e))
            weeutil.weeutil.log_traceback("        ****  ")
            return

        if log_success:
            t2 = time.time()
            syslog.syslog(syslog.LOG_INFO,
                          "S3UploadGenerator: AWS-S3 S3'd %d files in %0.2f seconds" %
                          (n, (t2 - t1)))

# =============================================================================
#                    Class S3Upload
# =============================================================================
class S3Upload(object):
    
    def __init__(self,
                 bucket,
                 profile,
                 html_root,
                 remote_root,
                 name        = "S3",
                 max_tries   = 3,
                 debug       = 0,
                 secure_data = True):
                 
        self.bucket      = bucket
        self.profile     = profile
        self.html_root   = html_root
        self.remote_root = remote_root
        self.name        = name
        self.max_tries   = max_tries
        self.debug       = debug
        self.secure_data = secure_data

    def run(self):
        # Get the timestamp and members of the last upload:
        (timestamp, fileset) = self.getLastUpload()

        n_uploaded = 0
        # Try to connect to the S3 server up to max_tries times:
        
        # Walk the local directory structure
        for (dirpath, unused_dirnames, filenames) in os.walk(self.html_root):
            
            local_rel_dir_path = dirpath.replace(self.html_root, '.')
            if self._skipThisDir(local_rel_dir_path):
                continue
                    
            # Now iterate over all members of the local directory:
            for filename in filenames:
                        
                full_local_path = os.path.join(dirpath, filename)
                # See if this file can be skipped:
                if self._skipThisFile(timestamp, fileset, full_local_path):
                    continue
                
                # Retry up to max_tries times:
                for count in range(self.max_tries):

                    session         = boto3.Session(profile_name=self.profile)
                    s3              = session.resource('s3')

                    try:
                        if local_rel_dir_path != '.':
                            full_remote_path = os.path.join( self.bucket + self.remote_root + local_rel_dir_path.replace('.', '' ))
                        else:
                            full_remote_path = os.path.join( self.bucket + self.remote_root )
                        
                        print( 'filename is ', full_remote_path, filename)
                        
                        # response = s3.meta.client.upload_file(full_local_path , full_remote_path, filename)
                    except ClientError as e:
                        # Unsuccessful. Log it and go around again.
                        log.error("Attempt #%d. Failed uploading %s to %s. Reason: %s"
                                  % (count + 1, self.remote_root, self.server, e))

                    else:
                        # Success. Log it, break out of the loop
                        n_uploaded += 1
                        fileset.add(full_local_path)
                        log.debug("Uploaded file %s" % self.remote_root)
                        break

        timestamp = time.time()
        self.saveLastUpload(timestamp, fileset)
        return n_uploaded

    def getLastUpload(self):
        """Reads the time and members of the last upload from the local root"""

        timeStampFile = os.path.join(self.html_root, "#%s.last" % self.name)

        # If the file does not exist, an IOError exception will be raised.
        # If the file exists, but is truncated, an EOFError will be raised.
        # Either way, be prepared to catch it.
        try:
            with open(timeStampFile, "rb") as f:
                timestamp = cPickle.load(f)
                fileset = cPickle.load(f)
        except (IOError, EOFError, cPickle.PickleError, AttributeError):
            timestamp = 0
            fileset = set()
            # Either the file does not exist, or it is garbled.
            # Either way, it's safe to remove it.
            try:
                os.remove(timeStampFile)
            except OSError:
                pass

        return (timestamp, fileset)

    def saveLastUpload(self, timestamp, fileset):
        """Saves the time and members of the last upload in the local root."""
        timeStampFile = os.path.join(self.html_root, "#%s.last" % self.name)
        with open(timeStampFile, "wb") as f:
            cPickle.dump(timestamp, f)
            cPickle.dump(fileset, f)

    def _skipThisDir(self, local_dir):

        return os.path.basename(local_dir) in ('.svn', 'CVS')

    def _skipThisFile(self, timestamp, fileset, full_local_path):

        filename = os.path.basename(full_local_path)
        if filename[-1] == '~' or filename[0] == '#':
            return True

        if full_local_path not in fileset:
            return False

        if os.stat(full_local_path).st_mtime > timestamp:
            return False
            
        # Filename is in the set, and is up to date.
        return True

# =============================================================================
#                    Main
# =============================================================================
if __name__ == '__main__':
    import configobj

    import weewx
    import weeutil.logger

    weewx.debug = 1

    weeutil.logger.setup('S3upload', {})
    
    if len(sys.argv) < 2:
        print("""Usage: s3upload.py path-to-configuration-file [path-to-be-ftp'd]""")
        sys.exit(weewx.CMD_ERROR)

    try:
        config_dict = configobj.ConfigObj(sys.argv[1], file_error=True, encoding='utf-8')
    except IOError:
        print("Unable to open configuration file %s" % sys.argv[1])
        raise

    S3_upload = S3Upload(config_dict['StdReport']['AWS-S3']['S3_BUCKET'],
                         config_dict['StdReport']['AWS-S3']['AWS_Profile'],
                         config_dict['StdReport']['HTML_ROOT'],
                         config_dict['StdReport']['AWS-S3']['S3_ROOT'],
                         'S3')
                         
    print(config_dict['StdReport']['AWS-S3']['S3_BUCKET'],
    config_dict['StdReport']['AWS-S3']['AWS_Profile'],
    config_dict['WEEWX_ROOT'],
    config_dict['StdReport']['AWS-S3']['S3_ROOT'],
    'S3')
    S3_upload.run()

Reply via email to