def wrap_error(*args, **kwargs):
     try:
         set_reg_value('HKLM', APP_REG_KEY, 'internal_error', False)
         fn(*args, **kwargs)
     except rest.ErrorResponse, e:
         log.error('Application auth callback failure', exc_info=True,
             culprit=__culprit__)
         set_reg_value('HKLM', APP_REG_KEY, 'internal_error', True)
         redirect('/index.html')
    def run ( self ):

        try:
            port = get_reg_value(key=APP_REG_KEY, name='port')
            host = get_reg_value(key=APP_REG_KEY, name='host')
            bottle_run(__bottle_app__, host=host, port=port,
                        server=WSGIRefHandleOneServer, reloader=False,
                        quiet=True, notifyEvent=self.notifyEvent)
        except:
            log.error('Error in WebServerThread', exc_info=True)
def index():
    global htdocs, templates

    account_info = ''

    try:
        sess = get_session()
        if not app_container_exists(sess):
            create_container(sess)
    except ClientException, e:
        log.error('Swift get_session() error: %s' % e.message, exc_info=True, culprit=__culprit__)
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 unwatch_directory(directory):
    """ Remove the given directory from those being monitored for changes.

    """
    del_reg_value('HKLM', APP_DIR_REG_KEY, directory)
    log.debug('unwatch_directory(%s)' % directory)
    try:
        pipe = get_reg_value('HKLM', APP_REG_KEY, 'namedpipe')
        handle = CreateFile(pipe, GENERIC_WRITE, FILE_SHARE_READ, None,
            OPEN_EXISTING, 0, None)
        WriteFile(handle, 'refreshdirectories')
        CloseHandle(handle)
    except pywintypes.error:
        log.error('Error when calling the namedpipe with the refreshdirectories '
                  'command', culprit=__culprit__)
        pass
def app_container_exists(sess):
    """ Return whether the "App folder" exists in the linked users' dropbox

     By default, the "App folder" is "Anagogic Backup".  This can be changed
     via the web interface or by setting HLKM\Anagogic\Dropbox\appfolder

    """

    exists = False
    app_container = get_container()
    cnx = get_session()
    try:
        info = get_account_info()
        for container in info[1]:
            if container['name'] == app_container:
                exists = True
                break
    except ClientException, e:
        log.error('Error when checking for existence of '
                                   'app container: %s\nError message:\n\n%s'
                                   % (app_container, e.error_msg))
    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        # Looks like py2exe handles redirecting stdout and stderror for us
        #sys.stdout.close()
        #sys.stderr.close()
        #sys.stdout = NullOutput()
        #sys.stderr = NullOutput()
        # Create an event which we will use to wait on.
        # The "service stop" request will set this event.
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        # Event for named pipe operation
        self.overlapped = pywintypes.OVERLAPPED()
        self.overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None)
        # Internal timer
        self.timer = win32event.CreateWaitableTimer(None, 0, None)

        set_reg_value('HKLM', APP_REG_KEY, 'restartneeded', 0)
        # Setup Named pip for IPC
        pipename = get_reg_value('HKLM', APP_REG_KEY, 'namedpipe')
        self.pipe_handle = None
        if not pipename:
            log.error('No named pipe was specified in the registry',
                        culprit=__culprit__)
            self.SvcStop()
        else:
            openmode = PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED
            pipmode = PIPE_TYPE_MESSAGE
            sa = pywintypes.SECURITY_ATTRIBUTES()
            sa.SetSecurityDescriptorDacl(1, None, 0)
            self.pipe_handle = CreateNamedPipe(pipename, openmode, pipmode,
                                                PIPE_UNLIMITED_INSTANCES, 0, 0,
                                                0, sa)

        # Initialize a list of watched handles
        self.handles = list()
        self.mgmt_handles = list()
        self.mgmt_callbacks = list()
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)
                    # 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)
    except ClientException, e:
        log.error('Dropbox error: %s' % e.message, culprit=__culprit__)
    except Exception, e:
        log.error('Error', exc_info=True, culprit=__culprit__)
    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
                    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
        except:
            log.error('Uncaught error in main event loop', exc_info=True,
                      culprit='anagogic.service')
            servicemanager.LogErrorMsg(getTrace())

        # log a service stopped message
        servicemanager.LogMsg(
            servicemanager.EVENTLOG_INFORMATION_TYPE,
            servicemanager.PYS_SERVICE_STOPPED,
            (self._svc_name_, ' (%s) ' % self._svc_display_name_))


    def process_named_pipe(self, rc, handles, mgmt_handles):
        """ Read data from the named pipe and perform the appropriate action

        """
        hr, data = ReadFile(self.pipe_handle, 256)
        if data.strip() == 'refreshdirectories':