def save_settings(): port = get_reg_value('HKLM', APP_REG_KEY, 'port', default=4242) hostname = get_reg_value('HKLM', APP_REG_KEY, 'hostname', default='127.0.0.1') sentrydsn = get_reg_value('HKLM', APP_REG_KEY, 'sentry_dsn') sentrysite = get_reg_value('HKLM', APP_REG_KEY, 'sentry_site') restartneeded = 0 data = request.forms.settings_hostname if data: parts = data.split(':') if hostname <> parts[0].strip(): log.info("--%s-- | --%s--" % (hostname, parts[0].strip())) hostname = parts[0].strip() restartneeded = 1 if len(parts) > 1: try: if port <> int(parts[1].strip()): port = int(parts[1].strip()) log.info("--%d-- | --%d--" % (port, int(parts[1].strip()))) restartneeded = 1 except ValueError: log.error('Unable to set port to: %s' % parts[1].strip()) data = request.forms.sentry_dsn if request.forms.sentry_dsn.lower() <> 'none' else None if data and (data <> sentrydsn): sentrydsn = data restartneeded = 1 data = request.forms.sentry_site if request.forms.sentry_site.lower() <> 'none' else None if data and (data <> sentrysite): sentrysite = data restartneeded = 1 swift_key = get_reg_value('HKLM', APP_STORAGE_REG_KEY, 'key') if not swift_key: swift_key = request.forms.settings_swift_key swift_password = get_reg_value('HKLM', APP_STORAGE_REG_KEY, 'password') if not swift_password: swift_password = request.forms.settings_swift_password swift_account = get_reg_value('HKLM', APP_STORAGE_REG_KEY, 'account') if not swift_account: swift_account = request.forms.settings_swift_account swift_auth_url = get_reg_value('HKLM', APP_STORAGE_REG_KEY, 'auth_url') if not swift_auth_url: swift_auth_url = request.forms.settings_swift_auth_url container = request.forms.settings_container set_reg_value('HKLM', APP_REG_KEY, 'hostname', hostname) set_reg_value('HKLM', APP_REG_KEY, 'port', port) set_reg_value('HKLM', APP_REG_KEY, 'restartneeded', restartneeded) set_reg_value('HKLM', APP_STORAGE_REG_KEY, 'container', container) set_reg_value('HKLM', APP_STORAGE_REG_KEY, 'key', swift_key) set_reg_value('HKLM', APP_STORAGE_REG_KEY, 'password', swift_password) set_reg_value('HKLM', APP_STORAGE_REG_KEY, 'account', swift_account) set_reg_value('HKLM', APP_STORAGE_REG_KEY, 'auth_url', swift_auth_url) set_reg_value('HKLM', APP_REG_KEY, 'sentry_dsn', sentrydsn) set_reg_value('HKLM', APP_REG_KEY, 'sentry_site', sentrysite) redirect('/index.html')
def process_timer(self, rc, handles, mgmt_handles): dirs_pending = get_dirs_pending_changes() if dirs_pending: log.info('The following directories have pending changes:\n %s' % '\n '.join(dirs_pending), culprit='anagogic.service' ) for d in dirs_pending: if not upload_in_progress(d): _, changed, _, _ = get_watched_directory_info(d) if enough_time_elapsed(changed): sync_dir(d) else: log.info('Not enough time has elapsed since last backup ' 'for %s' % d, culprit=__culprit__) else: log.info('Backup in progress for %s' % d, culprit=__culprit__) return False
def process_directory_changes(handle, pos): """ Process the directory that changed """ FindNextChangeNotification(handle) state = STATES.get(pos % STATES_LEN, -1) if state < 0: pass else: watched_dirs = get_watched_directories() changed_dir = watched_dirs[pos / STATES_LEN] added, changed, _, _ = get_watched_directory_info(changed_dir) log.info('Processing change for %s' % changed_dir, culprit=__culprit__) if not upload_in_progress(changed_dir): if enough_time_elapsed(changed): log.info('Sufficient elapsed time. Sync dir', culprit=__culprit__) set_upload_in_progress(changed_dir) sync_dir(changed_dir) clear_upload_in_progress(changed_dir) else: set_pending_changes(changed_dir) else: log.info('Backup in progress for %s' % changed_dir, culprit=__culprit__) pass
def sync_dir(dir, sess=None): """ Sync the given directory to Dropbox """ start = datetime.datetime.now() backup_data = {} uploaded_file_list = [] deleted_file_list = [] try: if not sess: sess = get_session() log.info('got session') container = get_container() hash_path = HASHES + dir[3:].replace("\\", '_') log.info('created hash_path') try: log.info('getting hash from %s' % hash_path) manifest = json.loads(sess.get_object(container, hash_path)[1]) log.info('retrieved manifest') except ClientException, e: log.warning('Error getting manifest:\n Status: %d\n Message: %s' % (e.http_status, e.message), culprit=__culprit__) if e.http_status == 404: # The manifest didn't exist on swift. This means we need to seed # the directory. We can do so by starting with an empty manifest log.evtlog.info('Swift: manifest doesn\'t exist. Create a blank one') manifest = {} elif e.http_status == 400: log.error('Error loading manifest for %s\nError message:\n\n%s' % (dir, e.message), culprit=__culprit__) return files_changed = False visited_files = [] for root, dirs, files in os.walk(dir): for f in files: absolute_path = os.path.join(root, f) dbox_absolute_path = dbox_munge_path(absolute_path) visited_files.append(absolute_path) file_info = manifest.get(absolute_path, None) file_stats = get_file_stats(absolute_path) if (not file_info) or\ (file_info['filesize'] <> file_stats['filesize'] or\ file_info['filemtime'] <> file_stats['filemtime'] or\ file_info['filehash'] <> file_stats['filehash']): # File is either new or has been updated. Either way, we # need to upload the file to dropbox and update the manifest manifest[absolute_path] = file_stats uploaded_file_list.append(absolute_path) sess.put_object(container, dbox_absolute_path, open(absolute_path, 'rb')) files_changed = True continue continue backup_data['uploaded_files'] = '\n' + '\n'.join(uploaded_file_list) deleted_files = set(manifest.keys()).difference(set(visited_files)) for f in deleted_files: sess.delete_object(container, dbox_munge_path(f)) files_changed = True del manifest[f] deleted_file_list.append(absolute_path) continue backup_data['deleted_files'] = '\n' + '\n'.join(deleted_file_list) if files_changed: sess.put_object(container, hash_path, json.dumps(manifest)) set_directory_change_time(dir) end = datetime.datetime.now() backup_data['duration'] = str(end - start) backup_data['start'] = start.strftime('%H:%M:%S') backup_data['end'] = end.strftime('%H:%M:%S') if files_changed: log.sentry.info('Backup complete', culprit=__culprit__, extra=backup_data)
def SvcDoRun(self): import servicemanager # log a service started message servicemanager.LogMsg( servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_, ' (%s)' % self._svc_display_name_)) try: # Spawn off web server self.thread_event = Event() self.thread_event.set() log.info('Before try block to spawn thread') try: if self._svc_thread_class: log.info('Thread class specified, instantiating now') self.service_thread = self._svc_thread_class(self.thread_event) log.info('Thread instantiated, starting thread') self.service_thread.start() log.info('Thread started') else: log.error("No Service thread was provided", culprit=__culprit__) self.SvcStop() except Exception, info: log.error('Uncaught error in thread', exc_info=True, culprit=__culprit__) errmsg = getTrace() servicemanager.LogErrorMsg(errmsg) self.SvcStop() # Start watching directories self.mgmt_handles = [] self.handles = watch_directories() self.add_mgmt_event_handler(self.timer, self.process_timer) self.add_mgmt_event_handler(self.overlapped.hEvent, self.process_named_pipe) self.add_mgmt_event_handler(self.hWaitStop, lambda a, b, c: True) self.handles.extend(self.mgmt_handles) # Set internal timer # default to 2 minute period timer_period = get_reg_value('HKLM', APP_REG_KEY, 'timer', default=120000) win32event.SetWaitableTimer(self.timer, 0, timer_period, None, None, False) while 1: hr = ConnectNamedPipe(self.pipe_handle, self.overlapped) rc = win32event.WaitForMultipleObjects(self.handles, 0, win32event.INFINITE) if rc == win32event.WAIT_FAILED: log.error('WAIT_FAILED for unknown reason') self.SvcStop() break elif rc == win32event.WAIT_TIMEOUT: log.error('WAIT_TIMEOUT: This should NEVER happen') pass elif (rc >= win32event.WAIT_OBJECT_0) and \ (rc < (len(self.handles) - len(self.mgmt_handles))): process_directory_changes(self.handles[rc], rc) else: offset = rc - len(self.handles) + len(self.mgmt_handles) dobreak = self.mgmt_callbacks[offset](rc, self.handles, self.mgmt_handles) if dobreak: break continue