def __resetdata__(self): self.INTERNAL_MODEL_DATA[self.task_folder()] = common.DataDict({ common.FileItem: common.DataDict({}), common.SequenceItem: common.DataDict({}), }) self.__initdata__() self.endResetModel()
def __initdata__(self): self.beginResetModel() self.INTERNAL_USER_DATA = common.DataDict() channels = self.client.get_channels() profiles = self.client.get_user_profiles() # Channels try: for channel in sorted(channels, key=lambda x: x['name']): idx = len(self.INTERNAL_USER_DATA) self.INTERNAL_USER_DATA[idx] = common.DataDict({ QtCore.Qt.DisplayRole: u'Channel: ' + channel['name'], QtCore.Qt.DecorationRole: QtGui.QIcon(), QtCore.Qt.SizeHintRole: self.row_size, QtCore.Qt.FontRole: common.font_db.primary_font( font_size=common.SMALL_FONT_SIZE())[0], IdRole: channel[u'id'], ThumbnailHashRole: None, ThumbnailUrlRole: None, }) except Exception as e: log.error(u'Could not get channels.') try: for profile in sorted(profiles, key=self.get_pretty_name): idx = len(self.INTERNAL_USER_DATA) self.INTERNAL_USER_DATA[idx] = common.DataDict({ QtCore.Qt.DisplayRole: self.get_pretty_name(profile), QtCore.Qt.DecorationRole: QtGui.QIcon(), QtCore.Qt.SizeHintRole: self.row_size, QtCore.Qt.FontRole: common.font_db.primary_font( font_size=common.SMALL_FONT_SIZE())[0], IdRole: profile[u'id'], ThumbnailHashRole: profile[u'profile']['avatar_hash'], ThumbnailUrlRole: profile[u'profile']['image_32'], }) index = self.index(idx, 0) self.get_icon(index) except Exception as e: log.error('Could not get profiles') self.endResetModel()
def __initdata__(self): """Collects the data needed to populate the bookmarks model. Bookmarks are made up of a tuple of ``(server, job, root)`` values and are stored in the local user system settings, eg. the Registry in under windows. Each bookmarks can be associated with a thumbnail, custom description and a list of comments, todo items. Note: This model does not have threads associated with it as fetching necessary data is relatively inexpensive. """ def dflags(): """The default flags to apply to the item.""" return (QtCore.Qt.ItemIsDropEnabled | QtCore.Qt.ItemNeverHasChildren | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) task_folder = self.task_folder() active_paths = settings.local_settings.verify_paths() favourites = settings.local_settings.favourites() bookmarks = settings.local_settings.value(u'bookmarks') bookmarks = bookmarks if bookmarks else {} _height = self.ROW_SIZE.height() - common.ROW_SEPARATOR() for k, v in bookmarks.iteritems(): if not all(v.values()): continue file_info = QtCore.QFileInfo(k) exists = file_info.exists() if exists: flags = dflags() pixmap = images.ImageCache.get_rsc_pixmap( u'bookmark_sm', common.ADD, _height) else: flags = dflags() | common.MarkedAsArchived pixmap = images.ImageCache.get_rsc_pixmap( u'failed', common.REMOVE, _height) placeholder_image = pixmap default_thumbnail_image = pixmap filepath = file_info.filePath().lower() # Active Flag if all((v[u'server'] == active_paths[u'server'], v[u'job'] == active_paths[u'job'], v[u'root'] == active_paths[u'root'])): flags = flags | common.MarkedAsActive # Favourite Flag if filepath in favourites: flags = flags | common.MarkedAsFavourite text = u'{} | {}'.format( v[u'job'], v[u'root'], # v[u'root'].split(u'/').pop(), ) data = self.INTERNAL_MODEL_DATA[task_folder][common.FileItem] idx = len(data) data[idx] = common.DataDict({ QtCore.Qt.DisplayRole: text, QtCore.Qt.EditRole: text, QtCore.Qt.StatusTipRole: filepath, QtCore.Qt.ToolTipRole: filepath, QtCore.Qt.SizeHintRole: self.ROW_SIZE, # common.TextSegmentRole: self.get_text_segments(text), # common.EntryRole: [], common.FlagsRole: flags, common.ParentPathRole: (v[u'server'], v[u'job'], v[u'root']), common.DescriptionRole: u'', common.TodoCountRole: 0, common.FileDetailsRole: None, common.SequenceRole: None, common.EntryRole: [], common.FileInfoLoaded: False, common.StartpathRole: None, common.EndpathRole: None, # common.ThumbnailLoaded: False, # common.TypeRole: common.FileItem, # common.SortByNameRole: text, common.SortByLastModifiedRole: file_info.lastModified().toMSecsSinceEpoch(), common.SortBySizeRole: file_info.size(), # common.AssetCountRole: 0, # common.IdRole: idx }) db = None n = 0 db = bookmark_db.get_db( v[u'server'], v[u'job'], v[u'root'], ) with db.transactions(): # Item flags flags = data[idx][common.FlagsRole] v = db.value(data[idx][QtCore.Qt.StatusTipRole], u'flags') flags = flags | v if v is not None else flags data[idx][common.FlagsRole] = flags # Todos are a little more convoluted - the todo count refers to # all the current outstanding todos af all assets, including # the bookmark itself n = 0 for v in db.values(u'notes').itervalues(): if not v: continue if v[u'notes']: try: v = base64.b64decode(v[u'notes']) d = json.loads(v) n += len([ k for k in d if not d[k][u'checked'] and d[k][u'text'] ]) except (ValueError, TypeError): log.error(u'Error decoding JSON notes') data[idx][common.TodoCountRole] = n self.update_description(db, data[idx]) self.activeChanged.emit(self.active_index())
def __initdata__(self): """The method is responsible for getting the bare-bones file and sequence definitions by running a file-iterator stemming from ``self.parent_path``. Getting all additional information, like description, item flags, thumbnails are costly and therefore are populated by thread-workers. The method will iterate through all files in every subfolder and will automatically save individual ``FileItems`` and collapsed ``SequenceItems``. Switching between the two datasets is done via emitting the ``dataTypeChanged`` signal. Note: Experiencing serious performance issues with the built-in QDirIterator on Mac OS X samba shares and the performance isn't great on windows either. Querrying the filesystem using the method is magnitudes slower than using the same methods on windows. A workaround I found was to use Python 3+'s ``scandir`` module. Both on Windows and Mac OS X the performance seems to be good. Internally, the actual files are returned by `self._entry_iterator()`, this is where scandir is evoked. """ def dflags(): """The default flags to apply to the item.""" return (QtCore.Qt.ItemNeverHasChildren | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) task_folder = self.task_folder().lower() SEQUENCE_DATA = common.DataDict() MODEL_DATA = common.DataDict({ common.FileItem: common.DataDict(), common.SequenceItem: common.DataDict(), }) favourites = settings.local_settings.favourites() sfavourites = set(favourites) activefile = settings.local_settings.value(u'activepath/file') server, job, root, asset = self.parent_path task_folder_extensions = defaultpaths.get_task_folder_extensions( task_folder) parent_path = u'/'.join(self.parent_path).lower() + \ u'/' + task_folder nth = 987 c = 0 if not QtCore.QFileInfo(parent_path).exists(): return for entry in self._entry_iterator(parent_path): if self._interrupt_requested: break # skipping directories if entry.is_dir(): continue filename = entry.name.lower() if filename[0] == u'.': continue if u'thumbs.db' in filename: continue filepath = entry.path.lower().replace(u'\\', u'/') ext = filename.split(u'.')[-1] if task_folder_extensions and ext not in task_folder_extensions: continue # Progress bar c += 1 if not c % nth: self.progressMessage.emit(u'Loading files (found ' + unicode(c) + u' items)...') QtWidgets.QApplication.instance().processEvents() # Getting the fileroot fileroot = filepath.replace(parent_path, u'') fileroot = u'/'.join(fileroot.split(u'/')[:-1]).strip(u'/') seq = common.get_sequence(filepath) flags = dflags() if seq: seqpath = seq.group(1) + common.SEQPROXY + \ seq.group(3) + u'.' + seq.group(4) seqpath = seqpath.lower() if seqpath in sfavourites: flags = flags | common.MarkedAsFavourite else: if filepath in sfavourites: flags = flags | common.MarkedAsFavourite if activefile: if activefile in filepath: flags = flags | common.MarkedAsActive parent_path_role = (server, job, root, asset, task_folder, fileroot) # Let's limit the maximum number of items we load idx = len(MODEL_DATA[common.FileItem]) if idx >= common.MAXITEMS: break MODEL_DATA[common.FileItem][idx] = common.DataDict({ QtCore.Qt.DisplayRole: filename, QtCore.Qt.EditRole: filename, QtCore.Qt.StatusTipRole: filepath, QtCore.Qt.SizeHintRole: self.ROW_SIZE, # common.EntryRole: [ entry, ], common.FlagsRole: flags, common.ParentPathRole: parent_path_role, common.DescriptionRole: u'', common.TodoCountRole: 0, common.FileDetailsRole: u'', common.SequenceRole: seq, common.FramesRole: [], common.FileInfoLoaded: False, common.StartpathRole: None, common.EndpathRole: None, # common.ThumbnailLoaded: False, # common.TypeRole: common.FileItem, # common.SortByNameRole: common.namekey(filepath), common.SortByLastModifiedRole: 0, common.SortBySizeRole: 0, # common.IdRole: idx # non-mutable }) # If the file in question is a sequence, we will also save a reference # to it in `self._model_data[location][True]` dictionary. if seq: # If the sequence has not yet been added to our dictionary # of seqeunces we add it here if seqpath not in SEQUENCE_DATA: # ... and create it if it doesn't exist seqname = seqpath.split(u'/')[-1] flags = dflags() if seqpath in sfavourites: flags = flags | common.MarkedAsFavourite SEQUENCE_DATA[seqpath] = common.DataDict({ QtCore.Qt.DisplayRole: seqname, QtCore.Qt.EditRole: seqname, QtCore.Qt.StatusTipRole: seqpath, QtCore.Qt.SizeHintRole: self.ROW_SIZE, common.EntryRole: [], common.FlagsRole: flags, common.ParentPathRole: parent_path_role, common.DescriptionRole: u'', common.TodoCountRole: 0, common.FileDetailsRole: u'', common.SequenceRole: seq, common.FramesRole: [], common.FileInfoLoaded: False, common.StartpathRole: None, common.EndpathRole: None, # common.ThumbnailLoaded: False, # common.TypeRole: common.SequenceItem, common.SortByNameRole: common.namekey(seqpath), common.SortByLastModifiedRole: 0, common.SortBySizeRole: 0, # Initializing with null-size # common.IdRole: 0 }) SEQUENCE_DATA[seqpath][common.FramesRole].append(seq.group(2)) SEQUENCE_DATA[seqpath][common.EntryRole].append(entry) else: SEQUENCE_DATA[filepath] = MODEL_DATA[common.FileItem][idx] # Casting the sequence data back onto the model for v in SEQUENCE_DATA.itervalues(): idx = len(MODEL_DATA[common.SequenceItem]) if len(v[common.FramesRole]) == 1: # A sequence with only one element is not a sequence _seq = v[common.SequenceRole] filepath = _seq.group(1) + v[common.FramesRole][ 0] + _seq.group(3) + u'.' + _seq.group(4) filename = filepath.split(u'/')[-1] v[QtCore.Qt.DisplayRole] = filename v[QtCore.Qt.EditRole] = filename v[QtCore.Qt.StatusTipRole] = filepath v[common.TypeRole] = common.FileItem v[common.SortByNameRole] = common.namekey(filepath) v[common.SortByLastModifiedRole] = 0 flags = dflags() if filepath.lower() in sfavourites: flags = flags | common.MarkedAsFavourite if activefile: if activefile in filepath: flags = flags | common.MarkedAsActive v[common.FlagsRole] = flags elif len(v[common.FramesRole]) == 0: v[common.TypeRole] = common.FileItem else: if activefile: _seq = v[common.SequenceRole] _firsframe = _seq.group(1) + min( v[common.FramesRole]) + _seq.group( 3) + u'.' + _seq.group(4) if activefile in _firsframe: v[common.FlagsRole] = v[ common.FlagsRole] | common.MarkedAsActive MODEL_DATA[common.SequenceItem][idx] = v MODEL_DATA[common.SequenceItem][idx][common.IdRole] = idx self.INTERNAL_MODEL_DATA[task_folder] = MODEL_DATA
def __initdata__(self): """Bookmarks and assets are static. But files will be any number of """ task_folder = self.task_folder() self.INTERNAL_MODEL_DATA[task_folder] = common.DataDict({ common.FileItem: common.DataDict(), common.SequenceItem: common.DataDict() }) flags = (QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDropEnabled | QtCore.Qt.ItemIsEditable) data = self.model_data() if not self.parent_path: return # Thumbnail image default_thumbnail = images.ImageCache.get_rsc_pixmap( u'folder_sm', common.SECONDARY_TEXT, self.ROW_SIZE.height()) default_thumbnail = default_thumbnail.toImage() parent_path = u'/'.join(self.parent_path) entries = sorted(([f for f in _scandir.scandir(parent_path)]), key=lambda x: x.name) for entry in entries: if entry.name.startswith(u'.'): continue if not entry.is_dir(): continue idx = len(data) data[idx] = common.DataDict({ QtCore.Qt.DisplayRole: entry.name, QtCore.Qt.EditRole: entry.name, QtCore.Qt.StatusTipRole: entry.path.replace(u'\\', u'/'), QtCore.Qt.ToolTipRole: u'', QtCore.Qt.ToolTipRole: defaultpaths.get_description(entry.name), QtCore.Qt.SizeHintRole: self.ROW_SIZE, # common.FlagsRole: flags, common.ParentPathRole: self.parent_path, # common.FileInfoLoaded: False, common.ThumbnailLoaded: True, common.TodoCountRole: 0, # common.IdRole: idx, }) thread = self.threads[common.InfoThread][0] thread.add_to_queue(weakref.ref(data[idx]))
def __initdata__(self): """Collects the data needed to populate the bookmarks model by querrying the path stored in ``self.parent_path``. Note: Getting asset information is relatively cheap, hence the model does not have any threads associated with it. """ def dflags(): """The default flags to apply to the item.""" return (QtCore.Qt.ItemNeverHasChildren | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) if not self.parent_path: return if not all(self.parent_path): return task_folder = self.task_folder() dtype = self.data_type() self.INTERNAL_MODEL_DATA[task_folder] = common.DataDict({ common.FileItem: common.DataDict(), common.SequenceItem: common.DataDict() }) favourites = settings.local_settings.favourites() sfavourites = set(favourites) activeasset = settings.local_settings.value(u'activepath/asset') server, job, root = self.parent_path bookmark_path = u'{}/{}/{}'.format(server, job, root) # Let's get the identifier from the bookmark database db = bookmark_db.get_db(server, job, root) ASSET_IDENTIFIER = db.value(1, u'identifier', table='properties') nth = 1 c = 0 for entry in _scandir.scandir(bookmark_path): if entry.name.startswith(u'.'): continue if not entry.is_dir(): continue filepath = entry.path.replace(u'\\', u'/') if ASSET_IDENTIFIER: identifier = u'{}/{}'.format(filepath, ASSET_IDENTIFIER) if not QtCore.QFileInfo(identifier).exists(): continue # Progress bar c += 1 if not c % nth: self.progressMessage.emit(u'Found {} assets...'.format(c)) QtWidgets.QApplication.instance().processEvents( QtCore.QEventLoop.ExcludeUserInputEvents) filename = entry.name flags = dflags() if filepath.lower() in sfavourites: flags = flags | common.MarkedAsFavourite if activeasset: if activeasset.lower() == filename.lower(): flags = flags | common.MarkedAsActive idx = len(self.INTERNAL_MODEL_DATA[task_folder][dtype]) name = re.sub(ur'[_]{1,}', u' ', filename).strip(u'_') self.INTERNAL_MODEL_DATA[task_folder][dtype][ idx] = common.DataDict({ QtCore.Qt.DisplayRole: name, QtCore.Qt.EditRole: filename, QtCore.Qt.StatusTipRole: filepath, QtCore.Qt.SizeHintRole: self.ROW_SIZE, # common.EntryRole: [ entry, ], common.FlagsRole: flags, common.ParentPathRole: (server, job, root, filename), common.DescriptionRole: u'', common.TodoCountRole: 0, common.FileDetailsRole: u'', common.SequenceRole: None, common.FramesRole: [], common.FileInfoLoaded: False, common.StartpathRole: None, common.EndpathRole: None, # common.ThumbnailLoaded: False, # common.TypeRole: common.FileItem, # common.SortByNameRole: common.namekey(filepath), common.SortByLastModifiedRole: 0, common.SortBySizeRole: 0, # common.IdRole: idx }) # Explicitly emit signal to notify the other dependent model self.activeChanged.emit(self.active_index())
def __init__(self, token, parent=None): super(UsersModel, self).__init__(parent=parent) self.client = Client(token) self.INTERNAL_USER_DATA = common.DataDict() self.modelDataResetRequested.connect(self.__initdata__)