def run(self, name):
		"""Import movies, function called in a loop over source files"""
		from add import validate_details, edit_movie
		from gutils import find_next_available
		from sqlalchemy import Select, func
		import gtk
		
		if not self.set_source(name):
			self.debug.show("Can't read data from file %s" % name)
			return False
		
		self.widgets['pwindow'].show()
		while gtk.events_pending():	# give GTK some time for updates
			gtk.main_iteration()

		# progressbar
		update_on = []
		count = self.count_movies()
		if count > 0:
			for i in range(0,100):
				update_on.append(int(float(i)/100*count))

		statement = Select( [ func.max(self.db.Movie.c.number) ] )
		number = statement.execute().fetchone()[0]
		if number is None:
			number = 1
		else:
			number += 1

		statement = Select([self.db.Movie.c.number])

		processed = 0
		while self._abort is False:
			details = self.get_movie_details()
			if details is None:
				break

			processed += 1
			if processed in update_on:
				self.widgets['progressbar'].set_fraction(float(processed)/float(count))
				gtk.main_iteration()
				self.widgets['progressbar'].set_text("%s (%s/%s)" % (str(self.imported), str(processed), str(count)))
				gtk.main_iteration()
				gtk.main_iteration() # extra iteration for abort button

			if (details.has_key('o_title') and details['o_title']) or (details.has_key('title') and details['title']):
				if details.has_key('o_title') and details['o_title']:
					statement.whereclause = func.lower(self.db.Movie.c.o_title)==details['o_title'].lower()
					if details.has_key('title') and details['title']:
						statement.append_whereclause( func.lower(self.db.Movie.c.title)==details['title'].lower() )
					tmp = statement.execute().fetchone()
					if tmp is not None:
						self.debug.show("movie already exists (number=%s, o_title=%s)" % (tmp.number, details['o_title']))
						continue
				elif details.has_key('title') and details['title']:
					statement.whereclause = func.lower(self.db.Movie.c.title)==details['title'].lower()
					tmp = statement.execute().fetchone()
					if tmp is not None:
						self.debug.show("movie already exists (number=%s, title=%s)" % (tmp.number, details['title']))
						continue
				validate_details(details, self.fields_to_import)
				if self.edit is True:
					response = edit_movie(self.parent, details)	# FIXME: wait until save or cancel button pressed
					if response == 1:
						self.imported += 1
				else:
					if not details.has_key('number') or (details.has_key('number') and details['number'] is None):
						#details['number'] = find_next_available(self.db)
						details['number'] = number
						number += 1
					#movie = self.db.Movie()
					#movie.add_to_db(details)
					try:
						self.db.Movie.mapper.mapped_table.insert().execute(details)
						self.imported += 1
					except Exception, e:
						self.debug.show("movie details are not unique, skipping: %s" % str(e))
			else:
				self.debug.show('skipping movie without title or original title')
