Exemple #1
0
    def getDate(self):
        '''Method to return datetime object and formatted date string'''
        try:
            date = datetime(int(self.year.text()), int(self.month.text()),
                            int(self.day.text()), int(self.hour.text()))
        except:
            self.log.error('Must set the date!')
            # Log an error
            criticalMessage("Must set the date!!!").exec_()
            # Generate error message dialog
            return None, None
            # Return None for the date and date string

        # Dialog to remind user to make sure date is entered correctly
        dial = confirmMessage(
          "Are you sure you entered to date correctly?\n\n" + \
          "It MUST be in UTC time!"
        )
        # Initialize confirmation dialog
        dial.exec_()
        # Execute the dialog; make it appear
        if not dial.check():  # If the user clicked no
            self.log.warning('Canceled because incorrect date')
            # Log a warning
            return None, None

        return date, date.strftime(settings.date_fmt)
Exemple #2
0
 def ftp_upload(self, *args):
   if self.ranFTP:
     self.log.info( 'You already ran this step!' );
     criticalMessage( "You already tried to upload to FTP" ).exec_();          # Initialize confirmation for quitting
     return;
   self.ranFTP = True;                                                         # Set ran FTP to True
   for key in self.ftpInfo:                                                    # Iterate over all keys in the ftpInfo dictionary
     self.log.info( 'Uploading data to: {}'.format(self.ftpInfo[key]['url']) );# Log some info
     try:                                                                      # Try to...
       ftp = ftpUpload( self.ftpInfo[key]['url'] );                            # Set up and FTP instance
     except:                                                                   # On exception...
       self.log.critical( 
         'Error initializing the FTP upload: {}'.format(
           self.ftpInfo[key]['url']
         )
       );                                                                      # Log a critical error
     else:                                                                     # Else...
       self.ftpInfo[key]['upload'] = ftp.uploadFiles(
         self.ftpInfo[key]['dir'], 
         self.ftpInfo[key]['files'], 
         user   = self.ftpInfo[key]['user'],
         passwd = self.ftpInfo[key]['passwd'],
       );                                                                      # Attempt to upload the files
     if not self.ftpInfo[key]['upload']:                                       # If one or more files failed to upload
       msg = 'FAILED!!! Upload to {} NOT successful';                          # Formatter for error message
       self.log.critical( msg.format( self.ftpInfo[key]['url'] ) );            # Log a critical error
       criticalMessage( 
         "Something went wrong!\n\n" + \
         "There was an error uploading one or more files to the FTP.\n\n"  + \
         "FTP Address: {}\n\n".format( self.ftpInfo[key]['url'] )          + \
         "Check the logs to determine which file(s) failed to upload.\n\n" + \
         "YOU MUST MANUALLY UPLOAD ANY FILES THAT FAILED!!!"
       ).exec_();
     else:
       self.log.info( 'Data upload successful!' );
   if self.ftpInfo['ucar']['upload']:                                          # If the upload to UCAR was a success
     self.uploadSucces.show();                                                 # Show green light next to the 'FTP Upload' button to indicate that step is complete
     self.checkButton.setEnabled(True)
