def set_user_count(normal, ops): """ sets the amount of users in the current channel. """ m_users = gettext.ngettext("%d User", "%d Users", normal) % (normal) m_ops = gettext.ngettext("%d Operator", "%d Operators", ops) % (ops) widgets.get_object("nick_stats_label").set_text("%(users)s – %(ops)s" % {"users": m_users, "ops": m_ops})
def __updateStatusbar(self): """ Update the status bar """ # Tracklist count = len(self.tracklist) if count == 0: self.status1.set_label('') else: self.status1.set_label(ngettext('One track in playlist [%(length)s]', '%(count)u tracks in playlist [%(length)s]', count) \ % {'count': count, 'length': tools.sec2str(self.playtime)}) # Selected tracks count = len(self.selTracks) if count == 0: self.status2.set_label('') else: selection = ngettext('One track selected', '%(count)u tracks selected', count) % {'count': count} audioType = self.selTracks[0].getType() for track in self.selTracks[1:]: if track.getType() != audioType: audioType = _('various') break bitrate = self.selTracks[0].getBitrate() for track in self.selTracks[1:]: if track.getBitrate() != bitrate: bitrate = _('various') break self.status2.set_label(_('%(selection)s (Type: %(type)s, Bitrate: %(bitrate)s)') % {'selection': selection, 'type': audioType, 'bitrate': bitrate})
def beautify_time_delta(seconds): """ Converts the given time in seconds to a human-readable estimate. This is intended for "Unsaved changes" and "Backup file found" dialogs. """ mins = seconds / 60 sec = int(seconds % 60) hours = mins / 60 mins = int(mins % 60) days = int(hours / 24) hours = int(hours % 24) parts = [] if days > 0: parts.append(ngettext("%d day", "%d days", days) % days) if hours > 0: parts.append(ngettext("%d hour", "%d hours", hours) % hours) if days == 0 and mins > 0: parts.append(ngettext("%d minute", "%d minutes", mins) % mins) if hours == 0 and mins < 2 and sec: parts.append(ngettext("%d second", "%d seconds", sec) % sec) return ", ".join(parts)
def secs_to_readable(self, seconds): '''Convert seconds to a more friendly format.''' if seconds >= 60: minutes = seconds / 60 return ngettext("%d minute", "%d minutes", minutes) % (minutes,) else: return ngettext("%d second", "%d seconds", seconds) % (seconds,)
def _sourcesStoppedImportingCb(self, unused_project): self.debug("Importing took %.3f seconds", time.time() - self.import_start_time) self._flushPendingRows() self._progressbar.hide() if self._errors: errors_amount = len(self._errors) btn_text = ngettext("View error", "View errors", errors_amount) # Translators: {0:d} is just like %d (integer number variable) text = ngettext("An error occurred while importing.", "{0:d} errors occurred while importing.", errors_amount) # Do the {0:d} (aka "%d") substitution using "format" instead of %, # avoiding tracebacks as %d would be missing in the singular form: text = text.format(errors_amount) self._view_error_button.set_label(btn_text) self._warning_label.set_text(text) self._import_warning_infobar.show_all() missing_thumbs = self._missing_thumbs self._missing_thumbs = [] if missing_thumbs: self.info("Generating missing thumbnails: %d", len(missing_thumbs)) self._thumbs_process = threading.Thread( target=MediaLibraryWidget._generateThumbnailsThread, args=(self, missing_thumbs)) self._thumbs_process.start() self._selectLastImportedUris()
def make_status_info(status_lines, toplevel): """Return a GtkLabel with a summary of changed/untracked files. Also, a tooltip reveals the project's toplevel path and all changed/ untracked files with their git status code. """ status_lines = status_lines.rstrip("\x00") tooltip_text = _("Toplevel path") + ":\n %s" % toplevel if not status_lines: status_info = _("Everything up-to-date.") else: status_array = status_lines.split("\x00") untracked = [status.lstrip("?? ") for status in status_array if status.startswith("?")] changed = [status for status in status_array if status.lstrip("?? ") not in untracked] num_untracked = len(untracked) num_changed = len(changed) status_info = "" if num_changed > 0: status_info = gettext.ngettext("%d change", "%d changes", num_changed) % num_changed tooltip_text += "\n\n" + _("Changes") + ":\n " + "\n ".join(changed) if num_untracked > 0: if num_changed: status_info += ", " status_info += gettext.ngettext("%d untracked", "%d untracked", num_untracked) % num_untracked tooltip_text += "\n\n" + _("Untracked") + ":\n " + "\n ".join(untracked) widget = Gtk.Label(status_info) widget.set_tooltip_text(tooltip_text) return widget
def get_info_markup(self, info = None): seasons = len(self.get_seasons()) if seasons: episodes_info = info or self.get_episodes_info() episodes_to_watch = episodes_info['episodes_to_watch'] next_episode = episodes_info['next_episode'] show_info = gettext.ngettext('%s season', '%s seasons', seasons) \ % seasons if self.is_completely_watched(): show_info += '<br/>' + _('Completely watched') if self.status and self.status == 'Ended': show_info += '<br/>' + _('Show has ended') else: if episodes_to_watch: n_episodes_to_watch = len(episodes_to_watch) show_info += '<br/>' + gettext.ngettext('%s episode not watched', '%s episodes not watched', n_episodes_to_watch) \ % n_episodes_to_watch else: show_info += '<br/>' + _('No episodes to watch') if next_episode: next_air_date = next_episode.air_date if next_air_date: show_info += '<br/>' + _('<i>Next:</i> %s, %s') % \ (next_episode.get_episode_show_number(), \ next_episode.get_air_date_text()) else: show_info += '<br/>' + _('<i>Next:</i> %s') % \ next_episode.get_episode_show_number() else: show_info = '' return show_info
def statstext(self, stats): # XXX translate expressions, not words statslabel = '%s %s\n.' % (stats['songs'], gettext.ngettext('song', 'songs', int(stats['songs']))) statslabel += '%s %s\n.' % (stats['albums'], gettext.ngettext('album', 'albums', int(stats['albums']))) statslabel += '%s %s\n.' % (stats['artists'], gettext.ngettext('artist', 'artists', int(stats['artists']))) try: db_playtime = float(stats['db_playtime']) hours_of_playtime = misc.convert_time(db_playtime).split(':')[-3] except: hours_of_playtime = '0' if int(hours_of_playtime) >= 24: days_of_playtime = str(int(hours_of_playtime) / 24) statslabel += '%s %s.' % (days_of_playtime, gettext.ngettext('day of bliss', 'days of bliss', int(days_of_playtime))) else: statslabel += '%s %s.' % (hours_of_playtime, gettext.ngettext('hour of bliss', 'hours of bliss', int(hours_of_playtime))) return statslabel
def _create_unhide_item(self, files, hidden_path, hidden): """Creates the 'Unhide file(s)' menu item.""" item = Nemo.MenuItem(name="NemoHide::UnhideFile", label=ngettext("Un_hide File", "Un_hide Files", len(files)), tip=ngettext("Unhide this file", "Unhide these files", len(files))) item.connect("activate", self._unhide_run, files, hidden_path, hidden) return item
def check_status(self): changed = False countInstall = 0 countRemove = 0 for (lang, langInfo) in self._langlist: if langInfo.changes: changed = True for item in langInfo.languagePkgList.values(): if item.doChange: if item.installed: countRemove = countRemove + 1 else: countInstall = countInstall + 1 #print "%(INSTALL)d to install, %(REMOVE)d to remove" % (countInstall, countRemove) # Translators: %(INSTALL)d is parsed; either keep it exactly as is or remove it entirely, but don't translate "INSTALL". textInstall = gettext.ngettext("%(INSTALL)d to install", "%(INSTALL)d to install", countInstall) % {'INSTALL': countInstall} # Translators: %(REMOVE)d is parsed; either keep it exactly as is or remove it entirely, but don't translate "REMOVE". textRemove = gettext.ngettext("%(REMOVE)d to remove", "%(REMOVE)d to remove", countRemove) % {'REMOVE': countRemove} if countRemove == 0 and countInstall == 0: self.label_install_remove.set_text("") elif countRemove == 0: self.label_install_remove.set_text(textInstall) elif countInstall == 0: self.label_install_remove.set_text(textRemove) else: # Translators: this string will concatenate the "%n to install" and "%n to remove" strings, you can replace the comma if you need to. self.label_install_remove.set_text(_("%s, %s") % (textInstall, textRemove)) if changed: self.button_apply.set_sensitive(True) else: self.button_apply.set_sensitive(False)
def you_win_callback (self, grid): if hasattr(self, 'dancer'): return self.won = True # increase difficulty for next time. self.mateconf['difficulty'] = self.mateconf['difficulty'] + 0.1 self.timer.finish_timing() self.sudoku_tracker.finish_game(self) sublabel = _("You completed the puzzle in %(totalTime)s (%(activeTime)s active)") % {'totalTime': self.timer.total_time_string(), 'activeTime': self.timer.active_time_string() } sublabel += "\n" sublabel += ngettext("You got %(n)s hint", "You got %(n)s hints", self.gsd.hints) % {'n':self.gsd.hints} sublabel += "\n" if self.gsd.impossible_hints: sublabel += ngettext("You had %(n)s impossibility pointed out.", "You had %(n)s impossibilities pointed out.", self.gsd.impossible_hints) % {'n':self.gsd.impossible_hints} sublabel += "\n" if self.gsd.auto_fills: sublabel += ngettext("You used the auto-fill %(n)s time", "You used the auto-fill %(n)s times", self.gsd.auto_fills) % {'n':self.gsd.auto_fills} import dancer self.dancer = dancer.GridDancer(self.gsd) self.dancer.start_dancing() dialog_extras.show_message(_("You win!"), label = _("You win!"), sublabel = sublabel )
def _create_hide_item(self, files, hidden_path, hidden): """Creates the 'Hide file(s)' menu item.""" item = Nautilus.MenuItem(name="NautilusHide::HideFile", label=ngettext("_Hide File", "_Hide Files", len(files)), tip=ngettext("Hide this file", "Hide these files", len(files))) item.connect("activate", self._hide_run, files, hidden_path, hidden) return item
def get_status_text(self): """return user readable status text suitable for a status bar""" # no status text in the details page if self.notebook.get_current_page() == self.PAGE_APP_DETAILS: return "" # otherwise, show status based on search or not model = self.app_view.get_model() if not model: return "" length = len(self.app_view.get_model()) if self.channel.installed_only: if len(self.searchentry.get_text()) > 0: return gettext.ngettext("%(amount)s matching item", "%(amount)s matching items", length) % {'amount': length} else: return gettext.ngettext("%(amount)s item installed", "%(amount)s items installed", length) % {'amount': length} else: if len(self.searchentry.get_text()) > 0: return gettext.ngettext("%(amount)s matching item", "%(amount)s matching items", length) % {'amount': length} else: return gettext.ngettext("%(amount)s item available", "%(amount)s items available", length) % {'amount': length}
def format_friendly_date (tim): local_tim = time.localtime(tim) diff = int(time.time() - tim) curr_hour, curr_min = time.localtime()[3:5] now_to_yesterday = curr_hour * 60 * 60 + curr_min * 60 if diff < now_to_yesterday: # Then we're today if diff < 60: # within the minute return ngettext("%(n)s second ago", "%(n)s seconds ago", diff) % {'n': diff} elif diff < (60 * 60): # within the hour... minute = int(diff / 60) return ngettext("%(n)s minute ago", "%(n)s minutes ago", minute) % {'n': minute} else: # Translators, see strftime manual in order to translate %? format strings return time.strftime(_("at %I:%M %p"), local_tim) elif diff < now_to_yesterday + (60 * 60 * 24): # Translators, see strftime manual in order to translate %? format strings return time.strftime(_("yesterday at %I:%M %p"), local_tim) elif diff < now_to_yesterday + (60 * 60 * 24) * 6: # Translators, see strftime manual in order to translate %? format strings return time.strftime(_("%A %I:%M %p"), local_tim) else: # Translators, see strftime manual in order to translate %? format strings return time.strftime(_("%B %e"), local_tim)
def get_nice_date_string(cur_t): """ return a "nice" human readable date, like "2 minutes ago" """ import datetime dt = datetime.datetime.utcnow() - cur_t days = dt.days secs = dt.seconds if days < 1: if secs < 120: # less than 2 minute ago s = _('a few minutes ago') # dont be fussy elif secs < 3600: # less than an hour ago s = gettext.ngettext("%(min)i minute ago", "%(min)i minutes ago", (secs / 60)) % {'min': (secs / 60)} else: # less than a day ago s = gettext.ngettext("%(hours)i hour ago", "%(hours)i hours ago", (secs / 3600)) % {'hours': (secs / 3600)} elif days <= 5: # less than a week ago s = gettext.ngettext("%(days)i day ago", "%(days)i days ago", days) % {'days': days} else: # any timedelta greater than 5 days old # YYYY-MM-DD s = cur_t.isoformat().split('T')[0] return s
def get_last_synced(folder): try: timestamp = open(os.path.join(folder, 'synced')).read() now = time.time() o_delta = datetime.timedelta(seconds=float(timestamp)) n_delta = datetime.timedelta(seconds=now) difference = n_delta - o_delta weeks, days = divmod(difference.days, 7) minutes, seconds = divmod(difference.seconds, 60) hours, minutes = divmod(minutes, 60) if weeks: return ngettext('%d week ago', '%d weeks ago', weeks) % weeks if days: return ngettext('%d day ago', '%d days ago', days) % days if hours: return ngettext('%d hour ago', '%d hours ago', hours) % hours if minutes: return ngettext('%d minute ago', '%d minutes ago', minutes) % minutes return _('Just Now') except: return _('Never')
def __disabled_pubs_info(self, disabled_pubs): if len(disabled_pubs) == 0: return num = len(disabled_pubs) msg = ngettext( "The following publisher is disabled:\n", "The following publishers are disabled:\n", num) for pub in disabled_pubs: msg += _("\t<b>%s</b>\n") % pub msg += ngettext( "\nClicking OK will enable the publisher before proceeding with " "install. On completion it will be disabled again.", "\nClicking OK will enable the publishers before proceeding with " "install.\nOn completion they will be disabled again.", num) msgbox = gtk.MessageDialog( parent = self.w_webinstall_dialog, buttons = gtk.BUTTONS_OK_CANCEL, flags = gtk.DIALOG_MODAL, type = gtk.MESSAGE_INFO, message_format = None) msgbox.set_markup(msg) title = ngettext("Disabled Publisher", "Disabled Publishers", len(disabled_pubs)) msgbox.set_title(title) msgbox.set_default_response(gtk.RESPONSE_OK) response = msgbox.run() if response == gtk.RESPONSE_OK: gobject.idle_add(self.__proceed) msgbox.destroy() return
def _about(self, action, param): """ Setup about dialog @param action as Gio.SimpleAction @param param as GLib.Variant """ builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/AboutDialog.ui') if self.scanner.is_locked(): builder.get_object('button').set_sensitive(False) builder.get_object('button').connect('clicked', self._on_reset_clicked, builder.get_object('progress')) artists = self.artists.count() albums = self.albums.count() tracks = self.tracks.count() builder.get_object('artists').set_text( ngettext("%d artist", "%d artists", artists) % artists) builder.get_object('albums').set_text( ngettext("%d album", "%d albums", albums) % albums) builder.get_object('tracks').set_text( ngettext("%d track", "%d tracks", tracks) % tracks) about = builder.get_object('about_dialog') about.set_transient_for(self.window) about.connect("response", self._about_response) about.show()
def pithy_timesince(d, preposition=''): ''' Concise timesince. Modified from Pownce pithy_timesince and django timesince. ''' if d is None: return None chunks = ( (60 * 60 * 24 * 365, lambda n, d: _('%(prep)s %(date)s') % { 'prep': preposition, 'date': defaultfilters.date(d, 'M j, Y') }), # 1 year+ (60 * 60 * 24 * 7, lambda n, d: _('%(prep)s %(date)s') % { 'prep': preposition, 'date': defaultfilters.date(d, 'M jS') }), # 1 week+ (60 * 60 * 24, lambda n, d: ngettext('%d day ago', '%d days ago', n // (60 * 60 * 24)) % (n // (60 * 60 * 24),)), # 1 day+ (60 * 60, lambda n, d: ngettext('%d hour ago', '%d hours ago', n // (60 * 60)) % (n // (60 * 60),)), # 1 hour+ (60 * 2, lambda n, d: ngettext('%d minute ago', '%d minutes ago', n // 60) % (n // 60,)), # 2 minutes+ (1, lambda n, d: _('just now')) # under 2 mins ago ) t = time.localtime() if d.tzinfo: tz = LocalTimezone(d) else: tz = None now = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], tzinfo=tz) # ignore microsecond part of 'd' since we removed it from 'now' delta = now - (d - datetime.timedelta(0, 0, d.microsecond)) since = delta.days * 24 * 60 * 60 + delta.seconds for i, (seconds, label) in enumerate(chunks): count = since // seconds # truncated division if count != 0: break return label(since, d)
def _get_last_apt_get_update_text(self): """ return a human readable string with the information when the last apt-get update was run """ ago_hours = self._get_last_apt_get_update_hours() if ago_hours is None: return _("It is unknown when the package information was " "updated last. Please try clicking on the 'Check' " "button to update the information.") ago_days = int( ago_hours / 24 ) if ago_days > self.NO_UPDATE_WARNING_DAYS: return _("The package information was last updated %(days_ago)s " "days ago.\n" "Press the 'Check' button below to check for new software " "updates.") % { "days_ago" : ago_days, } elif ago_days > 0: return ngettext("The package information was last updated %(days_ago)s day ago.", "The package information was last updated %(days_ago)s days ago.", ago_days) % { "days_ago" : ago_days, } elif ago_hours > 0: return ngettext("The package information was last updated %(hours_ago)s hour ago.", "The package information was last updated %(hours_ago)s hours ago.", ago_hours) % { "hours_ago" : ago_hours, } else: return _("The package information was last updated less than one hour ago.") return None
def ldnp(td, ctxt, id, idp, n, *args): if not dir or nolocales: _die("please set a locale directory with l_dir() before using other translate functions") if idp: args = (n,) + args out = None if dry: if not nowrite: save = [] if td: save.push(' # domain: '+td) if ctxt: save.push('msgctxt: "'+gettext_escape(ctxt)+'"') save.push('msgid "'+gettext_escape(id)+'"') if idp: save.push('msgid_plural "'+gettext_escape(idp)+'"') wd(save) out = (idp if idp and n != 1 else id) % args else: if td and not ctxt and id and idp and n: out = sprintf(dngettext(td, id, idp, n), *args) elif not td and not ctxt and id and idp and n: out = sprintf(ngettext(id, idp, n), *args) elif not td and not ctxt and id and not idp and not n: out = sprintf(gettext(id), *args) elif td and not ctxt and id and not idp and not n: out = sprintf(dgettext(td, id), *args) # with context magic if td and ctxt and id and idp and n: out = sprintf(dngettext(td, ctxt+'\x04'+id, ctxt+'\x04'+idp, n), *args) elif not td and ctxt and id and idp and n: out = sprintf(ngettext(ctxt+'\x04'+id, ctxt+'\x04'+idp, n), *args) elif not td and ctxt and id and not idp and not n: out = sprintf(gettext(ctxt+'\x04'+id), *args) elif td and ctxt and id and not idp and not n: out = sprintf(dgettext(td, ctxt+'\x04'+id), *args) return out
def __set_updates_str(self, str_fmt): if self.n_updates == 0: updates_str = "" else: updates_fmt = ngettext("%d Update,", "%d Updates,", self.n_updates) updates_str = updates_fmt % self.n_updates if self.n_installs == 0: installs_str = "" else: installs_fmt = ngettext("%d Install,", "%d Installs,", self.n_installs) installs_str = installs_fmt % self.n_installs if self.n_removes == 0: removes_str = "" else: removes_fmt = ngettext("%d Remove", "%d Removes", self.n_removes) removes_str = removes_fmt % self.n_removes updates_str = str_fmt % \ {"updates": updates_str, "installs": installs_str, "removes": removes_str} updates_str = updates_str.rstrip(', ') return updates_str
def update_progress_bar (self): if self.generateForTargetRadio.get_active(): tot = int(self.newSudokusSpinButton.get_value()) self.prog.set_fraction( float(self.generated())/tot ) try: txt = ngettext('Generated %(n)s out of %(total)s puzzle', 'Generated %(n)s out of %(total)s puzzles', tot) % {'n':self.generated(), 'total':tot} except TypeError: # Allow for fuzzy translation badness caused by a # previous version having this done the wrong way # (i.e. the previous version didn't use the dictionary # method for the format string, which meant # translators couldn't change the word order here. try: txt = ngettext('Generated %(n)s out of %(total)s puzzle', 'Generated %(n)s out of %(total)s puzzles', tot) % (self.generated(), tot) except: # Fallback to English txt = 'Generated %s out of %s puzzles' % (self.generated(), tot) else: self.prog.pulse() txt = ngettext('Generated %(n)s puzzle', 'Generated %(n)s puzzles', self.generated()) % {'n':self.generated()} if self.paused: txt = txt + ' (' + _('Paused') + ')' self.prog.set_text(txt)
def can_close(self): if self._force_close: return True elif downloadmanager.can_quit(): return True else: alert = Alert() alert.props.title = ngettext('Download in progress', 'Downloads in progress', downloadmanager.num_downloads()) message = ngettext('Stopping now will erase your download', 'Stopping now will erase your downloads', downloadmanager.num_downloads()) alert.props.msg = message cancel_icon = Icon(icon_name='dialog-cancel') cancel_label = ngettext('Continue download', 'Continue downloads', downloadmanager.num_downloads()) alert.add_button(Gtk.ResponseType.CANCEL, cancel_label, cancel_icon) stop_icon = Icon(icon_name='dialog-ok') alert.add_button(Gtk.ResponseType.OK, _('Stop'), stop_icon) stop_icon.show() self.add_alert(alert) alert.connect('response', self.__inprogress_response_cb) alert.show() self.present() return False
def timestamp_diff(timestamp, reference_time): """ Takes as input the timestamp and outputs a text representing the time difference of the timestamp from a reference_time. :param timestamp: Timestamp for which difference is calculated. :param reference_time: Reference time for difference to be calculated. """ timediff = time.mktime(reference_time)-time.mktime(timestamp) d = datetime.timedelta(seconds=timediff) total_secs = d.total_seconds() if total_secs < 60: return "Just Now" elif total_secs < 3600: minutes = d.seconds // 60 return ngettext("A minute ago", "{minutes} minutes ago", minutes).format(minutes=minutes) elif total_secs <= 43200: hours = d.seconds // 3600 return ngettext("An hour ago", "{hours} hours ago", hours).format(hours=hours) elif d.days == 0: return "Today" elif d.days == 1: return "Yesterday" elif total_secs // 3600 < 7 * 24 - reference_time.tm_hour: return time.strftime("%A", timestamp) elif d.days < 14: return "1 week ago" elif d.days <= reference_time.tm_yday: return time.strftime("%B", timestamp) else: return time.strftime("%Y", timestamp)
def beautify_length(length): """Converts the specified duration to a human readable string. Args: length (int): The duration in nanoseconds. """ if length == Gst.CLOCK_TIME_NONE: return "" sec = length / Gst.SECOND mins = int(sec / 60) sec = int(sec % 60) hours = int(mins / 60) mins = int(mins % 60) parts = [] if hours: parts.append(ngettext("%d hour", "%d hours", hours) % hours) if mins: parts.append(ngettext("%d minute", "%d minutes", mins) % mins) if not hours and sec: parts.append(ngettext("%d second", "%d seconds", sec) % sec) return ", ".join(parts)
def on_transfer_progress(self, _transfer, progress): self.transferred = progress if self._last_bytes == 0: self.total_transferred += progress else: self.total_transferred += (progress - self._last_bytes) self._last_bytes = progress tm = time.time() if tm - self._last_update > 0.5: spd = self.speed.calc(self.total_transferred) (size, units) = format_bytes(spd) try: x = ((self.total_bytes - self.total_transferred) / spd) + 1 if x > 60: x /= 60 eta = ngettext("%.0f Minute", "%.0f Minutes", round(x)) % x else: eta = ngettext("%.0f Second", "%.0f Seconds", round(x)) % x except ZeroDivisionError: eta = "∞" self.pb.props.text = _("Sending File") + (" %(0)s/%(1)s (%(2).2f %(3)s/s) " + _("ETA:") + " %(4)s") % { "1": self.num_files, "0": (self.num_files - len(self.files) + 1), "2": size, "3": units, "4": eta} self._last_update = tm self.pb.props.fraction = float(self.total_transferred) / self.total_bytes
def _fail_feature(self): failed_msg = ngettext('{} scenario failed', '{} scenarios failed', self._scenarios_failed) passed_msg = ngettext('{} scenario passed', '{} scenarios passed', self._scenarios_passed) msg = u'{}, {}'.format(failed_msg, passed_msg).format(self._scenarios_failed, self._scenarios_passed) prefix = '-' * 66 for step_line, tb, exc in self._exceptions: msg += u'\n{}{}\n{}{}'.format(prefix, step_line, tb, exc).replace(u'\n', u'\n ') assert self._scenarios_failed == 0, msg
def _formatClientCount(value): if isinstance(value, (int, long)): template = gettext.ngettext( N_("%d client"), N_("%d clients"), value) else: template = gettext.ngettext( N_("%.2f client"), N_("%.2f clients"), value) return template % value
def _str_time(self, seconds): if seconds < 0: return _('unknown time') minutes = seconds / 60 hours = minutes / 60 minutes = minutes % 60 return gettext.ngettext('%d Hour', '%d Hours', hours) + " " + gettext.ngettext('%d Minutes', '%d Minutes', minutes)
def convert(self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]) -> t.Any: # Match through normalization and case sensitivity # first do token_normalize_func, then lowercase # preserve original `value` to produce an accurate message in # `self.fail` normed_value = value normed_choices = {choice: choice for choice in self.choices} if ctx is not None and ctx.token_normalize_func is not None: normed_value = ctx.token_normalize_func(value) normed_choices = { ctx.token_normalize_func(normed_choice): original for normed_choice, original in normed_choices.items() } if not self.case_sensitive: normed_value = normed_value.casefold() normed_choices = { normed_choice.casefold(): original for normed_choice, original in normed_choices.items() } if normed_value in normed_choices: return normed_choices[normed_value] choices_str = ", ".join(map(repr, self.choices)) self.fail( ngettext( "{value!r} is not {choice}.", "{value!r} is not one of {choices}.", len(self.choices), ).format(value=value, choice=choices_str, choices=choices_str), param, ctx, )
def wait_for_flatpak_steam(timeout=99): """Wait for Flatpak version of Steam to be running.""" loginvdf = os.path.expanduser("~/.local/share/Steam/config/loginusers.vdf") try: stat = os.stat(loginvdf) loginvdf_timestamp = stat.st_mtime except OSError: loginvdf_timestamp = 0 waittime = timeout while waittime > 0: # "\r" can't be used here because this helper is subprocess print(ngettext("Waiting {} second for steam to start up.", "Waiting {} seconds for steam to start up.", waittime).format(waittime), flush=True) time.sleep(1) waittime -= 1 try: stat = os.stat(loginvdf) if stat.st_mtime > loginvdf_timestamp: break except OSError: pass
def main(): files = do_options() # should parse files[] to read \version? if global_options.show_rules: show_rules(sys.stdout, global_options.from_version, global_options.to_version) sys.exit(0) identify() errors = 0 for f in files: if f == '-': f = '' elif not os.path.isfile(f): ly.error(_("%s: Unable to open file") % f) errors += 1 continue try: errors += do_one_file(f) except UnknownVersion: ly.error(_("%s: Unable to determine version. Skipping") % f) errors += 1 except InvalidVersion as v: ly.error( _("%s: Invalid version string `%s' \n" "Valid version strings consist of three numbers, " "separated by dots, e.g. `2.8.12'") % (f, v.version)) errors += 1 if errors: ly.warning( gettext.ngettext("There was %d error.", "There were %d errors.", errors) % errors) sys.exit(1)
def ngettext(self, singular, plural, n): """ Return the unicode translated singular/plural string. The translation of singular/plural is returned unless the translation is not available and the singular contains the separator. In that case, the returned value is the portion of singular following the last separator. Default separator is '|'. :param singular: The singular form of the string to be translated. may contain a context separator :type singular: unicode :param plural: The plural form of the string to be translated. :type plural: unicode :param n: the amount for which to decide the translation :type n: int :returns: The translated singular/plural message :rtype: unicode """ if self.__trans is None: return unicode(gettext.ngettext(singular, plural, n)) else: return self.__trans.ungettext(singular, plural, n)
def get_unsupported_suggestion_text(self, term, category, state): if state.filter is None: return None supported_only = state.filter.get_supported_only() if not supported_only: return None state.filter.set_supported_only(False) #if category: # category_query = category.query #else: # category_query = None enq = self.enquirer enq.set_query(enq.search_query, limit=self.pane.get_app_items_limit(), sortmode=self.pane.get_sort_mode(), nonapps_visible=True, filter=state.filter, nonblocking_load=False) state.filter.set_supported_only(True) if enq.nr_apps > 0: text = self.BULLET % gettext.ngettext( "Try " "<a href=\"search-unsupported:\">the %(amount)d item " "that matches</a> in software not maintained by Canonical", "Try <a href=\"search-unsupported:\">the %(amount)d items " "that match</a> in software not maintained by Canonical", enq.nr_apps) % { 'amount': enq.nr_apps } return text return None
def _execute_status(self): state_map = { 'play': _('Playing'), 'pause': _('Paused'), 'stop': _('Stopped') } aprint(3, '%s: %s' % (_('State'), state_map[self.status['state']])) aprint(3, '%s %s' % (_('Repeat:'), _('On') if self.status['repeat'] == '1'\ else _('Off'))) aprint(3, '%s %s' % (_('Random:'), _('On') if self.status['random'] == '1'\ else _('Off'))) aprint(3, '%s %s' % (_('Single:'), _('On') if self.status['single'] == '1'\ else _('Off'))) aprint(3, '%s %s' % (_('Consume:'), _('On')\ if self.status['consume'] == '1' else _('Off'))) aprint(3, '%s: %s/100' % (_('Volume'), self.status['volume'])) aprint(3, '%s: %s %s' % (_('Crossfade'), self.status['xfade'], gettext.ngettext('second', 'seconds', int(self.status['xfade']))))
def format_time (time, round_at=None): time = int(time) time_strings = [] units = [(int(365.25*24*60*60), lambda years: ngettext("%s year","%s years",years)%years), (31*24*60*60, lambda months: ngettext("%s month","%s months",months)%months), (7*24*60*60, lambda weeks: ngettext("%s week","%s weeks",weeks)%weeks), (24*60*60, lambda days: ngettext("%s day","%s days",days)%days), (60*60, lambda hours: ngettext("%s hour","%s hours",hours)%hours), (60, lambda minutes: ngettext("%s minute","%s minutes",minutes)%minutes), (1, lambda seconds: ngettext("%s second","%s seconds",seconds)%seconds)] for divisor,unit_formatter in units: time_covered = time / divisor if time_covered: if round_at and len(time_strings)+1>=round_at: time_covered = int(round(float(time)/divisor)) time_strings.append(unit_formatter(time_covered)) break else: time_strings.append(unit_formatter(time_covered)) time = time - time_covered * divisor if len(time_strings)>2: # Translators... this is a messay way of concatenating # lists. In English we do lists this way: 1, 2, 3, 4, 5 # and 6. This set-up allows for the English system only. # You can of course make your language only use commas or # ands or spaces or whatever you like by translating both # ", " and " and " with the same string. return _(" and ").join([_(", ").join(time_strings[0:-1]),time_strings[-1]]) else: return _(" and ").join(time_strings)
def validate(self): """ Validates the state of this Library Content Module Instance. This is the override of the general XBlock method, and it will also ask its superclass to validate. """ validation = super(LibraryContentDescriptor, self).validate() if not isinstance(validation, StudioValidation): validation = StudioValidation.copy(validation) library_tools = self.runtime.service(self, "library_tools") if not (library_tools and library_tools.can_use_library_content(self)): validation.set_summary( StudioValidationMessage( StudioValidationMessage.ERROR, _(u"This course does not support content libraries. " u"Contact your system administrator for more information." ))) return validation if not self.source_library_id: validation.set_summary( StudioValidationMessage( StudioValidationMessage.NOT_CONFIGURED, _(u"A library has not yet been selected."), action_class='edit-button', action_label=_(u"Select a Library."))) return validation lib_tools = self.runtime.service(self, 'library_tools') self._validate_library_version(validation, lib_tools, self.source_library_version, self.source_library_key) # Note: we assume refresh_children() has been called # since the last time fields like source_library_id or capa_types were changed. matching_children_count = len(self.children) # pylint: disable=no-member if matching_children_count == 0: self._set_validation_error_if_empty( validation, StudioValidationMessage( StudioValidationMessage.WARNING, _(u'There are no matching problem types in the specified libraries.' ), action_class='edit-button', action_label=_(u"Select another problem type."))) if matching_children_count < self.max_count: self._set_validation_error_if_empty( validation, StudioValidationMessage( StudioValidationMessage.WARNING, (ngettext( u'The specified library is configured to fetch {count} problem, ', u'The specified library is configured to fetch {count} problems, ', self.max_count) + ngettext( u'but there is only {actual} matching problem.', u'but there are only {actual} matching problems.', matching_children_count)).format( count=self.max_count, actual=matching_children_count), action_class='edit-button', action_label=_(u"Edit the library configuration."))) return validation
def test_plural_forms1(self): eq = self.assertEqual x = gettext.ngettext('There is %s file', 'There are %s files', 1) eq(x, 'Hay %s fichero') x = gettext.ngettext('There is %s file', 'There are %s files', 2) eq(x, 'Hay %s ficheros')
del _sys from glob import glob as _glob for location in prefix_share, src_share: mo_files = _glob(_path.join(location, 'locale', '*', 'LC_MESSAGES', lc_domain + '.mo')) if mo_files: return _path.join(location, 'locale') # del _path locale.setlocale(locale.LC_ALL, '') language, encoding = locale.getlocale() del locale _LOCALE_DOMAIN = _NAME.lower() path = _find_locale_path(_LOCALE_DOMAIN) _gettext.bindtextdomain(_LOCALE_DOMAIN, path) _gettext.textdomain(_LOCALE_DOMAIN) _gettext.install(_LOCALE_DOMAIN) try: unicode # noqa: F821 _ = lambda x: _gettext.gettext(x).decode('UTF-8') ngettext = lambda *x: _gettext.ngettext(*x).decode('UTF-8') except Exception: _ = _gettext.gettext ngettext = _gettext.ngettext
def extras_tab(self, cbs): """Construct and layout the extras tab""" if not self.scrobbler.imported(): self.config.as_enabled = False extraslabel = ui.label(markup='<b>' + _('Extras') + '</b>') frame = gtk.Frame() frame.set_label_widget(extraslabel) frame.set_shadow_type(gtk.SHADOW_NONE) as_checkbox = gtk.CheckButton(_("_Audioscrobbling (Last.fm)")) as_checkbox.set_active(self.config.as_enabled) as_user_label = ui.label(textmn=_("_Username:"******"_Password:"******"Popup _notification on song changes")) display_notification.set_active(self.config.show_notification) time_names = ["%s %s" % (i , gettext.ngettext('second', 'seconds', int(i))) for i in cbs.popuptimes if i != _('Entire song')] time_names.append(_('Entire song')) notification_options = ui.combo(items=time_names, active=self.config.popup_option, changed_cb=self._notiftime_changed) notification_locs = ui.combo(items=cbs.popuplocations, active=self.config.traytips_notifications_location, changed_cb=self._notiflocation_changed) notifhbox = gtk.HBox(spacing=6) notifhbox.pack_end(notification_locs, False, False) notifhbox.pack_end(notification_options, False, False) display_notification.connect('toggled', cbs.notif_toggled, notifhbox) if not self.config.show_notification: notifhbox.set_sensitive(False) crossfadespin = gtk.SpinButton() crossfadespin.set_range(1, 30) crossfadespin.set_value(self.config.xfade) crossfadespin.set_numeric(True) crossfadespin.set_increments(1, 5) crossfadespin.connect('value-changed', cbs.crossfade_changed) crossfadelabel2 = ui.label(textmn=_("_Fade length:")) crossfadelabel2.set_mnemonic_widget(crossfadespin) crossfadelabel3 = ui.label(text=_("sec")) crossfadebox = gtk.HBox(spacing=12) crossfadebox.pack_end(crossfadelabel3, False, False) crossfadebox.pack_end(crossfadespin, False, False) crossfadebox.pack_end(crossfadelabel2, False, False) crossfadecheck = gtk.CheckButton(_("C_rossfade")) crossfadecheck.connect('toggled', self._crossfadecheck_toggled, crossfadespin, crossfadelabel2, crossfadelabel3) crossfadecheck.connect('toggled', cbs.crossfade_toggled, crossfadespin) crossfadecheck.set_active(self.config.xfade_enabled) crossfadecheck.toggled() # Force the toggled callback widgets = (as_checkbox, as_entries, display_notification, notifhbox, crossfadecheck, crossfadebox) table = gtk.Table(len(widgets), 1) table.set_col_spacings(12) table.set_row_spacings(6) for i, widget in enumerate(widgets): table.attach(widget, 0, 1, i, i+1, gtk.FILL|gtk.EXPAND, gtk.FILL) alignment = gtk.Alignment(0.5, 0.5, 1.0, 1.0) alignment.set_padding(12, 0, 12, 0) alignment.add(table) frame.add(alignment) tab = gtk.Alignment(0.5, 0.5, 1.0, 1.0) tab.set_padding(12, 12, 12, 12) tab.add(frame) as_checkbox.connect('toggled', self._as_enabled_toggled, as_user_entry, as_pass_entry, as_user_label, as_pass_label) if not self.config.as_enabled or not self.scrobbler.imported(): for widget in (as_user_entry, as_pass_entry, as_user_label, as_pass_label): widget.set_sensitive(False) return tab
def _on_duration_changed(self, coredisc, duration): mins = (coredisc.props.duration // 60) + 1 self._running_info_label.props.label = ngettext( "{} minute", "{} minutes", mins).format(mins)
def __str__(self): count = len(self._receiver) return (_("No paired devices.") if count == 0 else ngettext( "%(count)s paired device.", "%(count)s paired devices.", count) % { 'count': count })
def __init__(self): """ Init dialog """ self.__choosers = [] self.__cover_tid = None self.__mix_tid = None self.__popover = None builder = Gtk.Builder() builder.add_from_resource("/org/gnome/Lollypop/SettingsDialog.ui") self.__progress = builder.get_object("progress") self.__infobar = builder.get_object("infobar") self.__reset_button = builder.get_object("reset_button") if Lp().lastfm is None or Lp().lastfm.is_goa: builder.get_object("lastfm_grid").hide() if Lp().scanner.is_locked(): builder.get_object("reset_button").set_sensitive(False) artists = Lp().artists.count() albums = Lp().albums.count() tracks = Lp().tracks.count() builder.get_object("artists").set_text( ngettext("%d artist", "%d artists", artists) % artists) builder.get_object("albums").set_text( ngettext("%d album", "%d albums", albums) % albums) builder.get_object("tracks").set_text( ngettext("%d track", "%d tracks", tracks) % tracks) self.__popover_content = builder.get_object("popover") duration = builder.get_object("duration") duration.set_range(1, 20) duration.set_value(Lp().settings.get_value("mix-duration").get_int32()) self.__settings_dialog = builder.get_object("settings_dialog") self.__settings_dialog.set_transient_for(Lp().window) if Lp().settings.get_value("disable-csd"): self.__settings_dialog.set_title(_("Preferences")) else: headerbar = builder.get_object("header_bar") headerbar.set_title(_("Preferences")) self.__settings_dialog.set_titlebar(headerbar) switch_scan = builder.get_object("switch_scan") switch_scan.set_state(Lp().settings.get_value("auto-update")) switch_view = builder.get_object("switch_dark") if Lp().gtk_application_prefer_dark_theme: switch_view.set_sensitive(False) else: switch_view.set_state(Lp().settings.get_value("dark-ui")) switch_background = builder.get_object("switch_background") switch_background.set_state(Lp().settings.get_value("background-mode")) switch_state = builder.get_object("switch_state") switch_state.set_state(Lp().settings.get_value("save-state")) switch_mix = builder.get_object("switch_mix") switch_mix.set_state(Lp().settings.get_value("mix")) self._switch_song_notifications = builder.get_object( "switch_song_notifications", ) self._switch_song_notifications.set_state( not Lp().settings.get_value("disable-song-notifications"), ) self._switch_song_notifications.set_sensitive( not Lp().settings.get_value("disable-notifications"), ) Lp().settings.connect( "changed::disable-notifications", self._on_notifications_setting_changed, ) self.__helper = TouchHelper(switch_mix, None, None) self.__helper.set_long_func(self.__mix_long_func, switch_mix) self.__helper.set_short_func(self.__mix_short_func, switch_mix) switch_mix_party = builder.get_object("switch_mix_party") switch_mix_party.set_state(Lp().settings.get_value("party-mix")) switch_artwork_tags = builder.get_object("switch_artwork_tags") grid_behaviour = builder.get_object("grid_behaviour") # Check portal for kid3-cli dbus_helper = DBusHelper() dbus_helper.call("CanSetCover", None, self.__on_can_set_cover, (switch_artwork_tags, grid_behaviour)) if GLib.find_program_in_path("youtube-dl") is None or\ not Lp().settings.get_value("network-access"): builder.get_object("charts_grid").hide() else: switch_charts = builder.get_object("switch_charts") switch_charts.set_state(Lp().settings.get_value("show-charts")) switch_genres = builder.get_object("switch_genres") switch_genres.set_state(Lp().settings.get_value("show-genres")) switch_compilations = builder.get_object("switch_compilations") switch_compilations.set_state( Lp().settings.get_value("show-compilations")) switch_artwork = builder.get_object("switch_artwork") switch_artwork.set_state(Lp().settings.get_value("artist-artwork")) switch_spotify = builder.get_object("switch_spotify") switch_spotify.set_state(Lp().settings.get_value("search-spotify")) switch_itunes = builder.get_object("switch_itunes") switch_itunes.set_state(Lp().settings.get_value("search-itunes")) if GLib.find_program_in_path("youtube-dl") is None: builder.get_object("yt-dl").show() combo_orderby = builder.get_object("combo_orderby") combo_orderby.set_active(Lp().settings.get_enum(("orderby"))) combo_preview = builder.get_object("combo_preview") scale_coversize = builder.get_object("scale_coversize") scale_coversize.set_range(150, 300) scale_coversize.set_value( Lp().settings.get_value("cover-size").get_int32()) self.__settings_dialog.connect("destroy", self.__edit_settings_close) builder.connect_signals(self) main_chooser_box = builder.get_object("main_chooser_box") self.__chooser_box = builder.get_object("chooser_box") self.__set_outputs(combo_preview) # # Music tab # dirs = [] for directory in Lp().settings.get_value("music-uris"): dirs.append(directory) # Main chooser self.__main_chooser = ChooserWidget() image = Gtk.Image.new_from_icon_name("list-add-symbolic", Gtk.IconSize.MENU) self.__main_chooser.set_icon(image) self.__main_chooser.set_action(self.__add_chooser) main_chooser_box.pack_start(self.__main_chooser, False, True, 0) if len(dirs) > 0: uri = dirs.pop(0) else: filename = GLib.get_user_special_dir( GLib.UserDirectory.DIRECTORY_MUSIC) if filename: uri = GLib.filename_to_uri(filename) else: uri = "" self.__main_chooser.set_dir(uri) # Others choosers for directory in dirs: self.__add_chooser(directory) # # Google tab # key = Lp().settings.get_value("cs-api-key").get_string() or\ Lp().settings.get_default_value("cs-api-key").get_string() builder.get_object("cs-entry").set_text(key) from lollypop.helper_passwords import PasswordsHelper helper = PasswordsHelper() # # Last.fm tab # if Lp().lastfm is not None: self.__lastfm_test_image = builder.get_object("lastfm_test_image") self.__lastfm_login = builder.get_object("lastfm_login") self.__lastfm_password = builder.get_object("lastfm_password") helper.get("lastfm", self.__on_get_password) builder.get_object("lastfm_grid").set_sensitive(True) builder.get_object("lastfm_error_label").hide() # # Libre.fm tab # if Lp().librefm is not None: self.__librefm_test_image = builder.get_object( "librefm_test_image") self.__librefm_login = builder.get_object("librefm_login") self.__librefm_password = builder.get_object("librefm_password") helper.get("librefm", self.__on_get_password) builder.get_object("librefm_grid").set_sensitive(True) builder.get_object("librefm_error_label").hide()
def delete(self, rogue): for cert in rogue: try: cert.delete() self.report.rogue.append(cert) except OSError, er: log.exception(er) log.warn("Failed to delete cert") # If we just deleted certs, we need to refresh the now stale # entitlement directory before we go to delete expired certs. rogue_count = len(self.report.rogue) if rogue_count > 0: print gettext.ngettext("%s local certificate has been deleted.", "%s local certificates have been deleted.", rogue_count) % rogue_count self.ent_dir.refresh() class EntitlementCertBundlesInstaller(object): """Install a list of entitlement cert bundles. pre_install() is triggered before any of the ent cert bundles are installed. post_install() is triggered after all of the ent cert bundles are installed. """ def __init__(self, report): self.exceptions = [] self.report = report
def search(self, text, format): """Execute the search process (to be executed in a dedicated thread)""" self.searchRunning = True symbols = self.vocabularyController.getCurrentProject().getVocabulary( ).getSymbols() # Reset the progress bar GObject.idle_add(self._view.searchProgressBar.show) GObject.idle_add(self._view.searchProgressBar.set_fraction, 0.0) # create a task for the text searcher = Searcher(self.vocabularyController.getCurrentProject(), self.updateProgessBar) # generate variations for each provided format (see glade file) if format == "string": searchTasks = searcher.getSearchedDataForString(text) elif format == "hexa": searchTasks = searcher.getSearchedDataForHexadecimal(text) elif format == "decimal": searchTasks = searcher.getSearchedDataForDecimal(text) elif format == "octal": searchTasks = searcher.getSearchedDataForOctal(text) elif format == "binary": searchTasks = searcher.getSearchedDataForBinary(text) elif format == "ipv4": searchTasks = searcher.getSearchedDataForIP(text) else: searchTasks = None self.log.error( "Cannot search for data if provided with type {0}".format( format)) if searchTasks is not None and len(searchTasks) > 0: self.executedSearchTasks = searcher.search(searchTasks) self.idResult = -1 self.nbResult = 0 for searchTask in self.executedSearchTasks: self.nbResult += len(searchTask.getResults()) if self.nbResult == 0: GObject.idle_add(self._view.imageWarning.show) GObject.idle_add(self._view.numberOfResultLabel.show) GObject.idle_add(self._view.numberOfResultLabel.set_label, _("No occurrence found.")) else: GObject.idle_add(self._view.imageWarning.hide) GObject.idle_add(self._view.numberOfResultLabel.show) label = ngettext("{0} occurrence found.", "{0} occurrences found.", self.nbResult).format(self.nbResult) GObject.idle_add(self._view.numberOfResultLabel.set_label, label) if not self.stopFlag and self.nbResult > 0: # if search has completed (not stopped), nav. is allowed GObject.idle_add(self._view.research_previous.set_sensitive, False) GObject.idle_add(self._view.research_next.set_sensitive, True) else: self.executedSearchTasks = None self.idResult = 0 self.searchRunning = False self.stopFlag = False GObject.idle_add(self._view.searchProgressBar.hide)
def __init__(self, parent, sourceslist, source_renderer, get_comparable, datadir, file): print(file) self.parent = parent self.source_renderer = source_renderer self.sourceslist = sourceslist self.get_comparable = get_comparable self.file = self.format_uri(file) setup_ui(self, os.path.join(datadir, "gtkbuilder", "dialog-add-sources-list.ui"), domain="software-properties") self.dialog = self.dialog_add_sources_list self.label = self.label_sources self.treeview = self.treeview_sources self.scrolled = self.scrolled_window self.image = self.image_sources_list self.dialog.realize() if self.parent != None: self.dialog.set_transient_for(parent) else: self.dialog.set_title(_("Add Software Channels")) self.dialog.get_window().set_functions(Gdk.WMFunction.MOVE) # Setup the treeview self.store = Gtk.ListStore(GObject.TYPE_STRING) self.treeview.set_model(self.store) cell = Gtk.CellRendererText() cell.set_property("xpad", 2) cell.set_property("ypad", 2) column = Gtk.TreeViewColumn("Software Channel", cell, markup=0) column.set_max_width(500) self.treeview.append_column(column) # Parse the source.list file try: self.new_sources = SingleSourcesList(self.file) except: self.error() return # show the found channels or an error message if len(self.new_sources.list) > 0: counter = 0 for source in self.new_sources.list: if source.invalid or source.disabled: continue self.new_sources.matcher.match(source) # sort the list self.new_sources.list.sort(key=self.get_comparable) for source in self.new_sources.list: if source.invalid or source.disabled: continue counter = counter + 1 line = self.source_renderer(source) self.store.append([line]) if counter == 0: self.error() return header = gettext.ngettext( "Install software additionally or " "only from this source?", "Install software additionally or " "only from these sources?", counter) body = _( "You can either add the following sources or replace your " "current sources by them. Only install software from " "trusted sources.") self.label.set_markup("<big><b>%s</b></big>\n\n%s" % (header, body)) else: self.error() return
def _update_countdown_message(self): self._second_message = gettext.ngettext("Settings will be reverted in %d second", "Settings will be reverted in %d seconds", self._countdown)
def get_comment(self): return ngettext("%d item", "%d items", trash_monitor.get_count()) \ % trash_monitor.get_count()
def _builtin_field_metadata(): # This is a function so that changing the UI language allows newly created # field metadata objects to have correctly translated labels for builtin # fields. return [ ('authors', { 'table': 'authors', 'column': 'name', 'link_column': 'author', 'category_sort': 'sort', 'datatype': 'text', 'is_multiple': { 'cache_to_list': ',', 'ui_to_list': '&', 'list_to_ui': ' & ' }, 'kind': 'field', 'name': _('Authors'), 'search_terms': ['authors', 'author'], 'is_custom': False, 'is_category': True, 'is_csp': False }), ('languages', { 'table': 'languages', 'column': 'lang_code', 'link_column': 'lang_code', 'category_sort': 'lang_code', 'datatype': 'text', 'is_multiple': { 'cache_to_list': ',', 'ui_to_list': ',', 'list_to_ui': ', ' }, 'kind': 'field', 'name': _('Languages'), 'search_terms': ['languages', 'language'], 'is_custom': False, 'is_category': True, 'is_csp': False }), ('series', { 'table': 'series', 'column': 'name', 'link_column': 'series', 'category_sort': '(title_sort(name))', 'datatype': 'series', 'is_multiple': {}, 'kind': 'field', 'name': ngettext('Series', 'Series', 1), 'search_terms': ['series'], 'is_custom': False, 'is_category': True, 'is_csp': False }), ('formats', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': { 'cache_to_list': ',', 'ui_to_list': ',', 'list_to_ui': ', ' }, 'kind': 'field', 'name': _('Formats'), 'search_terms': ['formats', 'format'], 'is_custom': False, 'is_category': True, 'is_csp': False }), ('publisher', { 'table': 'publishers', 'column': 'name', 'link_column': 'publisher', 'category_sort': 'name', 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': _('Publisher'), 'search_terms': ['publisher'], 'is_custom': False, 'is_category': True, 'is_csp': False }), ('rating', { 'table': 'ratings', 'column': 'rating', 'link_column': 'rating', 'category_sort': 'rating', 'datatype': 'rating', 'is_multiple': {}, 'kind': 'field', 'name': _('Rating'), 'search_terms': ['rating'], 'is_custom': False, 'is_category': True, 'is_csp': False }), ('news', { 'table': 'news', 'column': 'name', 'category_sort': 'name', 'datatype': None, 'is_multiple': {}, 'kind': 'category', 'name': _('News'), 'search_terms': [], 'is_custom': False, 'is_category': True, 'is_csp': False }), ('tags', { 'table': 'tags', 'column': 'name', 'link_column': 'tag', 'category_sort': 'name', 'datatype': 'text', 'is_multiple': { 'cache_to_list': ',', 'ui_to_list': ',', 'list_to_ui': ', ' }, 'kind': 'field', 'name': _('Tags'), 'search_terms': ['tags', 'tag'], 'is_custom': False, 'is_category': True, 'is_csp': False }), ('identifiers', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': { 'cache_to_list': ',', 'ui_to_list': ',', 'list_to_ui': ', ' }, 'kind': 'field', 'name': _('Identifiers'), 'search_terms': ['identifiers', 'identifier', 'isbn'], 'is_custom': False, 'is_category': True, 'is_csp': True }), ('author_sort', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': _('Author Sort'), 'search_terms': ['author_sort'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('au_map', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': { 'cache_to_list': ',', 'ui_to_list': None, 'list_to_ui': None }, 'kind': 'field', 'name': None, 'search_terms': [], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('comments', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': _('Comments'), 'search_terms': ['comments', 'comment'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('cover', { 'table': None, 'column': None, 'datatype': 'int', 'is_multiple': {}, 'kind': 'field', 'name': _('Cover'), 'search_terms': ['cover'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('id', { 'table': None, 'column': None, 'datatype': 'int', 'is_multiple': {}, 'kind': 'field', 'name': None, 'search_terms': ['id'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('last_modified', { 'table': None, 'column': None, 'datatype': 'datetime', 'is_multiple': {}, 'kind': 'field', 'name': _('Modified'), 'search_terms': ['last_modified'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('ondevice', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': _('On Device'), 'search_terms': ['ondevice'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('path', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': _('Path'), 'search_terms': [], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('pubdate', { 'table': None, 'column': None, 'datatype': 'datetime', 'is_multiple': {}, 'kind': 'field', 'name': _('Published'), 'search_terms': ['pubdate'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('marked', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': None, 'search_terms': ['marked'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('series_index', { 'table': None, 'column': None, 'datatype': 'float', 'is_multiple': {}, 'kind': 'field', 'name': None, 'search_terms': ['series_index'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('series_sort', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': _('Series Sort'), 'search_terms': ['series_sort'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('sort', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': _('Title Sort'), 'search_terms': ['title_sort'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('size', { 'table': None, 'column': None, 'datatype': 'float', 'is_multiple': {}, 'kind': 'field', 'name': _('Size'), 'search_terms': ['size'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('timestamp', { 'table': None, 'column': None, 'datatype': 'datetime', 'is_multiple': {}, 'kind': 'field', 'name': _('Date'), 'search_terms': ['date'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('title', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': _('Title'), 'search_terms': ['title'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ('uuid', { 'table': None, 'column': None, 'datatype': 'text', 'is_multiple': {}, 'kind': 'field', 'name': None, 'search_terms': ['uuid'], 'is_custom': False, 'is_category': False, 'is_csp': False }), ]
def _get_confirmation_alert_message(self, entries_len): return ngettext('Do you want to copy %d entry?', 'Do you want to copy %d entries?', entries_len) % (entries_len)
def ngettext(singular, plural, n): t = gettext.dngettext("YouTube", singular, plural, n) if t in (singular, plural): t = gettext.ngettext(singular, plural, n) return t
def main(args): """ Handles the command line arguments args is the list of arguments passed return (int): value to return to the OS as program exit code """ # arguments handling parser = argparse.ArgumentParser(description="File format conversion utility") parser.add_argument('--version', dest="version", action='store_true', help="show program's version number and exit") parser.add_argument("--input", "-i", dest="input", help="name of the input file") parser.add_argument("--tiles", "-t", dest="tiles", nargs="+", help="list of files acquired in tiles to re-assemble") parser.add_argument("--effcomp", dest="effcomp", help="name of a spectrum efficiency compensation table (in CSV format)") fmts = dataio.get_available_formats(os.O_WRONLY) parser.add_argument("--output", "-o", dest="output", help="name of the output file. " "The file format is derived from the extension (%s are supported)." % (" and ".join(fmts))) # TODO: automatically select pyramidal format if image > 4096px? parser.add_argument("--pyramid", "-p", dest="pyramid", action='store_true', help="Export the data in pyramidal format. " "It takes about 2x more space, but allows to visualise large images. " "Currently, only the TIFF format supports this option.") parser.add_argument("--minus", "-m", dest="minus", action='append', help="name of an acquisition file whose data is subtracted from the input file.") parser.add_argument("--weaver", "-w", dest="weaver", help="name of weaver to be used during stitching. Options: 'mean': MeanWeaver " "(blend overlapping regions of adjacent tiles), 'collage': CollageWeaver " "(paste tiles as-is at calculated position)", choices=("mean", "collage", "collage_reverse"), default='mean') parser.add_argument("--registrar", "-r", dest="registrar", help="name of registrar to be used during stitching. Options: 'identity': IdentityRegistrar " "(place tiles at original position), 'shift': ShiftRegistrar (use cross-correlation " "algorithm to correct for suboptimal stage movement), 'global_shift': GlobalShiftRegistrar " "(uses cross-correlation algorithm with global optimization)", choices=("identity", "shift", "global_shift"), default="global_shift") # TODO: --export (spatial) image that defaults to a HFW corresponding to the # smallest image, and can be overridden by --hfw xxx (in µm). # TODO: --range parameter to select which image to select from the input # (like: 1-4,5,6-10,12) options = parser.parse_args(args[1:]) # Cannot use the internal feature, because it doesn't support multi-line if options.version: print(odemis.__fullname__ + " " + odemis.__version__ + "\n" + odemis.__copyright__ + "\n" + "Licensed under the " + odemis.__license__) return 0 infn = options.input tifns = options.tiles ecfn = options.effcomp outfn = options.output if not (infn or tifns or ecfn) or not outfn: raise ValueError("--input/--tiles/--effcomp and --output arguments must be provided.") if sum(not not o for o in (infn, tifns, ecfn)) != 1: raise ValueError("--input, --tiles, --effcomp cannot be provided simultaneously.") if infn: data, thumbs = open_acq(infn) logging.info("File contains %d %s (and %d %s)", len(data), ngettext("image", "images", len(data)), len(thumbs), ngettext("thumbnail", "thumbnails", len(thumbs))) elif tifns: registration_method = {"identity": REGISTER_IDENTITY, "shift": REGISTER_SHIFT, "global_shift": REGISTER_GLOBAL_SHIFT}[options.registrar] weaving_method = {"collage": WEAVER_COLLAGE, "mean": WEAVER_MEAN, "collage_reverse": WEAVER_COLLAGE_REVERSE}[options.weaver] data = stitch(tifns, registration_method, weaving_method) thumbs = [] logging.info("File contains %d %s", len(data), ngettext("stream", "streams", len(data))) elif ecfn: data = open_ec(ecfn) thumbs = [] logging.info("File contains %d coefficients", data[0].shape[0]) if options.minus: if thumbs: logging.info("Dropping thumbnail due to subtraction") thumbs = [] for fn in options.minus: sdata, _ = open_acq(fn) data = minus(data, sdata) save_acq(outfn, data, thumbs, options.pyramid) logging.info("Successfully generated file %s", outfn)
import gettext n = 5 ng1 = gettext.ngettext("ngettext1", "ngettext1-plural", n) dng1 = gettext.dngettext("test-domain", "dngettext1", "dngettext1-plural", n) dng2 = gettext.dngettext("some-other-domain", "dngettext2", "dngettext2-plural", n)
def foo(): # Note: This will have the TRANSLATOR: tag but shouldn't # be included on the extracted stuff print ngettext('FooBar', 'FooBars', 1)
def show(self, tids=None): self.tids_todelete = tids or self.tids_todelete if not self.tids_todelete: # We must at least have something to delete! return [] # Get full task list to delete tasklist = [] self.update_tags = [] for tid in self.tids_todelete: task = self.req.get_task(tid) self.recursive_list_tasks(tasklist, task) # Prepare Labels singular = len(tasklist) cancel_text = ngettext("Keep selected task", "Keep selected tasks", singular) delete_text = ngettext("Permanently remove task", "Permanently remove tasks", singular) label_text = ngettext("Deleting a task cannot be undone, " "and will delete the following task: ", "Deleting a task cannot be undone, " "and will delete the following tasks: ", singular) label_text = label_text[0:label_text.find(":") + 1] missing_titles_count = len(tasklist) - self.MAXIMUM_TIDS_TO_SHOW if missing_titles_count >= 2: tasks = tasklist[: self.MAXIMUM_TIDS_TO_SHOW] titles_suffix = _(f"\nAnd {missing_titles_count:d} more tasks") else: tasks = tasklist titles_suffix = "" titles = "".join("\n• " + task.get_title() for task in tasks) # Build and run dialog dialog = Gtk.MessageDialog(transient_for=self.window, modal=True) dialog.add_button(cancel_text, Gtk.ResponseType.CANCEL) delete_btn = dialog.add_button(delete_text, Gtk.ResponseType.YES) delete_btn.get_style_context().add_class("destructive-action") dialog.props.use_markup = True dialog.props.text = "<span weight=\"bold\">" + label_text + "</span>" dialog.props.secondary_text = titles + titles_suffix response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: self.on_delete_confirm() elif response == Gtk.ResponseType.CANCEL: tasklist = [] return tasklist
def main(): global config, options # Parse command line... parser = ArgumentParser(usage="%(prog)s [options] " "[APPID[:VERCODE] [APPID[:VERCODE] ...]]") common.setup_global_opts(parser) parser.add_argument("appid", nargs='*', help=_("applicationId with optional versionCode in the form APPID[:VERCODE]")) metadata.add_metadata_arguments(parser) options = parser.parse_args() metadata.warnings_action = options.W config = common.read_config(options) if not ('jarsigner' in config and 'keytool' in config): logging.critical(_('Java JDK not found! Install in standard location or set java_paths!')) sys.exit(1) common.assert_config_keystore(config) log_dir = 'logs' if not os.path.isdir(log_dir): logging.info(_("Creating log directory")) os.makedirs(log_dir) tmp_dir = 'tmp' if not os.path.isdir(tmp_dir): logging.info(_("Creating temporary directory")) os.makedirs(tmp_dir) output_dir = 'repo' if not os.path.isdir(output_dir): logging.info(_("Creating output directory")) os.makedirs(output_dir) unsigned_dir = 'unsigned' if not os.path.isdir(unsigned_dir): logging.warning(_("No unsigned directory - nothing to do")) sys.exit(1) if not os.path.exists(config['keystore']): logging.error("Config error - missing '{0}'".format(config['keystore'])) sys.exit(1) # It was suggested at # https://dev.guardianproject.info/projects/bazaar/wiki/FDroid_Audit # that a package could be crafted, such that it would use the same signing # key as an existing app. While it may be theoretically possible for such a # colliding package ID to be generated, it seems virtually impossible that # the colliding ID would be something that would be a) a valid package ID, # and b) a sane-looking ID that would make its way into the repo. # Nonetheless, to be sure, before publishing we check that there are no # collisions, and refuse to do any publishing if that's the case... allapps = metadata.read_metadata() vercodes = common.read_pkg_args(options.appid, True) allaliases = [] for appid in allapps: m = hashlib.md5() m.update(appid.encode('utf-8')) keyalias = m.hexdigest()[:8] if keyalias in allaliases: logging.error(_("There is a keyalias collision - publishing halted")) sys.exit(1) allaliases.append(keyalias) logging.info(ngettext('{0} app, {1} key aliases', '{0} apps, {1} key aliases', len(allapps)).format(len(allapps), len(allaliases))) # Process any APKs or ZIPs that are waiting to be signed... for apkfile in sorted(glob.glob(os.path.join(unsigned_dir, '*.apk')) + glob.glob(os.path.join(unsigned_dir, '*.zip'))): appid, vercode = common.publishednameinfo(apkfile) apkfilename = os.path.basename(apkfile) if vercodes and appid not in vercodes: continue if appid in vercodes and vercodes[appid]: if vercode not in vercodes[appid]: continue logging.info(_("Processing {apkfilename}").format(apkfilename=apkfile)) # There ought to be valid metadata for this app, otherwise why are we # trying to publish it? if appid not in allapps: logging.error("Unexpected {0} found in unsigned directory" .format(apkfilename)) sys.exit(1) app = allapps[appid] if app.Binaries: # It's an app where we build from source, and verify the apk # contents against a developer's binary, and then publish their # version if everything checks out. # The binary should already have been retrieved during the build # process. srcapk = re.sub(r'.apk$', '.binary.apk', apkfile) # Compare our unsigned one with the downloaded one... compare_result = common.verify_apks(srcapk, apkfile, tmp_dir) if compare_result: logging.error("...verification failed - publish skipped : " + compare_result) else: # Success! So move the downloaded file to the repo, and remove # our built version. shutil.move(srcapk, os.path.join(output_dir, apkfilename)) os.remove(apkfile) publish_source_tarball(apkfilename, unsigned_dir, output_dir) logging.info('Published ' + apkfilename) elif apkfile.endswith('.zip'): # OTA ZIPs built by fdroid do not need to be signed by jarsigner, # just to be moved into place in the repo shutil.move(apkfile, os.path.join(output_dir, apkfilename)) publish_source_tarball(apkfilename, unsigned_dir, output_dir) logging.info('Published ' + apkfilename) else: # It's a 'normal' app, i.e. we sign and publish it... skipsigning = False # First we handle signatures for this app from local metadata signingfiles = common.metadata_find_developer_signing_files(appid, vercode) if signingfiles: # There's a signature of the app developer present in our # metadata. This means we're going to prepare both a locally # signed APK and a version signed with the developers key. signaturefile, signedfile, manifest = signingfiles with open(signaturefile, 'rb') as f: devfp = common.signer_fingerprint_short(f.read()) devsigned = '{}_{}_{}.apk'.format(appid, vercode, devfp) devsignedtmp = os.path.join(tmp_dir, devsigned) shutil.copy(apkfile, devsignedtmp) common.apk_implant_signatures(devsignedtmp, signaturefile, signedfile, manifest) if common.verify_apk_signature(devsignedtmp): shutil.move(devsignedtmp, os.path.join(output_dir, devsigned)) else: os.remove(devsignedtmp) logging.error('...verification failed - skipping: %s', devsigned) skipsigning = True # Now we sign with the F-Droid key. # Figure out the key alias name we'll use. Only the first 8 # characters are significant, so we'll use the first 8 from # the MD5 of the app's ID and hope there are no collisions. # If a collision does occur later, we're going to have to # come up with a new alogrithm, AND rename all existing keys # in the keystore! if not skipsigning: if appid in config['keyaliases']: # For this particular app, the key alias is overridden... keyalias = config['keyaliases'][appid] if keyalias.startswith('@'): m = hashlib.md5() m.update(keyalias[1:].encode('utf-8')) keyalias = m.hexdigest()[:8] else: m = hashlib.md5() m.update(appid.encode('utf-8')) keyalias = m.hexdigest()[:8] logging.info("Key alias: " + keyalias) # See if we already have a key for this application, and # if not generate one... env_vars = { 'FDROID_KEY_STORE_PASS': config['keystorepass'], 'FDROID_KEY_PASS': config['keypass'], } p = FDroidPopen([config['keytool'], '-list', '-alias', keyalias, '-keystore', config['keystore'], '-storepass:env', 'FDROID_KEY_STORE_PASS'], envs=env_vars) if p.returncode != 0: logging.info("Key does not exist - generating...") p = FDroidPopen([config['keytool'], '-genkey', '-keystore', config['keystore'], '-alias', keyalias, '-keyalg', 'RSA', '-keysize', '2048', '-validity', '10000', '-storepass:env', 'FDROID_KEY_STORE_PASS', '-keypass:env', 'FDROID_KEY_PASS', '-dname', config['keydname']], envs=env_vars) if p.returncode != 0: raise BuildException("Failed to generate key", p.output) signed_apk_path = os.path.join(output_dir, apkfilename) if os.path.exists(signed_apk_path): raise BuildException("Refusing to sign '{0}' file exists in both " "{1} and {2} folder.".format(apkfilename, unsigned_dir, output_dir)) # TODO replace below with common.sign_apk() once it has proven stable # Sign the application... p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'], '-storepass:env', 'FDROID_KEY_STORE_PASS', '-keypass:env', 'FDROID_KEY_PASS', '-sigalg', 'SHA1withRSA', '-digestalg', 'SHA1', apkfile, keyalias], envs=env_vars) if p.returncode != 0: raise BuildException(_("Failed to sign application"), p.output) # Zipalign it... p = SdkToolsPopen(['zipalign', '-v', '4', apkfile, os.path.join(output_dir, apkfilename)]) if p.returncode != 0: raise BuildException(_("Failed to align application")) os.remove(apkfile) publish_source_tarball(apkfilename, unsigned_dir, output_dir) logging.info('Published ' + apkfilename) store_stats_fdroid_signing_key_fingerprints(allapps.keys()) logging.info('published list signing-key fingerprints')
def ngettext(singular, plural, n): t = gettext.dngettext('EPGRefresh', singular, plural, n) if t in (singular, plural): t = gettext.ngettext(singular, plural, n) return t
def __init__(self): """ Init dialog """ self.__choosers = [] self.__cover_tid = None self.__mix_tid = None self.__popover = None cs_api_key = Lp().settings.get_value('cs-api-key').get_string() default_cs_api_key = Lp().settings.get_default_value( 'cs-api-key').get_string() if (not cs_api_key or cs_api_key == default_cs_api_key) and\ get_network_available() and\ Lp().notify is not None: Lp().notify.send( _("Google Web Services need a custom API key"), _("Lollypop needs this to search artwork and music.")) builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/SettingsDialog.ui') self.__progress = builder.get_object('progress') self.__infobar = builder.get_object('infobar') self.__reset_button = builder.get_object('reset_button') if Lp().lastfm is None or Lp().lastfm.is_goa: builder.get_object('lastfm_grid').hide() if Lp().scanner.is_locked(): builder.get_object('reset_button').set_sensitive(False) artists = Lp().artists.count() albums = Lp().albums.count() tracks = Lp().tracks.count() builder.get_object('artists').set_text( ngettext("%d artist", "%d artists", artists) % artists) builder.get_object('albums').set_text( ngettext("%d album", "%d albums", albums) % albums) builder.get_object('tracks').set_text( ngettext("%d track", "%d tracks", tracks) % tracks) self.__popover_content = builder.get_object('popover') duration = builder.get_object('duration') duration.set_range(1, 20) duration.set_value(Lp().settings.get_value('mix-duration').get_int32()) self.__settings_dialog = builder.get_object('settings_dialog') self.__settings_dialog.set_transient_for(Lp().window) if Lp().settings.get_value('disable-csd'): self.__settings_dialog.set_title(_("Preferences")) else: headerbar = builder.get_object('header_bar') headerbar.set_title(_("Preferences")) self.__settings_dialog.set_titlebar(headerbar) switch_scan = builder.get_object('switch_scan') switch_scan.set_state(Lp().settings.get_value('auto-update')) switch_view = builder.get_object('switch_dark') if Lp().gtk_application_prefer_dark_theme: switch_view.set_sensitive(False) else: switch_view.set_state(Lp().settings.get_value('dark-ui')) switch_background = builder.get_object('switch_background') switch_background.set_state(Lp().settings.get_value('background-mode')) switch_state = builder.get_object('switch_state') switch_state.set_state(Lp().settings.get_value('save-state')) switch_mix = builder.get_object('switch_mix') switch_mix.set_state(Lp().settings.get_value('mix')) self.__helper = TouchHelper(switch_mix, None, None) self.__helper.set_long_func(self.__mix_long_func, switch_mix) self.__helper.set_short_func(self.__mix_short_func, switch_mix) switch_mix_party = builder.get_object('switch_mix_party') switch_mix_party.set_state(Lp().settings.get_value('party-mix')) switch_librefm = builder.get_object('switch_librefm') switch_librefm.set_state(Lp().settings.get_value('use-librefm')) switch_artwork_tags = builder.get_object('switch_artwork_tags') # Check portal for kid3-cli can_set_cover = False try: bus = Gio.bus_get_sync(Gio.BusType.SESSION, None) proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None, 'org.gnome.Lollypop.Portal', '/org/gnome/LollypopPortal', 'org.gnome.Lollypop.Portal', None) can_set_cover = proxy.call_sync('CanSetCover', None, Gio.DBusCallFlags.NO_AUTO_START, 500, None)[0] except Exception as e: print( "You are missing lollypop-portal: " "https://github.com/gnumdk/lollypop-portal", e) if not can_set_cover: grid = builder.get_object('grid_behaviour') h = grid.child_get_property(switch_artwork_tags, 'height') w = grid.child_get_property(switch_artwork_tags, 'width') l = grid.child_get_property(switch_artwork_tags, 'left-attach') t = grid.child_get_property(switch_artwork_tags, 'top-attach') switch_artwork_tags.destroy() label = Gtk.Label.new(_("You need to install kid3-cli")) label.get_style_context().add_class('dim-label') label.set_property('halign', Gtk.Align.END) label.show() grid.attach(label, l, t, w, h) else: switch_artwork_tags.set_state( Lp().settings.get_value('save-to-tags')) if GLib.find_program_in_path("youtube-dl") is None: builder.get_object('charts_grid').hide() else: switch_charts = builder.get_object('switch_charts') switch_charts.set_state(Lp().settings.get_value('show-charts')) switch_genres = builder.get_object('switch_genres') switch_genres.set_state(Lp().settings.get_value('show-genres')) switch_compilations = builder.get_object('switch_compilations') switch_compilations.set_state( Lp().settings.get_value('show-compilations')) switch_artwork = builder.get_object('switch_artwork') switch_artwork.set_state(Lp().settings.get_value('artist-artwork')) switch_spotify = builder.get_object('switch_spotify') switch_spotify.set_state(Lp().settings.get_value('search-spotify')) switch_itunes = builder.get_object('switch_itunes') switch_itunes.set_state(Lp().settings.get_value('search-itunes')) if GLib.find_program_in_path("youtube-dl") is None: builder.get_object('yt-dl').show() combo_orderby = builder.get_object('combo_orderby') combo_orderby.set_active(Lp().settings.get_enum(('orderby'))) combo_preview = builder.get_object('combo_preview') scale_coversize = builder.get_object('scale_coversize') scale_coversize.set_range(150, 300) scale_coversize.set_value( Lp().settings.get_value('cover-size').get_int32()) self.__settings_dialog.connect('destroy', self.__edit_settings_close) builder.connect_signals(self) main_chooser_box = builder.get_object('main_chooser_box') self.__chooser_box = builder.get_object('chooser_box') self.__set_outputs(combo_preview) # # Music tab # dirs = [] for directory in Lp().settings.get_value('music-uris'): dirs.append(directory) # Main chooser self.__main_chooser = ChooserWidget() image = Gtk.Image.new_from_icon_name("list-add-symbolic", Gtk.IconSize.MENU) self.__main_chooser.set_icon(image) self.__main_chooser.set_action(self.__add_chooser) main_chooser_box.pack_start(self.__main_chooser, False, True, 0) if len(dirs) > 0: uri = dirs.pop(0) else: filename = GLib.get_user_special_dir( GLib.UserDirectory.DIRECTORY_MUSIC) if filename: uri = GLib.filename_to_uri(filename) else: uri = "" self.__main_chooser.set_dir(uri) # Others choosers for directory in dirs: self.__add_chooser(directory) # # Google tab # builder.get_object('cs-entry').set_text( Lp().settings.get_value('cs-api-key').get_string()) # # Last.fm tab # if Lp().lastfm is not None and Secret is not None: self.__test_img = builder.get_object('test_img') self.__login = builder.get_object('login') self.__password = builder.get_object('password') schema = Secret.Schema.new("org.gnome.Lollypop", Secret.SchemaFlags.NONE, SecretSchema) Secret.password_lookup(schema, SecretAttributes, None, self.__on_password_lookup) builder.get_object('lastfm_grid').set_sensitive(True) builder.get_object('lastfm_error').hide() self.__login.set_text( Lp().settings.get_value('lastfm-login').get_string())
def rebuild_oneconfview(): # FIXME for P: hide the search entry self.searchentry.hide() self.cat_docid_map = {} enq = self.enquirer query = xapian.Query("") if self.state.channel and self.state.channel.query: query = xapian.Query(xapian.Query.OP_AND, query, self.state.channel.query) i = 0 # First search: missing apps only xfilter = AppFilter(self.db, self.cache) xfilter.set_restricted_list(self.oneconf_additional_pkg) xfilter.set_not_installed_only(True) enq.set_query( query, sortmode=SortMethods.BY_ALPHABET, nonapps_visible=self.nonapps_visible, filter=xfilter, nonblocking_load=True, # we don't block this one for # better oneconf responsiveness persistent_duplicate_filter=(i > 0)) L = len(enq.matches) if L: cat_title = utf8( ngettext( u'%(amount)s item on “%(machine)s” not on this computer', u'%(amount)s items on “%(machine)s” not on this computer', L)) % { 'amount': L, 'machine': utf8(self.current_hostname) } i += L docs = enq.get_documents() self.cat_docid_map["missingpkg"] = set( [doc.get_docid() for doc in docs]) model.set_nocategory_documents( docs, untranslated_name="additionalpkg", display_name=cat_title) # Second search: additional apps xfilter.set_restricted_list(self.oneconf_missing_pkg) xfilter.set_not_installed_only(False) xfilter.set_installed_only(True) enq.set_query(query, sortmode=SortMethods.BY_ALPHABET, nonapps_visible=self.nonapps_visible, filter=xfilter, nonblocking_load=False, persistent_duplicate_filter=(i > 0)) L = len(enq.matches) if L: cat_title = utf8( ngettext( u'%(amount)s item on this computer not on “%(machine)s”', '%(amount)s items on this computer not on “%(machine)s”', L)) % { 'amount': L, 'machine': utf8(self.current_hostname) } i += L docs = enq.get_documents() self.cat_docid_map["additionalpkg"] = set( [doc.get_docid() for doc in docs]) model.set_nocategory_documents( docs, untranslated_name="additionalpkg", display_name=cat_title) if i: self.app_view.tree_view.set_cursor(Gtk.TreePath(), None, False) if i <= 10: self.app_view.tree_view.expand_all() # cache the installed app count self.installed_count = i self.app_view._append_appcount(self.installed_count, mode=AppView.DIFF_MODE) self.app_view.set_model(self.treefilter) if keep_state: self._restore_treeview_state(treeview_state) # hide the local spinner self.hide_installed_view_spinner() if window: window.set_cursor(None) self.emit("app-list-changed", i) return