Exemple #2
0
    def run(self, name):
        """Import movies, function called in a loop over source files"""
        from add import validate_details, edit_movie
        from sqlalchemy import select
        import gtk

        name = name.decode('utf-8')
        if not self.set_source(name):
            log.info("Can't read data from file %s", name)
            return False

        self.widgets['pwindow'].show()
        while gtk.events_pending():  # give GTK some time for updates
            gtk.main_iteration()

        # progressbar
        update_on = []
        count = self.count_movies()
        if count > 0:
            for i in range(0, 100):
                update_on.append(int(float(i) / 100 * count))

        session = self.db.Session()
        session.bind = self.db.session.bind

        # move some stuff outside the loop to speed it up
        set_fraction = self.widgets['progressbar'].set_fraction
        set_text = self.widgets['progressbar'].set_text
        main_iteration = gtk.main_iteration

        # get some values from DB to avoid queries in the loop
        statement = select([db.Movie.number, db.Movie.title, db.Movie.o_title])
        data = session.execute(statement).fetchall()
        numbers = set(i[0] for i in data)
        titles = set(i[1].lower() for i in data if i[1])
        o_titles = set(i[2].lower() for i in data if i[2])

        gc_was_enabled = gc.isenabled()
        if gc_was_enabled:
            gc.collect()
            gc.disable()

        begin = time.time()
        processed = 0
        try:
            while self._continue:
                details = self.get_movie_details()
                if details is None:
                    break

                processed += 1
                if processed in update_on:
                    set_fraction(float(processed) / count)
                    main_iteration()
                    set_text("%s (%s/%s)" % (self.imported, processed, count))
                    main_iteration()
                    main_iteration()  # extra iteration for abort button

                o_title_lower = details.get('o_title', '').lower()
                title_lower = details.get('title', '').lower()

                if o_title_lower or title_lower:
                    if o_title_lower and o_title_lower in o_titles:
                        if title_lower and title_lower in titles:
                            log.info(
                                "movie already exists (o_title=%s, title=%s)",
                                details['o_title'], details['title'])
                            continue
                    elif title_lower and title_lower in titles:  # o_title is not available so lets check title only
                        log.info("movie already exists (title=%s)",
                                 details['title'])
                        continue
                    if self.edit:  # XXX: not used for now
                        validate_details(details, self.fields_to_import)
                        response = edit_movie(
                            self.parent, details
                        )  # FIXME: wait until save or cancel button pressed
                        if response == 1:
                            self.imported += 1
                    else:
                        # get the number and make it unique. number is needed later
                        number = details.get('number', 1)
                        while number in numbers:
                            number += 1
                        if 'tags' in details:
                            tags = details.pop('tags')
                        else:
                            tags = None
                        poster = None
                        if 'poster' in details:
                            poster = details.pop('poster')
                        elif 'image' in details:
                            poster = details.pop('image')
                        try:
                            # optional: do mapping of lookup data
                            if not self.foreignkeymaps:
                                self._loadmappings()
                            for fkcolumnname in self.foreignkeymaps:
                                try:
                                    if fkcolumnname in details and details[
                                            fkcolumnname]:
                                        fkcolumn_id = int(
                                            details[fkcolumnname])
                                except:
                                    try:
                                        fkcolumn_id = self.normalizename(
                                            details[fkcolumnname])
                                        currentmap = self.foreignkeymaps[
                                            fkcolumnname]
                                        if fkcolumn_id in currentmap:
                                            details[fkcolumnname] = currentmap[
                                                fkcolumn_id]
                                        else:
                                            details[
                                                fkcolumnname] = self._addmappingvalue(
                                                    fkcolumnname,
                                                    details[fkcolumnname])
                                    except:
                                        log.exception(fkcolumnname)
                                        details[fkcolumnname] = None
                            # validation before insertion
                            validate_details(details, self.fields_to_import)
                            # set number here again because if it is not selected validate_details will remove it
                            details['number'] = number
                            # insert the movie in the database
                            movie = db.tables.movies.insert(
                                bind=self.db.session.bind).execute(details)
                            self.imported += 1
                            # optional: adding tags
                            if tags:
                                if self.tagmap is None:
                                    self.loadmappings()
                                for tag in tags:
                                    try:
                                        if isinstance(tag, (str, unicode)):
                                            # TODO: adding new tag names?
                                            tag_id = self.tagmap[tag.lower()]
                                        else:
                                            tag_id = int(tag)
                                        db.tables.movie_tag.insert(
                                            bind=self.db.session.bind).execute(
                                                {
                                                    'movie_id':
                                                    movie.lastrowid,
                                                    'tag_id': tag_id
                                                })
                                    except:
                                        pass
                            self.db.session.commit()
                            # adding poster
                            if poster:
                                if len(poster) > 4:
                                    # check for JPEG/PNG header otherwise it should be a filename
                                    header = struct.unpack_from('4s',
                                                                poster)[0]
                                    if header == '\xff\xd8\xff\xe0' or \
                                       header == '\x89\x50\x4e\x47':
                                        # make a temporary file
                                        try:
                                            posterfilefd, posterfilename = mkstemp(
                                                '.img')
                                            try:
                                                os.write(posterfilefd, poster)
                                            finally:
                                                os.close(posterfilefd)
                                            edit.update_image(
                                                self.parent, number,
                                                posterfilename)
                                        finally:
                                            if os.path.isfile(posterfilename):
                                                os.remove(posterfilename)
                                    else:
                                        edit.update_image(
                                            self.parent, number, poster)
                        except Exception:
                            log.exception(
                                "movie details are not unique, skipping")
                        numbers.add(number)
                else:
                    log.info('skipping movie without title and original title')
        finally:
            log.info("Import process took %s s; %s/%s movies imported",
                     (time.time() - begin), processed, count)
            if gc_was_enabled:
                gc.enable()
            self.widgets['pwindow'].hide()
        return True
    def run(self, name):
        """Import movies, function called in a loop over source files"""
        from add import validate_details, edit_movie
        from gutils import find_next_available
        from sqlalchemy import select, func
        import gtk
        
        if not self.set_source(name):
            log.info("Can't read data from file %s", name)
            return False
        
        self.widgets['pwindow'].show()
        while gtk.events_pending():    # give GTK some time for updates
            gtk.main_iteration()

        # progressbar
        update_on = []
        count = self.count_movies()
        if count > 0:
            for i in range(0,100):
                update_on.append(int(float(i)/100*count))

        session = self.db.Session()
        session.bind = self.db.session.bind
        
        # move some stuff outside the loop to speed it up
        set_fraction = self.widgets['progressbar'].set_fraction
        set_text = self.widgets['progressbar'].set_text
        main_iteration = gtk.main_iteration

        # get some values from DB to avoid queries in the loop
        statement = select([db.Movie.number, db.Movie.title, db.Movie.o_title])
        data = session.execute(statement).fetchall()
        numbers = set(i[0] for i in data)
        titles = set(i[1].lower() for i in data)
        o_titles = set(i[2].lower() for i in data)

        gc_was_enabled = gc.isenabled()
        if gc_was_enabled:
            gc.collect()
            gc.disable()

        begin = time.time()
        processed = 0
        while self._continue:
            details = self.get_movie_details()
            if details is None:
                break
            
            processed += 1
            if processed in update_on:
                set_fraction(float(processed)/count)
                main_iteration()
                set_text("%s (%s/%s)" % (self.imported, processed, count))
                main_iteration()
                main_iteration() # extra iteration for abort button

            o_title_avail = 'o_title' in details
            title_avail = 'title' in details

            if (o_title_avail and details['o_title']) or (title_avail and details['title']):
                if o_title_avail and details['o_title'].lower() in o_titles:
                    if title_avail and details['title'].lower() in titles:
                        log.info("movie already exists (o_title=%s, title=%s)", details['o_title'], details['title'])
                        continue
                elif title_avail and details['title'].lower() in titles: # o_title is not available so lets check title only
                    log.info("movie already exists (title=%s)", details['title'])
                    continue
                validate_details(details, self.fields_to_import)
                if self.edit: # XXX: not used for now
                    response = edit_movie(self.parent, details)    # FIXME: wait until save or cancel button pressed
                    if response == 1:
                        self.imported += 1
                else:
                    number = details.get('number', 1)
                    while number in numbers:
                        number += 1
                    details['number'] = number
                    #movie = db.Movie()
                    #movie.add_to_db(details)
                    try:
                        db.movies_table.insert(bind=self.db.session.bind).execute(details)
                        self.imported += 1
                    except Exception, e:
                        log.info("movie details are not unique, skipping: %s", e)
                    numbers.add(number)
            else:
                log.info('skipping movie without title and original title')
    def run(self, name):
        """Import movies, function called in a loop over source files"""
        from add import validate_details, edit_movie
        from sqlalchemy import select
        import gtk

        if not self.set_source(name):
            log.info("Can't read data from file %s", name)
            return False

        self.widgets['pwindow'].show()
        while gtk.events_pending():    # give GTK some time for updates
            gtk.main_iteration()

        # progressbar
        update_on = []
        count = self.count_movies()
        if count > 0:
            for i in range(0, 100):
                update_on.append(int(float(i) / 100 * count))

        session = self.db.Session()
        session.bind = self.db.session.bind

        # move some stuff outside the loop to speed it up
        set_fraction = self.widgets['progressbar'].set_fraction
        set_text = self.widgets['progressbar'].set_text
        main_iteration = gtk.main_iteration

        # get some values from DB to avoid queries in the loop
        statement = select([db.Movie.number, db.Movie.title, db.Movie.o_title])
        data = session.execute(statement).fetchall()
        numbers = set(i[0] for i in data)
        titles = set(i[1].lower() for i in data if i[1])
        o_titles = set(i[2].lower() for i in data if i[2])

        gc_was_enabled = gc.isenabled()
        if gc_was_enabled:
            gc.collect()
            gc.disable()

        begin = time.time()
        processed = 0
        try:
            while self._continue:
                details = self.get_movie_details()
                if details is None:
                    break

                processed += 1
                if processed in update_on:
                    set_fraction(float(processed) / count)
                    main_iteration()
                    set_text("%s (%s/%s)" % (self.imported, processed, count))
                    main_iteration()
                    main_iteration() # extra iteration for abort button

                o_title_lower = details.get('o_title', '').lower()
                title_lower = details.get('title', '').lower()

                if o_title_lower or title_lower:
                    if o_title_lower and o_title_lower in o_titles:
                        if title_lower and title_lower in titles:
                            log.info("movie already exists (o_title=%s, title=%s)", details['o_title'], details['title'])
                            continue
                    elif title_lower and title_lower in titles: # o_title is not available so lets check title only
                        log.info("movie already exists (title=%s)", details['title'])
                        continue
                    if self.edit: # XXX: not used for now
                        validate_details(details, self.fields_to_import)
                        response = edit_movie(self.parent, details)    # FIXME: wait until save or cancel button pressed
                        if response == 1:
                            self.imported += 1
                    else:
                        number = details.get('number', 1)
                        while number in numbers:
                            number += 1
                        details['number'] = number
                        if 'tags' in details:
                            tags = details.pop('tags')
                        else:
                            tags = None
                        if 'poster' in details:
                            poster = details.pop('poster')
                        else:
                            poster = None
                        try:
                            # optional: do mapping of lookup data
                            if not self.foreignkeymaps:
                                self._loadmappings()
                            for fkcolumnname in self.foreignkeymaps:
                                try:
                                    if fkcolumnname in details and details[fkcolumnname]:
                                        fkcolumn_id = int(details[fkcolumnname])
                                except:
                                    try:
                                        fkcolumn_id = self.normalizename(details[fkcolumnname])
                                        currentmap = self.foreignkeymaps[fkcolumnname]
                                        if fkcolumn_id in currentmap:
                                            details[fkcolumnname] = currentmap[fkcolumn_id]
                                        else:
                                            details[fkcolumnname] = self._addmappingvalue(fkcolumnname, details[fkcolumnname])
                                    except:
                                        log.exception(fkcolumnname)
                                        details[fkcolumnname] = None
                            # validation before insertion
                            validate_details(details, self.fields_to_import)
                            # insert the movie in the database
                            movie = db.tables.movies.insert(bind=self.db.session.bind).execute(details)
                            self.imported += 1
                            # optional: adding tags
                            if tags:
                                if self.tagmap is None:
                                    self.loadmappings()
                                for tag in tags:
                                    try:
                                        if isinstance(tag, (str, unicode)):
                                            # TODO: adding new tag names?
                                            tag_id = self.tagmap[tag.lower()]
                                        else:
                                            tag_id = int(tag)
                                        db.tables.movie_tag.insert(bind=self.db.session.bind).execute({'movie_id': movie.lastrowid, 'tag_id': tag_id})
                                    except:
                                        pass
                            # adding poster
                            if poster:
                                if len(poster) > 4:
                                    # check for JPEG/PNG header otherwise it should be a filename
                                    header = struct.unpack_from('4s', poster)[0]
                                    if header == '\xff\xd8\xff\xe0' or \
                                       header == '\x89\x50\x4e\x47':
                                        # make a temporary file
                                        try:
                                            posterfilefd, posterfilename = mkstemp('.img')
                                            try:
                                                os.write(posterfilefd, poster)
                                            finally:
                                                os.close(posterfilefd)
                                            edit.update_image(self.parent, number, posterfilename)
                                        finally:
                                            if os.path.isfile(posterfilename):
                                                os.remove(posterfilename)
                                    else:
                                        edit.update_image(self.parent, number, poster)
                        except Exception:
                            log.exception("movie details are not unique, skipping")
                        numbers.add(number)
                else:
                    log.info('skipping movie without title and original title')
        finally:
            log.info("Import process took %s s; %s/%s movies imported", (time.time() - begin), processed, count)
            if gc_was_enabled:
                gc.enable()
            self.widgets['pwindow'].hide()
        return True