Exemple #3
0
  def gen_sounding(self, *args):
    '''
    Method for generating the SPC-like sounding using the
    SPCWindow class of SHARPpy.
    '''
    self.log.info( 'Generating Skew-T diagram' );                               # Log some information
    sndDataPNG      = settings.skewT_fmt.format( self.date_str );               # Set the name for the skewT file using the settings.skew_T_fmt string
    self.sndDataPNG = os.path.join( self.dst_dirFull, sndDataPNG );             # Set the sndDataPNG attribute using the dst_dirFull attribute and sndDataFile variable

    save_msg = "Check that the image looks okay.\n " + \
      "If ok, click save, else click cancel";                                   # Confirmation message for the save dialog for Skew-T; will update if cannot save Skew-T due to issue in SHARPpy
    sharppy_bug = False;                                                        # Flag for if sharppy bug encountered
    try:                                                                        # Try to...
      decoder = SPCDecoder( self.sndDataFile );                                 # Decode the sounding file using the SPCDecoder
      profile = decoder.getProfiles();                                          # Get the profiles from the file
      stn_id  = decoder.getStnId();                                             # Get the station id from the file
    except:                                                                     # On exception
      criticalMessage( 
        "There was an error loading the sounding data\n\n"
      ).exec_();                                                                # Initialize and display critical error dialog
      return;                                                                   # Return from method
    model     = "Archive";                                                      # Set model to 'Archive'; not sure why but was in the SHARPpy full_gui.py 
    disp_name = stn_id;                                                         # Set the display name to the station ID from the sounding data file
    run       = profile.getCurrentDate();                                       # Set the run to the current date from the sounding data
    profile.setMeta('model', model);                                            # Set the model in the sounding data
    profile.setMeta('loc',   disp_name);                                        # Set the display name in the sounding data
    profile.setMeta('run',   run);                                              # Set the run in the sounding data
    
    if not profile.getMeta('observed'):                                         # If it's not an observed profile
      profile.setAsync( AsyncThreads(2, debug) );                               # Generate profile objects in background. Not sure why works but in SHARPpy full_gui.py
    
    self.log.debug('Generating SHARPpy window')
    if self.skew is None:                                                       # If there is no skew window setup; there should never be...
      self.skew = SPCWindow(cfg=self.config);                                   # Initialize a new SPCWindow object
      self.skew.closed.connect(self.__skewAppClosed);                           # Connect the closed method to the __skewAppClosed private method
      self.skew.addProfileCollection(profile);                                  # Add the profile data to the SPCWindow object
      try:
        self.skew.show();                                                         # Show the window
      except:
        sharppy_bug = True;
        self.log.warning("SHARPpy didn't like that sounding very much!")
        save_msg = "Congradulations!\n\n"   + \
          "You just found a bug in SHARPpy.\n" + \
          "There is nothing we can about this. No Skew-T can be created.\n" + \
          "Just click 'Save' and continue with the uploading";
    dial = saveMessage( save_msg );                                             # Set up save message pop-up
    dial.exec_();                                                               # Display the save message pop-up
    if dial.check():                                                            # If clicked save
      if not sharppy_bug:                                                       # If the SHARPpy bug did NOT occur
        self.ftpInfo['ucar']['files'].append( self.sndDataPNG );                # Append the SHARPpy image file name to the ftpInfo['ucar']['files'] list
        self.log.info('Saving the Skew-T to: {}'.format( self.sndDataPNG ) );   # Log some information
        pixmap = QPixmap.grabWidget( self.skew );                               # Grab the image from the skew T window
        pixmap.save( self.sndDataPNG, 'PNG', 100);                              # Save the image
        self.config.set('paths', 'save_img', os.path.dirname(self.sndDataPNG)); # Add image path to the config object

      self.log.debug( 'Files to upload to UCAR: {}'.format( 
        ', '.join(self.ftpInfo['ucar']['files']) ) )
      self.genSucces.show();                                                    # Show green light next to the 'Generate Sounding' button to indicate that step is complete
      self.uploadButton.setEnabled( True );                                     # Enable the upload button
    else:                                                                       # Else
      self.log.critical('Skew-T save aborted! Not allowed to upload!');         # Log an error
    try:
      self.skew.close();                                                        # Close the skew T window
    except:
      pass;
Exemple #4
0
  def proc_files(self, *args):
    '''
    Method for processing sounding files;
      i.e., renaming and removing values where ballon is descending in
      sounding
    '''
    failed = False;                                                             # Initialize failed to False
    self.log.info( 'Processing files' );    
    files = os.listdir( self.dst_dirFull );                                     # Get list of all files in the directory
    rename_status  = dict.fromkeys( settings.rename.keys(),  False);            # Status of file renaming
    process_status = dict.fromkeys( settings.convert.keys(), False);            # Status of file processing

    for file in files:                                                          # Iterate over the list of files
      for key in settings.rename:                                               # Loop over the keys in the settings.rename dictionary
        if key in file:                                                         # If the key is in the source file name
          rename_status[key] = True;                                            # Add rname status as True
          dst_file = settings.rename[key].format( self.date_str );              # Set a destination file name
          dst      = os.path.join( self.dst_dirFull, dst_file );                # Build the destination file path
          src      = os.path.join( self.dst_dirFull, file );                    # Set source file path
