def adjustContent(self, videoWindow, animate): if videoWindow.is_fullscreen: self.popInOutButton.setHidden_(YES) self.popInOutLabel.setHidden_(YES) image_path = resources.path('images/fullscreen_exit.png') self.fsButton.setImage_(NSImage.alloc().initWithContentsOfFile_(filename_to_unicode(image_path))) else: if app.playback_manager.detached_window is None: image_path = resources.path('images/popout.png') label = _('Pop Out') else: image_path = resources.path('images/popin.png') label = _('Pop In') self.popInOutButton.setImage_(NSImage.alloc().initWithContentsOfFile_(filename_to_unicode(image_path))) self.popInOutButton.setHidden_(NO) self.popInOutLabel.setHidden_(NO) self.popInOutLabel.setStringValue_(label) image_path = resources.path('images/fullscreen_enter.png') self.fsButton.setImage_(NSImage.alloc().initWithContentsOfFile_(filename_to_unicode(image_path))) newFrame = self.window().frame() if videoWindow.is_fullscreen or app.playback_manager.detached_window is not None: self.titleLabel.setHidden_(NO) self.feedLabel.setHidden_(NO) newFrame.size.height = 198 else: self.titleLabel.setHidden_(YES) self.feedLabel.setHidden_(YES) newFrame.size.height = 144 newFrame.origin.x = self.getHorizontalPosition(videoWindow, newFrame.size.width) self.window().setFrame_display_animate_(newFrame, YES, animate) self.playbackControls.setNeedsDisplay_(YES)
def adjustContent(self, videoWindow, animate): if videoWindow.is_fullscreen: self.popInOutButton.setHidden_(YES) self.popInOutLabel.setHidden_(YES) image_path = resources.path("images/fullscreen_exit.png") self.fsButton.setImage_(NSImage.alloc().initWithContentsOfFile_(filename_to_unicode(image_path))) else: if app.playback_manager.detached_window is None: image_path = resources.path("images/popout.png") label = _("Pop Out") else: image_path = resources.path("images/popin.png") label = _("Pop In") self.popInOutButton.setImage_(NSImage.alloc().initWithContentsOfFile_(filename_to_unicode(image_path))) self.popInOutButton.setHidden_(NO) self.popInOutLabel.setHidden_(NO) self.popInOutLabel.setStringValue_(label) image_path = resources.path("images/fullscreen_enter.png") self.fsButton.setImage_(NSImage.alloc().initWithContentsOfFile_(filename_to_unicode(image_path))) newFrame = self.window().frame() if videoWindow.is_fullscreen or app.playback_manager.detached_window is not None: self.titleLabel.setHidden_(NO) self.feedLabel.setHidden_(NO) newFrame.size.height = 198 else: self.titleLabel.setHidden_(YES) self.feedLabel.setHidden_(YES) newFrame.size.height = 144 newFrame.origin.x = self.getHorizontalPosition(videoWindow, newFrame.size.width) self.window().setFrame_display_animate_(newFrame, YES, animate) self.playbackControls.setNeedsDisplay_(YES)
def _makeSearchIcon(engine): popupRectangle = NSImage.imageNamed_(u'search_popup_triangle') popupRectangleSize = popupRectangle.size() engineIconPath = resources.path('images/search_icon_%s.png' % engine.name) if not os.path.exists(engineIconPath): return nil engineIcon = NSImage.alloc().initByReferencingFile_( filename_to_unicode(engineIconPath)) engineIconSize = engineIcon.size() searchIconSize = (engineIconSize.width + popupRectangleSize.width + 2, engineIconSize.height) searchIcon = NSImage.alloc().initWithSize_(searchIconSize) searchIcon.lockFocus() try: engineIcon.drawAtPoint_fromRect_operation_fraction_( (0,0), NSZeroRect, NSCompositeSourceOver, 1.0) popupRectangleX = engineIconSize.width + 2 popupRectangleY = (engineIconSize.height - popupRectangleSize.height) / 2 popupRectangle.drawAtPoint_fromRect_operation_fraction_( (popupRectangleX, popupRectangleY), NSZeroRect, NSCompositeSourceOver, 1.0) finally: searchIcon.unlockFocus() return searchIcon
def handle_watched_folder_list(self, info_list): """Handle the WatchedFolderList message.""" for info in info_list: iter = self.model.append(info.id, filename_to_unicode(info.path), info.visible) self._iter_map[info.id] = iter self.emit('changed')
def item_matches(item, search_text): """Test if a single ItemInfo matches a search :param item: Item to test :param search_text: search_text to search with :returns: True if the item matches the search string """ parsed_search = _get_boolean_search(search_text) match_against = [item.title, item.description, item.entry_description] match_against.append(item.artist) match_against.append(item.album) match_against.append(item.genre) match_against.append(item.get_source_for_search()) if item.filename: filename = os.path.basename(item.filename) match_against.append(filename_to_unicode(filename)) match_against_text = " ".join(term.lower() for term in match_against if term is not None) for term in parsed_search.positive_terms: if term not in match_against_text: return False for term in parsed_search.negative_terms: if term in match_against_text: return False return True
def add_device_item(self, file_type, path, old_item, metadata_manager): """Insert a device_item row for an old item.""" values = [] # copy data from old_item so that we don't modify it old_data = dict(old_item) if path in self.paths_in_metadata_table: # This item comes from a 5.x database, so there's data in the # metadata tables for it. metadata_dict = metadata_manager.get_metadata(path) for key, value in metadata_dict.items(): old_data[key] = value for name, field in schema.DeviceItemSchema.fields: # get value from the old item if name == 'id': value = self.id_counter.next() elif name == 'filename': value = filename_to_unicode(path) elif name == 'file_type': value = file_type elif name == 'net_lookup_enabled': value = False else: value = old_data.get(name) # convert value if value is not None: if isinstance(field, schema.SchemaDateTime): value = datetime.datetime.fromtimestamp(value) values.append(value) self.cursor.execute(self.device_item_insert_sql, values)
def _makeSearchIcon(engine): popupRectangle = NSImage.imageNamed_(u'search_popup_triangle') popupRectangleSize = popupRectangle.size() engineIconPath = resources.path('images/search_icon_%s.png' % engine.name) if not os.path.exists(engineIconPath): return nil engineIcon = NSImage.alloc().initByReferencingFile_( filename_to_unicode(engineIconPath)) engineIconSize = engineIcon.size() searchIconSize = (engineIconSize.width + popupRectangleSize.width + 2, engineIconSize.height) searchIcon = NSImage.alloc().initWithSize_(searchIconSize) searchIcon.lockFocus() try: engineIcon.drawAtPoint_fromRect_operation_fraction_( (0, 0), NSZeroRect, NSCompositeSourceOver, 1.0) popupRectangleX = engineIconSize.width + 2 popupRectangleY = (engineIconSize.height - popupRectangleSize.height) / 2 popupRectangle.drawAtPoint_fromRect_operation_fraction_( (popupRectangleX, popupRectangleY), NSZeroRect, NSCompositeSourceOver, 1.0) finally: searchIcon.unlockFocus() return searchIcon
def item_matches(item, search_text): """Test if a single ItemInfo matches a search :param item: Item to test :param search_text: search_text to search with :returns: True if the item matches the search string """ parsed_search = _get_boolean_search(search_text) match_against = [item.title, item.description] match_against.append(item.artist) match_against.append(item.album) match_against.append(item.genre) match_against.append(item.get_source_for_search()) if item.filename: filename = os.path.basename(item.filename) match_against.append(filename_to_unicode(filename)) match_against_text = (' '.join(term.lower() for term in match_against if term is not None)) for term in parsed_search.positive_terms: if term not in match_against_text: return False for term in parsed_search.negative_terms: if term in match_against_text: return False return True
def awakeFromNib(self): image_path = resources.path('images/subtitles_down.png') self.subtitlesButton.setImage_(NSImage.alloc().initWithContentsOfFile_(filename_to_unicode(image_path))) self.subtitlesLabel.setTitleWithMnemonic_(_("Subtitles")) self.fsLabel.setTitleWithMnemonic_(_("Fullscreen")) self.shareButton.setImage_(getOverlayButtonImage(self.shareButton.bounds().size)) self.shareButton.setAlternateImage_(getOverlayButtonAlternateImage(self.shareButton.bounds().size)) self.shareButton.setTitle_(_("Share")) self.keepButton.setImage_(getOverlayButtonImage(self.keepButton.bounds().size)) self.keepButton.setAlternateImage_(getOverlayButtonAlternateImage(self.keepButton.bounds().size)) self.keepButton.setTitle_(_("Keep")) self.deleteButton.setImage_(getOverlayButtonImage(self.deleteButton.bounds().size)) self.deleteButton.setAlternateImage_(getOverlayButtonAlternateImage(self.deleteButton.bounds().size)) self.deleteButton.setTitle_(_("Delete")) self.seekForwardButton.setCell_(SkipSeekButtonCell.cellFromButtonCell_direction_delay_(self.seekForwardButton.cell(), 1, 0.0)) self.seekForwardButton.cell().setAllowsSkipping(False) self.seekBackwardButton.setCell_(SkipSeekButtonCell.cellFromButtonCell_direction_delay_(self.seekBackwardButton.cell(), -1, 0.0)) self.seekBackwardButton.cell().setAllowsSkipping(False) self.progressSlider.cursor = NSImage.imageNamed_(u'fs-progress-slider') self.progressSlider.sliderWasClicked = self.progressSliderWasClicked self.progressSlider.sliderWasDragged = self.progressSliderWasDragged self.progressSlider.sliderWasReleased = self.progressSliderWasReleased self.progressSlider.setShowCursor_(True) self.volumeSlider.cursor = NSImage.imageNamed_(u'fs-volume-slider') self.volumeSlider.sliderWasClicked = self.volumeSliderWasClicked self.volumeSlider.sliderWasDragged = self.volumeSliderWasDragged self.volumeSlider.sliderWasReleased = self.volumeSliderWasReleased self.volumeSlider.setShowCursor_(True)
def _convert_status_to_sql(self, status_dict): to_save = status_dict.copy() filename_fields = schema.SchemaStatusContainer.filename_fields for key in filename_fields: value = to_save.get(key) if value is not None: to_save[key] = filename_to_unicode(value) return repr(to_save)
def _item_exists_for_path(path): # in SQLite, LIKE is case insensitive, so we can use it to only look at # filenames that possibly will match for item_ in item.Item.make_view('filename LIKE ?', (filename_to_unicode(path),)): if samefile(item_.filename, path): return item_ return False
def __init__(self, path): Widget.__init__(self) self.nsimage = NSImage.alloc().initByReferencingFile_( filename_to_unicode(path)) self.view = MiroImageView.alloc().init() self.view.setImage_(self.nsimage) # enabled when viewWillMoveToWindow:aWindow invoked self.view.setAnimates_(NO)
def init(self): self = super(MiroSearchTextField, self).init() imagepath = filename_to_unicode( resources.path('images/search_icon_all.png')) image = NSImage.alloc().initByReferencingFile_(imagepath) self.cell().searchButtonCell().setImage_(image) self.cell().searchButtonCell().setAlternateImage_(image) return self
def item_matches_search(item_info, search_text): """Check if an item matches search text.""" if search_text == '': return True match_against = [item_info.name, item_info.description] if item_info.video_path is not None: match_against.append(filename_to_unicode(item_info.video_path)) return search.match(search_text, match_against)
def to_dict(self): data = {} for k, v in self.__dict__.items(): if v is not None and k not in (u'device', u'file_type', u'id', u'video_path', u'_deferred_update'): if ((k == u'screenshot' or k == u'cover_art')): v = filename_to_unicode(v) data[k] = v return data
def handle_change_clicked(widget): dir_ = dialogs.ask_for_directory( _("Choose directory to search for media files"), initial_directory=_get_user_media_directory(), transient_for=self) if dir_: search_entry.set_text(filename_to_unicode(dir_)) self.search_directory = dir_ else: self.search_directory = _get_user_media_directory()
def handle_watched_folders_changed(self, added, changed, removed): """Handle the WatchedFoldersChanged message.""" self.handle_watched_folder_list(added) for info in changed: iter = self._iter_map[info.id] self.model.update_value(iter, 1, filename_to_unicode(info.path)) self.model.update_value(iter, 2, info.visible) for id in removed: iter = self._iter_map.pop(id) self.model.remove(iter) self.emit('changed')
def handle_change_clicked(widget): dir_ = dialogs.ask_for_directory( _("Choose directory to search for media files"), initial_directory=get_default_search_dir(), transient_for=self) if dir_: search_entry.set_text(filename_to_unicode(dir_)) self.search_directory = dir_ else: self.search_directory = get_default_search_dir() # reset the search results if they change the directory self.gathered_media_files = None
def _calc_search_text(item_info): match_against = [ item_info.name, item_info.description ] match_against.append(item_info.artist) match_against.append(item_info.album) match_against.append(item_info.genre) if item_info.feed_name is not None: match_against.append(item_info.feed_name) if item_info.download_info and item_info.download_info.torrent: match_against.append(u'torrent') if item_info.video_path: filename = os.path.basename(item_info.video_path) match_against.append(filename_to_unicode(filename)) return (' '.join(match_against)).lower()
def test_goodfile(self): # Our file templates. Try a vanilla version and one with escapes, # and a path for Windows. path1 = "/Users/xxx/Music/iTunes/iTunes%20Music/" path2 = ("/Volumes/%E3%83%9B%E3%83%BC%E3%83%A0/" "xxx/Music/iTunes/iTunes%20Media/") path3 = ("C:/Documents%20and%20Settings/Paul/" "My%20Documents/My%20Music/iTunes/iTunes%20Media/") file_snippet1 = file_template % dict(path=(self.file_url + path1)) file_snippet2 = file_template % dict(path=(self.file_url + path2)) file_snippet3 = file_template % dict(path=(self.file_url + path3)) tmpf_dir = os.path.dirname(self.tmpf_path) # Test vanilla path self._clean_tmpf() self.tmpf.write(file_snippet1) self.tmpf.flush() path = import_itunes_path(tmpf_dir) self.assertEquals(type(path), unicode) self.assertEquals(path, filename_to_unicode( urllib.url2pathname(path1))) # Test path with utf-8 escapes self._clean_tmpf() self.tmpf.write(file_snippet2) self.tmpf.flush() path = import_itunes_path(tmpf_dir) self.assertEquals(type(path), unicode) self.assertEquals(path, filename_to_unicode( urllib.url2pathname(path2))) # Test Windows path self._clean_tmpf() self.tmpf.write(file_snippet3) self.tmpf.flush() path = import_itunes_path(tmpf_dir) self.assertEquals(type(path), unicode) self.assertEquals(path, filename_to_unicode( urllib.url2pathname(path3)))
def _getEngineIcon(engine): engineIconPath = resources.path('images/search_icon_%s.png' % engine.name) if app.config.get(prefs.THEME_NAME) and engine.filename: if engine.filename.startswith(resources.theme_path( app.config.get(prefs.THEME_NAME), 'searchengines')): # this search engine came from a theme; look up the icon in the # theme directory instead engineIconPath = resources.theme_path( app.config.get(prefs.THEME_NAME), 'images/search_icon_%s.png' % engine.name) if not os.path.exists(engineIconPath): return nil return NSImage.alloc().initByReferencingFile_( filename_to_unicode(engineIconPath))
def run_dialog(self): """ Returns (directory, show-in-sidebar) or None """ try: extra = widgetset.VBox(spacing=10) if self.previous_error: extra.pack_start(widgetset.Label(self.previous_error)) self.folder_entry = widgetset.TextEntry() self.folder_entry.set_activates_default(True) self.folder_entry.set_text(filename_to_unicode(self.path)) self.folder_entry.set_size_request(300, -1) choose_button = widgetset.Button(_("Choose...")) choose_button.connect('clicked', self.handle_choose) h = widgetset.HBox(spacing=5) h.pack_start(widgetutil.align_middle( widgetset.Label(_("Directory:")))) h.pack_start(widgetutil.align_middle(self.folder_entry)) h.pack_start(widgetutil.align_middle(choose_button)) extra.pack_start(h) self.visible_checkbox = widgetset.Checkbox( _("Show in my sidebar as a podcast")) self.visible_checkbox.set_checked(True) extra.pack_start(self.visible_checkbox) self.vbox = extra self.set_extra_widget(extra) self.add_button(BUTTON_ADD_FOLDER.text) self.add_button(BUTTON_CANCEL.text) ret = self.run() if ret == 0: # 17407 band-aid - don't init with PlatformFilenameType since # str use ascii codec dir = self.folder_entry.get_text() if PlatformFilenameType == str: dir = dir.encode('utf-8') return (dir, self.visible_checkbox.get_checked()) return None except StandardError: logging.exception("newwatchedfolder threw exception.")
def run_dialog(self): """ Returns (directory, show-in-sidebar) or None """ try: extra = widgetset.VBox(spacing=10) if self.previous_error: extra.pack_start(widgetset.Label(self.previous_error)) self.folder_entry = widgetset.TextEntry() self.folder_entry.set_activates_default(True) self.folder_entry.set_text(filename_to_unicode(self.path)) self.folder_entry.set_size_request(300, -1) choose_button = widgetset.Button(_("Choose...")) choose_button.connect('clicked', self.handle_choose) h = widgetset.HBox(spacing=5) h.pack_start( widgetutil.align_middle(widgetset.Label(_("Directory:")))) h.pack_start(widgetutil.align_middle(self.folder_entry)) h.pack_start(widgetutil.align_middle(choose_button)) extra.pack_start(h) self.visible_checkbox = widgetset.Checkbox( _("Show in my sidebar as a podcast")) self.visible_checkbox.set_checked(True) extra.pack_start(self.visible_checkbox) self.vbox = extra self.set_extra_widget(extra) self.add_button(BUTTON_ADD_FOLDER.text) self.add_button(BUTTON_CANCEL.text) ret = self.run() if ret == 0: # 17407 band-aid - don't init with PlatformFilenameType since # str use ascii codec dir = self.folder_entry.get_text() if PlatformFilenameType == str: dir = dir.encode('utf-8') return (dir, self.visible_checkbox.get_checked()) return None except StandardError: logging.exception("newwatchedfolder threw exception.")
def _getEngineIcon(engine): engineIconPath = resources.path('images/search_icon_%s.png' % engine.name) if app.config.get(prefs.THEME_NAME) and engine.filename: if engine.filename.startswith( resources.theme_path(app.config.get(prefs.THEME_NAME), 'searchengines')): # this search engine came from a theme; look up the icon in the # theme directory instead engineIconPath = resources.theme_path( app.config.get(prefs.THEME_NAME), 'images/search_icon_%s.png' % engine.name) if not os.path.exists(engineIconPath): return nil return NSImage.alloc().initByReferencingFile_( filename_to_unicode(engineIconPath))
def _calc_search_text(item_info): match_against = [item_info.name, item_info.description] if item_info.artist is not None: match_against.append(item_info.artist) if item_info.album is not None: match_against.append(item_info.album) if item_info.genre is not None: match_against.append(item_info.genre) if item_info.feed_name is not None: match_against.append(item_info.feed_name) if item_info.download_info and item_info.download_info.torrent: match_against.append(u'torrent') if item_info.video_path: filename = os.path.basename(item_info.video_path) match_against.append(filename_to_unicode(filename)) return (' '.join(match_against)).lower()
def check_movies_gone(check_unmounted=True): """Checks to see if the movies directory is gone. """ movies_dir = fileutil.expand_filename( app.config.get(prefs.MOVIES_DIRECTORY)) movies_dir = filename_to_unicode(movies_dir) # if the directory doesn't exist, create it. if (not os.path.exists(movies_dir) and should_create_movies_directory(movies_dir)): try: fileutil.makedirs(movies_dir) except OSError: logging.info( "Movies directory can't be created -- calling handler") # FIXME - this isn't technically correct, but it's probably # close enough that a user can fix the issue and Miro can # run happily. msg = _( "Permissions error: %(appname)s couldn't " "create the folder.", {"appname": app.config.get(prefs.SHORT_APP_NAME)}) _movies_directory_gone_handler(msg, movies_dir) return # make sure the directory is writeable if not os.access(movies_dir, os.W_OK): logging.info("Can't write to movies directory -- calling handler") msg = _("Permissions error: %(appname)s can't " "write to the folder.", {"appname": app.config.get(prefs.SHORT_APP_NAME)}) _movies_directory_gone_handler(msg, movies_dir) return # make sure that the directory is populated if we've downloaded stuff to # it if check_unmounted and check_movies_directory_unmounted(): logging.info("Movies directory is gone -- calling handler.") msg = _("The folder contains no files: " "is it on a drive that's disconnected?") _movies_directory_gone_handler(msg, movies_dir, allow_continue=True) return eventloop.add_urgent_call(finish_backend_startup, "reconnect downloaders")
def export_content(self, pathname, feeds, sites): """Given a pathname (which is just written into the opml), a list of feeds, and a list of sites (formerly know as channel guides), generates the OPML and returns it as a utf-8 encoded string. """ self.io = StringIO() self.current_folder = None now = datetime.now() self.io.write(u'<?xml version="1.0" encoding="utf-8" ?>\n') self.io.write(u'<!-- OPML generated by Miro v%s on %s -->\n' % (app.config.get(prefs.APP_VERSION), now.ctime())) self.io.write(u'<opml version="2.0"\n') self.io.write( u' xmlns:miro="http://getmiro.com/opml/subscriptions">\n') self.io.write(u'<head>\n') self.io.write(u'\t<title>%s</title>\n' % (filename_to_unicode(os.path.basename(pathname)))) self.io.write(u'\t<dateCreated>%s</dateCreated>\n' % now.ctime()) self.io.write(u'\t<docs>http://www.opml.org/spec2</docs>\n') self.io.write(u'</head>\n') self.io.write(u'<body>\n') for obj in feeds: if isinstance(obj, folder.ChannelFolder): self._open_folder_entry(obj) elif isinstance(obj, feed.Feed): self._write_feed_entry(obj) if self.current_folder is not None: self._close_folder_entry() for obj in sites: self._write_site_entry(obj) self.io.write(u'</body>\n') self.io.write(u'</opml>\n') try: outstring = self.io.getvalue().encode("utf-8") except UnicodeError: logging.exception("Could not encode unicode to utf-8.") return u"" return outstring
def check_movies_gone(self, check_unmounted=True): """Checks to see if the movies directory is gone. """ movies_dir = fileutil.expand_filename(app.config.get( prefs.MOVIES_DIRECTORY)) movies_dir = filename_to_unicode(movies_dir) # if the directory doesn't exist, create it. if (not os.path.exists(movies_dir) and should_create_movies_directory(movies_dir)): try: fileutil.makedirs(movies_dir) except OSError: logging.info("Movies directory can't be created -- calling handler") # FIXME - this isn't technically correct, but it's probably # close enough that a user can fix the issue and Miro can # run happily. msg = _("Permissions error: %(appname)s couldn't " "create the folder.", {"appname": app.config.get(prefs.SHORT_APP_NAME)}) self.movies_directory_gone_handler(msg, movies_dir) return # make sure the directory is writeable if not os.access(movies_dir, os.W_OK): logging.info("Can't write to movies directory -- calling handler") msg = _("Permissions error: %(appname)s can't " "write to the folder.", {"appname": app.config.get(prefs.SHORT_APP_NAME)}) self.movies_directory_gone_handler(msg, movies_dir) return # make sure that the directory is populated if we've downloaded stuff to # it if check_unmounted and check_movies_directory_unmounted(): logging.info("Movies directory is gone -- calling handler.") msg = _("The folder contains no files: " "is it on a drive that's disconnected?") self.movies_directory_gone_handler(msg, movies_dir, allow_continue=True) return self.all_checks_done()
def export_content(self, pathname, media_tabs, site_tabs): """Given a pathname (which is just written into the opml), a list of media_tabs, and a list of site_tabs, generates the OPML and returns it as a utf-8 encoded string. """ self.io = StringIO() self.current_folder = None now = datetime.now() self.io.write(u'<?xml version="1.0" encoding="utf-8" ?>\n') self.io.write(u'<!-- OPML generated by Miro v%s on %s -->\n' % ( app.config.get(prefs.APP_VERSION), now.ctime())) self.io.write(u'<opml version="2.0"\n') self.io.write(u' xmlns:miro="http://getmiro.com/opml/subscriptions">\n') self.io.write(u'<head>\n') self.io.write(u'\t<title>%s</title>\n' % ( filename_to_unicode(os.path.basename(pathname)))) self.io.write(u'\t<dateCreated>%s</dateCreated>\n' % now.ctime()) self.io.write(u'\t<docs>http://www.opml.org/spec2</docs>\n') self.io.write(u'</head>\n') self.io.write(u'<body>\n') for obj in media_tabs: if isinstance(obj, folder.ChannelFolder): self._open_folder_entry(obj) elif isinstance(obj, feed.Feed): self._write_feed_entry(obj) if self.current_folder is not None: self._close_folder_entry() for obj in site_tabs: self._write_site_entry(obj) self.io.write(u'</body>\n') self.io.write(u'</opml>\n') try: outstring = self.io.getvalue().encode("utf-8") except UnicodeError: logging.exception("Could not encode unicode to utf-8.") return u"" return outstring
def search(self, search_text): """Search through the index items. :param search_text: search_text to search with :returns: set of ids that match the search """ parsed_search = _get_boolean_search(search_text) # filter out terms smaller than the smallest N-gram we index. positive_terms = [ t for t in parsed_search.positive_terms if len(t) >= NGRAM_MIN ] negative_terms = [ t for t in parsed_search.negative_terms if len(t) >= NGRAM_MIN ] if positive_terms: first_term = positive_terms[0] matching_ids = self._term_search(first_term) for term in positive_terms[1:]: matching_ids.intersection_update(self._term_search(term)) else: matching_ids = set(self._item_ngrams.keys()) for term in negative_terms: matching_ids.difference_update(self._term_search(term)) return matching_ids match_against = [item_info.name, item_info.description] if item_info.artist is not None: match_against.append(item_info.artist) if item_info.album is not None: match_against.append(item_info.album) if item_info.genre is not None: match_against.append(item_info.genre) if item_info.feed_name is not None: match_against.append(item_info.feed_name) if item_info.download_info and item_info.download_info.torrent: match_against.append(u'torrent') if item_info.video_path: filename = os.path.basename(item_info.video_path) match_against.append(filename_to_unicode(filename)) return (' '.join(match_against)).lower()
def _on_button_clicked(self, button): d = dialogs.ask_for_directory(_("Choose Movies Directory"), initial_directory=app.config.get(prefs.MOVIES_DIRECTORY), transient_for=_pref_window) if d is not None: try: if not os.path.exists(d): os.makedirs(d) if not os.access(d, os.W_OK): raise IOError # Pretend we got an IOError. except (OSError, IOError): dialogs.show_message(_("Directory not valid"), _("Directory '%s' could not be created. " + "Please choose a directory you have " + "write access to."), dialogs.WARNING_MESSAGE) return logging.info("Created directory. It's valid.") self.path = d self.label.set_text(filename_to_unicode(d))
def scan_device_for_files(device): known_files = clean_database(device) device.database.set_bulk_mode(True) device.database.setdefault('sync', {}) for filename in fileutil.miro_allfiles(device.mount): short_filename = filename[len(device.mount):] ufilename = filename_to_unicode(short_filename) if os.path.normcase(ufilename) in known_files: continue if filetypes.is_video_filename(ufilename): item_type = 'video' elif filetypes.is_audio_filename(ufilename): item_type = 'audio' else: continue device.database[item_type][ufilename] = {} device.database.set_bulk_mode(False)
def _execute_insert_sql(cursor, savable): table_name = savable.classString.replace("-", "_") column_names = [] values = [] schema = _class_to_schema[savable.classString] for name, schema_item in schema.fields: value = savable.savedData[name] column_names.append(name) if value is not None: if isinstance(schema_item, schema_mod.SchemaBinary): value = sqlite3.Binary(value) elif isinstance(schema_item, schema_mod.SchemaTimeDelta): value = repr(value) elif isinstance(schema_item, schema_mod.SchemaFilename): value = filename_to_unicode(value) values.append(value) sql = ("REPLACE INTO %s (%s) VALUES(%s)" % (table_name, ', '.join(column_names), ', '.join('?' for i in xrange(len(column_names))))) cursor.execute(sql, values)
def _execute_insert_sql(cursor, savable): table_name = savable.classString.replace("-", "_") column_names = [] values = [] schema = _class_to_schema[savable.classString] for name, schema_item in schema.fields: value = savable.savedData[name] column_names.append(name) if value is not None: if isinstance(schema_item, schema_mod.SchemaBinary): value = sqlite3.Binary(value) elif isinstance(schema_item, schema_mod.SchemaTimeDelta): value = repr(value) elif isinstance(schema_item, schema_mod.SchemaFilename): value = filename_to_unicode(value) values.append(value) sql = ("REPLACE INTO %s (%s) VALUES(%s)" % (table_name, ', '.join(column_names), ', '.join( '?' for i in xrange(len(column_names))))) cursor.execute(sql, values)
def search(self, search_text): """Search through the index items. :param search_text: search_text to search with :returns: set of ids that match the search """ parsed_search = _get_boolean_search(search_text) # filter out terms smaller than the smallest N-gram we index. positive_terms = [t for t in parsed_search.positive_terms if len(t) >= NGRAM_MIN] negative_terms = [t for t in parsed_search.negative_terms if len(t) >= NGRAM_MIN] if positive_terms: first_term = positive_terms[0] matching_ids = self._term_search(first_term) for term in positive_terms[1:]: matching_ids.intersection_update(self._term_search(term)) else: matching_ids = set(self._item_ngrams.keys()) for term in negative_terms: matching_ids.difference_update(self._term_search(term)) return matching_ids match_against = [item_info.name, item_info.description] if item_info.artist is not None: match_against.append(item_info.artist) if item_info.album is not None: match_against.append(item_info.album) if item_info.genre is not None: match_against.append(item_info.genre) if item_info.feed_name is not None: match_against.append(item_info.feed_name) if item_info.download_info and item_info.download_info.torrent: match_against.append(u'torrent') if item_info.video_path: filename = os.path.basename(item_info.video_path) match_against.append(filename_to_unicode(filename)) return (' '.join(match_against)).lower()
def set_filename(self, s): self._filename = filename_to_unicode(s)
def build_find_files_page(self): vbox = widgetset.VBox(spacing=5) vbox.pack_start( _build_paragraph_text( _( "%(name)s can find music and video on your computer " "and show them in your %(name)s library. No files " "will be copied or duplicated.", {"name": app.config.get(prefs.SHORT_APP_NAME)}))) vbox.pack_start( _build_title_question( _( "Would you like %(name)s to search your computer " "for media files?", {"name": app.config.get(prefs.SHORT_APP_NAME)}))) rbg = widgetset.RadioButtonGroup() no_rb = widgetset.RadioButton(_("No"), rbg) yes_rb = widgetset.RadioButton(_("Yes"), rbg) no_rb.set_selected() vbox.pack_start(widgetutil.align_left(no_rb, left_pad=10)) vbox.pack_start( widgetutil.align_left(yes_rb, left_pad=10, bottom_pad=5)) group_box = widgetset.VBox(spacing=5) rbg2 = widgetset.RadioButtonGroup() restrict_rb = widgetset.RadioButton(_("Search everywhere."), rbg2) search_rb = widgetset.RadioButton(_("Just search in this folder:"), rbg2) restrict_rb.set_selected() group_box.pack_start(widgetutil.align_left(restrict_rb, left_pad=30)) group_box.pack_start(widgetutil.align_left(search_rb, left_pad=30)) search_entry = widgetset.TextEntry( filename_to_unicode(get_default_search_dir())) search_entry.set_width(20) change_button = widgetset.Button(_("Choose...")) hbox = widgetutil.build_hbox((widgetutil.align_middle(search_entry), widgetutil.align_middle(change_button))) group_box.pack_start(widgetutil.align_left(hbox, left_pad=30)) def handle_change_clicked(widget): dir_ = dialogs.ask_for_directory( _("Choose directory to search for media files"), initial_directory=get_default_search_dir(), transient_for=self) if dir_: search_entry.set_text(filename_to_unicode(dir_)) self.search_directory = dir_ else: self.search_directory = get_default_search_dir() # reset the search results if they change the directory self.gathered_media_files = None change_button.connect('clicked', handle_change_clicked) vbox.pack_start(group_box) prev_button = widgetset.Button(_("< Previous")) prev_button.connect('clicked', lambda x: self.prev_page()) def handle_search_finish_clicked(widget): if widget.mode == "search": if rbg2.get_selected() == restrict_rb: self.search_directory = get_default_search_dir() self.next_page() else: self.destroy() search_button = widgetset.Button(_("Search")) search_button.connect('clicked', handle_search_finish_clicked) # FIXME - this is goofy naming search_button.text_faces = {"search": _("Next >"), "next": _("Finish")} search_button.mode = "search" def switch_mode(mode): search_button.set_text(search_button.text_faces[mode]) search_button.mode = mode vbox.pack_start(self._force_space_label()) vbox.pack_start(widgetutil.align_bottom( widgetutil.align_right( widgetutil.build_hbox((prev_button, search_button)))), expand=True) def handle_radio_button_clicked(widget): # Uggh this is a bit messy. if widget is no_rb: group_box.disable() search_entry.disable() change_button.disable() switch_mode("next") self.gathered_media_files = None elif widget is yes_rb: group_box.enable() if rbg2.get_selected() is restrict_rb: search_entry.disable() change_button.disable() else: search_entry.enable() change_button.enable() switch_mode("search") elif widget is restrict_rb: search_entry.disable() change_button.disable() self.gathered_media_files = None elif widget is search_rb: search_entry.enable() change_button.enable() self.gathered_media_files = None if widget is restrict_rb or widget is search_rb: switch_mode("search") no_rb.connect('clicked', handle_radio_button_clicked) yes_rb.connect('clicked', handle_radio_button_clicked) restrict_rb.connect('clicked', handle_radio_button_clicked) search_rb.connect('clicked', handle_radio_button_clicked) handle_radio_button_clicked(restrict_rb) handle_radio_button_clicked(no_rb) vbox = widgetutil.pad(vbox) return vbox
def parse_command_line_args(args): """ This goes through a list of files which could be arguments passed in on the command line or a list of files from other source. """ if not _started_up: _command_line_args.extend(args) return for i in xrange(len(args)): if args[i].startswith('file://'): args[i] = args[i][len('file://'):] reset_command_line_view() added_videos = False added_downloads = False for arg in args: if arg.startswith('file://'): arg = download_utils.get_file_url_path(arg) elif arg.startswith('miro:'): add_subscription_url('miro:', 'application/x-miro', arg) elif arg.startswith('democracy:'): add_subscription_url('democracy:', 'application/x-democracy', arg) elif (arg.startswith('http:') or arg.startswith('https:') or arg.startswith('feed:') or arg.startswith('feeds:') or is_magnet_uri(arg)): singleclick.add_download(filename_to_unicode(arg)) elif os.path.exists(arg): ext = os.path.splitext(arg)[1].lower() if ext in ('.torrent', '.tor'): try: torrent_infohash = get_torrent_info_hash(arg) except ValueError: title = _("Invalid Torrent") msg = _( "The torrent file %(filename)s appears to be corrupt " "and cannot be opened.", {"filename": os.path.basename(arg)} ) dialogs.MessageBoxDialog(title, msg).run() continue except (IOError, OSError): title = _("File Error") msg = _( "The torrent file %(filename)s could not be opened. " "Please ensure it exists and you have permission to " "access this file.", {"filename": os.path.basename(arg)} ) dialogs.MessageBoxDialog(title, msg).run() continue add_torrent(arg, torrent_infohash) added_downloads = True elif ext in ('.rss', '.rdf', '.atom', '.ato'): feed.add_feed_from_file(arg) elif ext in ('.miro', '.democracy', '.dem', '.opml'): opml.Importer().import_subscriptions(arg, show_summary=False) else: add_video(arg) added_videos = True else: logging.warning("parse_command_line_args: %s doesn't exist", arg) # if the user has Miro set up to play all videos externally, then # we don't want to play videos added by the command line. # # this fixes bug 12362 where if the user has his/her system set up # to use Miro to play videos and Miro goes to play a video # externally, then it causes an infinite loop and dies. if added_videos and app.config.get(prefs.PLAY_IN_MIRO): item_infos = [itemsource.DatabaseItemSource._item_info_for(i) for i in _command_line_videos] messages.PlayMovie(item_infos).send_to_frontend() if added_downloads: # FIXME - switch to downloads tab? pass
def set_directory(self, d): self._directory = filename_to_unicode(d)
def _filename_to_sql(self, value, schema_item): return filename_to_unicode(value)
def __init__(self, path): self._set_image(NSImage.alloc().initByReferencingFile_( filename_to_unicode(path)))
def __init__(self, **kwargs): self.__initialized = False for required in ('video_path', 'file_type', 'device'): if required not in kwargs: raise TypeError('DeviceItem must be given a "%s" argument' % required) self.file_format = self.size = None self.release_date = self.feed_name = self.feed_id = None self.keep = True self.isContainerItem = False self.url = self.payment_link = None self.comments_link = self.permalink = self.file_url = None self.license = self.downloader = None self.duration = self.screenshot = self.thumbnail_url = None self.resumeTime = 0 self.subtitle_encoding = self.enclosure_type = None self.file_type = None self.creation_time = None self.is_playing = False metadata.Store.setup_new(self) self.__dict__.update(kwargs) if isinstance(self.video_path, unicode): # make sure video path is a filename and ID is Unicode self.id = self.video_path self.video_path = utf8_to_filename(self.video_path.encode('utf8')) else: self.id = filename_to_unicode(self.video_path) if isinstance(self.screenshot, unicode): self.screenshot = utf8_to_filename(self.screenshot.encode('utf8')) if isinstance(self.cover_art, unicode): self.cover_art = utf8_to_filename(self.cover_art.encode('utf8')) if self.file_format is None: self.file_format = filename_to_unicode( os.path.splitext(self.video_path)[1]) if self.file_type == 'audio': self.file_format = self.file_format + ' audio' try: # filesystem operations if self.size is None: self.size = os.path.getsize(self.get_filename()) if self.release_date is None or self.creation_time is None: ctime = fileutil.getctime(self.get_filename()) if self.release_date is None: self.release_date = ctime if self.creation_time is None: self.creation_time = ctime if not self.metadata_version: # haven't run read_metadata yet. We don't check the actual # version because upgrading metadata isn't supported. self.read_metadata() if not self.get_title(): self.title = filename_to_unicode( os.path.basename(self.video_path)) except (OSError, IOError): # if there was an error reading the data from the filesystem, don't # bother continuing with other FS operations or starting moviedata logging.debug('error reading %s', self.id, exc_info=True) else: if self.mdp_state is None: # haven't run MDP yet moviedata.movie_data_updater.request_update(self) self.__initialized = True
def set_initial_path(self): self.path = self.initial_path = app.config.get(prefs.MOVIES_DIRECTORY) self.label.set_text(filename_to_unicode(self.path))
def parse_command_line_args(args): """ This goes through a list of files which could be arguments passed in on the command line or a list of files from other source. """ if not _started_up: _command_line_args.extend(args) return for i in xrange(len(args)): if args[i].startswith('file://'): args[i] = args[i][len('file://'):] reset_command_line_view() added_videos = False added_downloads = False for arg in args: if arg.startswith('file://'): arg = download_utils.get_file_url_path(arg) elif arg.startswith('miro:'): add_subscription_url('miro:', 'application/x-miro', arg) elif arg.startswith('democracy:'): add_subscription_url('democracy:', 'application/x-democracy', arg) elif (arg.startswith('http:') or arg.startswith('https:') or arg.startswith('feed:') or arg.startswith('feeds:') or is_magnet_uri(arg)): singleclick.add_download(filename_to_unicode(arg)) elif os.path.exists(arg): ext = os.path.splitext(arg)[1].lower() if ext in ('.torrent', '.tor'): try: torrent_infohash = get_torrent_info_hash(arg) except ValueError: title = _("Invalid Torrent") msg = _( "The torrent file %(filename)s appears to be corrupt " "and cannot be opened.", {"filename": os.path.basename(arg)}) dialogs.MessageBoxDialog(title, msg).run() continue except (IOError, OSError): title = _("File Error") msg = _( "The torrent file %(filename)s could not be opened. " "Please ensure it exists and you have permission to " "access this file.", {"filename": os.path.basename(arg)}) dialogs.MessageBoxDialog(title, msg).run() continue add_torrent(arg, torrent_infohash) added_downloads = True elif ext in ('.rss', '.rdf', '.atom', '.ato'): feed.add_feed_from_file(arg) elif ext in ('.miro', '.democracy', '.dem', '.opml'): opml.Importer().import_subscriptions(arg, show_summary=False) else: add_video(arg) added_videos = True else: logging.warning("parse_command_line_args: %s doesn't exist", arg) # if the user has Miro set up to play all videos externally, then # we don't want to play videos added by the command line. # # this fixes bug 12362 where if the user has his/her system set up # to use Miro to play videos and Miro goes to play a video # externally, then it causes an infinite loop and dies. if added_videos and app.config.get(prefs.PLAY_IN_MIRO): item_ids = [i.id for i in _command_line_videos] item_infos = app.db.fetch_item_infos(item_ids) messages.PlayMovies(item_infos).send_to_frontend() if added_downloads: # FIXME - switch to downloads tab? pass
def scan_device_for_files(device): # XXX is this as_idle() safe? # prepare paths to add logging.debug('starting scan on %s', device.mount) known_files = clean_database(device) item_data = [] start = time.time() def _continue(): if not app.device_manager.running: # user quit, so we will too logging.debug('stopping scan on %s: user quit', device.mount) return False if not os.path.exists(device.mount): # device disappeared logging.debug('stopping scan on %s: disappeared', device.mount) return False if app.device_manager._is_hidden(device): # device no longer being # shown logging.debug('stopping scan on %s: hidden', device.mount) return False return True for filename in fileutil.miro_allfiles(device.mount): short_filename = filename[len(device.mount):] ufilename = filename_to_unicode(short_filename) item_type = None if os.path.normcase(short_filename) in known_files: continue if filetypes.is_video_filename(ufilename): item_type = u'video' elif filetypes.is_audio_filename(ufilename): item_type = u'audio' if item_type is not None: item_data.append((ufilename, item_type)) app.metadata_progress_updater.will_process_path(filename, device) if time.time() - start > 0.4: yield # let other stuff run if not _continue(): break start = time.time() if app.device_manager.running and os.path.exists(device.mount): # we don't re-check if the device is hidden because we still want to # save the items we found in that case yield # yield after prep work device.database.setdefault(u'sync', {}) logging.debug('scanned %s, found %i files (%i total)', device.mount, len(item_data), len(known_files) + len(item_data)) device.database.set_bulk_mode(True) start = time.time() for ufilename, item_type in item_data: i = DeviceItem(video_path=ufilename, file_type=item_type, device=device) device.database[item_type][ufilename] = i.to_dict() device.database.emit('item-added', i) if time.time() - start > 0.4: device.database.set_bulk_mode(False) # save the database yield # let other idle functions run if not _continue(): break device.database.set_bulk_mode(True) start = time.time() device.database.set_bulk_mode(False)