Example #1
0
	def run(self):
		config.log.info('syncer starts running')
		self.conn = sqlite3.connect(DAEMON_DB_PATH, isolation_level = None)
		self.conn.row_factory = sqlite3.Row
		self.cursor = self.conn.cursor()
		
		# when switch is set, the thread should stop
		while not self.switch.is_set():
			# block until there is something in the queue
			self.empty_lock.wait()
			# clear task queue
			
			while not self.switch.is_set() and not self.queue.empty():
				entry = self.queue.get()
				
				try:
					self.merge_dir(entry)
				except live_api.AuthError as e:
					config.log.error(e.__class__.__name__ + ': ' + str(e))
					app_tokens = self.api.refresh_token(config.APP_CONFIG['token']['refresh_token'])
					self.api.set_access_token(app_tokens['access_token'])
					config.save_token(app_tokens)
					config.save_config()
					self.enqueue(entry[0], entry[1])
				except live_api.NetworkError:
					config.log.error('Network error. Wait for {} seconds.'.format(NETWORKERR_WAIT_INTERVAL))
					time.sleep(NETWORKERR_WAIT_INTERVAL)
					self.enqueue(entry)
				
				self.queue.task_done()
			self.empty_lock.clear()
			config.log.debug('queue is now empty.')
		
		self.conn.close()
		config.log.info('syncer stops.')
Example #2
0
 def show_auth_dialog(self):
     print('=' * 30)
     if not query_yes_no(
             'Do you want to authorize onedrive-d to access your OneDrive account?'
     ):
         print('	Skipped.')
         return
     print(
         '\nYou will need to visit the OneDrive authorization page manually, '
     )
     print(
         'log in and authorize the onedrive-d, and then copy and paste the '
     )
     print('callback URL, which should start with \n"%s".\n' %
           self.api.client_redirect_uri)
     print(
         'The callback url is the URL when the authorization page finally goes blank.\n'
     )
     print('Please visit the authorization page via URL:\n')
     print(self.api.get_auth_uri())
     callback_uri = input('\nPlease paste the callback URL:\n')
     try:
         app_tokens = self.api.get_access_token(uri=callback_uri)
         config.save_token(app_tokens)
         config.save_config()
         print('\nonedrive-d has been successfully authorized.')
     except OneDrive_Error as e:
         print(
             'CRITICAL: failed to authorize the client with the given URL.')
         print('%s' % e)
Example #3
0
 def handle(self, event_id, event_args=None):
     print('Dialog object received {} event.'.format(event_id))
     if event_id == 'refresh_code':
         app_tokens = self.api.get_access_token(uri=event_args)
         config.save_token(app_tokens)
         config.save_config()
     elif event_id == 'child_close':
         pass