#           self.uploadFiles.append( dst );                                     # Append the file to the uploadFile list
          self.log.info( 'Moving file: {} -> {}'.format(src, dst) );            # Log some information
          os.rename( src, dst );                                                # Move the file
          if not os.path.isfile( dst ):                                         # If the renamed file does NOT exist
            self.log.error( 'There was an error renaming the file!' );          # Log an error
            failed = True;                                                      # Set failed to True
      
      file_found = False;                                                       # Flag for in the file to process is found!
      for key in settings.convert:                                              # Loop over the keys in the settings.rename dictionary
        if key in file:                                                         # If the key is in the source file name
          process_status[key] = True;                                           # Set to true if the file is found
          dst_file = settings.convert[key].format( self.date_str );             # Set a destination file name
          self.sndDataFile = os.path.join( self.dst_dirFull, dst_file );        # Build the destination file path
          src              = os.path.join( self.dst_dirFull, file );            # Set source file path
#           self.uploadFiles.append( dst );                                     # Append the file to the uploadFile list
          
          self.log.info( 'Converting sounding data to SHARPpy format...' );     # Log some information
          res = iMet2SHARPpy( src, self.stationName.text().upper(), 
            datetime = self.date, output = self.sndDataFile);                   # Run function to convert data to SHARPpy format
          if res and os.path.isfile( self.sndDataFile ):                        # If function returned True and the output file exists
            for key in self.ftpInfo:                                            # Iterate over keys in ftpInfo attribute
              self.ftpInfo[key]['files'].append( self.sndDataFile );            # Append sounding data file path to files key in ftpInfo dictionary
          else:
            failed = True;                                                      # Set failed to True
            self.sndDataFile = None;                                            # if the function failed to run OR the output file does NOT exist
            self.log.error( 'There was an error creating SHARPpy file!' );      # Log an error
            criticalMessage(
              'Problem converting the sounding data to SHARPpy format!'
            ).exec_();                                                          # Generate critical error message box
    
    if not all( rename_status.values() ):
      failed = True;
      self.log.error( 'There was an error renaming one or more files!' );       # Log an error
      criticalMessage(
        'Problem renaming one or more files!'
      ).exec_();                                                          # Generate critical error message box

    if not all( process_status.values() ):
      failed = True;
      self.log.error( 'There was an error converting one or more files to SHARPpy format!' );       # Log an error
      criticalMessage(
        'Problem converting one or more files to SHARPpy format!'
      ).exec_();                                                          # Generate critical error message box

    if not failed:                                                              # If failed is False
      self.procSucces.show();                                                   # Show green light next to the 'Process Files' button to indicate that step is complete
      if self.date <= datetime.utcnow():                                        # If the date for the sound is NOT in the future
        self.timeCheck.emit();                                                  # Emit signal to activate the 'Generate Sounding' button
      else:                                                                     # Else, date for sounding IS in the future
        dt  = self.date - datetime.utcnow();                                    # Compute the current time difference between the sounding and utcnow
        msg = ['Date requested is in the future!', 
               'Sounding generation disabled until requested sounding time',
               'Wait time remaining {}'.format( str(dt) ) ];                    # List that contains message for the logger
        self.log.warning( '\n'.join(msg) );                                     # Log the message as a warning
        criticalMessage(
          'The data processing has completed!\n\n' + \
          'However, the requested date/time for the\n' + \
          'sounding is in the future!\n\n' +\
          'The \'Generate Sounding\' button will activate\n' + \
          'when the current time is after the requested time!'
        ).exec_();                                                              # Generate critical error message box
        dt = (int( dt.total_seconds() ) + 2) * 1000;                            # Get total time between now and future time, add 2 seconds, convert to integer, then conver to milliseconds
        QTimer.singleShot( dt, self._timeCheck );                               # Run single shot timer thread for the _timeCheck method, waiting dt milliseconds before running
