[Syncropated-commits] r167 - trunk/src

zimmerle at garage.maemo.org zimmerle at garage.maemo.org
Tue Jan 30 02:25:52 EET 2007


Author: zimmerle
Date: 2007-01-30 02:25:51 +0200 (Tue, 30 Jan 2007)
New Revision: 167

Added:
   trunk/src/MediaScanHandler.py
Log:
MediaScanHandler first import

Added: trunk/src/MediaScanHandler.py
===================================================================
--- trunk/src/MediaScanHandler.py	2007-01-30 00:12:37 UTC (rev 166)
+++ trunk/src/MediaScanHandler.py	2007-01-30 00:25:51 UTC (rev 167)
@@ -0,0 +1,419 @@
+
+
+import gobject
+import os
+import sys
+import time
+import gtk
+from Logger import Logger
+from Configuration import Configuration
+from Utils import Utils
+from Icons import Icons
+import threading
+
+
+log = Logger()
+config = Configuration()
+utils = Utils()
+icons = Icons()
+
+class MediaScanHandler(gobject.GObject, threading.Thread):
+	"""
+	Scan and monitoring the files.
+
+	Now its using the mtime, but in the next release (i hope)
+	it will use a better way :P
+
+	"""
+
+	__gsignals__ = {
+		'configuration_changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
+			(gobject.TYPE_STRING, gobject.TYPE_STRING)),
+	}
+
+	__files = {}
+	__running_scan = False
+
+	__checking_file_label = None
+	__schedule_file_label = None
+	__progress_bar = None
+	__directory_label = None
+	__files_loaded_label = None
+	__cancel_watch_marked = False
+	__cancel_add_new_paths_marked = False
+	__window = None
+	__paths = []
+	__total_of_files = 0
+	obj = {}
+
+	def __init__(self, media_manager):
+		gobject.GObject.__init__(self)
+		threading.Thread.__init__ ( self )
+		self.__media_type = media_manager.TYPE
+		self.media_type = media_manager.TYPE
+		self.content_verify = getattr(media_manager, 'content_verify_func')
+		config.connect('configuration_changed', self.cb_configuration_changed)
+		self.media_manager_del_registrys = media_manager.del_registrys
+		self.media_manager_add_registry = media_manager.add_registry
+
+		self.__files = {}
+		self.__running_scan = False
+
+		self.__checking_file_label = None
+		self.__schedule_file_label = None
+		self.__progress_bar = None
+		self.__directory_label = None
+		self.__files_loaded_label = None
+		self.__cancel_watch_marked = False
+		self.__cancel_add_new_paths_marked = False
+		self.__window = None
+		self.__paths = []
+		self.__total_of_files = 0
+
+
+	def run(self):
+		gobject.idle_add(self._start)
+
+
+	def _start(self):
+		"""
+		Starts the scanner process....
+
+		"""
+		self.__setup_status_window()
+		gobject.timeout_add(int(config.getValue('watch_files_rescan_time')),
+			self.__cb_watch_files)
+
+		paths = config.getValue('media_' + self.__media_type + '_paths')
+
+		log.debug('MediaScanHandler :: ' + self.__media_type + 
+			' :: paths from config: ' + str(paths))
+
+		if paths == None:
+			return
+
+		paths = paths.split(";")
+		pos = 0
+		log.debug('MediaScanHandler :: ' + self.__media_type + ' :: Loaded paths: ' + str(self.__paths))
+		for path in paths:
+			# We need to watch the file and the subfolders. The user also can stop the folder scan process.
+			#if pos != 0 and len(paths) != 0:
+			#	self.__progress_bar.set_fraction(float(float(pos)/float(len(paths))))
+
+			#self.__progress_bar.set_text('Directory ' + str(pos) + ' of ' + str(len(paths)) + '...')
+			self.__directory_label.set_markup('<i>Directory: ' + str(path) + '</i>')
+			self.add_path_and_subpaths(path)
+			pos += 1
+			self.__paths.append(path)
+
+		log.debug('MediaScanHandler :: ' + self.__media_type + ' :: Loaded paths: ' + str(self.__paths))
+		#log.debug('MediaScanHandler :: ' + self.__media_type + ' :: add_path_and_subpaths is ready to work again!!')
+		#self.__cancel_add_new_paths_marked = False
+
+
+	def add_path_and_subpaths(self, path):
+		"""
+		Schedule the scan of path and sub-paths
+
+		"""
+		if path == '':
+			return
+
+		# Lets do something important...
+		while gtk.events_pending():
+				gtk.main_iteration_do(False)
+
+		if self.__cancel_add_new_paths_marked:
+			log.debug('MediaScanHandler :: ' + self.__media_type + 
+				' :: Sorry, but im asked to stop...')
+			return
+
+		#if os.path.isdir(path):
+		self.__add_watch(path)
+
+		try:
+			for new_path in os.listdir(path):
+				new_path = os.path.join(path, new_path)
+	
+				if os.path.isdir(new_path) == True:
+					self.add_path_and_subpaths(new_path)
+				if os.path.split(new_path)[0] == path:
+					self.__add_watch(new_path)
+		except:
+			pass
+
+
+	def __get_removed_files(self, path):
+		"""
+		Return the removed files, if its exist.
+
+		"""
+
+		removed = []
+
+		for file_uri in self.__files.keys():
+			if os.path.split(file_uri)[0] == path:
+				if os.path.isdir(file_uri):
+					continue
+				if not os.path.isfile(file_uri):
+					removed.append(file_uri)
+
+				log.info('MadiaScanHandler :: Ok Ok i need to check: '
+					+ file_uri)
+
+		log.debug('MediaScanHandler :: ' + self.__media_type + 
+			' :: Removed files: ' + str(removed))
+
+		return removed
+
+
+	def __get_added_files(self, path):
+		"""
+		Returned the added files, if its exist.
+
+		"""
+		added = []
+
+		for file_uri in os.listdir(path):
+			# FIXME: should create a new list, with interested records.
+			file_uri = os.path.join(path, file_uri)
+			if not file_uri in self.__files.keys():
+				added.append(file_uri)
+
+		log.debug('MediaScanHandler :: ' + self.__media_type + 
+			' :: Added files: ' + str(added))
+
+		return added
+
+
+	def __cb_watch_files(self):
+		if self.__running_scan == True:
+			log.warning("MediaScanHandler :: " + self.__media_type + 
+				" :: Wow!!! Too fast for me, im still scaning...")
+			return True
+
+		self.__running_scan = True
+
+		log.info("MediaScanHandler :: " + self.__media_type + 
+			" :: Watching files...  (" + str(len(self.__files)) + " to watch)")
+
+		for path in self.__files.keys():
+			for_continue = True
+
+			while gtk.events_pending():
+				gtk.main_iteration_do(False)
+
+			if self.__cancel_watch_marked:
+				self.__cancel_watch_maked = False
+				self.__running_scan = False
+				return True
+
+			try:
+				f_stat = os.stat(path)
+			except:
+				for_continue = False
+
+			if for_continue:
+				if self.__files[path] == None or self.__files[path] < f_stat.st_mtime:
+					if os.path.isdir(path):
+						log.debug('MediaScanHandler :: ' + self.__media_type + 
+							' :: it\'s a directory, A file is removed or created.')
+
+
+						### We need to know whats happened to this folder, first of all, lets check if this
+						### folder is new or old. If its new, we have nothing to do. If its old, we need to
+						### check the current watched files recored to know if its a new file or a removed one.
+
+						if self.__files[path] != None:
+							for removed_uri in self.__get_removed_files(path):
+								log.info('MediaScanHandler :: ' + self.__media_type + 
+									' :: File/Folder has been removed: ' + removed_uri)
+
+								self.media_manager_del_registrys(removed_uri, self.obj[removed_uri])
+
+								del self.__files[removed_uri]
+
+							for added_uri in self.__get_added_files(path):
+								log.info('MediaScanHandler :: ' + self.__media_type + 
+									' :: File/Folder has been added: ' + added_uri)
+								if os.path.isdir(added_uri):
+									self.add_path_and_subpaths(added_uri)
+								else:
+									if self.content_verify(added_uri):
+										self.__add_watch(added_uri)
+									else: 
+										log.info('MediaScanHandler :: ' + self.__media_type + 
+											' :: Sorry content is not supported.')
+
+					else:
+						log.debug('MediaScanHandler :: ' + self.__media_type + 
+							' :: Path: ' + str(path) + ' changed.')
+
+						if self.__files[path] != None:
+							self.media_manager_del_registrys(path, self.obj[path])
+
+						self.__get_content(path)
+
+					self.__files[path] = f_stat.st_mtime
+			else:
+				try:
+					del self.__files[path]
+					self.media_manager_del_registrys(removed_uri, self.obj[removed_uri])
+				except:
+					pass
+
+		self.__running_scan = False
+
+		return True
+
+
+	def __add_watch(self, path):
+		"""
+		Add files in the watch queue
+
+		"""
+		if self.content_verify(path) or os.path.isdir(path):
+			log.debug("MediaScanHandler :: " + self.__media_type +
+				" :: Watching a new file: " + str(path))
+			file_label = os.path.split(path)[1]
+			file_label = utils.unicodify(file_label)
+			file_label = utils.resize_string(file_label, 40)
+			self.__schedule_file_label.set_text(file_label)
+			self.__files[path] = None
+			log.debug("MediaScanHandler :: " + self.__media_type + 
+				" ::                    : " + str(self.__files))
+			if self.content_verify(path):
+				log.info('progress bar: ' + str(path))
+				self.__total_of_files += 1
+
+
+	def __get_content(self, path):
+		"""
+		Pass all files to media manager.
+
+		"""
+		if os.path.isdir(path):
+			log.debug('MediaScanHandler :: ' + self.__media_type + 
+				' :: its a directory, remove all files and add again?')
+		else:
+			log.debug('MediaScanHandler :: ' + self.__media_type + 
+				' :: Adding... ' + path)
+			self.obj[path] = self.media_manager_add_registry(path, 
+					(self.__checking_file_label, self.files_loaded_label,
+						self.__progress_bar, self.__total_of_files))
+
+
+	def cb_configuration_changed(self, emitent, key, value):
+		"""
+		Configuration callback, called when some configuration was changed.
+
+		"""
+		log.debug('MediaScanHandler :: ' + self.__media_type + 
+			' :: Rcvd a congiruration_changed event - key: ' + str(key))
+
+		if key == 'media_' + self.__media_type + '_paths':
+			#if self.__running_scan:
+			#	log.debug('MediaScanHandler :: 
+			#		Wating for the end of the scan process...')
+			#	self.__running_scan = False
+			#	return True
+
+			self.__running_scan = True
+
+			paths = value.split(";")
+
+			log.debug('MediaScanHandler :: ' + self.__media_type + 
+				' :: Old paths : ' + str(self.__paths))
+			log.debug('MediaScanHandler :: ' + self.__media_type + 
+				' :: New paths : ' + str(paths))
+
+			# A really new path ?
+			#really_new_paths = [] ## Debug
+			for tmp_path in paths:
+				if not tmp_path in self.__paths:
+					self.add_path_and_subpaths(tmp_path)
+					#really_new_paths.append(tmp_path) ## Debug
+
+			# Hum... a deleted path?
+			deleted_paths = []
+			for tmp_path in self.__paths:
+				if not tmp_path in paths:
+					self.__delete_files_in_path(tmp_path)
+					deleted_paths.append(tmp_path)
+
+
+			#log.debug('MediaScanHandler :: Really new paths : ' + 
+			#	str(really_new_paths)) ## Debug
+			log.debug('MediaScanHandler :: ' + self.__media_type + 
+				' :: Deleted paths    : ' + str(deleted_paths))
+
+			self.__paths = paths
+
+			self.__running_scan = False
+
+
+	def __delete_files_in_path(self, path):
+		"""
+		Remove all files in `path` from the watches queue
+
+		"""
+		try:
+			registers = self.media_manager_del_registrys(path, self.obj[path])
+			log.debug('MediaScanHandler :: ' + self.__media_type + 
+				' :: Needs to delete: ' + str(registers)) 
+		except:
+			# if exepct is a directory...
+			pass
+
+		# We just need to remove from the files dict and emit a signal.
+		for i in self.__files.keys():
+
+			if i == path:
+				continue
+			
+			try:
+				log.debug('MediaScanHandler :: Deleting key: ' +
+					str(i) + ' <=> ' + str(path))
+				if utils.is_path_to([i], path):
+					log.debug('MediaScanHandler :: Deleting key: ' + 
+						str(i) + '  -> ' + str(self.obj[i]))
+					self.media_manager_del_registrys(path, self.obj[i])
+					del self.__files[i]
+			except:
+				pass
+
+
+	def __setup_status_window(self):
+		"""
+		Load and configure the status window.
+
+		"""
+		xml = gtk.glade.XML(utils.get_glade_fullpath('status.glade'))
+
+		self.__window = xml.get_widget('status_window')
+		self.__schedule_file_label = xml.get_widget('schedule_file_label')
+		self.__checking_file_label = xml.get_widget('checking_file_label')
+
+		self.__progress_bar = xml.get_widget('progressbar1')
+		self.__directory_label = xml.get_widget('directory_label')
+		self.files_loaded_label = xml.get_widget('files_loaded_label')
+
+		icon = xml.get_widget('icon')
+		icon.set_from_pixbuf(icons.load_icon(self.__media_type + "-x-generic", 64, 0))
+
+		cancel_button = xml.get_widget('cancel_button')
+		cancel_button.connect('clicked', self.__cb_cancel_clicked)
+
+		self.__window.show()
+
+
+	def __cb_cancel_clicked(self, button):
+		"""
+		When someone ask to stop...
+
+		"""
+		log.debug('MediaScanHandler :: ' + self.__media_type + ' :: Cancel button pressed.')
+		self.__cancel_add_new_paths_marked = True
+		self.__window.hide()
+
+



More information about the Syncropated-commits mailing list