Example #4
0
	def run(self):
		config.log.info('worker starts running.')
		
		self.conn = sqlite3.connect(DAEMON_DB_PATH, isolation_level = None)
		self.conn.row_factory = sqlite3.Row
		self.cursor = self.conn.cursor()
		
		while True:
			self.sem.acquire()
			if self.switch.is_set(): break
			config.log.debug('I passed two locks.')
			row = self.fetch_one_task()
			if row == None: continue
			config.log.debug('I get a row from tasks table.')
			try:
				if row['task_type'] == 'get':
					config.log.info('Downloading "' + row['local_path'] + '".')
					f = open(row['local_path'], 'wb')
					f.write(self.api.get(entry_id = row['remote_id']))
					f.close()
					#new_mtime = timegm)
					#os.utime(t.p1, (new_mtime, new_mtime))
					self.do_postwork(row)
					self.delete_task(row)
					self.add_notify('local', row['local_path'], 'downloaded')
				elif row['task_type'] == 'put':
					config.log.info('Uploading "' + row['local_path'] + '".')
					if os.path.isdir(row['local_path']):
						# if the path is a dir, recursive put
						ne = self.op_mkdir(row)
						for item in os.listdir(row['local_path']):
							self.add_work('put', row['local_path'] + '/' + item, remote_parent_id = ne['id'], postwork = 'n')
					else:
						update = self.api.put(name = os.path.basename(row['local_path']), 
							folder_id = row['remote_parent_id'], 
							local_path = row['local_path'])
						self.do_postwork(row, update)
						self.delete_task(row)
						self.add_notify('local', row['local_path'], 'uploaded')
				elif row['task_type'] == 'mkdir':
					self.op_mkdir(row)
					self.add_notify('remote', row['local_path'], 'created')
					# no special postwork to do
				elif row['task_type'] in ['rm', 'moved_from']:
					config.log.info('Delete remotely "' + row['local_path'] + '"')
					self.api.rm(entry_id = row['remote_id'])
					self.do_postwork(row)
					self.add_notify('remote', row['local_path'], 'deleted')
					# TODO: update entries db.
				elif row['task_type'] == 'cp':
					config.log.info('Copying remotely "' + row['local_path'] + '" to dir "' + row['remote_parent_id'] + '"')
					self.api.cp(target_id = row['remote_id'], dest_folder_id = row['remote_parent_id'])
					# TODO: update entries db.
				elif row['task_type'] == 'mv':
					dirname, basename = os.path.split(row['local_path'])
					config.log.info('Moving remotely "' + row['local_path'] + '" to dir "' + row['remote_parent_id'] + '"')
					ret = self.api.mv(target_id = row['remote_id'], dest_folder_id = row['remote_parent_id'])
					self.cursor.execute('UPDATE entries SET parent_path=?, name=?, id=?, ' +
						'parent_id=?, client_updated_time=?, status="synced" WHERE id=?', 
						(dirname, basename, ret['id'], ret['parent_id'], ret['client_updated_time'], row['remote_id']))
					#t = config.str_to_timestamp(ret['client_updated_time'])
					#os.utime(row['local_path'], (t, t))
					# self.cursor.execute()
					self.conn.commit()
				elif row['task_type'] == 'clean':
					# move the local path to local trash.
					# the path has been deleted remotely.
					self.move_to_trash(row['local_path'])
					self.add_notify('local', row['local_path'], 'moved to trash')
					self.delete_task(row)
			
				time.sleep(WORKER_EVENT_INTERVAL)
				
			except live_api.AuthError as e:
				config.log.error(e.__class__.__name__ + ': ' + str(e))
				app_tokens = self.api.refresh_token(config.APP_CONFIG['token']['refresh_token'])
				self.api.set_access_token(app_tokens['access_token'])
				config.save_token(app_tokens)
				config.save_config()
				self.reset_task(row)
			except live_api.NetworkError:
				config.log.error('Network error. Wait for {} seconds.'.format(NETWORKERR_WAIT_INTERVAL))
				time.sleep(NETWORKERR_WAIT_INTERVAL)
				self.reset_task(row)
			#except live_api.OneDrive_Error as e:
			#	config.log.error(e.__class__.__name__ + ': ' + str(e))
			except OSError as e:
				config.log.error('OSError {0}: {1}. Path: {2}.'.format(e.errno, e.strerr, e.filename))
			
			self.parent.notify_all()
		
		self.conn.close()
		
		config.log.info('worker stops.')
Example #5
0
def main():
	# print help info if '--help' is a cmd arg
	if '--help' in sys.argv:
		print_help()
		sys.exit(0)
	
	api = live_api.OneDrive_API(config.APP_CLIENT_ID, config.APP_CLIENT_SECRET)
	
	app_tokens = config.get_token()
	if app_tokens == None:
		token_invalid = True
		if config.has_token():
			# try to refresh the token
			try:
				app_tokens = api.refresh_token(config.APP_CONFIG['token']['refresh_token'])
				config.save_token(app_tokens)
				config.save_config()
				token_invalid = False
			except live_api.NetworkError:
				print('Failed to reach OneDrive server. Please check your internet connection.')
				sys.exit(1)
			except live_api.AuthError:
				print('The client authorization has expired.')
				if '--no-prompt' in sys.argv:
					print('Please run `onedrive-prefs` to authorize the client.')
					sys.exit(1)
		if token_invalid:
			# failed to renew the token, show pref dialog
			# the pref program should guide users to set up all confs.
			if '--no-gui' in sys.argv:
				pass
			else:
				pass
	
	if not config.test_base_path():
		print('Path of local OneDrive repository is unset or invalid. Exit.')
		sys.exit(1)
	
	api.set_access_token(config.APP_CONFIG['token']['access_token'])
	
	# now start the threads
	# the MainThread is used for heart-beating
	
	from daemon import OneDrive_DaemonThread
	daemon_lock = threading.Event()
	daemon_thread = OneDrive_DaemonThread(api, daemon_lock)
	
	ui_component = ''
	for arg in sys.argv:
		if arg.startswith('--ui='):
			ui_component = arg.split('=')[1]
			break
	
	observer_thread = None
	if ui_component == 'gtk':
		from observer_gtk import OneDrive_Observer
		observer_thread = OneDrive_Observer()
	elif ui_component != '':
		print('The UI component "' + ui_component + '" is not found. Exit.')
		sys.exit(1)
	
	if observer_thread != None:
		daemon_thread.add_observer(observer_thread)
		observer_thread.start()
	
	# heart-beating for MainThread
	try:
		daemon_thread.start()
		while True:
			daemon_lock.set()
			time.sleep(DAEMON_PULL_INTERVAL)
	except KeyboardInterrupt:
		config.log.info('propagating stop signals.')
		daemon_thread.stop()
		if observer_thread != None:
			observer_thread.stop()
			observer_thread.join()
		daemon_thread.join()
		sys.exit(0)