Exemple #5
0
  def copy_files(self, *args):
    '''
    Method for copying files from source to destination, renaming
    files along the way
    '''
    if self.dst_dir is None: 
      self.log.error( 'Destination directory NOT set!' );
      return;
    if self.src_dir  is None:
      self.log.error( 'Source directory NOT set!' );
      return;

    if self.iopName.text() == '':
      self.log.error( 'IOP Number NOT set!!!' )
      criticalMessage( "Must set the IOP Number!!!" ).exec_();
      return
    if self.stationName.text() == '':
      self.log.error( 'Station Name NOT set!!!' )
      criticalMessage( "Must set the Station Name!!!" ).exec_();
      return

    # Main copying code
    failed = False;                                                             # Initialize failed to False    
    self.__init_ftpInfo();                                                      # Initialize ftpInfo attribute using method
    self.date, self.date_str = self.dateFrame.getDate( );                       # Get datetime object and date string as entered in the gui
    if self.date is None: return;                                               # If the date variable is set to None
    self.dst_dirFull  = os.path.join( 
      self.dst_dir, 'IOP'+self.iopName.text(), self.date_str
    );                                                                          # Build destination directory using the dst_dir, iopName, and date string
    if not os.path.isdir( self.dst_dirFull ):                                   # If the output directory does NOT exist
      self.log.info( 'Creating directory: ' + self.dst_dirFull );               # Log some information
      os.makedirs( self.dst_dirFull );                                          # IF the dst_dir does NOT exist, then create it
    else:                                                                       # Else, the directory exists, so check to over write
      dial = confirmMessage( 
        "The destination directory exists!\n" + \
        "Do you want to overwrite it?\n\n" + \
        "YOU CANNOT UNDO THIS ACTION!!!" 
      );
      dial.exec_();                                                             # Generate the message window
      if dial.check():
        self.log.info( 'Removing directory: ' + self.dst_dirFull );             # Log some information
        shutil.rmtree( self.dst_dirFull );                                      # Delete the directory
        self.log.info( 'Creating directory: ' + self.dst_dirFull );             # Log some information
        os.makedirs( self.dst_dirFull );                                        # IF the dst_dir does NOT exist, then create it
      else:                                                                     # Else, don't do anything
        self.log.warning('Cannot over write data!');                            # Log a warning
        return;                                                                 # Return from function

    self.log.info( 'Source directory: {}'.format(self.src_dir) );               # Log some information
    self.log.info( 'Destination directory: {}'.format(self.dst_dirFull) );      # Log some information
    self.log.info( 'Copying directory' );                                       # Log some information
    for root, dirs, files in os.walk( self.src_dir ):                           # Walk over the source directory
      for file in files:                                                        # Loop over all files
        src = os.path.join( root, file );                                       # Set the source file path
        dst = os.path.join( self.dst_dirFull, file );                           # Set the destination path
        shutil.copy2( src, dst );                                               # Copy all data from the source directory to the dst_dir
        if not os.path.isfile( dst ):                                           # If the destination file does NOT exist
          self.log.error( 'There was an error copying file: {}'.format(file) ); # Log a warning
          failed = True;                                                        # Set failed to True
          break;                                                                # Break the for loop
    if not failed:
      self.log.info( 'Finished copying' );                                      # log some information
      self.log.info( 'Ready to process data files!' );                          # Log some info
      self.copySucces.show();                                                   # Show green light next to the 'Copy Files' button to indicate that step is complete
      self.procButton.setEnabled( True );                                       # Enable the 'Process Files' button
    else:                                                                       # Else, something went wrong
      criticalMessage(
        "Something went wrong!\n\n" + \
        "There was an error copying a data file.\n" + \
        "Please check the logs and directories to see what happened."
      ).exec_();