├── ARTISTS ├── VERSION.in ├── NEWS ├── po ├── LINGUAS ├── POTFILES.in ├── pt.po ├── cs.po ├── fi.po ├── hu.po ├── sv.po ├── pl.po ├── sr.po ├── sr@latin.po ├── it.po ├── pt_BR.po ├── lt.po ├── sl.po ├── el.po ├── es.po └── de.po ├── data ├── icons │ ├── hicolor_apps_16x16_gnome-news.png │ ├── hicolor_apps_22x22_gnome-news.png │ ├── hicolor_apps_24x24_gnome-news.png │ ├── hicolor_apps_32x32_gnome-news.png │ ├── hicolor_apps_48x48_gnome-news.png │ ├── hicolor_apps_256x256_gnome-news.png │ ├── hicolor_apps_512x512_gnome-news.png │ ├── Makefile.am │ └── hicolor_apps_symbolic_gnome-news-symbolic.svg ├── org.gnome.News.desktop.in ├── theme │ ├── Adwaita.css │ └── reader.css ├── gtk │ └── menus.ui ├── gnome-news.gresource.xml ├── org.gnome.News.gschema.xml ├── org.gnome.News.appdata.xml.in ├── Makefile.am └── ui │ ├── window.ui │ ├── empty-view.ui │ └── headerbar.ui ├── .editorconfig ├── AUTHORS ├── gnomenews ├── Makefile.am ├── __init__.py ├── about.py ├── application.py ├── post.py ├── toolbar.py ├── window.py ├── tracker.py └── view.py ├── Dockerfile ├── circle.yml ├── README ├── configure.ac ├── gnome-news.doap ├── autogen.sh ├── Makefile.am ├── gnome-news.in └── git.mk /ARTISTS: -------------------------------------------------------------------------------- 1 | Allan Day 2 | -------------------------------------------------------------------------------- /VERSION.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_VERSION@ 2 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | ============= 2 | Version 0.0.1 3 | ============= 4 | 5 | This is the first preview of News. 6 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | cs 2 | de 3 | el 4 | es 5 | fi 6 | hu 7 | it 8 | lt 9 | pl 10 | pt 11 | pt_BR 12 | sl 13 | sr 14 | sr@latin 15 | sv 16 | -------------------------------------------------------------------------------- /data/icons/hicolor_apps_16x16_gnome-news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igor-raits/gnome-news/HEAD/data/icons/hicolor_apps_16x16_gnome-news.png -------------------------------------------------------------------------------- /data/icons/hicolor_apps_22x22_gnome-news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igor-raits/gnome-news/HEAD/data/icons/hicolor_apps_22x22_gnome-news.png -------------------------------------------------------------------------------- /data/icons/hicolor_apps_24x24_gnome-news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igor-raits/gnome-news/HEAD/data/icons/hicolor_apps_24x24_gnome-news.png -------------------------------------------------------------------------------- /data/icons/hicolor_apps_32x32_gnome-news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igor-raits/gnome-news/HEAD/data/icons/hicolor_apps_32x32_gnome-news.png -------------------------------------------------------------------------------- /data/icons/hicolor_apps_48x48_gnome-news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igor-raits/gnome-news/HEAD/data/icons/hicolor_apps_48x48_gnome-news.png -------------------------------------------------------------------------------- /data/icons/hicolor_apps_256x256_gnome-news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igor-raits/gnome-news/HEAD/data/icons/hicolor_apps_256x256_gnome-news.png -------------------------------------------------------------------------------- /data/icons/hicolor_apps_512x512_gnome-news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/igor-raits/gnome-news/HEAD/data/icons/hicolor_apps_512x512_gnome-news.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | end_of_line = lf 4 | insert_final_newline = true 5 | 6 | [*.py] 7 | indent_style = space 8 | indent_size = 4 9 | max_line_length = 100 10 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Generated by Makefile. Do not edit. 2 | 3 | Carlos Garnacho 4 | Felipe Borges 5 | Igor Gnatenko 6 | Michael Catanzaro 7 | Patrick Grififis 8 | Vadim Rutkovsky 9 | Yosef Or Boczko 10 | -------------------------------------------------------------------------------- /data/org.gnome.News.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | _Name=News 3 | _Comment=Feed reader for GNOME 4 | Exec=gnome-news 5 | Icon=gnome-news 6 | Terminal=false 7 | Type=Application 8 | Categories=Network;Feed;News;GNOME;GTK; 9 | Keywords=News;Feed; 10 | -------------------------------------------------------------------------------- /gnomenews/Makefile.am: -------------------------------------------------------------------------------- 1 | appdir = $(pythondir)/gnomenews/ 2 | 3 | app_PYTHON = \ 4 | __init__.py \ 5 | about.py \ 6 | application.py \ 7 | post.py \ 8 | window.py \ 9 | toolbar.py \ 10 | tracker.py \ 11 | view.py \ 12 | $(NULL) 13 | 14 | -include $(top_srcdir)/git.mk 15 | -------------------------------------------------------------------------------- /data/theme/Adwaita.css: -------------------------------------------------------------------------------- 1 | .feeds-list { 2 | padding-top: 20px; 3 | margin: 15px; 4 | } 5 | 6 | .feed-box { 7 | border: 1px solid #a1a1a1; 8 | box-shadow: inset 0 0 0 1px rgba(74, 144, 217, 0), 0 1px white; 9 | background-color: #ffffff; 10 | } 11 | 12 | .sidebar .list { 13 | background-color: @sidebar_bg_color; 14 | } 15 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM fedora:rawhide 2 | MAINTAINER Vadim Rutkovsky 3 | 4 | # Install dependencies 5 | RUN dnf install -y libappstream-glib-devel autoconf autoconf-archive automake \ 6 | intltool gcc glib2-devel make findutils tar xz 7 | 8 | ADD . /opt/gnome-news/ 9 | WORKDIR /opt/gnome-news/ 10 | 11 | # Build 12 | RUN ./autogen.sh && make 13 | 14 | # Install required check tools 15 | RUN dnf install -y python3-pep8 python3-pyflakes 16 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | # List of source files containing translatable strings. 2 | # Please keep this file sorted alphabetically. 3 | [encoding: UTF-8] 4 | [type: gettext/glade]data/gtk/menus.ui 5 | data/org.gnome.News.appdata.xml.in 6 | data/org.gnome.News.desktop.in 7 | data/org.gnome.News.gschema.xml 8 | [type: gettext/glade]data/ui/empty-view.ui 9 | [type: gettext/glade]data/ui/headerbar.ui 10 | gnomenews/application.py 11 | gnomenews/toolbar.py 12 | gnomenews/view.py 13 | gnomenews/window.py 14 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | services: 3 | - docker 4 | 5 | dependencies: 6 | cache_directories: 7 | - "~/docker" 8 | 9 | override: 10 | - if [[ -e ~/docker/image.tar ]]; then docker load -i ~/docker/image.tar; fi 11 | - docker build -t gnome-news . 12 | - mkdir -p ~/docker; docker save gnome-news > ~/docker/image.tar 13 | 14 | test: 15 | override: 16 | - docker run gnome-news python3-pyflakes gnomenews 17 | - docker run gnome-news python3-pep8 gnomenews/*.py --ignore=E501 18 | -------------------------------------------------------------------------------- /data/gtk/menus.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | About 7 | app.about 8 | 9 | 10 | Quit 11 | app.quit 12 | <Primary>q 13 | 14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | GNOME News 2 | ========== 3 | 4 | Requirements 5 | ------------ 6 | To use `autogen.sh` you need autoconf-archive. 7 | 8 | All GObject Introspection (typelib) modules you want to use gnome-news: 9 | * GLib-2.0 10 | * Gio-2.0 11 | * GObject-2.0 12 | * Gtk-3.0 >= 3.12 13 | * Gdk-3.0 >= 3.12 14 | * Tracker-1.0 >= 1.5.1 15 | * WebKit2-4.0 16 | 17 | Debugging 18 | --------- 19 | Remove all channels and feeds from tracker first. 20 | For adding channels use `tracker-miner-rss -a URL` or add from GUI. 21 | DON'T ADD FEEDS YOURSELF. 22 | 23 | Delete all messages/channels: 24 | $ tracker sparql -qu "DELETE { ?u a rdfs:Resource } WHERE { ?u a mfo:FeedChannel }" 25 | $ tracker sparql -qu "DELETE { ?u a rdfs:Resource } WHERE { ?u a mfo:FeedMessage }" 26 | -------------------------------------------------------------------------------- /data/gnome-news.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ../VERSION 5 | ../ARTISTS 6 | ../AUTHORS 7 | gtk/menus.ui 8 | ui/empty-view.ui 9 | ui/headerbar.ui 10 | ui/window.ui 11 | theme/Adwaita.css 12 | theme/reader.css 13 | 14 | 15 | -------------------------------------------------------------------------------- /data/org.gnome.News.gschema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | [768, 600] 6 | Window size 7 | Window size (width and height). 8 | 9 | 10 | [] 11 | Window position 12 | Window position (x and y). 13 | 14 | 15 | true 16 | Window maximized 17 | Window maximized state. 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT([GNOME News], 2 | [0.0.1], 3 | [https://github.com/ignatenkobrain/gnome-news/issues/new], 4 | [gnome-news], 5 | [https://wiki.gnome.org/Design/Apps/Potential/News]) 6 | AX_IS_RELEASE([git-directory]) 7 | 8 | AM_INIT_AUTOMAKE([check-news dist-xz no-dist-gzip subdir-objects]) 9 | AC_CONFIG_MACRO_DIR([m4]) 10 | AM_MAINTAINER_MODE([enable]) 11 | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) 12 | 13 | AM_PATH_PYTHON([3.4]) 14 | 15 | # GResources 16 | AC_PATH_PROG([GLIB_COMPILE_RESOURCES], [glib-compile-resources]) 17 | 18 | # Internationalisation 19 | GETTEXT_PACKAGE=gnome-news 20 | AC_SUBST(GETTEXT_PACKAGE) 21 | AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"], [gettext package name]) 22 | IT_PROG_INTLTOOL([0.50.2]) 23 | 24 | # GSettings 25 | AX_REQUIRE_DEFINED([GLIB_GSETTINGS]) 26 | GLIB_GSETTINGS 27 | 28 | # AppData 29 | AX_REQUIRE_DEFINED([APPSTREAM_XML]) 30 | APPSTREAM_XML 31 | 32 | AC_CONFIG_FILES([ 33 | VERSION 34 | Makefile 35 | data/Makefile 36 | data/icons/Makefile 37 | gnomenews/Makefile 38 | po/Makefile.in 39 | ]) 40 | AC_OUTPUT 41 | -------------------------------------------------------------------------------- /data/org.gnome.News.appdata.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.gnome.News.desktop 5 | CC0-1.0 6 | GPL-3.0+ 7 | 8 | <_name>News 9 | 10 | <_summary>Feed Reader 11 | 12 | 13 | <_p> 14 | GNOME News can be used to read news. 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | https://wiki.gnome.org/Design/Apps/Potential/News 26 | https://github.com/ignatenkobrain/gnome-news/issues 27 | ignatenko@src.gnome.org 28 | 29 | -------------------------------------------------------------------------------- /gnome-news.doap: -------------------------------------------------------------------------------- 1 | 6 | 7 | News 8 | Feed Reader 9 | 10 | 11 | 12 | A GNOME 3 Feed Reader. 13 | 14 | 15 | Python 16 | 17 | 18 | 19 | Igor Gnatenko 20 | 21 | ignatenko 22 | 23 | 24 | 25 | 26 | Vadim Rutkovsky 27 | 28 | vrutkovsky 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Run this to generate all the initial makefiles, etc. 3 | test -n "$srcdir" || srcdir=`dirname "$0"` 4 | test -n "$srcdir" || srcdir=. 5 | 6 | olddir=`pwd` 7 | 8 | cd "$srcdir" 9 | 10 | (test -f $srcdir/configure.ac) || { 11 | echo "**Error**: Directory "\`$srcdir\'" does not look like the top-level project directory" 12 | exit 1 13 | } 14 | 15 | PKG_NAME=`autoconf --trace 'AC_INIT:$1' "$srcdir/configure.ac"` 16 | 17 | if [ "$#" = 0 -a "x$NOCONFIGURE" = "x" ]; then 18 | echo "**Warning**: I am going to run \`configure' with no arguments." >&2 19 | echo "If you wish to pass any to it, please specify them on the" >&2 20 | echo \`$0\'" command line." >&2 21 | echo "" >&2 22 | fi 23 | 24 | touch ChangeLog 25 | touch INSTALL 26 | 27 | set -x 28 | 29 | aclocal --install || exit 1 30 | glib-gettextize --force --copy || exit 1 31 | intltoolize --force --copy --automake || exit 1 32 | autoreconf --verbose --force --install -Wno-portability || exit 1 33 | 34 | { set +x; } 2>/dev/null 35 | 36 | cd "$olddir" 37 | 38 | if [ "$NOCONFIGURE" = "" ]; then 39 | set -x 40 | $srcdir/configure "$@" || exit 1 41 | { set +x; } 2>/dev/null 42 | 43 | if [ "$1" = "--help" ]; then exit 0 else 44 | echo "Now type \`make\' to compile $PKG_NAME" || exit 1 45 | fi 46 | else 47 | echo "Skipping configure process." 48 | fi 49 | -------------------------------------------------------------------------------- /data/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = icons 2 | 3 | # Desktop file 4 | @INTLTOOL_DESKTOP_RULE@ 5 | desktopdir = $(datadir)/applications 6 | desktop_in_files = org.gnome.News.desktop.in 7 | desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) 8 | 9 | # GSettings 10 | @GSETTINGS_RULES@ 11 | gsettings_SCHEMAS = org.gnome.News.gschema.xml 12 | # For uninstalled use 13 | gschemas.compiled: $(gsettings_SCHEMAS) Makefile 14 | $(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) $(builddir) 15 | 16 | # AppData 17 | @INTLTOOL_XML_RULE@ 18 | @APPSTREAM_XML_RULES@ 19 | appstream_in_files = org.gnome.News.appdata.xml.in 20 | appstream_XML = $(appstream_in_files:.appdata.xml.in=.appdata.xml) 21 | 22 | resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --sourcedir=$(builddir) --generate-dependencies $(builddir)/gnome-news.gresource.xml) 23 | gnome-news.gresource: gnome-news.gresource.xml $(resource_files) 24 | $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --sourcedir=$(builddir) $< 25 | 26 | resourcedir = $(pkgdatadir) 27 | resource_DATA = gnome-news.gresource 28 | 29 | EXTRA_DIST = \ 30 | $(desktop_in_files) \ 31 | $(appstream_in_files) \ 32 | $(gsettings_SCHEMAS) \ 33 | $(resource_files) \ 34 | gnome-news.gresource.xml \ 35 | $(NULL) 36 | 37 | CLEANFILES = \ 38 | $(desktop_DATA) \ 39 | gnome-news.gresource \ 40 | $(appstream_XML) \ 41 | *.valid \ 42 | gschemas.compiled \ 43 | $(NULL) 44 | 45 | all-local: gschemas.compiled 46 | 47 | -include $(top_srcdir)/git.mk 48 | -------------------------------------------------------------------------------- /gnomenews/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Igor Gnatenko 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | from itertools import chain 17 | import logging 18 | import time 19 | logger = logging.getLogger(__name__) 20 | tabbing = 0 21 | 22 | 23 | def log(fn): 24 | if logger.getEffectiveLevel() > logging.DEBUG: 25 | return fn 26 | 27 | def wrapped(*v, **k): 28 | global tabbing 29 | name = fn.__name__ 30 | module = fn.__module__ 31 | filename = fn.__code__.co_filename.split('/')[-1] 32 | lineno = fn.__code__.co_firstlineno 33 | params = ", ".join(map(repr, chain(v, k.values()))) 34 | 35 | tabbing += 1 36 | start = time.time() 37 | retval = fn(*v, **k) 38 | elapsed = time.time() - start 39 | tabbing -= 1 40 | elapsed_time = '' 41 | if elapsed > 0.5: 42 | elapsed_time = ', took %02f' % elapsed 43 | logger.debug("%s:%s\t%s%s.%s(%s), returned %s%s", 44 | filename, lineno, '|' * tabbing, module, name, params, retval, elapsed_time) 45 | 46 | return retval 47 | return wrapped 48 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = data gnomenews po 2 | 3 | bin_SCRIPTS = gnome-news 4 | 5 | EXTRA_DIST = \ 6 | AUTHORS \ 7 | gnome-news.in \ 8 | VERSION.in \ 9 | $(NULL) 10 | 11 | CLEANFILES = \ 12 | $(bin_SCRIPTS) \ 13 | $(NULL) 14 | 15 | MAINTAINERCLEANFILES = \ 16 | $(GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL) \ 17 | $(GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN) \ 18 | $(GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL) 19 | 20 | DISTCHECK_CONFIGURE_FLAGS = \ 21 | --enable-appstream-util \ 22 | $(NULL) 23 | 24 | GITIGNOREFILES = \ 25 | **/*.swp \ 26 | m4/ \ 27 | autom4te.cache/ \ 28 | aclocal.m4 \ 29 | ChangeLog \ 30 | INSTALL \ 31 | install-sh \ 32 | missing \ 33 | py-compile \ 34 | VERSION \ 35 | gnomenews/__pycache__ \ 36 | $(NULL) 37 | 38 | dist-hook: AUTHORS 39 | 40 | AUTHORS: 41 | @if test -d "$(srcdir)/.git"; \ 42 | then \ 43 | echo Creating $@ && \ 44 | ( cd "$(top_srcdir)" && \ 45 | echo '# Generated by Makefile. Do not edit.'; echo; \ 46 | git log --no-merges --pretty=format:"%an" \ 47 | | sort | uniq ) > $@.tmp \ 48 | && mv -f $@.tmp $@ \ 49 | || ( rm -f $@.tmp ; \ 50 | echo Failed to generate $@ >&2 ); \ 51 | fi 52 | 53 | .PHONY: AUTHORS 54 | 55 | gnome-news: gnome-news.in Makefile 56 | $(AM_V_GEN)sed \ 57 | -e s!\@srcdir\@!$(abs_top_srcdir)! \ 58 | -e s!\@prefix\@!$(prefix)! \ 59 | -e s!\@datadir\@!$(datadir)! \ 60 | -e s!\@pkgdatadir\@!$(pkgdatadir)! \ 61 | -e s!\@libexecdir\@!$(libexecdir)! \ 62 | -e s!\@libdir\@!$(libdir)! \ 63 | -e s!\@pkglibdir\@!$(pkglibdir)! \ 64 | -e s!\@localedir\@!$(localedir)! \ 65 | -e s!\@pythondir\@!$(pythondir)! \ 66 | -e s!\@pyexecdir\@!$(pyexecdir)! \ 67 | -e s!\@PACKAGE\@!$(PACKAGE)! \ 68 | -e s!\@VERSION\@!$(VERSION)! \ 69 | < $< > $@ 70 | chmod a+x $@ 71 | 72 | all-local: gnome-news 73 | 74 | -include $(top_srcdir)/git.mk 75 | -------------------------------------------------------------------------------- /gnomenews/about.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Igor Gnatenko 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | from gi.repository import Gtk, Gio 17 | 18 | 19 | class AboutDialog(Gtk.AboutDialog): 20 | def __init__(self, parent): 21 | Gtk.AboutDialog.__init__(self) 22 | self.parent = parent 23 | self.set_modal(True) 24 | self.set_transient_for(parent) 25 | self.set_artists(self._read_file("ARTISTS")) 26 | self.set_authors(self._read_file("AUTHORS")) 27 | self.set_copyright("Copyright © 2015 GNOME Foundation") 28 | self.set_license_type(Gtk.License.GPL_3_0) 29 | self.set_version(self._read_file("VERSION")[0]) 30 | self.set_website("https://wiki.gnome.org/Design/Apps/Potential/News") 31 | self.set_logo_icon_name("gnome-news") 32 | 33 | @staticmethod 34 | def _read_file(fname): 35 | f = Gio.File.new_for_uri("resource:///org/gnome/News/%s" % fname) 36 | lines = f.load_contents(None)[1].decode().split("\n") 37 | # Drop lines which empty or starts with '#' 38 | lines_filtered = list(filter(lambda k: not k.startswith("#"), filter(None, lines))) 39 | return lines_filtered 40 | -------------------------------------------------------------------------------- /data/icons/Makefile.am: -------------------------------------------------------------------------------- 1 | NULL = 2 | 3 | public_icons_themes = \ 4 | hicolor \ 5 | $(NULL) 6 | 7 | public_icons = \ 8 | hicolor_apps_16x16_gnome-news.png \ 9 | hicolor_apps_22x22_gnome-news.png \ 10 | hicolor_apps_24x24_gnome-news.png \ 11 | hicolor_apps_32x32_gnome-news.png \ 12 | hicolor_apps_48x48_gnome-news.png \ 13 | hicolor_apps_256x256_gnome-news.png \ 14 | hicolor_apps_symbolic_gnome-news-symbolic.svg \ 15 | $(NULL) 16 | 17 | noinst_DATA = \ 18 | gnome-news.svg \ 19 | $(NULL) 20 | 21 | EXTRA_DIST = \ 22 | $(public_icons) \ 23 | $(noinst_DATA) \ 24 | $(NULL) 25 | 26 | ############################################################################### 27 | 28 | gtk_update_icon_cache = gtk-update-icon-cache -f -t 29 | 30 | update-icon-cache: 31 | @-if test -z "$(DESTDIR)"; then \ 32 | echo "Updating Gtk icon cache."; \ 33 | for theme in $(public_icons_themes); do \ 34 | $(gtk_update_icon_cache) $(datadir)/icons/$$theme; \ 35 | done; \ 36 | else \ 37 | echo "*** Icon cache not updated. After (un)install, run this:"; \ 38 | for theme in $(public_icons_themes); do \ 39 | echo "*** $(gtk_update_icon_cache) $(datadir)/icons/$$theme"; \ 40 | done; \ 41 | fi 42 | 43 | install-icons: 44 | for icon in $(public_icons); do \ 45 | THEME=`echo $$icon | cut -d_ -f1`; \ 46 | CONTEXT=`echo $$icon | cut -d_ -f2`; \ 47 | SIZE=`echo $$icon | cut -d_ -f3`; \ 48 | ICONFILE=`echo $$icon | cut -d_ -f4`; \ 49 | mkdir -p $(DESTDIR)$(datadir)/icons/$$THEME/$$SIZE/$$CONTEXT; \ 50 | $(INSTALL_DATA) $(srcdir)/$$icon $(DESTDIR)$(datadir)/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \ 51 | done 52 | 53 | uninstall-icons: 54 | -for icon in $(public_icons); do \ 55 | THEME=`echo $$icon | cut -d_ -f1`; \ 56 | CONTEXT=`echo $$icon | cut -d_ -f2`; \ 57 | SIZE=`echo $$icon | cut -d_ -f3`; \ 58 | ICONFILE=`echo $$icon | cut -d_ -f4`; \ 59 | rm -f $(DESTDIR)$(datadir)/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \ 60 | done 61 | 62 | install-data-local: install-icons 63 | install-data-hook: update-icon-cache 64 | 65 | uninstall-local: uninstall-icons 66 | uninstall-hook: update-icon-cache 67 | 68 | -include $(top_srcdir)/git.mk 69 | -------------------------------------------------------------------------------- /gnome-news.in: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import signal 5 | import os 6 | import locale 7 | import gettext 8 | 9 | # Make sure we'll find the pygobject module, even in JHBuild 10 | sys.path.insert(1, "@pyexecdir@") 11 | # Make sure we'll find the gnomenews module, even in JHBuild 12 | sys.path.insert(1, "@pythondir@") 13 | 14 | import argparse 15 | import logging 16 | try: 17 | import gi 18 | except ImportError: 19 | sys.exit("Missing pygobject") 20 | try: 21 | gi.require_version('GLib', '2.0') 22 | gi.require_version('Gio', '2.0') 23 | gi.require_version('GObject', '2.0') 24 | gi.require_version('Gtk', '3.0') 25 | gi.require_version('Gdk', '3.0') 26 | gi.require_version('Tracker', '1.0') 27 | gi.require_version('WebKit2', '4.0') 28 | except ValueError as e: 29 | sys.exit("Missing dependency: {}".format(e)) 30 | from gi.repository import Gio 31 | import gnomenews 32 | 33 | localedir = "@localedir@" 34 | srcdir = os.path.abspath(os.path.join(os.path.dirname(gnomenews.__file__), "..")) 35 | if os.path.exists(os.path.join(srcdir, "gnome-news.doap")): 36 | print("Running from source tree, using local files") 37 | pkgdatadir = os.path.join(srcdir, "data") 38 | if not os.environ.get("GSETTINGS_SCHEMA_DIR"): 39 | os.environ["GSETTINGS_SCHEMA_DIR"] = pkgdatadir 40 | else: 41 | pkgdatadir = "@pkgdatadir@" 42 | 43 | def install_excepthook(): 44 | """ Make sure we exit when an unhandled exception occurs. """ 45 | from gi.repository import Gtk 46 | old_hook = sys.excepthook 47 | 48 | def new_hook(etype, evalue, etb): 49 | old_hook(etype, evalue, etb) 50 | while Gtk.main_level(): 51 | Gtk.main_quit() 52 | sys.exit() 53 | sys.excepthook = new_hook 54 | 55 | if __name__ == "__main__": 56 | install_excepthook() 57 | 58 | parser = argparse.ArgumentParser() 59 | parser.add_argument("-d", "--debug", action="store_true", default=False, dest="debug") 60 | args = parser.parse_args() 61 | if args.debug: 62 | logging.basicConfig( 63 | level=logging.DEBUG, 64 | format="%(asctime)s %(levelname)s\t%(message)s", 65 | datefmt="%H:%M:%S") 66 | os.environ["TRACKER_VERBOSITY"] = "3" 67 | # Gtk hates "-d" switch, so lets drop it 68 | if "-d" in sys.argv: 69 | sys.argv.remove("-d") 70 | if "--debug" in sys.argv: 71 | sys.argv.remove("--debug") 72 | else: 73 | logging.basicConfig( 74 | level=logging.WARN, 75 | format="%(asctime)s %(levelname)s\t%(message)s", 76 | datefmt="%H:%M:%S") 77 | 78 | locale.bindtextdomain("gnome-news", localedir) 79 | locale.textdomain("gnome-news") 80 | gettext.bindtextdomain("gnome-news", localedir) 81 | gettext.textdomain("gnome-news") 82 | 83 | resource = Gio.resource_load(os.path.join(pkgdatadir, "gnome-news.gresource")) 84 | Gio.Resource._register(resource) 85 | 86 | from gnomenews.application import Application 87 | 88 | app = Application() 89 | signal.signal(signal.SIGINT, signal.SIG_DFL) 90 | exit_status = app.run(sys.argv) 91 | sys.exit(exit_status) 92 | -------------------------------------------------------------------------------- /po/pt.po: -------------------------------------------------------------------------------- 1 | # Portuguese translation for gnome-news. 2 | # Copyright (C) 2015 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # Pedro Albuquerque , 2015. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: gnome-news master\n" 9 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 10 | "news&keywords=I18N+L10N&component=general\n" 11 | "POT-Creation-Date: 2015-12-04 21:27+0000\n" 12 | "PO-Revision-Date: 2015-12-05 08:20+0000\n" 13 | "Last-Translator: Pedro Albuquerque \n" 14 | "Language-Team: Português \n" 15 | "Language: pt\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\\n\n" 20 | "X-Generator: Gtranslator 2.91.6\n" 21 | 22 | #: ../data/HeaderBar.ui.h:1 23 | msgid "Add a new feed" 24 | msgstr "Adicionar nova fonte" 25 | 26 | #: ../data/HeaderBar.ui.h:2 27 | msgid "Enter feed address to add" 28 | msgstr "Insira o endereço da fonte a adicionar" 29 | 30 | #: ../data/HeaderBar.ui.h:3 31 | msgid "Add" 32 | msgstr "Adicionar" 33 | 34 | #: ../data/HeaderBar.ui.h:4 35 | msgid "You are already subscribed to that feed!" 36 | msgstr "Já subscreveu essa fonte!" 37 | 38 | #: ../data/HeaderBar.ui.h:5 39 | msgid "Select All" 40 | msgstr "Selecionar tudo" 41 | 42 | #: ../data/HeaderBar.ui.h:6 43 | msgid "Select None" 44 | msgstr "Não selecionar nada" 45 | 46 | #: ../data/HeaderBar.ui.h:7 47 | msgid "Click on items to select them" 48 | msgstr "Clique nos itens para os selecionar" 49 | 50 | #: ../data/HeaderBar.ui.h:8 51 | msgid "Search" 52 | msgstr "Procurar" 53 | 54 | #: ../data/HeaderBar.ui.h:9 55 | msgid "Select" 56 | msgstr "Selecionar" 57 | 58 | #: ../data/HeaderBar.ui.h:10 59 | msgid "Back" 60 | msgstr "Recuar" 61 | 62 | #: ../data/Menu.ui.h:1 63 | msgid "About" 64 | msgstr "Sobre" 65 | 66 | #: ../data/Menu.ui.h:2 67 | msgid "Quit" 68 | msgstr "Sair" 69 | 70 | #. TRANSLATORS: the application name 71 | #: ../data/org.gnome.News.desktop.in.h:1 72 | #: ../data/org.gnome.News.appdata.xml.in.h:2 ../gnomenews/application.py:36 73 | #: ../gnomenews/window.py:35 74 | msgid "News" 75 | msgstr "Notícias" 76 | 77 | #: ../data/org.gnome.News.desktop.in.h:2 78 | msgid "Feed reader for GNOME" 79 | msgstr "Leitor de fontes para o GNOME" 80 | 81 | #. TRANSLATORS: one-line description for the app 82 | #: ../data/org.gnome.News.appdata.xml.in.h:4 83 | msgid "Feed Reader" 84 | msgstr "Leitor de fontes" 85 | 86 | #. TRANSLATORS: AppData description marketing paragraph 87 | #: ../data/org.gnome.News.appdata.xml.in.h:6 88 | msgid "GNOME News can be used to read news." 89 | msgstr "O Notícias do GNOME pode ser usado para ler notícias." 90 | 91 | #: ../gnomenews/view.py:116 92 | msgid "Unknown feed" 93 | msgstr "Fonte desconhecida" 94 | 95 | #: ../gnomenews/view.py:231 96 | msgid "New" 97 | msgstr "Nova" 98 | 99 | #: ../gnomenews/view.py:240 100 | msgid "Feeds" 101 | msgstr "Fontes" 102 | 103 | #: ../gnomenews/view.py:289 104 | msgid "Starred" 105 | msgstr "Com estrela" 106 | -------------------------------------------------------------------------------- /data/theme/reader.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 4 | * You can obtain one at http://mozilla.org/MPL/2.0/. 5 | * 6 | * Alternatively, the contents of this file may be used under the terms 7 | * of the GNU General Public License Version 3, as described below: 8 | * 9 | * This file is free software: you may copy, redistribute and/or modify 10 | * it under the terms of the GNU General Public License as published by the 11 | * Free Software Foundation, either version 3 of the License, or (at your 12 | * option) any later version. 13 | * 14 | * This file is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 17 | * Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program. If not, see http://www.gnu.org/licenses/. 21 | * 22 | * Changes 23 | * - replace Firefox specific css extensions with WebKit css extensions 24 | * - append FeedView css selectors 25 | */ 26 | 27 | h1, 28 | h2, 29 | h3 { 30 | font-weight: bold; 31 | } 32 | 33 | h1 { 34 | font-size: 1.6em; 35 | line-height: 1.25em; 36 | } 37 | 38 | h2 { 39 | font-size: 1.2em; 40 | line-height: 1.51em; 41 | } 42 | 43 | h3 { 44 | font-size: 1em; 45 | line-height: 1.66em; 46 | } 47 | 48 | a { 49 | text-decoration: underline; 50 | font-weight: normal; 51 | } 52 | 53 | a, 54 | a:visited, 55 | a:hover, 56 | a:active { 57 | color: #0095dd; 58 | } 59 | 60 | * { 61 | max-width: 100%; 62 | height: auto; 63 | } 64 | 65 | p, 66 | code, 67 | pre, 68 | blockquote, 69 | ul, 70 | ol, 71 | li, 72 | figure, 73 | .wp-caption { 74 | margin: 0 0 30px 0; 75 | } 76 | 77 | p > img:only-child, 78 | p > a:only-child > img:only-child, 79 | .wp-caption img, 80 | figure img { 81 | display: block; 82 | } 83 | 84 | .caption, 85 | .wp-caption-text, 86 | figcaption { 87 | font-size: 0.9em; 88 | line-height: 1.48em; 89 | font-style: italic; 90 | } 91 | 92 | code, 93 | pre { 94 | white-space: pre-wrap; 95 | } 96 | 97 | blockquote { 98 | padding: 0; 99 | -webkit-padding-start: 16px; 100 | } 101 | 102 | ul, 103 | ol { 104 | padding: 0; 105 | } 106 | 107 | ul { 108 | -webkit-padding-start: 30px; 109 | list-style: disc; 110 | } 111 | 112 | ol { 113 | -webkit-padding-start: 30px; 114 | list-style: decimal; 115 | } 116 | 117 | /* Hide elements with common "hidden" class names */ 118 | .visually-hidden, 119 | .visuallyhidden, 120 | .hidden, 121 | .invisible, 122 | .sr-only { 123 | display: none; 124 | } 125 | 126 | /* FeedView */ 127 | 128 | article { 129 | overflow-y: hidden; 130 | margin: 20px auto; 131 | width: 640px; 132 | color: #333; 133 | font-family: Sans; 134 | font-size: 18px; 135 | word-wrap:break-word; 136 | } 137 | 138 | #footer { 139 | font-size: 14px; 140 | color: #777; 141 | } 142 | 143 | #footer a:link, 144 | #footer a:active, 145 | #footer a:visited { 146 | text-decoration: none; 147 | color: #777; 148 | } 149 | 150 | #footer a:hover { 151 | text-decoration: underline; 152 | } 153 | -------------------------------------------------------------------------------- /gnomenews/application.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Vadim Rutkovsky 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | 17 | from gi.repository import Gtk, GLib, Gio, Gdk 18 | from gettext import gettext as _ 19 | 20 | CACHE_PATH = GLib.get_user_cache_dir() 21 | 22 | from gnomenews import log 23 | from gnomenews.window import Window 24 | from gnomenews.about import AboutDialog 25 | 26 | import os 27 | import os.path 28 | 29 | 30 | 31 | class Application(Gtk.Application): 32 | @log 33 | def __init__(self): 34 | Gtk.Application.__init__(self, 35 | application_id='org.gnome.News', 36 | flags=Gio.ApplicationFlags.FLAGS_NONE) 37 | GLib.set_application_name(_("News")) 38 | GLib.set_prgname('gnome-news') 39 | self.settings = Gio.Settings.new('org.gnome.News') 40 | 41 | cssProviderFile = Gio.File.new_for_uri('resource:///org/gnome/News/theme/Adwaita.css') 42 | cssProvider = Gtk.CssProvider() 43 | cssProvider.load_from_file(cssProviderFile) 44 | screen = Gdk.Screen.get_default() 45 | styleContext = Gtk.StyleContext() 46 | styleContext.add_provider_for_screen(screen, cssProvider, 47 | Gtk.STYLE_PROVIDER_PRIORITY_USER) 48 | 49 | self._window = None 50 | self._about_dialog = None 51 | 52 | delete_action = Gio.SimpleAction.new('delete_channel', parameter_type=GLib.VariantType.new('i')) 53 | self.add_action(delete_action) 54 | 55 | self.create_cache() 56 | 57 | @log 58 | def create_cache(self): 59 | if not os.path.isdir(CACHE_PATH): 60 | GLib.mkdir_with_parents(CACHE_PATH, 0o0755) 61 | 62 | @log 63 | def do_startup(self): 64 | actions = ["about", "quit"] 65 | 66 | for action_name in actions: 67 | action = Gio.SimpleAction.new(action_name, None) 68 | action.connect("activate", getattr(self, action_name)) 69 | self.add_action(action) 70 | 71 | Gtk.Application.do_startup(self) 72 | 73 | @log 74 | def quit(self, action=None, param=None): 75 | self._window.destroy() 76 | 77 | @log 78 | def about(self, action, param): 79 | def on_destroy(window): 80 | self._about_dialog = None 81 | 82 | if not self._about_dialog: 83 | self._about_dialog = AboutDialog(self._window) 84 | 85 | self._about_dialog.connect("destroy", on_destroy) 86 | self._about_dialog.present() 87 | 88 | def do_activate(self): 89 | if not self._window: 90 | self._window = Window(self) 91 | 92 | self._window.present() 93 | -------------------------------------------------------------------------------- /data/icons/hicolor_apps_symbolic_gnome-news-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | image/svg+xml 9 | 10 | Gnome Symbolic Icon Theme 11 | 12 | 13 | 14 | 15 | 16 | 17 | Gnome Symbolic Icon Theme 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /gnomenews/post.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Felipe Borges 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | from gi.repository import WebKit2, GObject, GLib 17 | 18 | import hashlib 19 | import os.path 20 | import re 21 | 22 | from gnomenews import log 23 | from gnomenews.application import CACHE_PATH 24 | import logging 25 | logger = logging.getLogger(__name__) 26 | 27 | THUMBNAIL_WIDTH = 256 28 | THUMBNAIL_HEIGHT = 256 29 | 30 | NAME_REGEX = re.compile("\(([^\)]+)\)") 31 | 32 | 33 | class Post(GObject.GObject): 34 | 35 | __gsignals__ = { 36 | 'info-updated': (GObject.SignalFlags.RUN_FIRST, None, (GObject.GObject,)), 37 | } 38 | 39 | @log 40 | def __init__(self, cursor): 41 | GObject.GObject.__init__(self) 42 | 43 | self.cursor = cursor 44 | 45 | self.title = cursor['title'] 46 | self.content = cursor['content'] 47 | self.url = cursor['url'] 48 | self.is_read = cursor['is_read'] 49 | self.is_starred = cursor['is_starred'] 50 | 51 | self.author = self.sanitize_author(cursor['fullname']) 52 | self.author_email = cursor['author_email'] 53 | self.author_homepage = cursor['author_homepage'] 54 | 55 | # Check cache first 56 | hashed_url = hashlib.md5(cursor['url'].encode()).hexdigest() 57 | self.cached_thumbnail_path = os.path.join(CACHE_PATH, '%s.png' % hashed_url) 58 | 59 | GLib.idle_add(self.try_to_load_image_from_cache) 60 | 61 | @staticmethod 62 | @log 63 | def sanitize_author(author): 64 | """Separates Name from Email in an author string 65 | 66 | RSS 2.0 from https://planet.gnome.org/rss20.xml returns 67 | "me@example.com - (Firstname Lastname)" as author fiels. This is a 68 | workaround for it. 69 | 70 | TODO: fix this hack in pluggable methods or in libgrss 71 | 72 | Args: 73 | author (str): an author string extracted from a rss feed 74 | """ 75 | try: 76 | return re.findall(NAME_REGEX, author)[0] 77 | except: 78 | return author 79 | 80 | @log 81 | def try_to_load_image_from_cache(self): 82 | if os.path.isfile(self.cached_thumbnail_path): 83 | self.thumbnail = self.cached_thumbnail_path 84 | self.emit('info-updated', self) 85 | else: 86 | self.webview = WebKit2.WebView(sensitive=False) 87 | self.webview.connect('load-changed', self._draw_thumbnail) 88 | self._generate_thumbnail() 89 | 90 | @log 91 | def _generate_thumbnail(self): 92 | self.webview.load_html(""" 93 |
94 |

%s

95 | %s 96 | %s 97 |
""" % (self.title, self.author, self.content)) 98 | 99 | @log 100 | def _draw_thumbnail(self, webview, event): 101 | if event == WebKit2.LoadEvent.FINISHED: 102 | self.webview.get_snapshot(WebKit2.SnapshotRegion.FULL_DOCUMENT, 103 | WebKit2.SnapshotOptions.NONE, 104 | None, self._save_thumbnail, None) 105 | 106 | @log 107 | def _save_thumbnail(self, webview, res, data): 108 | try: 109 | original_surface = self.webview.get_snapshot_finish(res) 110 | 111 | import cairo 112 | new_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT) 113 | ctx = cairo.Context(new_surface) 114 | ctx.set_source_surface(original_surface, 0, 0) 115 | ctx.paint() 116 | 117 | new_surface.write_to_png(self.cached_thumbnail_path) 118 | 119 | self.thumbnail = self.cached_thumbnail_path 120 | self.emit('info-updated', self) 121 | except Exception as e: 122 | logger.error("Could not draw thumbnail for %s: %s" % (self.title, str(e))) 123 | -------------------------------------------------------------------------------- /po/cs.po: -------------------------------------------------------------------------------- 1 | # Czech translation for gnome-news. 2 | # Copyright (C) 2015 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # Marek Černocký , 2015, 2016. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: gnome-news master\n" 9 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 10 | "news&keywords=I18N+L10N&component=general\n" 11 | "POT-Creation-Date: 2016-03-08 14:37+0000\n" 12 | "PO-Revision-Date: 2016-03-14 03:30+0100\n" 13 | "Last-Translator: Marek Černocký \n" 14 | "Language-Team: Czech \n" 15 | "Language: cs\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" 20 | "X-Generator: Gtranslator 2.91.7\n" 21 | 22 | #: ../data/gtk/menus.ui.h:1 23 | msgid "About" 24 | msgstr "O aplikaci" 25 | 26 | #: ../data/gtk/menus.ui.h:2 27 | msgid "Quit" 28 | msgstr "Ukončit" 29 | 30 | #. TRANSLATORS: the application name 31 | #: ../data/org.gnome.News.appdata.xml.in.h:2 32 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 33 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 34 | msgid "News" 35 | msgstr "Zpravodajství" 36 | 37 | #. TRANSLATORS: one-line description for the app 38 | #: ../data/org.gnome.News.appdata.xml.in.h:4 39 | msgid "Feed Reader" 40 | msgstr "Čtečka kanálů" 41 | 42 | #. TRANSLATORS: AppData description marketing paragraph 43 | #: ../data/org.gnome.News.appdata.xml.in.h:6 44 | msgid "GNOME News can be used to read news." 45 | msgstr "Zpravodajství GNOME můžete použít ke čtení aktualit." 46 | 47 | #: ../data/org.gnome.News.desktop.in.h:2 48 | msgid "Feed reader for GNOME" 49 | msgstr "Čtečka kanálů pro GNOME" 50 | 51 | #: ../data/org.gnome.News.gschema.xml.h:1 52 | msgid "Window size" 53 | msgstr "Velikost okna" 54 | 55 | #: ../data/org.gnome.News.gschema.xml.h:2 56 | msgid "Window size (width and height)." 57 | msgstr "Velikost okna (šířka a výška)." 58 | 59 | #: ../data/org.gnome.News.gschema.xml.h:3 60 | msgid "Window position" 61 | msgstr "Poloha okna" 62 | 63 | #: ../data/org.gnome.News.gschema.xml.h:4 64 | msgid "Window position (x and y)." 65 | msgstr "Poloha okna (x a y)." 66 | 67 | #: ../data/org.gnome.News.gschema.xml.h:5 68 | msgid "Window maximized" 69 | msgstr "Okno je maximalizováno" 70 | 71 | #: ../data/org.gnome.News.gschema.xml.h:6 72 | msgid "Window maximized state." 73 | msgstr "Stav maximalizace okna." 74 | 75 | #: ../data/ui/empty-view.ui.h:1 76 | msgid "No Results Found" 77 | msgstr "Nebyly nalezeny žádné výsledky" 78 | 79 | #: ../data/ui/empty-view.ui.h:2 80 | msgid "Try a different search" 81 | msgstr "Zkuste hledat jinak" 82 | 83 | #: ../data/ui/empty-view.ui.h:3 84 | msgid "No Starred Articles Found" 85 | msgstr "Nebyl nalezen žádný oblíbený článek" 86 | 87 | #: ../data/ui/empty-view.ui.h:4 88 | msgid "You can see your starred articles after marking them" 89 | msgstr "Své oblíbené články zde uvidíte, až je označíte zvězdičkou" 90 | 91 | #: ../data/ui/empty-view.ui.h:5 92 | msgid "No Feed Subscription Found" 93 | msgstr "Nebyl nalezen žádný přihlášený odběr" 94 | 95 | #: ../data/ui/empty-view.ui.h:6 96 | msgid "You can subscribe to feeds using the \"+\" button" 97 | msgstr "K odběru kanálů se můžete přihlásit tlačítkem „+“" 98 | 99 | #: ../data/ui/headerbar.ui.h:1 100 | msgid "Add a new feed" 101 | msgstr "Přidat nový kanál" 102 | 103 | #: ../data/ui/headerbar.ui.h:2 104 | msgid "Enter feed address to add" 105 | msgstr "Zadejte adresu kanálu, který se má přidat" 106 | 107 | #: ../data/ui/headerbar.ui.h:3 108 | msgid "Add" 109 | msgstr "Přidat" 110 | 111 | #: ../data/ui/headerbar.ui.h:4 112 | msgid "You are already subscribed to that feed!" 113 | msgstr "K tomuto kanálu jste již přihlášeni!" 114 | 115 | #: ../data/ui/headerbar.ui.h:5 116 | msgid "Select All" 117 | msgstr "Vybrat vše" 118 | 119 | #: ../data/ui/headerbar.ui.h:6 120 | msgid "Select None" 121 | msgstr "Zrušit výběr" 122 | 123 | #: ../data/ui/headerbar.ui.h:7 124 | msgid "Click on items to select them" 125 | msgstr "Vyberte položky klikáním" 126 | 127 | #: ../data/ui/headerbar.ui.h:8 128 | msgid "Mark this article as starred" 129 | msgstr "Označit tento článek jako oblíbený" 130 | 131 | #: ../data/ui/headerbar.ui.h:9 132 | msgid "Search" 133 | msgstr "Hledat" 134 | 135 | #: ../data/ui/headerbar.ui.h:10 136 | msgid "Select" 137 | msgstr "Vybrat" 138 | 139 | #: ../data/ui/headerbar.ui.h:11 140 | msgid "Back" 141 | msgstr "Zpět" 142 | 143 | #: ../gnomenews/toolbar.py:96 144 | #, python-format 145 | msgid "Searching for \"%s\"" 146 | msgstr "Hledá se „%s“" 147 | 148 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 149 | msgid "This article was already read" 150 | msgstr "Tento článek jste již četli" 151 | 152 | #: ../gnomenews/view.py:174 153 | msgid "New" 154 | msgstr "Nový" 155 | 156 | #: ../gnomenews/view.py:191 157 | msgid "Feeds" 158 | msgstr "Kanály" 159 | 160 | #: ../gnomenews/view.py:268 161 | msgid "Unknown feed" 162 | msgstr "Neznámý kanál" 163 | 164 | #: ../gnomenews/view.py:361 165 | msgid "Starred" 166 | msgstr "Oblíbené" 167 | -------------------------------------------------------------------------------- /po/fi.po: -------------------------------------------------------------------------------- 1 | # Finnish translation for gnome-news. 2 | # Copyright (C) 2016 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # Jiri Grönroos , 2016. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: gnome-news master\n" 9 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 10 | "news&keywords=I18N+L10N&component=general\n" 11 | "POT-Creation-Date: 2016-03-08 14:37+0000\n" 12 | "PO-Revision-Date: 2016-03-13 17:59+0200\n" 13 | "Last-Translator: Jiri Grönroos \n" 14 | "Language-Team: suomi \n" 15 | "Language: fi\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | "X-Generator: Gtranslator 2.91.7\n" 21 | 22 | #: ../data/gtk/menus.ui.h:1 23 | msgid "About" 24 | msgstr "Tietoja" 25 | 26 | #: ../data/gtk/menus.ui.h:2 27 | msgid "Quit" 28 | msgstr "Lopeta" 29 | 30 | #. TRANSLATORS: the application name 31 | #: ../data/org.gnome.News.appdata.xml.in.h:2 32 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 33 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 34 | msgid "News" 35 | msgstr "Uutiset" 36 | 37 | #. TRANSLATORS: one-line description for the app 38 | #: ../data/org.gnome.News.appdata.xml.in.h:4 39 | msgid "Feed Reader" 40 | msgstr "Syötteenlukija" 41 | 42 | #. TRANSLATORS: AppData description marketing paragraph 43 | #: ../data/org.gnome.News.appdata.xml.in.h:6 44 | msgid "GNOME News can be used to read news." 45 | msgstr "Gnomen syötteenlukijaa voi käyttää uutisten lukemiseen." 46 | 47 | #: ../data/org.gnome.News.desktop.in.h:2 48 | msgid "Feed reader for GNOME" 49 | msgstr "Syötteenlukija Gnomelle" 50 | 51 | #: ../data/org.gnome.News.gschema.xml.h:1 52 | msgid "Window size" 53 | msgstr "Ikkunan koko" 54 | 55 | #: ../data/org.gnome.News.gschema.xml.h:2 56 | msgid "Window size (width and height)." 57 | msgstr "Ikkunan koko (leveys ja korkeus)." 58 | 59 | #: ../data/org.gnome.News.gschema.xml.h:3 60 | msgid "Window position" 61 | msgstr "Ikkunan sijainti" 62 | 63 | #: ../data/org.gnome.News.gschema.xml.h:4 64 | msgid "Window position (x and y)." 65 | msgstr "Ikkunan sijainti (x ja y)." 66 | 67 | #: ../data/org.gnome.News.gschema.xml.h:5 68 | msgid "Window maximized" 69 | msgstr "Ikkuna suurennettu" 70 | 71 | #: ../data/org.gnome.News.gschema.xml.h:6 72 | msgid "Window maximized state." 73 | msgstr "Suurennetun ikkunan tila." 74 | 75 | #: ../data/ui/empty-view.ui.h:1 76 | msgid "No Results Found" 77 | msgstr "Tuloksia ei löytynyt" 78 | 79 | #: ../data/ui/empty-view.ui.h:2 80 | msgid "Try a different search" 81 | msgstr "Kokeile eri hakuehtoja" 82 | 83 | #: ../data/ui/empty-view.ui.h:3 84 | msgid "No Starred Articles Found" 85 | msgstr "Tähdellä merkittyjä artikkeleita ei löytynyt" 86 | 87 | #: ../data/ui/empty-view.ui.h:4 88 | msgid "You can see your starred articles after marking them" 89 | msgstr "Näet tähdellä merkityt artikkelit täällä, kunhan ensin merkitset ne" 90 | 91 | #: ../data/ui/empty-view.ui.h:5 92 | msgid "No Feed Subscription Found" 93 | msgstr "Syötetilausta ei löytynyt" 94 | 95 | #: ../data/ui/empty-view.ui.h:6 96 | msgid "You can subscribe to feeds using the \"+\" button" 97 | msgstr "Voit tilata syötteitä napsauttamalla \"+\"" 98 | 99 | #: ../data/ui/headerbar.ui.h:1 100 | msgid "Add a new feed" 101 | msgstr "Lisää uusi syöte" 102 | 103 | #: ../data/ui/headerbar.ui.h:2 104 | msgid "Enter feed address to add" 105 | msgstr "Anna lisättävän syötteen osoite" 106 | 107 | #: ../data/ui/headerbar.ui.h:3 108 | msgid "Add" 109 | msgstr "Lisää" 110 | 111 | #: ../data/ui/headerbar.ui.h:4 112 | msgid "You are already subscribed to that feed!" 113 | msgstr "Olet jo tilannut tämän syötteen!" 114 | 115 | #: ../data/ui/headerbar.ui.h:5 116 | msgid "Select All" 117 | msgstr "Valitse kaikki" 118 | 119 | #: ../data/ui/headerbar.ui.h:6 120 | msgid "Select None" 121 | msgstr "Älä valitse mitään" 122 | 123 | #: ../data/ui/headerbar.ui.h:7 124 | msgid "Click on items to select them" 125 | msgstr "Napsauta kohteita valitaksesi ne" 126 | 127 | #: ../data/ui/headerbar.ui.h:8 128 | msgid "Mark this article as starred" 129 | msgstr "Merkitse tämä artikkeli tähdellä" 130 | 131 | #: ../data/ui/headerbar.ui.h:9 132 | msgid "Search" 133 | msgstr "Etsi" 134 | 135 | #: ../data/ui/headerbar.ui.h:10 136 | msgid "Select" 137 | msgstr "Valitse" 138 | 139 | #: ../data/ui/headerbar.ui.h:11 140 | msgid "Back" 141 | msgstr "Takaisin" 142 | 143 | #: ../gnomenews/toolbar.py:96 144 | #, python-format 145 | msgid "Searching for \"%s\"" 146 | msgstr "Etsitään \"%s\"" 147 | 148 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 149 | msgid "This article was already read" 150 | msgstr "Tämä artikkeli on jo luettu" 151 | 152 | #: ../gnomenews/view.py:174 153 | msgid "New" 154 | msgstr "Uudet" 155 | 156 | #: ../gnomenews/view.py:191 157 | msgid "Feeds" 158 | msgstr "Syötteet" 159 | 160 | #: ../gnomenews/view.py:268 161 | msgid "Unknown feed" 162 | msgstr "Tuntematon syöte" 163 | 164 | #: ../gnomenews/view.py:361 165 | msgid "Starred" 166 | msgstr "Suosikit" 167 | -------------------------------------------------------------------------------- /po/hu.po: -------------------------------------------------------------------------------- 1 | # Hungarian translation for gnome-news. 2 | # Copyright (C) 2016 Free Software Foundation, Inc. 3 | # This file is distributed under the same license as the gnome-news package. 4 | # 5 | # Balázs Úr , 2016. 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: gnome-news master\n" 9 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 10 | "news&keywords=I18N+L10N&component=general\n" 11 | "POT-Creation-Date: 2016-03-14 21:29+0000\n" 12 | "PO-Revision-Date: 2016-03-15 08:56+0100\n" 13 | "Last-Translator: Balázs Úr \n" 14 | "Language-Team: Hungarian \n" 15 | "Language: hu\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | "X-Generator: Lokalize 1.2\n" 21 | 22 | #: ../data/gtk/menus.ui.h:1 23 | msgid "About" 24 | msgstr "Névjegy" 25 | 26 | #: ../data/gtk/menus.ui.h:2 27 | msgid "Quit" 28 | msgstr "Kilépés" 29 | 30 | #. TRANSLATORS: the application name 31 | #: ../data/org.gnome.News.appdata.xml.in.h:2 32 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 33 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 34 | msgid "News" 35 | msgstr "Hírek" 36 | 37 | #. TRANSLATORS: one-line description for the app 38 | #: ../data/org.gnome.News.appdata.xml.in.h:4 39 | msgid "Feed Reader" 40 | msgstr "Hírolvasó" 41 | 42 | #. TRANSLATORS: AppData description marketing paragraph 43 | #: ../data/org.gnome.News.appdata.xml.in.h:6 44 | msgid "GNOME News can be used to read news." 45 | msgstr "A GNOME Hírek a hírek olvasásához használható." 46 | 47 | #: ../data/org.gnome.News.desktop.in.h:2 48 | msgid "Feed reader for GNOME" 49 | msgstr "Hírolvasó a GNOME-hoz" 50 | 51 | #: ../data/org.gnome.News.gschema.xml.h:1 52 | msgid "Window size" 53 | msgstr "Ablakméret" 54 | 55 | #: ../data/org.gnome.News.gschema.xml.h:2 56 | msgid "Window size (width and height)." 57 | msgstr "Ablakméret (szélesség és magasság)." 58 | 59 | #: ../data/org.gnome.News.gschema.xml.h:3 60 | msgid "Window position" 61 | msgstr "Ablakpozíció" 62 | 63 | #: ../data/org.gnome.News.gschema.xml.h:4 64 | msgid "Window position (x and y)." 65 | msgstr "Ablakpozíció (x és y)." 66 | 67 | #: ../data/org.gnome.News.gschema.xml.h:5 68 | msgid "Window maximized" 69 | msgstr "Ablak teljes méretű" 70 | 71 | #: ../data/org.gnome.News.gschema.xml.h:6 72 | msgid "Window maximized state." 73 | msgstr "Az ablak maximalizált állapota." 74 | 75 | #: ../data/ui/empty-view.ui.h:1 76 | msgid "No Results Found" 77 | msgstr "Nincs találat" 78 | 79 | #: ../data/ui/empty-view.ui.h:2 80 | msgid "Try a different search" 81 | msgstr "Próbáljon másik keresést" 82 | 83 | #: ../data/ui/empty-view.ui.h:3 84 | msgid "No Starred Articles Found" 85 | msgstr "Nem találhatók csillagozott cikkek" 86 | 87 | #: ../data/ui/empty-view.ui.h:4 88 | msgid "You can see your starred articles after marking them" 89 | msgstr "Akkor láthatja a csillagozott cikkeit, miután megjelölte azokat" 90 | 91 | #: ../data/ui/empty-view.ui.h:5 92 | msgid "No Feed Subscription Found" 93 | msgstr "Nem található hírforrás-feliratkozás" 94 | 95 | #: ../data/ui/empty-view.ui.h:6 96 | msgid "You can subscribe to feeds using the \"+\" button" 97 | msgstr "A „+” gomb használatával iratkozhat fel a hírforrásokra" 98 | 99 | #: ../data/ui/headerbar.ui.h:1 100 | msgid "Add a new feed" 101 | msgstr "Új hírforrás hozzáadása" 102 | 103 | #: ../data/ui/headerbar.ui.h:2 104 | msgid "Enter feed address to add" 105 | msgstr "Adja meg a hozzáadandó hírforrás címét" 106 | 107 | #: ../data/ui/headerbar.ui.h:3 108 | msgid "Add" 109 | msgstr "Hozzáadás" 110 | 111 | #: ../data/ui/headerbar.ui.h:4 112 | msgid "You are already subscribed to that feed!" 113 | msgstr "Már fel van iratkozva arra a hírforrásra!" 114 | 115 | #: ../data/ui/headerbar.ui.h:5 116 | msgid "Select All" 117 | msgstr "Összes kijelölése" 118 | 119 | #: ../data/ui/headerbar.ui.h:6 120 | msgid "Select None" 121 | msgstr "Kijelölés megszüntetése" 122 | 123 | #: ../data/ui/headerbar.ui.h:7 124 | msgid "Click on items to select them" 125 | msgstr "Kattintson az elemekre a kiválasztásukhoz" 126 | 127 | #: ../data/ui/headerbar.ui.h:8 128 | msgid "Mark this article as starred" 129 | msgstr "Cikk megjelölése csillagozottként" 130 | 131 | #: ../data/ui/headerbar.ui.h:9 132 | msgid "Search" 133 | msgstr "Keresés" 134 | 135 | #: ../data/ui/headerbar.ui.h:10 136 | msgid "Select" 137 | msgstr "Kijelölés" 138 | 139 | #: ../data/ui/headerbar.ui.h:11 140 | msgid "Back" 141 | msgstr "Vissza" 142 | 143 | #: ../gnomenews/toolbar.py:96 144 | #, python-format 145 | msgid "Searching for \"%s\"" 146 | msgstr "„%s” keresése" 147 | 148 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 149 | msgid "This article was already read" 150 | msgstr "Ezt a cikket már elolvasta" 151 | 152 | #: ../gnomenews/view.py:174 153 | msgid "New" 154 | msgstr "Új" 155 | 156 | #: ../gnomenews/view.py:191 157 | msgid "Feeds" 158 | msgstr "Hírforrások" 159 | 160 | #: ../gnomenews/view.py:268 161 | msgid "Unknown feed" 162 | msgstr "Ismeretlen hírforrás" 163 | 164 | #: ../gnomenews/view.py:361 165 | msgid "Starred" 166 | msgstr "Csillagozott" 167 | 168 | -------------------------------------------------------------------------------- /po/sv.po: -------------------------------------------------------------------------------- 1 | # Swedish translation for gnome-news. 2 | # Copyright © 2016 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # Anders Jonsson , 2015. 5 | # Josef Andersson , 2016. 6 | # 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: gnome-news master\n" 10 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 11 | "news&keywords=I18N+L10N&component=general\n" 12 | "POT-Creation-Date: 2016-03-12 09:30+0000\n" 13 | "PO-Revision-Date: 2016-03-12 06:14+0100\n" 14 | "Last-Translator: Josef Andersson \n" 15 | "Language-Team: Swedish \n" 16 | "Language: sv\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 21 | "X-Generator: Poedit 1.8.4\n" 22 | 23 | #: ../data/gtk/menus.ui.h:1 24 | msgid "About" 25 | msgstr "Om" 26 | 27 | #: ../data/gtk/menus.ui.h:2 28 | msgid "Quit" 29 | msgstr "Avsluta" 30 | 31 | #. TRANSLATORS: the application name 32 | #: ../data/org.gnome.News.appdata.xml.in.h:2 33 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 34 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 35 | msgid "News" 36 | msgstr "Nyheter" 37 | 38 | #. TRANSLATORS: one-line description for the app 39 | #: ../data/org.gnome.News.appdata.xml.in.h:4 40 | msgid "Feed Reader" 41 | msgstr "Nyhetsläsare" 42 | 43 | #. TRANSLATORS: AppData description marketing paragraph 44 | #: ../data/org.gnome.News.appdata.xml.in.h:6 45 | msgid "GNOME News can be used to read news." 46 | msgstr "GNOME Nyheter kan användas för att läsa nyheter." 47 | 48 | #: ../data/org.gnome.News.desktop.in.h:2 49 | msgid "Feed reader for GNOME" 50 | msgstr "Nyhetsläsare för GNOME" 51 | 52 | #: ../data/org.gnome.News.gschema.xml.h:1 53 | msgid "Window size" 54 | msgstr "Fönsterstorlek" 55 | 56 | #: ../data/org.gnome.News.gschema.xml.h:2 57 | msgid "Window size (width and height)." 58 | msgstr "Fönsterstorlek (bredd och höjd)." 59 | 60 | #: ../data/org.gnome.News.gschema.xml.h:3 61 | msgid "Window position" 62 | msgstr "Fönsterposition" 63 | 64 | #: ../data/org.gnome.News.gschema.xml.h:4 65 | msgid "Window position (x and y)." 66 | msgstr "Fönsterposition (x och y)." 67 | 68 | #: ../data/org.gnome.News.gschema.xml.h:5 69 | msgid "Window maximized" 70 | msgstr "Maximerat fönster" 71 | 72 | #: ../data/org.gnome.News.gschema.xml.h:6 73 | msgid "Window maximized state." 74 | msgstr "Maximerat fönstertillstånd." 75 | 76 | #: ../data/ui/empty-view.ui.h:1 77 | msgid "No Results Found" 78 | msgstr "Inga resultat funna" 79 | 80 | #: ../data/ui/empty-view.ui.h:2 81 | msgid "Try a different search" 82 | msgstr "Prova en annan sökning" 83 | 84 | #: ../data/ui/empty-view.ui.h:3 85 | msgid "No Starred Articles Found" 86 | msgstr "Inga stjärnmärkta artiklar funna" 87 | 88 | #: ../data/ui/empty-view.ui.h:4 89 | msgid "You can see your starred articles after marking them" 90 | msgstr "Du kan se dina stjärnmärkta artiklar efter att du har markerat dem" 91 | 92 | #: ../data/ui/empty-view.ui.h:5 93 | msgid "No Feed Subscription Found" 94 | msgstr "Inga kanalprenumerationer funna" 95 | 96 | #: ../data/ui/empty-view.ui.h:6 97 | msgid "You can subscribe to feeds using the \"+\" button" 98 | msgstr "Du kan prenumerera på kanaler genom att använda knappen ”+”" 99 | 100 | #: ../data/ui/headerbar.ui.h:1 101 | msgid "Add a new feed" 102 | msgstr "Lägg till en ny kanal" 103 | 104 | #: ../data/ui/headerbar.ui.h:2 105 | msgid "Enter feed address to add" 106 | msgstr "Ange adress för kanal att lägga till" 107 | 108 | #: ../data/ui/headerbar.ui.h:3 109 | msgid "Add" 110 | msgstr "Lägg till" 111 | 112 | #: ../data/ui/headerbar.ui.h:4 113 | msgid "You are already subscribed to that feed!" 114 | msgstr "Du prenumererar redan på den kanalen!" 115 | 116 | #: ../data/ui/headerbar.ui.h:5 117 | msgid "Select All" 118 | msgstr "Markera alla" 119 | 120 | #: ../data/ui/headerbar.ui.h:6 121 | msgid "Select None" 122 | msgstr "Markera ingen" 123 | 124 | #: ../data/ui/headerbar.ui.h:7 125 | msgid "Click on items to select them" 126 | msgstr "Klicka på objekt för att markera dem" 127 | 128 | #: ../data/ui/headerbar.ui.h:8 129 | msgid "Mark this article as starred" 130 | msgstr "Markera denna artikel som stjärnmärkt" 131 | 132 | #: ../data/ui/headerbar.ui.h:9 133 | msgid "Search" 134 | msgstr "Sök" 135 | 136 | #: ../data/ui/headerbar.ui.h:10 137 | msgid "Select" 138 | msgstr "Välj" 139 | 140 | #: ../data/ui/headerbar.ui.h:11 141 | msgid "Back" 142 | msgstr "Bakåt" 143 | 144 | #: ../gnomenews/toolbar.py:96 145 | #, python-format 146 | msgid "Searching for \"%s\"" 147 | msgstr "Söker efter ”%s”" 148 | 149 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 150 | msgid "This article was already read" 151 | msgstr "Artikeln är redan läst" 152 | 153 | #: ../gnomenews/view.py:174 154 | msgid "New" 155 | msgstr "Nytt" 156 | 157 | #: ../gnomenews/view.py:191 158 | msgid "Feeds" 159 | msgstr "Kanaler" 160 | 161 | #: ../gnomenews/view.py:268 162 | msgid "Unknown feed" 163 | msgstr "Okänd kanal" 164 | 165 | #: ../gnomenews/view.py:361 166 | msgid "Starred" 167 | msgstr "Favoriter" 168 | -------------------------------------------------------------------------------- /po/pl.po: -------------------------------------------------------------------------------- 1 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 2 | # Aviary.pl 3 | # Jeśli masz jakiekolwiek uwagi odnoszące się do tłumaczenia lub chcesz 4 | # pomóc w jego rozwijaniu i pielęgnowaniu, napisz do nas: 5 | # gnomepl@aviary.pl 6 | # -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 7 | # Piotr Drąg , 2015-2016. 8 | # Aviary.pl , 2015-2016. 9 | msgid "" 10 | msgstr "" 11 | "Project-Id-Version: gnome-news\n" 12 | "Report-Msgid-Bugs-To: \n" 13 | "POT-Creation-Date: 2016-03-08 15:39+0100\n" 14 | "PO-Revision-Date: 2016-03-08 15:40+0100\n" 15 | "Last-Translator: Piotr Drąg \n" 16 | "Language-Team: Polish \n" 17 | "Language: pl\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " 22 | "|| n%100>=20) ? 1 : 2);\n" 23 | "X-Poedit-Language: Polish\n" 24 | "X-Poedit-Country: Poland\n" 25 | 26 | #: ../data/gtk/menus.ui.h:1 27 | msgid "About" 28 | msgstr "O programie" 29 | 30 | #: ../data/gtk/menus.ui.h:2 31 | msgid "Quit" 32 | msgstr "Zakończ" 33 | 34 | #. TRANSLATORS: the application name 35 | #: ../data/org.gnome.News.appdata.xml.in.h:2 36 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 37 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 38 | msgid "News" 39 | msgstr "Wiadomości" 40 | 41 | #. TRANSLATORS: one-line description for the app 42 | #: ../data/org.gnome.News.appdata.xml.in.h:4 43 | msgid "Feed Reader" 44 | msgstr "Czytnik kanałów" 45 | 46 | #. TRANSLATORS: AppData description marketing paragraph 47 | #: ../data/org.gnome.News.appdata.xml.in.h:6 48 | msgid "GNOME News can be used to read news." 49 | msgstr "Program do czytania wiadomości." 50 | 51 | #: ../data/org.gnome.News.desktop.in.h:2 52 | msgid "Feed reader for GNOME" 53 | msgstr "Czytnik kanałów dla środowiska GNOME" 54 | 55 | #: ../data/org.gnome.News.gschema.xml.h:1 56 | msgid "Window size" 57 | msgstr "Rozmiar okna" 58 | 59 | #: ../data/org.gnome.News.gschema.xml.h:2 60 | msgid "Window size (width and height)." 61 | msgstr "Rozmiar okna (szerokość i wysokość)." 62 | 63 | #: ../data/org.gnome.News.gschema.xml.h:3 64 | msgid "Window position" 65 | msgstr "Położenie okna" 66 | 67 | #: ../data/org.gnome.News.gschema.xml.h:4 68 | msgid "Window position (x and y)." 69 | msgstr "Położenie okna (na osi X i Y)." 70 | 71 | #: ../data/org.gnome.News.gschema.xml.h:5 72 | msgid "Window maximized" 73 | msgstr "Zmaksymalizowane okno" 74 | 75 | #: ../data/org.gnome.News.gschema.xml.h:6 76 | msgid "Window maximized state." 77 | msgstr "Stan maksymalizacji okna." 78 | 79 | #: ../data/ui/empty-view.ui.h:1 80 | msgid "No Results Found" 81 | msgstr "Brak wyników" 82 | 83 | #: ../data/ui/empty-view.ui.h:2 84 | msgid "Try a different search" 85 | msgstr "Proszę spróbować innych słów" 86 | 87 | #: ../data/ui/empty-view.ui.h:3 88 | msgid "No Starred Articles Found" 89 | msgstr "Brak ulubionych artykułów" 90 | 91 | #: ../data/ui/empty-view.ui.h:4 92 | msgid "You can see your starred articles after marking them" 93 | msgstr "Można wyświetlać ulubione artykuły po ich dodaniu" 94 | 95 | #: ../data/ui/empty-view.ui.h:5 96 | msgid "No Feed Subscription Found" 97 | msgstr "Brak subskrypcji kanałów" 98 | 99 | #: ../data/ui/empty-view.ui.h:6 100 | msgid "You can subscribe to feeds using the \"+\" button" 101 | msgstr "Można subskrybować kanały za pomocą przycisku „+”" 102 | 103 | #: ../data/ui/headerbar.ui.h:1 104 | msgid "Add a new feed" 105 | msgstr "Dodaje nowy kanał" 106 | 107 | #: ../data/ui/headerbar.ui.h:2 108 | msgid "Enter feed address to add" 109 | msgstr "Adres dodawanego kanału" 110 | 111 | #: ../data/ui/headerbar.ui.h:3 112 | msgid "Add" 113 | msgstr "Dodaj" 114 | 115 | #: ../data/ui/headerbar.ui.h:4 116 | msgid "You are already subscribed to that feed!" 117 | msgstr "Już subskrybowano ten kanał." 118 | 119 | #: ../data/ui/headerbar.ui.h:5 120 | msgid "Select All" 121 | msgstr "Zaznacz wszystko" 122 | 123 | #: ../data/ui/headerbar.ui.h:6 124 | msgid "Select None" 125 | msgstr "Odznacz wszystko" 126 | 127 | #: ../data/ui/headerbar.ui.h:7 128 | msgid "Click on items to select them" 129 | msgstr "Kliknięcie elementów zaznacza je" 130 | 131 | #: ../data/ui/headerbar.ui.h:8 132 | msgid "Mark this article as starred" 133 | msgstr "Dodaje ten artykuł do ulubionych" 134 | 135 | #: ../data/ui/headerbar.ui.h:9 136 | msgid "Search" 137 | msgstr "Wyszukuje" 138 | 139 | #: ../data/ui/headerbar.ui.h:10 140 | msgid "Select" 141 | msgstr "Zaznacza" 142 | 143 | #: ../data/ui/headerbar.ui.h:11 144 | msgid "Back" 145 | msgstr "Wstecz" 146 | 147 | #: ../gnomenews/toolbar.py:96 148 | #, python-format 149 | msgid "Searching for \"%s\"" 150 | msgstr "Wyszukiwanie „%s”" 151 | 152 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 153 | msgid "This article was already read" 154 | msgstr "Już przeczytano ten artykuł" 155 | 156 | #: ../gnomenews/view.py:174 157 | msgid "New" 158 | msgstr "Nowy" 159 | 160 | #: ../gnomenews/view.py:191 161 | msgid "Feeds" 162 | msgstr "Kanały" 163 | 164 | #: ../gnomenews/view.py:268 165 | msgid "Unknown feed" 166 | msgstr "Nieznany kanał" 167 | 168 | #: ../gnomenews/view.py:361 169 | msgid "Starred" 170 | msgstr "Ulubione" 171 | -------------------------------------------------------------------------------- /po/sr.po: -------------------------------------------------------------------------------- 1 | # Serbian translation for gnome-news. 2 | # Copyright (C) 2016 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # 5 | # Translators: 6 | # Мирослав Николић , 2016. 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: gnome-news master\n" 10 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 11 | "news&keywords=I18N+L10N&component=general\n" 12 | "POT-Creation-Date: 2016-03-08 14:37+0000\n" 13 | "PO-Revision-Date: 2016-03-09 09:05+0200\n" 14 | "Last-Translator: Мирослав Николић \n" 15 | "Language-Team: Serbian <(nothing)>\n" 16 | "Language: sr\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " 21 | "n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" 22 | "X-Project-Style: gnome\n" 23 | 24 | #: ../data/gtk/menus.ui.h:1 25 | msgid "About" 26 | msgstr "О програму" 27 | 28 | #: ../data/gtk/menus.ui.h:2 29 | msgid "Quit" 30 | msgstr "Изађи" 31 | 32 | #. TRANSLATORS: the application name 33 | #: ../data/org.gnome.News.appdata.xml.in.h:2 34 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 35 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 36 | msgid "News" 37 | msgstr "Вести" 38 | 39 | #. TRANSLATORS: one-line description for the app 40 | #: ../data/org.gnome.News.appdata.xml.in.h:4 41 | msgid "Feed Reader" 42 | msgstr "Читач довода" 43 | 44 | #. TRANSLATORS: AppData description marketing paragraph 45 | #: ../data/org.gnome.News.appdata.xml.in.h:6 46 | msgid "GNOME News can be used to read news." 47 | msgstr "Гномове вести се могу користити за читање вести." 48 | 49 | #: ../data/org.gnome.News.desktop.in.h:2 50 | msgid "Feed reader for GNOME" 51 | msgstr "Читач довода за Гном" 52 | 53 | #: ../data/org.gnome.News.gschema.xml.h:1 54 | msgid "Window size" 55 | msgstr "Величина прозора" 56 | 57 | #: ../data/org.gnome.News.gschema.xml.h:2 58 | msgid "Window size (width and height)." 59 | msgstr "Величина прозора (ширина и висина)." 60 | 61 | #: ../data/org.gnome.News.gschema.xml.h:3 62 | msgid "Window position" 63 | msgstr "Положај прозора" 64 | 65 | #: ../data/org.gnome.News.gschema.xml.h:4 66 | msgid "Window position (x and y)." 67 | msgstr "Положај прозора (х и у)." 68 | 69 | #: ../data/org.gnome.News.gschema.xml.h:5 70 | msgid "Window maximized" 71 | msgstr "Увећан прозор" 72 | 73 | #: ../data/org.gnome.News.gschema.xml.h:6 74 | msgid "Window maximized state." 75 | msgstr "Стање увећаног прозора." 76 | 77 | #: ../data/ui/empty-view.ui.h:1 78 | msgid "No Results Found" 79 | msgstr "Нема резултата" 80 | 81 | #: ../data/ui/empty-view.ui.h:2 82 | msgid "Try a different search" 83 | msgstr "Пробајте са другачијом претрагом" 84 | 85 | #: ../data/ui/empty-view.ui.h:3 86 | msgid "No Starred Articles Found" 87 | msgstr "Нисам нашао чланке са звездицама" 88 | 89 | #: ../data/ui/empty-view.ui.h:4 90 | msgid "You can see your starred articles after marking them" 91 | msgstr "Можете да видите ваше чланке са звездицама након што их означите" 92 | 93 | #: ../data/ui/empty-view.ui.h:5 94 | msgid "No Feed Subscription Found" 95 | msgstr "Нисам нашао претплату на довод" 96 | 97 | #: ../data/ui/empty-view.ui.h:6 98 | msgid "You can subscribe to feeds using the \"+\" button" 99 | msgstr "Можете да се претплатите на доводе користећи дугме +" 100 | 101 | #: ../data/ui/headerbar.ui.h:1 102 | msgid "Add a new feed" 103 | msgstr "Додај нови довод" 104 | 105 | #: ../data/ui/headerbar.ui.h:2 106 | msgid "Enter feed address to add" 107 | msgstr "Упишите адресу довода за додавање" 108 | 109 | #: ../data/ui/headerbar.ui.h:3 110 | msgid "Add" 111 | msgstr "Додај" 112 | 113 | #: ../data/ui/headerbar.ui.h:4 114 | msgid "You are already subscribed to that feed!" 115 | msgstr "Већ сте се претплатили на тај довод!" 116 | 117 | #: ../data/ui/headerbar.ui.h:5 118 | msgid "Select All" 119 | msgstr "Изабери све" 120 | 121 | #: ../data/ui/headerbar.ui.h:6 122 | msgid "Select None" 123 | msgstr "Поништи избор" 124 | 125 | #: ../data/ui/headerbar.ui.h:7 126 | msgid "Click on items to select them" 127 | msgstr "Притисните на ставке да их изаберете" 128 | 129 | #: ../data/ui/headerbar.ui.h:8 130 | msgid "Mark this article as starred" 131 | msgstr "Означите овај чланак да има звездице" 132 | 133 | #: ../data/ui/headerbar.ui.h:9 134 | msgid "Search" 135 | msgstr "Тражи" 136 | 137 | #: ../data/ui/headerbar.ui.h:10 138 | msgid "Select" 139 | msgstr "Изабери" 140 | 141 | #: ../data/ui/headerbar.ui.h:11 142 | msgid "Back" 143 | msgstr "Назад" 144 | 145 | #: ../gnomenews/toolbar.py:96 146 | #, python-format 147 | msgid "Searching for \"%s\"" 148 | msgstr "Тражим „%s“" 149 | 150 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 151 | msgid "This article was already read" 152 | msgstr "Овај чланак је већ прочитан" 153 | 154 | #: ../gnomenews/view.py:174 155 | msgid "New" 156 | msgstr "Ново" 157 | 158 | #: ../gnomenews/view.py:191 159 | msgid "Feeds" 160 | msgstr "Доводи" 161 | 162 | #: ../gnomenews/view.py:268 163 | msgid "Unknown feed" 164 | msgstr "Непознат довод" 165 | 166 | #: ../gnomenews/view.py:361 167 | msgid "Starred" 168 | msgstr "Започето" 169 | -------------------------------------------------------------------------------- /po/sr@latin.po: -------------------------------------------------------------------------------- 1 | # Serbian translation for gnome-news. 2 | # Copyright (C) 2016 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # 5 | # Translators: 6 | # Miroslav Nikolić , 2016. 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: gnome-news master\n" 10 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 11 | "news&keywords=I18N+L10N&component=general\n" 12 | "POT-Creation-Date: 2016-03-08 14:37+0000\n" 13 | "PO-Revision-Date: 2016-03-09 09:05+0200\n" 14 | "Last-Translator: Miroslav Nikolić \n" 15 | "Language-Team: Serbian <(nothing)>\n" 16 | "Language: sr\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " 21 | "n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" 22 | "X-Project-Style: gnome\n" 23 | 24 | #: ../data/gtk/menus.ui.h:1 25 | msgid "About" 26 | msgstr "O programu" 27 | 28 | #: ../data/gtk/menus.ui.h:2 29 | msgid "Quit" 30 | msgstr "Izađi" 31 | 32 | #. TRANSLATORS: the application name 33 | #: ../data/org.gnome.News.appdata.xml.in.h:2 34 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 35 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 36 | msgid "News" 37 | msgstr "Vesti" 38 | 39 | #. TRANSLATORS: one-line description for the app 40 | #: ../data/org.gnome.News.appdata.xml.in.h:4 41 | msgid "Feed Reader" 42 | msgstr "Čitač dovoda" 43 | 44 | #. TRANSLATORS: AppData description marketing paragraph 45 | #: ../data/org.gnome.News.appdata.xml.in.h:6 46 | msgid "GNOME News can be used to read news." 47 | msgstr "Gnomove vesti se mogu koristiti za čitanje vesti." 48 | 49 | #: ../data/org.gnome.News.desktop.in.h:2 50 | msgid "Feed reader for GNOME" 51 | msgstr "Čitač dovoda za Gnom" 52 | 53 | #: ../data/org.gnome.News.gschema.xml.h:1 54 | msgid "Window size" 55 | msgstr "Veličina prozora" 56 | 57 | #: ../data/org.gnome.News.gschema.xml.h:2 58 | msgid "Window size (width and height)." 59 | msgstr "Veličina prozora (širina i visina)." 60 | 61 | #: ../data/org.gnome.News.gschema.xml.h:3 62 | msgid "Window position" 63 | msgstr "Položaj prozora" 64 | 65 | #: ../data/org.gnome.News.gschema.xml.h:4 66 | msgid "Window position (x and y)." 67 | msgstr "Položaj prozora (h i u)." 68 | 69 | #: ../data/org.gnome.News.gschema.xml.h:5 70 | msgid "Window maximized" 71 | msgstr "Uvećan prozor" 72 | 73 | #: ../data/org.gnome.News.gschema.xml.h:6 74 | msgid "Window maximized state." 75 | msgstr "Stanje uvećanog prozora." 76 | 77 | #: ../data/ui/empty-view.ui.h:1 78 | msgid "No Results Found" 79 | msgstr "Nema rezultata" 80 | 81 | #: ../data/ui/empty-view.ui.h:2 82 | msgid "Try a different search" 83 | msgstr "Probajte sa drugačijom pretragom" 84 | 85 | #: ../data/ui/empty-view.ui.h:3 86 | msgid "No Starred Articles Found" 87 | msgstr "Nisam našao članke sa zvezdicama" 88 | 89 | #: ../data/ui/empty-view.ui.h:4 90 | msgid "You can see your starred articles after marking them" 91 | msgstr "Možete da vidite vaše članke sa zvezdicama nakon što ih označite" 92 | 93 | #: ../data/ui/empty-view.ui.h:5 94 | msgid "No Feed Subscription Found" 95 | msgstr "Nisam našao pretplatu na dovod" 96 | 97 | #: ../data/ui/empty-view.ui.h:6 98 | msgid "You can subscribe to feeds using the \"+\" button" 99 | msgstr "Možete da se pretplatite na dovode koristeći dugme +" 100 | 101 | #: ../data/ui/headerbar.ui.h:1 102 | msgid "Add a new feed" 103 | msgstr "Dodaj novi dovod" 104 | 105 | #: ../data/ui/headerbar.ui.h:2 106 | msgid "Enter feed address to add" 107 | msgstr "Upišite adresu dovoda za dodavanje" 108 | 109 | #: ../data/ui/headerbar.ui.h:3 110 | msgid "Add" 111 | msgstr "Dodaj" 112 | 113 | #: ../data/ui/headerbar.ui.h:4 114 | msgid "You are already subscribed to that feed!" 115 | msgstr "Već ste se pretplatili na taj dovod!" 116 | 117 | #: ../data/ui/headerbar.ui.h:5 118 | msgid "Select All" 119 | msgstr "Izaberi sve" 120 | 121 | #: ../data/ui/headerbar.ui.h:6 122 | msgid "Select None" 123 | msgstr "Poništi izbor" 124 | 125 | #: ../data/ui/headerbar.ui.h:7 126 | msgid "Click on items to select them" 127 | msgstr "Pritisnite na stavke da ih izaberete" 128 | 129 | #: ../data/ui/headerbar.ui.h:8 130 | msgid "Mark this article as starred" 131 | msgstr "Označite ovaj članak da ima zvezdice" 132 | 133 | #: ../data/ui/headerbar.ui.h:9 134 | msgid "Search" 135 | msgstr "Traži" 136 | 137 | #: ../data/ui/headerbar.ui.h:10 138 | msgid "Select" 139 | msgstr "Izaberi" 140 | 141 | #: ../data/ui/headerbar.ui.h:11 142 | msgid "Back" 143 | msgstr "Nazad" 144 | 145 | #: ../gnomenews/toolbar.py:96 146 | #, python-format 147 | msgid "Searching for \"%s\"" 148 | msgstr "Tražim „%s“" 149 | 150 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 151 | msgid "This article was already read" 152 | msgstr "Ovaj članak je već pročitan" 153 | 154 | #: ../gnomenews/view.py:174 155 | msgid "New" 156 | msgstr "Novo" 157 | 158 | #: ../gnomenews/view.py:191 159 | msgid "Feeds" 160 | msgstr "Dovodi" 161 | 162 | #: ../gnomenews/view.py:268 163 | msgid "Unknown feed" 164 | msgstr "Nepoznat dovod" 165 | 166 | #: ../gnomenews/view.py:361 167 | msgid "Starred" 168 | msgstr "Započeto" 169 | -------------------------------------------------------------------------------- /po/it.po: -------------------------------------------------------------------------------- 1 | # Italian translation for gnome-news. 2 | # Copyright (C) 2016 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # Gianvito Cavasoli , 2016. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: gnome-news master\n" 9 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 10 | "news&keywords=I18N+L10N&component=general\n" 11 | "POT-Creation-Date: 2016-03-08 14:37+0000\n" 12 | "PO-Revision-Date: 2016-03-22 12:28+0100\n" 13 | "Last-Translator: Gianvito Cavasoli \n" 14 | "Language-Team: Italiano \n" 15 | "Language: it\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | "X-Generator: Gtranslator 2.91.7\n" 21 | 22 | #: ../data/gtk/menus.ui.h:1 23 | msgid "About" 24 | msgstr "Informazioni" 25 | 26 | #: ../data/gtk/menus.ui.h:2 27 | msgid "Quit" 28 | msgstr "Esci" 29 | 30 | #. TRANSLATORS: the application name 31 | #: ../data/org.gnome.News.appdata.xml.in.h:2 32 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 33 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 34 | msgid "News" 35 | msgstr "Notizie" 36 | 37 | #. TRANSLATORS: one-line description for the app 38 | #: ../data/org.gnome.News.appdata.xml.in.h:4 39 | msgid "Feed Reader" 40 | msgstr "Lettore notiziari" 41 | 42 | #. TRANSLATORS: AppData description marketing paragraph 43 | #: ../data/org.gnome.News.appdata.xml.in.h:6 44 | msgid "GNOME News can be used to read news." 45 | msgstr "GNOME News può essere usato per leggere le notizie." 46 | 47 | #: ../data/org.gnome.News.desktop.in.h:2 48 | msgid "Feed reader for GNOME" 49 | msgstr "Lettore notiziari per GNOME" 50 | 51 | #: ../data/org.gnome.News.gschema.xml.h:1 52 | msgid "Window size" 53 | msgstr "Dimensione finestra" 54 | 55 | #: ../data/org.gnome.News.gschema.xml.h:2 56 | msgid "Window size (width and height)." 57 | msgstr "Dimensione finestra (larghezza e altezza)." 58 | 59 | #: ../data/org.gnome.News.gschema.xml.h:3 60 | msgid "Window position" 61 | msgstr "Posizione finestra" 62 | 63 | #: ../data/org.gnome.News.gschema.xml.h:4 64 | msgid "Window position (x and y)." 65 | msgstr "Posizione finestra (x e y)." 66 | 67 | #: ../data/org.gnome.News.gschema.xml.h:5 68 | msgid "Window maximized" 69 | msgstr "Finestra massimizzata" 70 | 71 | #: ../data/org.gnome.News.gschema.xml.h:6 72 | msgid "Window maximized state." 73 | msgstr "Stato finestra massimizzata." 74 | 75 | #: ../data/ui/empty-view.ui.h:1 76 | msgid "No Results Found" 77 | msgstr "Nessun risultato trovato" 78 | 79 | #: ../data/ui/empty-view.ui.h:2 80 | msgid "Try a different search" 81 | msgstr "Provare una differente ricerca" 82 | 83 | #: ../data/ui/empty-view.ui.h:3 84 | msgid "No Starred Articles Found" 85 | msgstr "Nessun articolo speciale trovato" 86 | 87 | #: ../data/ui/empty-view.ui.h:4 88 | msgid "You can see your starred articles after marking them" 89 | msgstr "È possibile vedere gli articoli speciali dopo averli contrassegnati" 90 | 91 | #: ../data/ui/empty-view.ui.h:5 92 | msgid "No Feed Subscription Found" 93 | msgstr "Nessun abbonamento al notiziario trovato" 94 | 95 | #: ../data/ui/empty-view.ui.h:6 96 | msgid "You can subscribe to feeds using the \"+\" button" 97 | msgstr "È possibile abbonarsi ai notiziari usando il pulsante «+»" 98 | 99 | #: ../data/ui/headerbar.ui.h:1 100 | msgid "Add a new feed" 101 | msgstr "Aggiunge un nuovo notiziario" 102 | 103 | #: ../data/ui/headerbar.ui.h:2 104 | msgid "Enter feed address to add" 105 | msgstr "Immettere l'indirizzo del notiziario da aggiungere" 106 | 107 | #: ../data/ui/headerbar.ui.h:3 108 | msgid "Add" 109 | msgstr "Aggiungi" 110 | 111 | #: ../data/ui/headerbar.ui.h:4 112 | msgid "You are already subscribed to that feed!" 113 | msgstr "Si è già abbonati a questo notiziario." 114 | 115 | #: ../data/ui/headerbar.ui.h:5 116 | msgid "Select All" 117 | msgstr "Seleziona tutto" 118 | 119 | #: ../data/ui/headerbar.ui.h:6 120 | msgid "Select None" 121 | msgstr "Nessuna selezione" 122 | 123 | #: ../data/ui/headerbar.ui.h:7 124 | msgid "Click on items to select them" 125 | msgstr "Fare clic sugli elementi per selezionarli" 126 | 127 | #: ../data/ui/headerbar.ui.h:8 128 | msgid "Mark this article as starred" 129 | msgstr "Contrassegna questo articolo come speciale" 130 | 131 | #: ../data/ui/headerbar.ui.h:9 132 | msgid "Search" 133 | msgstr "Cerca" 134 | 135 | #: ../data/ui/headerbar.ui.h:10 136 | msgid "Select" 137 | msgstr "Seleziona" 138 | 139 | #: ../data/ui/headerbar.ui.h:11 140 | msgid "Back" 141 | msgstr "Indietro" 142 | 143 | #: ../gnomenews/toolbar.py:96 144 | #, python-format 145 | msgid "Searching for \"%s\"" 146 | msgstr "Ricerca di «%s»" 147 | 148 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 149 | msgid "This article was already read" 150 | msgstr "Questo articolo è già stato letto" 151 | 152 | #: ../gnomenews/view.py:174 153 | msgid "New" 154 | msgstr "Nuovo" 155 | 156 | #: ../gnomenews/view.py:191 157 | msgid "Feeds" 158 | msgstr "Notiziari" 159 | 160 | #: ../gnomenews/view.py:268 161 | msgid "Unknown feed" 162 | msgstr "Notiziario sconosciuto" 163 | 164 | #: ../gnomenews/view.py:361 165 | msgid "Starred" 166 | msgstr "Speciale" 167 | -------------------------------------------------------------------------------- /po/pt_BR.po: -------------------------------------------------------------------------------- 1 | # Brazilian Portuguese translation for gnome-news. 2 | # Copyright (C) 2015 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # Enrico Nicoletto , 2015. 5 | # Rafael Fontenelle , 2016. 6 | # 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: gnome-news master\n" 10 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 11 | "news&keywords=I18N+L10N&component=general\n" 12 | "POT-Creation-Date: 2016-03-08 14:37+0000\n" 13 | "PO-Revision-Date: 2016-03-10 11:20-0300\n" 14 | "Last-Translator: Rafael Fontenelle \n" 15 | "Language-Team: Brazilian Portuguese \n" 16 | "Language: pt_BR\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 21 | "X-Generator: Poedit 1.8.7\n" 22 | 23 | #: ../data/gtk/menus.ui.h:1 24 | msgid "About" 25 | msgstr "Sobre" 26 | 27 | #: ../data/gtk/menus.ui.h:2 28 | msgid "Quit" 29 | msgstr "Sair" 30 | 31 | #. TRANSLATORS: the application name 32 | #: ../data/org.gnome.News.appdata.xml.in.h:2 33 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 34 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 35 | msgid "News" 36 | msgstr "Notícias" 37 | 38 | #. TRANSLATORS: one-line description for the app 39 | #: ../data/org.gnome.News.appdata.xml.in.h:4 40 | msgid "Feed Reader" 41 | msgstr "Leitor de feed" 42 | 43 | #. TRANSLATORS: AppData description marketing paragraph 44 | #: ../data/org.gnome.News.appdata.xml.in.h:6 45 | msgid "GNOME News can be used to read news." 46 | msgstr "GNOME News pode ser usado para ler notícias." 47 | 48 | #: ../data/org.gnome.News.desktop.in.h:2 49 | msgid "Feed reader for GNOME" 50 | msgstr "Leitor de feed para o GNOME" 51 | 52 | #: ../data/org.gnome.News.gschema.xml.h:1 53 | msgid "Window size" 54 | msgstr "Tamanho da janela" 55 | 56 | #: ../data/org.gnome.News.gschema.xml.h:2 57 | msgid "Window size (width and height)." 58 | msgstr "Tamanho da janela (largura e altura)." 59 | 60 | #: ../data/org.gnome.News.gschema.xml.h:3 61 | msgid "Window position" 62 | msgstr "Posição da janela" 63 | 64 | #: ../data/org.gnome.News.gschema.xml.h:4 65 | msgid "Window position (x and y)." 66 | msgstr "Posição da janela (x e y)." 67 | 68 | #: ../data/org.gnome.News.gschema.xml.h:5 69 | msgid "Window maximized" 70 | msgstr "Janela maximizada" 71 | 72 | #: ../data/org.gnome.News.gschema.xml.h:6 73 | msgid "Window maximized state." 74 | msgstr "Estado de janela maximizada" 75 | 76 | #: ../data/ui/empty-view.ui.h:1 77 | msgid "No Results Found" 78 | msgstr "Nenhum resultado encontrado" 79 | 80 | #: ../data/ui/empty-view.ui.h:2 81 | msgid "Try a different search" 82 | msgstr "Tente uma pesquisa diferente" 83 | 84 | #: ../data/ui/empty-view.ui.h:3 85 | msgid "No Starred Articles Found" 86 | msgstr "Nenhum artigo favorito encontrado" 87 | 88 | #: ../data/ui/empty-view.ui.h:4 89 | msgid "You can see your starred articles after marking them" 90 | msgstr "Você pode ver seus artigos favoritos após marcá-los" 91 | 92 | #: ../data/ui/empty-view.ui.h:5 93 | msgid "No Feed Subscription Found" 94 | msgstr "Nenhuma inscrição de feed encontrada" 95 | 96 | #: ../data/ui/empty-view.ui.h:6 97 | msgid "You can subscribe to feeds using the \"+\" button" 98 | msgstr "Você pode se inscrever aos feeds usando o botão \"\"" 99 | 100 | #: ../data/ui/headerbar.ui.h:1 101 | msgid "Add a new feed" 102 | msgstr "Adicionar um novo feed" 103 | 104 | #: ../data/ui/headerbar.ui.h:2 105 | msgid "Enter feed address to add" 106 | msgstr "Insira o endereço do feed para adicioná-lo" 107 | 108 | #: ../data/ui/headerbar.ui.h:3 109 | msgid "Add" 110 | msgstr "Adicionar" 111 | 112 | #: ../data/ui/headerbar.ui.h:4 113 | msgid "You are already subscribed to that feed!" 114 | msgstr "Você já está inscrito naquele feed!" 115 | 116 | #: ../data/ui/headerbar.ui.h:5 117 | msgid "Select All" 118 | msgstr "Selecionar tudo" 119 | 120 | #: ../data/ui/headerbar.ui.h:6 121 | msgid "Select None" 122 | msgstr "Selecionar nenhum" 123 | 124 | #: ../data/ui/headerbar.ui.h:7 125 | msgid "Click on items to select them" 126 | msgstr "Clique nos itens para selecioná-los" 127 | 128 | #: ../data/ui/headerbar.ui.h:8 129 | msgid "Mark this article as starred" 130 | msgstr "Marcar este artigo como favorito" 131 | 132 | #: ../data/ui/headerbar.ui.h:9 133 | msgid "Search" 134 | msgstr "Pesquisar" 135 | 136 | #: ../data/ui/headerbar.ui.h:10 137 | msgid "Select" 138 | msgstr "Selecionar" 139 | 140 | #: ../data/ui/headerbar.ui.h:11 141 | msgid "Back" 142 | msgstr "Voltar" 143 | 144 | #: ../gnomenews/toolbar.py:96 145 | #, python-format 146 | msgid "Searching for \"%s\"" 147 | msgstr "Pesquisando por \"%s\"" 148 | 149 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 150 | msgid "This article was already read" 151 | msgstr "Esta artigo já foi lido" 152 | 153 | #: ../gnomenews/view.py:174 154 | msgid "New" 155 | msgstr "Novo" 156 | 157 | #: ../gnomenews/view.py:191 158 | msgid "Feeds" 159 | msgstr "Feeds" 160 | 161 | #: ../gnomenews/view.py:268 162 | msgid "Unknown feed" 163 | msgstr "Feed desconhecido" 164 | 165 | #: ../gnomenews/view.py:361 166 | msgid "Starred" 167 | msgstr "Favorito" 168 | -------------------------------------------------------------------------------- /po/lt.po: -------------------------------------------------------------------------------- 1 | # Lithuanian translation for gnome-news. 2 | # Copyright (C) 2016 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # Moo , 2016. 5 | # Aurimas Černius , 2016. 6 | # 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: gnome-news master\n" 10 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 11 | "news&keywords=I18N+L10N&component=general\n" 12 | "POT-Creation-Date: 2016-03-08 14:37+0000\n" 13 | "PO-Revision-Date: 2016-03-14 21:36+0200\n" 14 | "Last-Translator: Aurimas Černius \n" 15 | "Language-Team: Lietuvių \n" 16 | "Language: lt\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" 21 | "%100<10 || n%100>=20) ? 1 : 2);\n" 22 | "X-Generator: Gtranslator 2.91.7\n" 23 | 24 | #: ../data/gtk/menus.ui.h:1 25 | msgid "About" 26 | msgstr "Apie" 27 | 28 | #: ../data/gtk/menus.ui.h:2 29 | msgid "Quit" 30 | msgstr "Išeiti" 31 | 32 | #. TRANSLATORS: the application name 33 | #: ../data/org.gnome.News.appdata.xml.in.h:2 34 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 35 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 36 | msgid "News" 37 | msgstr "Naujienos" 38 | 39 | #. TRANSLATORS: one-line description for the app 40 | #: ../data/org.gnome.News.appdata.xml.in.h:4 41 | msgid "Feed Reader" 42 | msgstr "Sklaidos kanalų skaitytuvė" 43 | 44 | #. TRANSLATORS: AppData description marketing paragraph 45 | #: ../data/org.gnome.News.appdata.xml.in.h:6 46 | msgid "GNOME News can be used to read news." 47 | msgstr "GNOME naujienos gali būti naudojamos naujienų skaitymui." 48 | 49 | #: ../data/org.gnome.News.desktop.in.h:2 50 | msgid "Feed reader for GNOME" 51 | msgstr "Sklaidos kanalų skaitytuvė, skirta GNOME" 52 | 53 | #: ../data/org.gnome.News.gschema.xml.h:1 54 | msgid "Window size" 55 | msgstr "Lango dydis" 56 | 57 | #: ../data/org.gnome.News.gschema.xml.h:2 58 | msgid "Window size (width and height)." 59 | msgstr "Lango dydis (plotis ir aukštis)." 60 | 61 | #: ../data/org.gnome.News.gschema.xml.h:3 62 | msgid "Window position" 63 | msgstr "Lango padėtis" 64 | 65 | #: ../data/org.gnome.News.gschema.xml.h:4 66 | msgid "Window position (x and y)." 67 | msgstr "Lango padėtis (x ir y)." 68 | 69 | #: ../data/org.gnome.News.gschema.xml.h:5 70 | msgid "Window maximized" 71 | msgstr "Langas išdidintas" 72 | 73 | #: ../data/org.gnome.News.gschema.xml.h:6 74 | msgid "Window maximized state." 75 | msgstr "Lango išdidinimo būsena." 76 | 77 | #: ../data/ui/empty-view.ui.h:1 78 | msgid "No Results Found" 79 | msgstr "Rezultatų nerasta" 80 | 81 | #: ../data/ui/empty-view.ui.h:2 82 | msgid "Try a different search" 83 | msgstr "Bandykite kitą paiešką" 84 | 85 | #: ../data/ui/empty-view.ui.h:3 86 | msgid "No Starred Articles Found" 87 | msgstr "Nerasta žvaigždute pažymėtų straipsnių" 88 | 89 | #: ../data/ui/empty-view.ui.h:4 90 | msgid "You can see your starred articles after marking them" 91 | msgstr "Pažymėkite straipsniu žvaigždute ir juos matysite" 92 | 93 | #: ../data/ui/empty-view.ui.h:5 94 | msgid "No Feed Subscription Found" 95 | msgstr "Prenumeratų nerasta" 96 | 97 | #: ../data/ui/empty-view.ui.h:6 98 | msgid "You can subscribe to feeds using the \"+\" button" 99 | msgstr "Galite prenumeruoti sklaidos kanalus naudodami mygtuką „+“" 100 | 101 | #: ../data/ui/headerbar.ui.h:1 102 | msgid "Add a new feed" 103 | msgstr "Pridėti naują kanalą" 104 | 105 | #: ../data/ui/headerbar.ui.h:2 106 | msgid "Enter feed address to add" 107 | msgstr "Įveskite kanalo, kurį pridėti, adresą" 108 | 109 | #: ../data/ui/headerbar.ui.h:3 110 | msgid "Add" 111 | msgstr "Pridėti" 112 | 113 | #: ../data/ui/headerbar.ui.h:4 114 | msgid "You are already subscribed to that feed!" 115 | msgstr "Jūs jau esate užsiprenumeravę šį kanalą!" 116 | 117 | #: ../data/ui/headerbar.ui.h:5 118 | msgid "Select All" 119 | msgstr "Pažymėti visus" 120 | 121 | #: ../data/ui/headerbar.ui.h:6 122 | msgid "Select None" 123 | msgstr "Nieko nežymėti" 124 | 125 | #: ../data/ui/headerbar.ui.h:7 126 | msgid "Click on items to select them" 127 | msgstr "Spauskite ant elementų, kad juos pažymėtumėte" 128 | 129 | #: ../data/ui/headerbar.ui.h:8 130 | msgid "Mark this article as starred" 131 | msgstr "Pažymėti šį straipsnį žvaigždute" 132 | 133 | #: ../data/ui/headerbar.ui.h:9 134 | msgid "Search" 135 | msgstr "Ieškoti" 136 | 137 | #: ../data/ui/headerbar.ui.h:10 138 | msgid "Select" 139 | msgstr "Pasirinkti" 140 | 141 | #: ../data/ui/headerbar.ui.h:11 142 | msgid "Back" 143 | msgstr "Atgal" 144 | 145 | #: ../gnomenews/toolbar.py:96 146 | #, python-format 147 | msgid "Searching for \"%s\"" 148 | msgstr "Ieškoma „%s“" 149 | 150 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 151 | msgid "This article was already read" 152 | msgstr "Šis straipsnis jau perskaitytas" 153 | 154 | #: ../gnomenews/view.py:174 155 | msgid "New" 156 | msgstr "Nauja" 157 | 158 | #: ../gnomenews/view.py:191 159 | msgid "Feeds" 160 | msgstr "Kanalai" 161 | 162 | #: ../gnomenews/view.py:268 163 | msgid "Unknown feed" 164 | msgstr "Nežinomas kanalas" 165 | 166 | #: ../gnomenews/view.py:361 167 | msgid "Starred" 168 | msgstr "Pažymėta žvaigždute" 169 | -------------------------------------------------------------------------------- /po/sl.po: -------------------------------------------------------------------------------- 1 | # Slovenian translation for gnome-news. 2 | # Copyright (C) 2016 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # 5 | # Matej Urbančič , 2016. 6 | # 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: gnome-news master\n" 10 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 11 | "news&keywords=I18N+L10N&component=general\n" 12 | "POT-Creation-Date: 2016-03-11 09:29+0000\n" 13 | "PO-Revision-Date: 2016-03-11 22:27+0100\n" 14 | "Last-Translator: Matej Urbančič \n" 15 | "Language-Team: Slovenian GNOME Translation Team \n" 17 | "Language: sl_SI\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || " 22 | "n%100==4 ? 3 : 0);\n" 23 | "X-Poedit-SourceCharset: utf-8\n" 24 | "X-Generator: Poedit 1.8.4\n" 25 | 26 | #: ../data/gtk/menus.ui.h:1 27 | msgid "About" 28 | msgstr "O programu" 29 | 30 | #: ../data/gtk/menus.ui.h:2 31 | msgid "Quit" 32 | msgstr "Končaj" 33 | 34 | #. TRANSLATORS: the application name 35 | #: ../data/org.gnome.News.appdata.xml.in.h:2 36 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 37 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 38 | msgid "News" 39 | msgstr "Novice" 40 | 41 | #. TRANSLATORS: one-line description for the app 42 | #: ../data/org.gnome.News.appdata.xml.in.h:4 43 | #, fuzzy 44 | msgid "Feed Reader" 45 | msgstr "Viri" 46 | 47 | #. TRANSLATORS: AppData description marketing paragraph 48 | #: ../data/org.gnome.News.appdata.xml.in.h:6 49 | msgid "GNOME News can be used to read news." 50 | msgstr "" 51 | 52 | #: ../data/org.gnome.News.desktop.in.h:2 53 | #, fuzzy 54 | msgid "Feed reader for GNOME" 55 | msgstr "Pridobivanje vira" 56 | 57 | #: ../data/org.gnome.News.gschema.xml.h:1 58 | #, fuzzy 59 | msgid "Window size" 60 | msgstr "Veikost okna" 61 | 62 | #: ../data/org.gnome.News.gschema.xml.h:2 63 | #, fuzzy 64 | msgid "Window size (width and height)." 65 | msgstr "Velikost okna (širina in višina)." 66 | 67 | #: ../data/org.gnome.News.gschema.xml.h:3 68 | #, fuzzy 69 | msgid "Window position" 70 | msgstr "Položaj okna" 71 | 72 | #: ../data/org.gnome.News.gschema.xml.h:4 73 | #, fuzzy 74 | msgid "Window position (x and y)." 75 | msgstr "Položaj okna (x in y)." 76 | 77 | #: ../data/org.gnome.News.gschema.xml.h:5 78 | #, fuzzy 79 | msgid "Window maximized" 80 | msgstr "Razpeto okno" 81 | 82 | #: ../data/org.gnome.News.gschema.xml.h:6 83 | #, fuzzy 84 | msgid "Window maximized state." 85 | msgstr "Razpeto stanje okna" 86 | 87 | #: ../data/ui/empty-view.ui.h:1 88 | #, fuzzy 89 | msgid "No Results Found" 90 | msgstr "Ni zadetkov" 91 | 92 | #: ../data/ui/empty-view.ui.h:2 93 | #, fuzzy 94 | msgid "Try a different search" 95 | msgstr "Poskusite drugačno iskanje" 96 | 97 | #: ../data/ui/empty-view.ui.h:3 98 | #, fuzzy 99 | msgid "No Starred Articles Found" 100 | msgstr "Zaznamovano" 101 | 102 | #: ../data/ui/empty-view.ui.h:4 103 | msgid "You can see your starred articles after marking them" 104 | msgstr "" 105 | 106 | #: ../data/ui/empty-view.ui.h:5 107 | #, fuzzy 108 | msgid "No Feed Subscription Found" 109 | msgstr "Viri" 110 | 111 | #: ../data/ui/empty-view.ui.h:6 112 | msgid "You can subscribe to feeds using the \"+\" button" 113 | msgstr "" 114 | 115 | #: ../data/ui/headerbar.ui.h:1 116 | #, fuzzy 117 | msgid "Add a new feed" 118 | msgstr "Ni mogoče dodati vira" 119 | 120 | #: ../data/ui/headerbar.ui.h:2 121 | #, fuzzy 122 | msgid "Enter feed address to add" 123 | msgstr "Vnesite uporabniško ime/geslo za vir" 124 | 125 | #: ../data/ui/headerbar.ui.h:3 126 | msgid "Add" 127 | msgstr "Dodaj" 128 | 129 | #: ../data/ui/headerbar.ui.h:4 130 | #, fuzzy 131 | msgid "You are already subscribed to that feed!" 132 | msgstr "Vir že obstaja!" 133 | 134 | #: ../data/ui/headerbar.ui.h:5 135 | msgid "Select All" 136 | msgstr "Izberi vse" 137 | 138 | #: ../data/ui/headerbar.ui.h:6 139 | msgid "Select None" 140 | msgstr "Odstrani izbor" 141 | 142 | #: ../data/ui/headerbar.ui.h:7 143 | #, fuzzy 144 | msgid "Click on items to select them" 145 | msgstr "S klikom se predmeti izberejo" 146 | 147 | #: ../data/ui/headerbar.ui.h:8 148 | #, fuzzy 149 | msgid "Mark this article as starred" 150 | msgstr "Članek" 151 | 152 | #: ../data/ui/headerbar.ui.h:9 153 | msgid "Search" 154 | msgstr "Iskanje" 155 | 156 | #: ../data/ui/headerbar.ui.h:10 157 | msgid "Select" 158 | msgstr "Izberi" 159 | 160 | #: ../data/ui/headerbar.ui.h:11 161 | msgid "Back" 162 | msgstr "Nazaj" 163 | 164 | #: ../gnomenews/toolbar.py:96 165 | #, fuzzy, python-format 166 | msgid "Searching for \"%s\"" 167 | msgstr "Vir za brskanje in iskanje fotografij flickr uporabnika %s" 168 | 169 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 170 | #, fuzzy 171 | msgid "This article was already read" 172 | msgstr "Članek" 173 | 174 | #: ../gnomenews/view.py:174 175 | msgid "New" 176 | msgstr "Novo" 177 | 178 | #: ../gnomenews/view.py:191 179 | msgid "Feeds" 180 | msgstr "Viri" 181 | 182 | #: ../gnomenews/view.py:268 183 | #, fuzzy 184 | msgid "Unknown feed" 185 | msgstr "Viri" 186 | 187 | #: ../gnomenews/view.py:361 188 | #, fuzzy 189 | msgid "Starred" 190 | msgstr "Zaznamovano" 191 | -------------------------------------------------------------------------------- /po/el.po: -------------------------------------------------------------------------------- 1 | # Greek translation for gnome-news. 2 | # Copyright (C) 2016 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # FIRST AUTHOR , YEAR. 5 | # Efstathios Iosifidis , 2016. 6 | # 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: gnome-news master\n" 10 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 11 | "news&keywords=I18N+L10N&component=general\n" 12 | "POT-Creation-Date: 2016-03-09 09:29+0000\n" 13 | "PO-Revision-Date: 2016-03-09 19:14+0200\n" 14 | "Last-Translator: Tom Tryfonidis \n" 15 | "Language-Team: Greek, Modern (1453-) \n" 17 | "Language: el\n" 18 | "MIME-Version: 1.0\n" 19 | "Content-Type: text/plain; charset=UTF-8\n" 20 | "Content-Transfer-Encoding: 8bit\n" 21 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 22 | "X-Generator: Poedit 1.8.7\n" 23 | 24 | #: ../data/gtk/menus.ui.h:1 25 | msgid "About" 26 | msgstr "Περί" 27 | 28 | #: ../data/gtk/menus.ui.h:2 29 | msgid "Quit" 30 | msgstr "Έξοδος" 31 | 32 | #. TRANSLATORS: the application name 33 | #: ../data/org.gnome.News.appdata.xml.in.h:2 34 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 35 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 36 | msgid "News" 37 | msgstr "Νέα" 38 | 39 | #. TRANSLATORS: one-line description for the app 40 | #: ../data/org.gnome.News.appdata.xml.in.h:4 41 | msgid "Feed Reader" 42 | msgstr "Αναγνώστης ροών" 43 | 44 | #. TRANSLATORS: AppData description marketing paragraph 45 | #: ../data/org.gnome.News.appdata.xml.in.h:6 46 | msgid "GNOME News can be used to read news." 47 | msgstr "Τα Νέα GNOME μπορούν να χρησιμοποιηθούν για να διαβάσετε ειδήσεις." 48 | 49 | #: ../data/org.gnome.News.desktop.in.h:2 50 | msgid "Feed reader for GNOME" 51 | msgstr "Αναγνώστης ροών για το GNOME" 52 | 53 | #: ../data/org.gnome.News.gschema.xml.h:1 54 | msgid "Window size" 55 | msgstr "Μέγεθος παραθύρου" 56 | 57 | #: ../data/org.gnome.News.gschema.xml.h:2 58 | msgid "Window size (width and height)." 59 | msgstr "Μέγεθος παραθύρου (πλάτος και ύψος)." 60 | 61 | #: ../data/org.gnome.News.gschema.xml.h:3 62 | msgid "Window position" 63 | msgstr "Θέση παραθύρου" 64 | 65 | #: ../data/org.gnome.News.gschema.xml.h:4 66 | msgid "Window position (x and y)." 67 | msgstr "Θέση παραθύρου (x και y)." 68 | 69 | #: ../data/org.gnome.News.gschema.xml.h:5 70 | msgid "Window maximized" 71 | msgstr "Μεγιστοποιημένο παράθυρο" 72 | 73 | #: ../data/org.gnome.News.gschema.xml.h:6 74 | msgid "Window maximized state." 75 | msgstr "Κατάσταση μεγιστοποιημένου παράθυρου." 76 | 77 | #: ../data/ui/empty-view.ui.h:1 78 | msgid "No Results Found" 79 | msgstr "Δεν βρέθηκαν αποτελέσματα" 80 | 81 | #: ../data/ui/empty-view.ui.h:2 82 | msgid "Try a different search" 83 | msgstr "Δοκιμάστε μια διαφορετική αναζήτηση" 84 | 85 | #: ../data/ui/empty-view.ui.h:3 86 | msgid "No Starred Articles Found" 87 | msgstr "Δεν βρέθηκαν διακεκριμένα άρθρα" 88 | 89 | #: ../data/ui/empty-view.ui.h:4 90 | msgid "You can see your starred articles after marking them" 91 | msgstr "Μπορείτε να δείτε τα διακεκριμένα άρθρα μετά από τη σήμανση τους" 92 | 93 | #: ../data/ui/empty-view.ui.h:5 94 | msgid "No Feed Subscription Found" 95 | msgstr "Δεν βρέθηκε ροή εγγραφής" 96 | 97 | #: ../data/ui/empty-view.ui.h:6 98 | msgid "You can subscribe to feeds using the \"+\" button" 99 | msgstr "Μπορείτε να εγγραφείτε στις ροές χρησιμοποιώντας το κουμπί «+»" 100 | 101 | #: ../data/ui/headerbar.ui.h:1 102 | msgid "Add a new feed" 103 | msgstr "Προσθήκη νέας ροής" 104 | 105 | #: ../data/ui/headerbar.ui.h:2 106 | msgid "Enter feed address to add" 107 | msgstr "Εισάγετε μια διεύθυνση ροής για να προστεθεί" 108 | 109 | #: ../data/ui/headerbar.ui.h:3 110 | msgid "Add" 111 | msgstr "Προσθήκη" 112 | 113 | #: ../data/ui/headerbar.ui.h:4 114 | msgid "You are already subscribed to that feed!" 115 | msgstr "Είστε ήδη εγγεγραμμένος σε αυτή τη ροή!" 116 | 117 | #: ../data/ui/headerbar.ui.h:5 118 | msgid "Select All" 119 | msgstr "Επιλογή όλων" 120 | 121 | #: ../data/ui/headerbar.ui.h:6 122 | msgid "Select None" 123 | msgstr "Καμία επιλογή" 124 | 125 | #: ../data/ui/headerbar.ui.h:7 126 | msgid "Click on items to select them" 127 | msgstr "Κάντε κλικ στα αντικείμενα για να τα επιλέξετε" 128 | 129 | #: ../data/ui/headerbar.ui.h:8 130 | msgid "Mark this article as starred" 131 | msgstr "Επισήμανση αυτού του άρθρου ως διακεκριμένο" 132 | 133 | #: ../data/ui/headerbar.ui.h:9 134 | msgid "Search" 135 | msgstr "Αναζήτηση" 136 | 137 | #: ../data/ui/headerbar.ui.h:10 138 | msgid "Select" 139 | msgstr "Επιλογή" 140 | 141 | #: ../data/ui/headerbar.ui.h:11 142 | msgid "Back" 143 | msgstr "Πίσω" 144 | 145 | #: ../gnomenews/toolbar.py:96 146 | #, python-format 147 | msgid "Searching for \"%s\"" 148 | msgstr "Αναζήτηση για \"%s\"" 149 | 150 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 151 | msgid "This article was already read" 152 | msgstr "Αυτό το άρθρο έχει ήδη διαβαστεί" 153 | 154 | #: ../gnomenews/view.py:174 155 | msgid "New" 156 | msgstr "Νέο" 157 | 158 | #: ../gnomenews/view.py:191 159 | msgid "Feeds" 160 | msgstr "Ροές" 161 | 162 | #: ../gnomenews/view.py:268 163 | msgid "Unknown feed" 164 | msgstr "Άγνωστη ροή" 165 | 166 | #: ../gnomenews/view.py:361 167 | msgid "Starred" 168 | msgstr "Διακεκριμένα" 169 | -------------------------------------------------------------------------------- /po/es.po: -------------------------------------------------------------------------------- 1 | # Spanish translation for gnome-news. 2 | # Copyright (C) 2015 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # Daniel Mustieles , 2015, 2016. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: gnome-news master\n" 9 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 10 | "news&keywords=I18N+L10N&component=general\n" 11 | "POT-Creation-Date: 2016-03-08 14:37+0000\n" 12 | "PO-Revision-Date: 2016-04-08 14:59+0200\n" 13 | "Last-Translator: Daniel Mustieles \n" 14 | "Language-Team: Español; Castellano \n" 15 | "Language: es\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 20 | "X-Generator: Gtranslator 2.91.6\n" 21 | 22 | #: ../data/gtk/menus.ui.h:1 23 | msgid "About" 24 | msgstr "Acerca de" 25 | 26 | #: ../data/gtk/menus.ui.h:2 27 | msgid "Quit" 28 | msgstr "Salir" 29 | 30 | #. TRANSLATORS: the application name 31 | #: ../data/org.gnome.News.appdata.xml.in.h:2 32 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 33 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 34 | msgid "News" 35 | msgstr "Noticias" 36 | 37 | #. TRANSLATORS: one-line description for the app 38 | #: ../data/org.gnome.News.appdata.xml.in.h:4 39 | msgid "Feed Reader" 40 | msgstr "Lector de noticias" 41 | 42 | #. TRANSLATORS: AppData description marketing paragraph 43 | #: ../data/org.gnome.News.appdata.xml.in.h:6 44 | msgid "GNOME News can be used to read news." 45 | msgstr "Noticias de GNOME se puede usar para leer noticias." 46 | 47 | #: ../data/org.gnome.News.desktop.in.h:2 48 | msgid "Feed reader for GNOME" 49 | msgstr "Lector de noticias para GNOME" 50 | 51 | #: ../data/org.gnome.News.gschema.xml.h:1 52 | msgid "Window size" 53 | msgstr "Tamaño de la ventana" 54 | 55 | #: ../data/org.gnome.News.gschema.xml.h:2 56 | msgid "Window size (width and height)." 57 | msgstr "Tamaño de la ventana (anchura y altura)." 58 | 59 | #: ../data/org.gnome.News.gschema.xml.h:3 60 | msgid "Window position" 61 | msgstr "Posición de la ventana" 62 | 63 | #: ../data/org.gnome.News.gschema.xml.h:4 64 | msgid "Window position (x and y)." 65 | msgstr "Posición de la ventana (x e y)" 66 | 67 | #: ../data/org.gnome.News.gschema.xml.h:5 68 | msgid "Window maximized" 69 | msgstr "Ventana maximizada" 70 | 71 | #: ../data/org.gnome.News.gschema.xml.h:6 72 | msgid "Window maximized state." 73 | msgstr "Estado maximizado de la ventana." 74 | 75 | #: ../data/ui/empty-view.ui.h:1 76 | msgid "No Results Found" 77 | msgstr "No se han encontrado resultados" 78 | 79 | #: ../data/ui/empty-view.ui.h:2 80 | msgid "Try a different search" 81 | msgstr "Pruebe una búsqueda diferente" 82 | 83 | #: ../data/ui/empty-view.ui.h:3 84 | msgid "No Starred Articles Found" 85 | msgstr "No se han encontrado artículos favoritos" 86 | 87 | #: ../data/ui/empty-view.ui.h:4 88 | msgid "You can see your starred articles after marking them" 89 | msgstr "Puede ver sus artículos favoritos después de marcarlos como tales" 90 | 91 | #: ../data/ui/empty-view.ui.h:5 92 | msgid "No Feed Subscription Found" 93 | msgstr "No se han encontrado suscripciones a proveedores" 94 | 95 | #: ../data/ui/empty-view.ui.h:6 96 | msgid "You can subscribe to feeds using the \"+\" button" 97 | msgstr "Puede suscribirse a proveedores usando el botón «+»" 98 | 99 | #: ../data/ui/headerbar.ui.h:1 100 | msgid "Add a new feed" 101 | msgstr "Añadir un proveedor nuevo" 102 | 103 | #: ../data/ui/headerbar.ui.h:2 104 | msgid "Enter feed address to add" 105 | msgstr "Introduzca la dirección del proveedor que añadir." 106 | 107 | #: ../data/ui/headerbar.ui.h:3 108 | msgid "Add" 109 | msgstr "Añadir" 110 | 111 | #: ../data/ui/headerbar.ui.h:4 112 | msgid "You are already subscribed to that feed!" 113 | msgstr "Ya está suscrito a ese proveedor." 114 | 115 | #: ../data/ui/headerbar.ui.h:5 116 | msgid "Select All" 117 | msgstr "Seleccionar todo" 118 | 119 | #: ../data/ui/headerbar.ui.h:6 120 | msgid "Select None" 121 | msgstr "No seleccionar nada" 122 | 123 | #: ../data/ui/headerbar.ui.h:7 124 | msgid "Click on items to select them" 125 | msgstr "Pulse sobre los elementos para seleccionarlos" 126 | 127 | #: ../data/ui/headerbar.ui.h:8 128 | msgid "Mark this article as starred" 129 | msgstr "Marcar este artículo como favorito" 130 | 131 | #: ../data/ui/headerbar.ui.h:9 132 | msgid "Search" 133 | msgstr "Buscar" 134 | 135 | #: ../data/ui/headerbar.ui.h:10 136 | msgid "Select" 137 | msgstr "Seleccionar" 138 | 139 | #: ../data/ui/headerbar.ui.h:11 140 | msgid "Back" 141 | msgstr "Atrás" 142 | 143 | #: ../gnomenews/toolbar.py:96 144 | #, python-format 145 | msgid "Searching for \"%s\"" 146 | msgstr "Buscando «%s»" 147 | 148 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 149 | msgid "This article was already read" 150 | msgstr "Este artículo ya se había leído" 151 | 152 | #: ../gnomenews/view.py:174 153 | msgid "New" 154 | msgstr "Nuevo" 155 | 156 | #: ../gnomenews/view.py:191 157 | msgid "Feeds" 158 | msgstr "Proveedores" 159 | 160 | #: ../gnomenews/view.py:268 161 | msgid "Unknown feed" 162 | msgstr "Proveedor desconocido" 163 | 164 | #: ../gnomenews/view.py:361 165 | msgid "Starred" 166 | msgstr "Favoritos" 167 | -------------------------------------------------------------------------------- /po/de.po: -------------------------------------------------------------------------------- 1 | # German translation for gnome-news. 2 | # Copyright (C) 2015 gnome-news's COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the gnome-news package. 4 | # Christian Kirbach , 2015. 5 | # Mario Blättermann , 2015. 6 | # 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: gnome-news master\n" 10 | "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" 11 | "news&keywords=I18N+L10N&component=general\n" 12 | "POT-Creation-Date: 2016-03-08 14:37+0000\n" 13 | "PO-Revision-Date: 2016-03-15 23:32+0100\n" 14 | "Last-Translator: Bernd Homuth \n" 15 | "Language-Team: German \n" 16 | "Language: de\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 21 | "X-Generator: Poedit 1.8.7\n" 22 | 23 | #: ../data/gtk/menus.ui.h:1 24 | msgid "About" 25 | msgstr "Info" 26 | 27 | #: ../data/gtk/menus.ui.h:2 28 | msgid "Quit" 29 | msgstr "Beenden" 30 | 31 | #. TRANSLATORS: the application name 32 | #: ../data/org.gnome.News.appdata.xml.in.h:2 33 | #: ../data/org.gnome.News.desktop.in.h:1 ../gnomenews/application.py:36 34 | #: ../gnomenews/toolbar.py:99 ../gnomenews/window.py:35 35 | msgid "News" 36 | msgstr "Nachrichten" 37 | 38 | #. TRANSLATORS: one-line description for the app 39 | #: ../data/org.gnome.News.appdata.xml.in.h:4 40 | msgid "Feed Reader" 41 | msgstr "Leser für Nachrichtenquellen" 42 | 43 | #. TRANSLATORS: AppData description marketing paragraph 44 | #: ../data/org.gnome.News.appdata.xml.in.h:6 45 | msgid "GNOME News can be used to read news." 46 | msgstr "GNOME Nachrichten kann zum Lesen von Nachrichten verwendet werden" 47 | 48 | #: ../data/org.gnome.News.desktop.in.h:2 49 | msgid "Feed reader for GNOME" 50 | msgstr "Leser für Nachrichtenquellen für GNOME" 51 | 52 | #: ../data/org.gnome.News.gschema.xml.h:1 53 | msgid "Window size" 54 | msgstr "Fenstergröße" 55 | 56 | #: ../data/org.gnome.News.gschema.xml.h:2 57 | msgid "Window size (width and height)." 58 | msgstr "Fenstergröße (Breite und Höhe)." 59 | 60 | #: ../data/org.gnome.News.gschema.xml.h:3 61 | msgid "Window position" 62 | msgstr "Fensterposition" 63 | 64 | #: ../data/org.gnome.News.gschema.xml.h:4 65 | msgid "Window position (x and y)." 66 | msgstr "Fensterposition (x und y)." 67 | 68 | #: ../data/org.gnome.News.gschema.xml.h:5 69 | msgid "Window maximized" 70 | msgstr "Fenster maximiert" 71 | 72 | #: ../data/org.gnome.News.gschema.xml.h:6 73 | msgid "Window maximized state." 74 | msgstr "Fenster im maximierten Status." 75 | 76 | #: ../data/ui/empty-view.ui.h:1 77 | msgid "No Results Found" 78 | msgstr "Keine Ergebnisse gefunden" 79 | 80 | #: ../data/ui/empty-view.ui.h:2 81 | msgid "Try a different search" 82 | msgstr "Versuchen Sie einen anderen Suchbegriff" 83 | 84 | #: ../data/ui/empty-view.ui.h:3 85 | msgid "No Starred Articles Found" 86 | msgstr "Keine markierten Artikel gefunden" 87 | 88 | #: ../data/ui/empty-view.ui.h:4 89 | msgid "You can see your starred articles after marking them" 90 | msgstr "Hier finden Sie Ihre markierten Artikel" 91 | 92 | #: ../data/ui/empty-view.ui.h:5 93 | msgid "No Feed Subscription Found" 94 | msgstr "Keine abonnierte Nachrichtenquelle gefunden" 95 | 96 | #: ../data/ui/empty-view.ui.h:6 97 | msgid "You can subscribe to feeds using the \"+\" button" 98 | msgstr "Sie können Nachrichtenquellen mit dem »+«-Knopf abonnieren" 99 | 100 | #: ../data/ui/headerbar.ui.h:1 101 | msgid "Add a new feed" 102 | msgstr "Neue Nachrichtenquelle hinzufügen" 103 | 104 | #: ../data/ui/headerbar.ui.h:2 105 | msgid "Enter feed address to add" 106 | msgstr "Geben Sie die Adresse der hinzuzufügenden Nachrichtenquelle ein" 107 | 108 | #: ../data/ui/headerbar.ui.h:3 109 | msgid "Add" 110 | msgstr "Hinzufügen" 111 | 112 | #: ../data/ui/headerbar.ui.h:4 113 | msgid "You are already subscribed to that feed!" 114 | msgstr "Sie haben diese Nachrichtenquelle bereits abonniert!" 115 | 116 | #: ../data/ui/headerbar.ui.h:5 117 | msgid "Select All" 118 | msgstr "Alle auswählen" 119 | 120 | #: ../data/ui/headerbar.ui.h:6 121 | msgid "Select None" 122 | msgstr "Keine auswählen" 123 | 124 | #: ../data/ui/headerbar.ui.h:7 125 | msgid "Click on items to select them" 126 | msgstr "Klicken Sie auf Objekte, um diese auszuwählen" 127 | 128 | #: ../data/ui/headerbar.ui.h:8 129 | msgid "Mark this article as starred" 130 | msgstr "Diesen Artikel markieren" 131 | 132 | #: ../data/ui/headerbar.ui.h:9 133 | msgid "Search" 134 | msgstr "Suchen" 135 | 136 | #: ../data/ui/headerbar.ui.h:10 137 | msgid "Select" 138 | msgstr "Auswählen" 139 | 140 | #: ../data/ui/headerbar.ui.h:11 141 | msgid "Back" 142 | msgstr "Zurück" 143 | 144 | #: ../gnomenews/toolbar.py:96 145 | #, python-format 146 | msgid "Searching for \"%s\"" 147 | msgstr "Suche nach »%s«" 148 | 149 | #: ../gnomenews/view.py:86 ../gnomenews/view.py:99 150 | msgid "This article was already read" 151 | msgstr "Dieser Artikel wurde bereits gelesen" 152 | 153 | #: ../gnomenews/view.py:174 154 | msgid "New" 155 | msgstr "Neu" 156 | 157 | #: ../gnomenews/view.py:191 158 | msgid "Feeds" 159 | msgstr "Nachrichtenquellen" 160 | 161 | #: ../gnomenews/view.py:268 162 | msgid "Unknown feed" 163 | msgstr "Unbekannte Nachrichtenquelle" 164 | 165 | #: ../gnomenews/view.py:361 166 | msgid "Starred" 167 | msgstr "Markiert" 168 | -------------------------------------------------------------------------------- /data/ui/window.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | True 7 | False 8 | vertical 9 | 10 | 11 | True 12 | True 13 | False 14 | True 15 | 16 | 17 | True 18 | True 19 | 40 20 | edit-find-symbolic 21 | False 22 | False 23 | 24 | 25 | 26 | 27 | False 28 | True 29 | 0 30 | 31 | 32 | 33 | 34 | True 35 | False 36 | True 37 | True 38 | 39 | 40 | True 41 | False 42 | True 43 | True 44 | crossfade 45 | 46 | 47 | 48 | 51 | 52 | 53 | -1 54 | 55 | 56 | 57 | 58 | True 59 | False 60 | center 61 | start 62 | none 63 | 64 | 65 | True 66 | False 67 | 0 68 | none 69 | 70 | 71 | True 72 | False 73 | 12 74 | 75 | 76 | True 77 | False 78 | 79 | 80 | False 81 | True 82 | 0 83 | 84 | 85 | 86 | 87 | True 88 | True 89 | True 90 | 91 | 92 | False 93 | True 94 | 1 95 | 96 | 97 | 98 | 99 | True 100 | True 101 | True 102 | none 103 | 104 | 105 | True 106 | False 107 | window-close-symbolic 108 | 109 | 110 | 113 | 114 | 115 | False 116 | True 117 | 2 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | False 135 | True 136 | 1 137 | 138 | 139 | 140 | 141 | False 142 | 143 | 144 | False 145 | True 146 | 2 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /gnomenews/toolbar.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Vadim Rutkovsky 2 | # Copyright (C) 2015 Igor Gnatenko 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | from gi.repository import Gtk, GObject, GLib 18 | 19 | from gettext import gettext as _ 20 | 21 | from gnomenews import log 22 | import logging 23 | logger = logging.getLogger(__name__) 24 | 25 | 26 | class ToolbarState: 27 | MAIN = 0 28 | CHILD_VIEW = 1 29 | SEARCH_VIEW = 2 30 | 31 | 32 | class Toolbar(GObject.GObject): 33 | 34 | __gsignals__ = { 35 | 'state-changed': (GObject.SignalFlags.RUN_FIRST, None, ()), 36 | 'toggle-starred': (GObject.SignalFlags.RUN_FIRST, None, (bool,)), 37 | } 38 | 39 | @log 40 | def __init__(self, window): 41 | GObject.GObject.__init__(self) 42 | self.window = window 43 | self._stack_switcher = Gtk.StackSwitcher( 44 | margin_top=2, margin_bottom=2, can_focus=False, halign="center") 45 | 46 | self._ui = Gtk.Builder() 47 | self._ui.add_from_resource('/org/gnome/News/ui/headerbar.ui') 48 | self.header_bar = self._ui.get_object('header-bar') 49 | self.header_bar.set_show_close_button(True) 50 | self.header_bar.set_custom_title(self._stack_switcher) 51 | 52 | self.add_toggle_button = self._ui.get_object('add-toggle-button') 53 | self.add_popover = self._ui.get_object('add-popover') 54 | self.add_popover.hide() 55 | self.add_toggle_button.set_popover(self.add_popover) 56 | 57 | self.new_url = self._ui.get_object('new-url') 58 | self.new_url.connect('changed', self.on_new_url_changed) 59 | self.add_button = self._ui.get_object('add-button') 60 | self.add_button.connect('clicked', self._add_new_feed) 61 | 62 | self._back_button = self._ui.get_object('back-button') 63 | self._back_button.connect('clicked', self.window.on_back_button_clicked) 64 | 65 | self._search_button = self._ui.get_object('search-button') 66 | self._search_button.bind_property('active', 67 | self.window.search_bar, 'search-mode-enabled', 68 | GObject.BindingFlags.BIDIRECTIONAL) 69 | 70 | self.window.search_entry.connect('search-changed', self._search_changed) 71 | 72 | # Starred button 73 | self._starred_button = self._ui.get_object('starred-button') 74 | self._starred_image = self._ui.get_object('starred-button-image') 75 | 76 | self._starred_button.connect('clicked', self._toggle_starred) 77 | self.starred = False 78 | 79 | self.set_state(ToolbarState.MAIN) 80 | 81 | self._stack_switcher.show() 82 | 83 | @log 84 | def reset_header_title(self): 85 | self.header_bar.set_custom_title(self._stack_switcher) 86 | 87 | @log 88 | def _toggle_starred(self, button): 89 | self.set_starred(not self.starred) 90 | self.emit('toggle-starred', self.starred) 91 | 92 | @log 93 | def _search_changed(self, entry, data=None): 94 | if entry.get_text_length() > 0: 95 | self.set_state(ToolbarState.SEARCH_VIEW) 96 | self.header_bar.set_title(_('Searching for "%s"') % entry.get_text()) 97 | else: 98 | self.set_state(ToolbarState.MAIN) 99 | self.header_bar.set_title(_("News")) 100 | 101 | @log 102 | def set_starred(self, starred): 103 | # Don't set the same value 104 | if starred is self.starred: 105 | return 106 | 107 | self.starred = starred 108 | 109 | if starred: 110 | self._starred_image.set_from_icon_name('starred-symbolic', Gtk.IconSize.BUTTON) 111 | else: 112 | self._starred_image.set_from_icon_name('non-starred-symbolic', Gtk.IconSize.BUTTON) 113 | 114 | @log 115 | def set_stack(self, stack): 116 | self._stack_switcher.set_stack(stack) 117 | 118 | @log 119 | def get_stack(self): 120 | return self._stack_switcher.get_stack() 121 | 122 | @log 123 | def hide_stack(self): 124 | self._stack_switcher.hide() 125 | 126 | @log 127 | def show_stack(self): 128 | self._stack_switcher.show() 129 | 130 | @log 131 | def set_state(self, state, btn=None): 132 | self._state = state 133 | self._update() 134 | self.emit('state-changed') 135 | 136 | @log 137 | def _update(self): 138 | if self._state != ToolbarState.MAIN: 139 | self.header_bar.set_custom_title(None) 140 | else: 141 | self.reset_header_title() 142 | 143 | self._back_button.set_visible(self._state == ToolbarState.CHILD_VIEW) 144 | self._search_button.set_visible(self._state != ToolbarState.CHILD_VIEW) 145 | self._starred_button.set_visible(self._state == ToolbarState.CHILD_VIEW) 146 | self.add_toggle_button.set_visible(self._state != ToolbarState.CHILD_VIEW) 147 | 148 | @log 149 | def _add_new_feed(self, button): 150 | new_url = self.new_url.get_text() 151 | self.window.tracker.add_channel(new_url) 152 | self.new_url.set_text('') 153 | self.add_popover.hide() 154 | 155 | @log 156 | def _update_title(self, view, post): 157 | self.set_state(ToolbarState.CHILD_VIEW) 158 | self.header_bar.set_title(post.title) 159 | self.header_bar.set_subtitle(post.author) 160 | self.window._open_article_view(post) 161 | 162 | def on_new_url_changed(self, entry): 163 | text = self.new_url.get_text() 164 | already_subscribed_label = self._ui.get_object("add-box-already-subscribed-label") 165 | if len(text) == 0: 166 | self.add_button.set_sensitive(False) 167 | already_subscribed_label.set_visible(False) 168 | else: 169 | if not GLib.uri_parse_scheme(text): 170 | self.add_button.set_sensitive(False) 171 | already_subscribed_label.set_visible(False) 172 | return 173 | if len(self.window.tracker.get_channels(text)) == 0: 174 | already_subscribed_label.set_visible(False) 175 | self.add_button.set_sensitive(True) 176 | else: 177 | self.add_button.set_sensitive(False) 178 | already_subscribed_label.set_visible(True) 179 | -------------------------------------------------------------------------------- /data/ui/empty-view.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | True 7 | False 8 | center 9 | center 10 | True 11 | True 12 | vertical 13 | 12 14 | 15 | 16 | True 17 | False 18 | 128 19 | edit-find-symbolic 20 | 23 | 24 | 25 | False 26 | True 27 | 0 28 | 29 | 30 | 31 | 32 | True 33 | False 34 | No Results Found 35 | 36 | 37 | 38 | 39 | 40 | 41 | False 42 | True 43 | 1 44 | 45 | 46 | 47 | 48 | True 49 | False 50 | Try a different search 51 | 54 | 55 | 56 | False 57 | True 58 | 2 59 | 60 | 61 | 62 | 63 | True 64 | False 65 | center 66 | center 67 | True 68 | True 69 | vertical 70 | 12 71 | 72 | 73 | True 74 | False 75 | 128 76 | starred-symbolic 77 | 80 | 81 | 82 | False 83 | True 84 | 0 85 | 86 | 87 | 88 | 89 | True 90 | False 91 | No Starred Articles Found 92 | 93 | 94 | 95 | 96 | 97 | 98 | False 99 | True 100 | 1 101 | 102 | 103 | 104 | 105 | True 106 | False 107 | You can see your starred articles after marking them 108 | 111 | 112 | 113 | False 114 | True 115 | 2 116 | 117 | 118 | 119 | 120 | True 121 | False 122 | center 123 | center 124 | True 125 | True 126 | vertical 127 | 12 128 | 129 | 130 | True 131 | False 132 | 128 133 | application-rss+xml-symbolic 134 | 137 | 138 | 139 | False 140 | True 141 | 0 142 | 143 | 144 | 145 | 146 | True 147 | False 148 | No Feed Subscription Found 149 | 150 | 151 | 152 | 153 | 154 | 155 | False 156 | True 157 | 1 158 | 159 | 160 | 161 | 162 | True 163 | False 164 | You can subscribe to feeds using the "+" button 165 | 168 | 169 | 170 | False 171 | True 172 | 2 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /gnomenews/window.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Vadim Rutkovsky 2 | # Copyright (C) 2015 Igor Gnatenko 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | from gi.repository import Gtk, Gio, GLib, GObject 18 | from gettext import gettext as _ 19 | 20 | from gnomenews.toolbar import Toolbar, ToolbarState 21 | from gnomenews.tracker import Tracker 22 | from gnomenews import view 23 | 24 | from gnomenews import log 25 | import logging 26 | logger = logging.getLogger(__name__) 27 | 28 | 29 | class Window(Gtk.ApplicationWindow): 30 | 31 | @log 32 | def __init__(self, app): 33 | Gtk.ApplicationWindow.__init__(self, 34 | application=app, 35 | title=_("News")) 36 | self.settings = Gio.Settings.new('org.gnome.News') 37 | self.set_size_request(200, 100) 38 | self.set_icon_name('gnome-news') 39 | 40 | self.tracker = Tracker() 41 | 42 | self.restore_saved_size() 43 | 44 | # Setup UI widgets 45 | self._setup_widgets() 46 | 47 | self.show() 48 | 49 | @log 50 | def restore_saved_size(self): 51 | 52 | # Restore window size from gsettings 53 | size_setting = self.settings.get_value('window-size') 54 | if isinstance(size_setting[0], int) and isinstance(size_setting[1], int): 55 | self.resize(size_setting[0], size_setting[1]) 56 | 57 | position_setting = self.settings.get_value('window-position') 58 | if len(position_setting) == 2 \ 59 | and isinstance(position_setting[0], int) \ 60 | and isinstance(position_setting[1], int): 61 | self.move(position_setting[0], position_setting[1]) 62 | 63 | if self.settings.get_value('window-maximized'): 64 | self.maximize() 65 | 66 | # Save changes to window size 67 | self.connect("key-press-event", self._on_key_press_event) 68 | self.connect("window-state-event", self._on_window_state_event) 69 | self.configure_event_handler = self.connect("configure-event", self._on_configure_event) 70 | 71 | def _on_window_state_event(self, widget, event): 72 | self.settings.set_boolean('window-maximized', 'GDK_WINDOW_STATE_MAXIMIZED' in event.new_window_state.value_names) 73 | 74 | def _on_configure_event(self, widget, event): 75 | with self.handler_block(self.configure_event_handler): 76 | GLib.idle_add(self._store_window_size_and_position, widget, priority=GLib.PRIORITY_LOW) 77 | 78 | def _on_key_press_event(self, widget, event): 79 | return self.search_bar.handle_event(event) 80 | 81 | def _store_window_size_and_position(self, widget): 82 | size = widget.get_size() 83 | self.settings.set_value('window-size', GLib.Variant('ai', [size[0], size[1]])) 84 | 85 | position = widget.get_position() 86 | self.settings.set_value('window-position', GLib.Variant('ai', [position[0], position[1]])) 87 | 88 | @log 89 | def _setup_widgets(self): 90 | self._ui = Gtk.Builder() 91 | self._ui.add_from_resource('/org/gnome/News/ui/window.ui') 92 | 93 | self._box = self._ui.get_object('box') 94 | self.add(self._box) 95 | 96 | # Views 97 | self.views = [] 98 | self._stack = self._ui.get_object('stack') 99 | self._overlay = self._ui.get_object('overlay') 100 | self._stack.connect("notify::visible-child", self.view_changed) 101 | 102 | # Action bar 103 | self.action_bar = self._ui.get_object('action_bar') 104 | 105 | # Search bar 106 | self.search_bar = self._ui.get_object('search_bar') 107 | self.search_entry = self._ui.get_object('search_entry') 108 | 109 | self.search_entry.connect('search-changed', self.on_search_changed) 110 | 111 | # Header bar 112 | self.toolbar = Toolbar(self) 113 | self.set_titlebar(self.toolbar.header_bar) 114 | 115 | self.toolbar.connect('toggle-starred', self.toggle_starred) 116 | 117 | self._add_views() 118 | 119 | self.toolbar._back_button.set_visible(False) 120 | 121 | @log 122 | def view_changed(self, stack, property_name): 123 | visible_view = self._stack.get_visible_child() 124 | if visible_view in self.views: 125 | visible_view.update() 126 | 127 | @log 128 | def toggle_starred(self, toolbar, starred): 129 | # Ignore the signal when we're not in FeedView 130 | if not self.feed_view: 131 | return 132 | 133 | post = self.feed_view.post 134 | post.is_starred = starred 135 | 136 | self.tracker.mark_post_as_starred(post.url, starred) 137 | 138 | @log 139 | def _add_views(self): 140 | self.views.append(view.NewView(self.tracker)) 141 | self.views.append(view.FeedsView(self.tracker)) 142 | self.views.append(view.StarredView(self.tracker)) 143 | 144 | for i in self.views: 145 | if i.title: 146 | self._stack.add_titled(i, i.name, i.title) 147 | else: 148 | self._stack.add_named(i, i.name) 149 | i.connect('open-article', self.toolbar._update_title) 150 | 151 | self.views.append(view.SearchView(self.tracker)) 152 | 153 | self.toolbar.set_stack(self._stack) 154 | self._stack.set_visible_child(self.views[0]) 155 | 156 | # Search view 157 | self.search_view = view.SearchView(self.tracker) 158 | 159 | self.search_entry.bind_property('text', self.search_view, 'search-query', 160 | GObject.BindingFlags.BIDIRECTIONAL) 161 | 162 | @log 163 | def _open_article_view(self, post): 164 | self.feed_view = view.FeedView(self.tracker, post) 165 | self._stack.previous_view = self._stack.get_visible_child() 166 | self._stack.add_named(self.feed_view, 'feedview') 167 | self._stack.set_visible_child(self.feed_view) 168 | 169 | self.toolbar.set_starred(post.is_starred) 170 | 171 | # Mark the post as read 172 | self.tracker.mark_post_as_read(post.url) 173 | 174 | @log 175 | def on_back_button_clicked(self, widget): 176 | self._stack.set_visible_child(self._stack.previous_view) 177 | self._stack.previous_view = None 178 | self._stack.remove(self.feed_view) 179 | self.toolbar.set_state(ToolbarState.MAIN) 180 | self.feed_view = None 181 | 182 | @log 183 | def on_search_changed(self, entry, data=None): 184 | if entry.get_text_length() > 0: 185 | # Add the view if it's not added yet 186 | if self.search_view not in self._stack.get_children(): 187 | self._stack.previous_view = self._stack.get_visible_child() 188 | self._stack.add_named(self.search_view, 'search_view') 189 | 190 | self._stack.set_visible_child(self.search_view) 191 | else: 192 | self._stack.set_visible_child(self._stack.previous_view) 193 | self._stack.previous_view = None 194 | self._stack.remove(self.search_view) 195 | -------------------------------------------------------------------------------- /data/ui/headerbar.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | True 6 | False 7 | center 8 | True 9 | Add a new feed 10 | 11 | 12 | True 13 | False 14 | center 15 | True 16 | vertical 17 | 10 18 | 6 19 | 20 | 21 | True 22 | False 23 | start 24 | true 25 | Enter feed address to add 26 | 29 | 30 | 31 | 32 | 33 | True 34 | False 35 | 6 36 | 37 | 38 | True 39 | url 40 | 30 41 | 42 | 43 | 44 | 45 | True 46 | False 47 | False 48 | Add 49 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | False 59 | False 60 | start 61 | You are already subscribed to that feed! 62 | 63 | 64 | 65 | 66 | 67 | 68 |
69 | 70 | Select All 71 | win.selectAll 72 | <Primary>a 73 | 74 | 75 | Select None 76 | win.selectNone 77 | 78 |
79 |
80 | 81 | selection-menu 82 | True 83 | True 84 | none 85 | False 86 | 87 | 88 | True 89 | False 90 | horizontal 91 | 6 92 | 93 | 94 | True 95 | False 96 | Click on items to select them 97 | 98 | 99 | start 100 | 0 101 | 102 | 103 | 104 | 105 | True 106 | False 107 | down 108 | none 109 | 110 | 111 | start 112 | 1 113 | 114 | 115 | 116 | 117 | 120 | 121 | 122 | True 123 | False 124 | 125 | 126 | False 127 | center 128 | True 129 | Mark this article as starred 130 | 133 | 134 | 135 | True 136 | False 137 | non-starred-symbolic 138 | 1 139 | 140 | 141 | 142 | 143 | end 144 | 145 | 146 | 147 | 148 | True 149 | False 150 | center 151 | True 152 | Search 153 | 156 | 157 | 158 | True 159 | False 160 | edit-find-symbolic 161 | 1 162 | 163 | 164 | 165 | 166 | end 167 | 168 | 169 | 170 | 171 | False 172 | center 173 | True 174 | Select 175 | 178 | 179 | 180 | True 181 | False 182 | object-select-symbolic 183 | 1 184 | 185 | 186 | 187 | 188 | end 189 | 190 | 191 | 192 | 193 | True 194 | False 195 | center 196 | True 197 | True 198 | Add a new feed 199 | 202 | 203 | 204 | True 205 | False 206 | list-add-symbolic 207 | 1 208 | 209 | 210 | 211 | 212 | start 213 | 214 | 215 | 216 | 217 | True 218 | False 219 | center 220 | True 221 | Back 222 | 225 | 226 | 227 | True 228 | False 229 | go-previous-symbolic 230 | 1 231 | 232 | 233 | 234 | 235 | start 236 | 237 | 238 | 239 |
240 | -------------------------------------------------------------------------------- /git.mk: -------------------------------------------------------------------------------- 1 | # git.mk, a small Makefile to autogenerate .gitignore files 2 | # for autotools-based projects. 3 | # 4 | # Copyright 2009, Red Hat, Inc. 5 | # Copyright 2010,2011,2012,2013 Behdad Esfahbod 6 | # Written by Behdad Esfahbod 7 | # 8 | # Copying and distribution of this file, with or without modification, 9 | # is permitted in any medium without royalty provided the copyright 10 | # notice and this notice are preserved. 11 | # 12 | # The latest version of this file can be downloaded from: 13 | GIT_MK_URL = https://raw.githubusercontent.com/behdad/git.mk/master/git.mk 14 | # 15 | # Bugs, etc, should be reported upstream at: 16 | # https://github.com/behdad/git.mk 17 | # 18 | # To use in your project, import this file in your git repo's toplevel, 19 | # then do "make -f git.mk". This modifies all Makefile.am files in 20 | # your project to -include git.mk. Remember to add that line to new 21 | # Makefile.am files you create in your project, or just rerun the 22 | # "make -f git.mk". 23 | # 24 | # This enables automatic .gitignore generation. If you need to ignore 25 | # more files, add them to the GITIGNOREFILES variable in your Makefile.am. 26 | # But think twice before doing that. If a file has to be in .gitignore, 27 | # chances are very high that it's a generated file and should be in one 28 | # of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES. 29 | # 30 | # The only case that you need to manually add a file to GITIGNOREFILES is 31 | # when remove files in one of mostlyclean-local, clean-local, distclean-local, 32 | # or maintainer-clean-local make targets. 33 | # 34 | # Note that for files like editor backup, etc, there are better places to 35 | # ignore them. See "man gitignore". 36 | # 37 | # If "make maintainer-clean" removes the files but they are not recognized 38 | # by this script (that is, if "git status" shows untracked files still), send 39 | # me the output of "git status" as well as your Makefile.am and Makefile for 40 | # the directories involved and I'll diagnose. 41 | # 42 | # For a list of toplevel files that should be in MAINTAINERCLEANFILES, see 43 | # Makefile.am.sample in the git.mk git repo. 44 | # 45 | # Don't EXTRA_DIST this file. It is supposed to only live in git clones, 46 | # not tarballs. It serves no useful purpose in tarballs and clutters the 47 | # build dir. 48 | # 49 | # This file knows how to handle autoconf, automake, libtool, gtk-doc, 50 | # gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu, appdata, 51 | # appstream. 52 | # 53 | # This makefile provides the following targets: 54 | # 55 | # - all: "make all" will build all gitignore files. 56 | # - gitignore: makes all gitignore files in the current dir and subdirs. 57 | # - .gitignore: make gitignore file for the current dir. 58 | # - gitignore-recurse: makes all gitignore files in the subdirs. 59 | # 60 | # KNOWN ISSUES: 61 | # 62 | # - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the 63 | # submodule doesn't find us. If you have configure.{in,ac} files in 64 | # subdirs, add a proxy git.mk file in those dirs that simply does: 65 | # "include $(top_srcdir)/../git.mk". Add more ..'s to your taste. 66 | # And add those files to git. See vte/gnome-pty-helper/git.mk for 67 | # example. 68 | # 69 | 70 | 71 | 72 | ############################################################################### 73 | # Variables user modules may want to add to toplevel MAINTAINERCLEANFILES: 74 | ############################################################################### 75 | 76 | # 77 | # Most autotools-using modules should be fine including this variable in their 78 | # toplevel MAINTAINERCLEANFILES: 79 | GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL = \ 80 | $(srcdir)/aclocal.m4 \ 81 | $(srcdir)/autoscan.log \ 82 | $(srcdir)/configure.scan \ 83 | `AUX_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_AUX_DIR:$$1' ./configure.ac); \ 84 | test "x$$AUX_DIR" = "x$(srcdir)/" && AUX_DIR=$(srcdir); \ 85 | for x in \ 86 | ar-lib \ 87 | compile \ 88 | config.guess \ 89 | config.sub \ 90 | depcomp \ 91 | install-sh \ 92 | ltmain.sh \ 93 | missing \ 94 | mkinstalldirs \ 95 | test-driver \ 96 | ylwrap \ 97 | ; do echo "$$AUX_DIR/$$x"; done` \ 98 | `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_HEADERS:$$1' ./configure.ac | \ 99 | head -n 1 | while read f; do echo "$(srcdir)/$$f.in"; done` 100 | # 101 | # All modules should also be fine including the following variable, which 102 | # removes automake-generated Makefile.in files: 103 | GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN = \ 104 | `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_FILES:$$1' ./configure.ac | \ 105 | while read f; do \ 106 | case $$f in Makefile|*/Makefile) \ 107 | test -f "$(srcdir)/$$f.am" && echo "$(srcdir)/$$f.in";; esac; \ 108 | done` 109 | # 110 | # Modules that use libtool and use AC_CONFIG_MACRO_DIR() may also include this, 111 | # though it's harmless to include regardless. 112 | GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL = \ 113 | `MACRO_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_MACRO_DIR:$$1' ./configure.ac); \ 114 | if test "x$$MACRO_DIR" != "x$(srcdir)/"; then \ 115 | for x in \ 116 | libtool.m4 \ 117 | ltoptions.m4 \ 118 | ltsugar.m4 \ 119 | ltversion.m4 \ 120 | lt~obsolete.m4 \ 121 | ; do echo "$$MACRO_DIR/$$x"; done; \ 122 | fi` 123 | 124 | 125 | 126 | ############################################################################### 127 | # Default rule is to install ourselves in all Makefile.am files: 128 | ############################################################################### 129 | 130 | git-all: git-mk-install 131 | 132 | git-mk-install: 133 | @echo "Installing git makefile" 134 | @any_failed=; \ 135 | find "`test -z "$(top_srcdir)" && echo . || echo "$(top_srcdir)"`" -name Makefile.am | while read x; do \ 136 | if grep 'include .*/git.mk' $$x >/dev/null; then \ 137 | echo "$$x already includes git.mk"; \ 138 | else \ 139 | failed=; \ 140 | echo "Updating $$x"; \ 141 | { cat $$x; \ 142 | echo ''; \ 143 | echo '-include $$(top_srcdir)/git.mk'; \ 144 | } > $$x.tmp || failed=1; \ 145 | if test x$$failed = x; then \ 146 | mv $$x.tmp $$x || failed=1; \ 147 | fi; \ 148 | if test x$$failed = x; then : else \ 149 | echo "Failed updating $$x"; >&2 \ 150 | any_failed=1; \ 151 | fi; \ 152 | fi; done; test -z "$$any_failed" 153 | 154 | git-mk-update: 155 | wget $(GIT_MK_URL) -O $(top_srcdir)/git.mk 156 | 157 | .PHONY: git-all git-mk-install git-mk-update 158 | 159 | 160 | 161 | ############################################################################### 162 | # Actual .gitignore generation: 163 | ############################################################################### 164 | 165 | $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk 166 | @echo "git.mk: Generating $@" 167 | @{ \ 168 | if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \ 169 | for x in \ 170 | $(DOC_MODULE)-decl-list.txt \ 171 | $(DOC_MODULE)-decl.txt \ 172 | tmpl/$(DOC_MODULE)-unused.sgml \ 173 | "tmpl/*.bak" \ 174 | xml html \ 175 | ; do echo "/$$x"; done; \ 176 | FLAVOR=$$(cd $(top_srcdir); $(AUTOCONF) --trace 'GTK_DOC_CHECK:$$2' ./configure.ac); \ 177 | case $$FLAVOR in *no-tmpl*) echo /tmpl;; esac; \ 178 | fi; \ 179 | if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \ 180 | for lc in $(DOC_LINGUAS); do \ 181 | for x in \ 182 | $(if $(DOC_MODULE),$(DOC_MODULE).xml) \ 183 | $(DOC_PAGES) \ 184 | $(DOC_INCLUDES) \ 185 | ; do echo "/$$lc/$$x"; done; \ 186 | done; \ 187 | for x in \ 188 | $(_DOC_OMF_ALL) \ 189 | $(_DOC_DSK_ALL) \ 190 | $(_DOC_HTML_ALL) \ 191 | $(_DOC_MOFILES) \ 192 | $(DOC_H_FILE) \ 193 | "*/.xml2po.mo" \ 194 | "*/*.omf.out" \ 195 | ; do echo /$$x; done; \ 196 | fi; \ 197 | if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \ 198 | for lc in $(HELP_LINGUAS); do \ 199 | for x in \ 200 | $(HELP_FILES) \ 201 | "$$lc.stamp" \ 202 | "$$lc.mo" \ 203 | ; do echo "/$$lc/$$x"; done; \ 204 | done; \ 205 | fi; \ 206 | if test "x$(gsettings_SCHEMAS)" = x; then :; else \ 207 | for x in \ 208 | $(gsettings_SCHEMAS:.xml=.valid) \ 209 | $(gsettings__enum_file) \ 210 | ; do echo "/$$x"; done; \ 211 | fi; \ 212 | if test "x$(appdata_XML)" = x; then :; else \ 213 | for x in \ 214 | $(appdata_XML:.xml=.valid) \ 215 | ; do echo "/$$x"; done; \ 216 | fi; \ 217 | if test "x$(appstream_XML)" = x; then :; else \ 218 | for x in \ 219 | $(appstream_XML:.xml=.valid) \ 220 | ; do echo "/$$x"; done; \ 221 | fi; \ 222 | if test -f $(srcdir)/po/Makefile.in.in; then \ 223 | for x in \ 224 | po/Makefile.in.in \ 225 | po/Makefile.in.in~ \ 226 | po/Makefile.in \ 227 | po/Makefile \ 228 | po/Makevars.template \ 229 | po/POTFILES \ 230 | po/Rules-quot \ 231 | po/stamp-it \ 232 | po/.intltool-merge-cache \ 233 | "po/*.gmo" \ 234 | "po/*.header" \ 235 | "po/*.mo" \ 236 | "po/*.sed" \ 237 | "po/*.sin" \ 238 | po/$(GETTEXT_PACKAGE).pot \ 239 | intltool-extract.in \ 240 | intltool-merge.in \ 241 | intltool-update.in \ 242 | ; do echo "/$$x"; done; \ 243 | fi; \ 244 | if test -f $(srcdir)/configure; then \ 245 | for x in \ 246 | autom4te.cache \ 247 | configure \ 248 | config.h \ 249 | stamp-h1 \ 250 | libtool \ 251 | config.lt \ 252 | ; do echo "/$$x"; done; \ 253 | fi; \ 254 | if test "x$(DEJATOOL)" = x; then :; else \ 255 | for x in \ 256 | $(DEJATOOL) \ 257 | ; do echo "/$$x.sum"; echo "/$$x.log"; done; \ 258 | echo /site.exp; \ 259 | fi; \ 260 | if test "x$(am__dirstamp)" = x; then :; else \ 261 | echo "$(am__dirstamp)"; \ 262 | fi; \ 263 | if test "x$(LTCOMPILE)" = x -a "x$(LTCXXCOMPILE)" = x -a "x$(GTKDOC_RUN)" = x; then :; else \ 264 | for x in \ 265 | "*.lo" \ 266 | ".libs" "_libs" \ 267 | ; do echo "$$x"; done; \ 268 | fi; \ 269 | for x in \ 270 | .gitignore \ 271 | $(GITIGNOREFILES) \ 272 | $(CLEANFILES) \ 273 | $(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \ 274 | $(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \ 275 | $(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \ 276 | so_locations \ 277 | $(MOSTLYCLEANFILES) \ 278 | $(TEST_LOGS) \ 279 | $(TEST_LOGS:.log=.trs) \ 280 | $(TEST_SUITE_LOG) \ 281 | $(TESTS:=.test) \ 282 | "*.gcda" \ 283 | "*.gcno" \ 284 | $(DISTCLEANFILES) \ 285 | $(am__CONFIG_DISTCLEAN_FILES) \ 286 | $(CONFIG_CLEAN_FILES) \ 287 | TAGS ID GTAGS GRTAGS GSYMS GPATH tags \ 288 | "*.tab.c" \ 289 | $(MAINTAINERCLEANFILES) \ 290 | $(BUILT_SOURCES) \ 291 | $(patsubst %.vala,%.c,$(filter %.vala,$(SOURCES))) \ 292 | $(filter %_vala.stamp,$(DIST_COMMON)) \ 293 | $(filter %.vapi,$(DIST_COMMON)) \ 294 | $(filter $(addprefix %,$(notdir $(patsubst %.vapi,%.h,$(filter %.vapi,$(DIST_COMMON))))),$(DIST_COMMON)) \ 295 | Makefile \ 296 | Makefile.in \ 297 | "*.orig" \ 298 | "*.rej" \ 299 | "*.bak" \ 300 | "*~" \ 301 | ".*.sw[nop]" \ 302 | ".dirstamp" \ 303 | ; do echo "/$$x"; done; \ 304 | for x in \ 305 | "*.$(OBJEXT)" \ 306 | $(DEPDIR) \ 307 | ; do echo "$$x"; done; \ 308 | } | \ 309 | sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \ 310 | sed 's@/[.]/@/@g' | \ 311 | LC_ALL=C sort | uniq > $@.tmp && \ 312 | mv $@.tmp $@; 313 | 314 | all: $(srcdir)/.gitignore gitignore-recurse-maybe 315 | gitignore: $(srcdir)/.gitignore gitignore-recurse 316 | 317 | gitignore-recurse-maybe: 318 | @for subdir in $(DIST_SUBDIRS); do \ 319 | case " $(SUBDIRS) " in \ 320 | *" $$subdir "*) :;; \ 321 | *) test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir");; \ 322 | esac; \ 323 | done 324 | gitignore-recurse: 325 | @for subdir in $(DIST_SUBDIRS); do \ 326 | test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir"); \ 327 | done 328 | 329 | maintainer-clean: gitignore-clean 330 | gitignore-clean: 331 | -rm -f $(srcdir)/.gitignore 332 | 333 | .PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe 334 | -------------------------------------------------------------------------------- /gnomenews/tracker.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Igor Gnatenko 2 | # Copyright (C) 2015 Vadim Rutkovsky 3 | # 4 | # This program is free software: you can redistribute it and/or modify 5 | # it under the terms of the GNU General Public License as published by 6 | # the Free Software Foundation, either version 3 of the License, or 7 | # (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program. If not, see . 16 | 17 | from gi.repository import GLib, GObject, Gio, Tracker as Trackr 18 | 19 | from gnomenews import log 20 | import logging 21 | logger = logging.getLogger(__name__) 22 | 23 | 24 | class Tracker(GObject.GObject): 25 | 26 | __gsignals__ = { 27 | # 'new-item': (GObject.SignalFlags.RUN_FIRST, None, (Grss.FeedChannel, Grss.FeedItem)), 28 | 'items-updated': (GObject.SignalFlags.RUN_LAST, None, ()), 29 | 'feeds-updated': (GObject.SignalFlags.RUN_LAST, None, ()), 30 | } 31 | 32 | @log 33 | def __init__(self): 34 | GObject.GObject.__init__(self) 35 | bus = Gio.bus_get_sync(Gio.BusType.SESSION, None) 36 | bus.signal_subscribe( 37 | "org.freedesktop.Tracker1", 38 | "org.freedesktop.Tracker1.Resources", 39 | "GraphUpdated", 40 | "/org/freedesktop/Tracker1/Resources", 41 | "http://www.tracker-project.org/temp/mfo#FeedMessage", 42 | Gio.DBusSignalFlags.NONE, 43 | self.on_graph_updated) 44 | self.sparql = Trackr.SparqlConnection.get(None) 45 | 46 | @log 47 | def get_post_sorted_by_date(self, unread=False, starred=False): 48 | query = """ 49 | SELECT 50 | nie:url(?msg) AS url 51 | nie:title(?msg) AS title 52 | nco:fullname(?creator) AS fullname 53 | nie:url(?website) AS author_homepage 54 | nco:emailAddress(?email) AS author_email 55 | nie:contentCreated(?msg) AS date 56 | nmo:htmlMessageContent(?msg) AS content 57 | nmo:isRead(?msg) AS is_read 58 | ?msg BOUND(?tag) as is_starred 59 | WHERE 60 | { ?msg a mfo:FeedMessage """ 61 | 62 | if unread: 63 | query += "; nmo:isRead false" 64 | 65 | if starred: 66 | query += "; nao:hasTag nao:predefined-tag-favorite " 67 | 68 | query += """. 69 | OPTIONAL { ?msg nco:creator ?creator . 70 | ?msg nao:hasTag ?tag . 71 | FILTER(?tag = nao:predefined-tag-favorite) . 72 | OPTIONAL {?creator nco:hasEmailAddress ?email } . 73 | OPTIONAL {?creator nco:websiteUrl ?website } 74 | } 75 | } 76 | ORDER BY DESC (nie:contentCreated(?msg)) 77 | """ 78 | 79 | results = self.sparql.query(query) 80 | ret = [] 81 | while (results.next(None)): 82 | ret.append(self.parse_sparql(results)) 83 | return ret 84 | 85 | @log 86 | def get_info_for_entry(self, url): 87 | query = """ 88 | SELECT 89 | nie:title(?msg) AS title 90 | nco:fullname(?creator) AS fullname 91 | nie:url(?website) AS author_homepage 92 | nco:emailAddress(?email) AS author_email 93 | WHERE 94 | { ?msg a mfo:FeedMessage ; 95 | nie:url <%s> . 96 | OPTIONAL { ?msg nco:creator ?creator . 97 | OPTIONAL { ?creator nco:hasEmailAddress ?email } . 98 | OPTIONAL { ?creator nco:websiteUrl ?website }} 99 | }""" % url 100 | 101 | results = self.sparql.query(query) 102 | ret = [] 103 | while (results.next(None)): 104 | ret.append(self.parse_sparql(results)) 105 | if len(ret) != 1: 106 | raise Exception("More than one result returned by feed with url %s" % url) 107 | return ret[0] 108 | 109 | @log 110 | def add_channel(self, url, update_interval=30): 111 | """Add channel to fetching by tracker 112 | 113 | Args: 114 | url (str): URL of the channel. 115 | update_interval (Optional[int]): Update interval in minutes. 116 | Don't use less than 1 minute. 117 | """ 118 | self.sparql.update(""" 119 | INSERT { 120 | _:FeedSettings a mfo:FeedSettings ; 121 | mfo:updateInterval %i . 122 | _:Feed a nie:DataObject, mfo:FeedChannel ; 123 | mfo:feedSettings _:FeedSettings ; 124 | nie:url "%s" } 125 | """ % (update_interval, url), GLib.PRIORITY_DEFAULT, None) 126 | 127 | @log 128 | def mark_post_as_read(self, url, data=None): 129 | """Marks given post as read 130 | 131 | Args: 132 | url (str): URL of the post. 133 | data (Optional): user data. 134 | """ 135 | 136 | query = """ 137 | DELETE 138 | { ?msg nmo:isRead ?any } 139 | WHERE 140 | { ?msg nie:url "%s"; 141 | nmo:isRead ?any } 142 | INSERT 143 | { ?msg nmo:isRead true } 144 | WHERE 145 | { ?msg nie:url "%s" } 146 | """ % (url, url) 147 | 148 | self.sparql.update(query, GLib.PRIORITY_DEFAULT, None) 149 | 150 | @log 151 | def mark_post_as_starred(self, url, starred=True): 152 | """Marks given post as starred 153 | 154 | Args: 155 | url (str): URL of the post. 156 | starred (Optional): whether the post is starred or not. 157 | """ 158 | 159 | query = '' 160 | 161 | if starred: 162 | query = """ 163 | INSERT 164 | { ?msg nao:hasTag nao:predefined-tag-favorite } 165 | WHERE 166 | { ?msg nie:url "%s" } 167 | """ % url 168 | else: 169 | query = """ 170 | DELETE 171 | { ?msg nao:hasTag nao:predefined-tag-favorite } 172 | WHERE 173 | { ?msg nie:url "%s"; 174 | nao:hasTag nao:predefined-tag-favorite } 175 | """ % url 176 | 177 | self.sparql.update(query, GLib.PRIORITY_DEFAULT, None) 178 | 179 | @log 180 | def remove_channel(self, url): 181 | """Drop channel from fetching by tracker 182 | 183 | Args: 184 | url (str): URL of the channel. 185 | """ 186 | query = """ 187 | DELETE 188 | { ?chan a rdfs:Resource } 189 | WHERE 190 | { ?chan nie:url "%s" }""" % url 191 | self.sparql.update(query, GLib.PRIORITY_DEFAULT, None) 192 | self.emit('feeds-updated') 193 | 194 | @log 195 | def get_posts_for_channel(self, url): 196 | """Get posts for channel id 197 | 198 | Args: 199 | url (str): URL of the channel. 200 | unread (Optional[bool]): return only unread items if True. 201 | """ 202 | query = """ 203 | SELECT 204 | nie:url(?msg) AS url 205 | nie:title(?msg) AS title 206 | nco:fullname(?creator) AS fullname 207 | nie:url(?website) AS author_homepage 208 | nco:emailAddress(?email) AS author_email 209 | nie:contentCreated(?msg) AS date 210 | nmo:htmlMessageContent(?msg) AS content 211 | nmo:isRead(?msg) AS is_read 212 | ?msg BOUND(?tag) as is_starred 213 | { ?msg a mfo:FeedMessage; 214 | nmo:communicationChannel ?chan . 215 | ?chan nie:url "%s" . 216 | OPTIONAL { ?msg nco:creator ?creator . 217 | ?msg nao:hasTag ?tag . 218 | FILTER(?tag = nao:predefined-tag-favorite) . 219 | OPTIONAL { ?creator nco:hasEmailAddress ?email } . 220 | OPTIONAL { ?creator nco:websiteUrl ?website }} 221 | } 222 | ORDER BY DESC (nie:contentCreated(?msg)) 223 | """ % url 224 | 225 | results = self.sparql.query(query) 226 | ret = [] 227 | while (results.next(None)): 228 | ret.append(self.parse_sparql(results)) 229 | return ret 230 | 231 | @log 232 | def get_channels(self, url=None): 233 | """Returns list of channels 234 | 235 | Args: 236 | url (Optional[str]): URL of the channel 237 | 238 | Returns: 239 | list of all channels of list limited to one channel if url is 240 | not None 241 | """ 242 | query = """ 243 | SELECT 244 | nie:url(?chan) AS url 245 | nie:title(?chan) AS title 246 | { ?chan a mfo:FeedChannel""" 247 | 248 | if url is not None: 249 | query += """; nie:url "%s" """ % url 250 | query += """ 251 | } 252 | ORDER BY nie:title(?chan) 253 | """ 254 | 255 | results = self.sparql.query(query) 256 | ret = [] 257 | while (results.next(None)): 258 | ret.append(self.parse_sparql(results)) 259 | return ret 260 | 261 | @log 262 | def get_text_matches(self, text, channel=None): 263 | """Do text search lookup 264 | 265 | Args: 266 | text (str): text to search for. 267 | channel (str): URL of the channel. 268 | """ 269 | query = """ 270 | SELECT 271 | nie:url(?msg) AS ?url 272 | nie:title(?msg) AS ?title 273 | nco:fullname(?creator) AS ?fullname 274 | nie:url(?website) AS ?author_homepage 275 | nco:emailAddress(?email) AS ?author_email 276 | nie:contentCreated(?msg) AS ?date_created 277 | nmo:htmlMessageContent(?msg) AS ?content 278 | nmo:isRead(?msg) AS ?is_read 279 | ?msg BOUND(?tag) as ?is_starred 280 | { ?msg a mfo:FeedMessage; """ 281 | 282 | if channel: 283 | query += """ 284 | nmo:communicationChannel ?chan; 285 | ?chan nie:url "%s" . """ 286 | 287 | query += """ 288 | fts:match "%s" . 289 | OPTIONAL { ?msg nco:creator ?creator . 290 | ?msg nao:hasTag ?tag . 291 | FILTER(?tag = nao:predefined-tag-favorite) . 292 | OPTIONAL { ?creator nco:hasEmailAddress ?email } . 293 | OPTIONAL { ?creator nco:websiteUrl ?website }} 294 | } 295 | ORDER BY fts:rank(?msg) 296 | """ 297 | 298 | if channel: 299 | query = query % Trackr.sparql_escape_string(text), channel 300 | else: 301 | query = query % Trackr.sparql_escape_string(text) 302 | 303 | try: 304 | results = self.sparql.query(query) 305 | ret = [] 306 | while (results.next(None)): 307 | ret.append(self.parse_sparql(results)) 308 | return ret 309 | except Exception: 310 | return [] 311 | 312 | @log 313 | def on_graph_updated(self, connection, sender_name, object_path, 314 | interface_name, signal_name, parameters, user_data=None): 315 | unpacked = parameters.unpack() 316 | # FIXME: handle deletes -- unpacked[1] 317 | GLib.idle_add(self._handle_insert_event, unpacked[2]) 318 | 319 | @log 320 | def _handle_insert_event(self, items): 321 | self.emit('items-updated') 322 | self.emit('feeds-updated') 323 | 324 | @staticmethod 325 | @log 326 | def parse_sparql(sparql_ret): 327 | ret = {} 328 | n_columns = sparql_ret.get_n_columns() 329 | for column in range(n_columns): 330 | t = sparql_ret.get_value_type(column) 331 | name = sparql_ret.get_variable_name(column) 332 | if any([t == Trackr.SparqlValueType.URI, 333 | t == Trackr.SparqlValueType.STRING]): 334 | value = sparql_ret.get_string(column)[0] 335 | elif t == Trackr.SparqlValueType.DATETIME: 336 | # Tracker returns ISO 8601 format 337 | tv = GLib.TimeVal.from_iso8601(sparql_ret.get_string(column)[0]) 338 | value = GLib.DateTime.new_from_timeval_local(tv[1]) 339 | elif t == Trackr.SparqlValueType.BOOLEAN: 340 | value = sparql_ret.get_boolean(column) 341 | elif t == Trackr.SparqlValueType.INTEGER: 342 | value = sparql_ret.get_integer(column) 343 | elif t == Trackr.SparqlValueType.DOUBLE: 344 | value = sparql_ret.get_double(column) 345 | else: 346 | try: 347 | value = sparql_ret.get_string(column)[0] 348 | except Exception: 349 | value = None 350 | logger.error("Can't get string value from sparql. name: %s, type: %s", name, t) 351 | ret[name] = value 352 | return ret 353 | 354 | 355 | class EventItem: 356 | def __init__(self, items): 357 | """ 358 | Args: 359 | items (tuple): item tuple 360 | """ 361 | self.graph_id = items[0] 362 | self.subject_id = items[1] 363 | self.pred_id = items[2] 364 | self.object_id = items[3] 365 | -------------------------------------------------------------------------------- /gnomenews/view.py: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Vadim Rutkovsky 2 | # 3 | # This program is free software: you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation, either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | from gi.repository import Gtk, GObject, WebKit2, GLib, Gdk, Gio 17 | 18 | from gettext import gettext as _ 19 | 20 | from gnomenews import log 21 | from gnomenews.post import Post 22 | import logging 23 | logger = logging.getLogger(__name__) 24 | 25 | 26 | class GenericFeedsView(Gtk.Stack): 27 | 28 | __gsignals__ = { 29 | 'open-article': (GObject.SignalFlags.RUN_FIRST, None, (GObject.GObject,)), 30 | } 31 | 32 | @log 33 | def __init__(self, tracker, name, title=None): 34 | Gtk.Stack.__init__(self, 35 | transition_type=Gtk.StackTransitionType.CROSSFADE) 36 | self.name = name 37 | self.title = title 38 | 39 | self._ui = Gtk.Builder() 40 | self._ui.add_from_resource('/org/gnome/News/ui/empty-view.ui') 41 | 42 | self.flowbox = Gtk.FlowBox( 43 | min_children_per_line=2, 44 | activate_on_single_click=True, 45 | row_spacing=10, column_spacing=10, 46 | margin=15, 47 | valign=Gtk.Align.START, 48 | selection_mode=Gtk.SelectionMode.NONE) 49 | self.flowbox.get_style_context().add_class('feeds-list') 50 | self.flowbox.connect('child-activated', self._post_activated) 51 | 52 | # Setup the layout 53 | self.setup_layout() 54 | 55 | # Setup the Empty state view 56 | self._empty_view = self._ui.get_object('empty-view') 57 | self.add_named(self._empty_view, 'empty') 58 | 59 | self.tracker = tracker 60 | self.show_all() 61 | 62 | @log 63 | def show_empty_view(self, show): 64 | if show: 65 | self.set_visible_child_name('empty') 66 | else: 67 | self.set_visible_child_name('view') 68 | 69 | @log 70 | def _add_a_new_preview(self, cursor, child=None): 71 | p = Post(cursor) 72 | if child: 73 | p.flowbox = child 74 | else: 75 | p.flowbox = self.flowbox 76 | p.connect('info-updated', self._insert_post) 77 | 78 | @log 79 | def _insert_post(self, source, post): 80 | image = Gtk.Image.new_from_file(post.thumbnail) 81 | image.get_style_context().add_class('feed-box') 82 | image.show() 83 | 84 | if post.is_read: 85 | image.set_opacity(0.5) 86 | image.set_tooltip_text(_('This article was already read')) 87 | 88 | # Store the post object to refer to it later on 89 | image.post = post.cursor 90 | 91 | source.flowbox.insert(image, -1) 92 | 93 | @log 94 | def _post_activated(self, box, child, user_data=None): 95 | cursor = child.get_children()[0].post 96 | post = Post(cursor) 97 | 98 | child.set_opacity(0.5) 99 | child.set_tooltip_text(_('This article was already read')) 100 | 101 | self.emit('open-article', post) 102 | 103 | @log 104 | def setup_layout(self): 105 | scrolledWindow = Gtk.ScrolledWindow() 106 | 107 | self._box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) 108 | self._box.pack_end(self.flowbox, True, True, 0) 109 | scrolledWindow.add(self._box) 110 | 111 | self.add_named(scrolledWindow, 'view') 112 | 113 | @log 114 | def update(self): 115 | pass 116 | 117 | 118 | class FeedView(Gtk.Stack): 119 | def __init__(self, tracker, post): 120 | Gtk.Stack.__init__(self, 121 | transition_type=Gtk.StackTransitionType.CROSSFADE) 122 | stylesheet = Gio.File.new_for_uri('resource:///org/gnome/News/theme/reader.css') 123 | webview = WebKit2.WebView() 124 | if post.content: 125 | html = """ 126 | 127 | 128 |
129 |

%s

130 | %s 131 |

%s

132 | 143 |
144 | 145 | """ % post.url 146 | 147 | webview.load_html(html) 148 | 149 | webview.connect("decide-policy", self._on_webview_decide_policy) 150 | self.add(webview) 151 | self.show_all() 152 | 153 | self.post = post 154 | self.url = post.url 155 | 156 | @staticmethod 157 | @log 158 | def _on_webview_decide_policy(web_view, decision, decision_type): 159 | if decision_type == WebKit2.PolicyDecisionType.NAVIGATION_ACTION: 160 | uri = decision.get_request().get_uri() 161 | if uri != "about:blank" and decision.get_navigation_type() == WebKit2.NavigationType.LINK_CLICKED: 162 | decision.ignore() 163 | try: 164 | Gtk.show_uri(None, uri, Gdk.CURRENT_TIME) 165 | except GLib.Error: 166 | # for example, irc://irc.gimp.org/#guadec 167 | logger.warning("Couldn't open URI: %s" % uri) 168 | return True 169 | return False 170 | 171 | 172 | class NewView(GenericFeedsView): 173 | def __init__(self, tracker): 174 | GenericFeedsView.__init__(self, tracker, 'new', _("New")) 175 | 176 | self.tracker.connect('items-updated', self.update) 177 | 178 | @log 179 | def update(self, _=None): 180 | [self.flowbox.remove(old_feed) for old_feed in self.flowbox.get_children()] 181 | 182 | posts = self.tracker.get_post_sorted_by_date(unread=True) 183 | [self._add_a_new_preview(post) for post in posts] 184 | self.show_all() 185 | 186 | self.show_empty_view(len(posts) is 0) 187 | 188 | 189 | class FeedsView(GenericFeedsView): 190 | def __init__(self, tracker): 191 | GenericFeedsView.__init__(self, tracker, 'feeds', _("Feeds")) 192 | 193 | # url -> (feed, row) 194 | self.feeds = {} 195 | 196 | app = Gio.Application.get_default() 197 | delete_channel_action = app.lookup_action('delete_channel') 198 | delete_channel_action.connect('activate', self.delete_channel) 199 | 200 | self.tracker.connect('items-updated', self.update_items) 201 | self.tracker.connect('feeds-updated', self.update) 202 | 203 | @log 204 | def update_items(self, _=None): 205 | for flowbox in self.feed_stack.get_children(): 206 | url = self.feed_stack.child_get_property(flowbox, 'name') 207 | 208 | [flowbox.remove(old_feed) for old_feed in flowbox.get_children()] 209 | 210 | posts = self.tracker.get_posts_for_channel(url) 211 | [self._add_a_new_preview(post, flowbox) for post in posts] 212 | 213 | @log 214 | def update(self, _=None): 215 | new_feeds = self.tracker.get_channels() 216 | new_feed_urls = [new_feed['url'] for new_feed in new_feeds] 217 | 218 | # Remove old feeds 219 | for feed in list(self.feeds.keys()): 220 | if feed not in new_feed_urls: 221 | logger.info("Removing channel %s" % feed) 222 | self.feed_stack.remove(self.feed_stack.get_child_by_name(feed)) 223 | self.listbox.remove(self.feeds[feed][1]) 224 | del self.feeds[feed] 225 | 226 | # Add new feeds 227 | for new_feed in new_feeds: 228 | if new_feed['url'] not in self.feeds: 229 | logger.info("Adding channel %s" % new_feed['url']) 230 | self._add_new_feed(new_feed) 231 | 232 | self.show_empty_view(len(new_feeds) is 0) 233 | 234 | @log 235 | def _add_new_feed(self, feed): 236 | # Check if we're not adding an already added feed 237 | if feed['url'] in self.feeds: 238 | return 239 | 240 | # Add a row to the listbox 241 | row = Gtk.ListBoxRow() 242 | row.add(Gtk.Label(label=feed['title'], margin=10, xalign=0)) 243 | row.set_tooltip_text(feed['url']) 244 | row.feed = feed 245 | row.show_all() 246 | 247 | self.listbox.add(row) 248 | 249 | # Add a flowbox with the items 250 | flowbox = Gtk.FlowBox( 251 | min_children_per_line=2, 252 | activate_on_single_click=True, 253 | row_spacing=10, column_spacing=10, 254 | valign=Gtk.Align.START, 255 | margin=15, 256 | selection_mode=Gtk.SelectionMode.NONE) 257 | flowbox.get_style_context().add_class('feeds-list') 258 | flowbox.connect('child-activated', self._post_activated) 259 | flowbox.show() 260 | 261 | flowbox.row = row 262 | flowbox.feed = feed 263 | 264 | posts = self.tracker.get_posts_for_channel(feed['url']) 265 | [self._add_a_new_preview(post, flowbox) for post in posts] 266 | 267 | if not feed['title']: 268 | feed['title'] = _("Unknown feed") 269 | self.feed_stack.add_titled(flowbox, feed['url'], feed['title']) 270 | 271 | self.feeds[feed['url']] = (feed, row) 272 | 273 | @log 274 | def delete_channel(self, action, index_variant): 275 | try: 276 | index = index_variant.get_int32() 277 | row = self.listbox.get_children()[index] 278 | url = row.feed['url'] 279 | self.tracker.remove_channel(url) 280 | except Exception as e: 281 | logger.warn("Failed to remove feed %s: %s" % (str(index_variant), str(e))) 282 | 283 | @log 284 | def setup_layout(self): 285 | self.feed_stack = Gtk.Stack( 286 | transition_type=Gtk.StackTransitionType.CROSSFADE, 287 | transition_duration=100, 288 | visible=True, 289 | can_focus=False) 290 | self.feed_stack.connect('notify::visible-child-name', self.visible_feed_changed) 291 | 292 | feedstackScrolledWindow = Gtk.ScrolledWindow(expand=True) 293 | feedstackScrolledWindow.add(self.feed_stack) 294 | 295 | self.listbox = Gtk.ListBox(selection_mode=Gtk.SelectionMode.SINGLE) 296 | self.listbox.set_sort_func(self.sort_function) 297 | self.listbox.connect('button-release-event', self._on_button_release) 298 | self.listbox.connect('row-selected', self._on_row_selected) 299 | 300 | listboxScrolledWindow = Gtk.ScrolledWindow(min_content_width=200) 301 | listboxScrolledWindow.add(self.listbox) 302 | 303 | self._box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) 304 | self._box.add(listboxScrolledWindow) 305 | self._box.add(Gtk.Separator.new(Gtk.Orientation.VERTICAL)) 306 | self._box.add(feedstackScrolledWindow) 307 | 308 | self.add_named(self._box, 'view') 309 | 310 | self._box.show_all() 311 | 312 | @log 313 | def visible_feed_changed(self, stack, property_name): 314 | if stack.get_visible_child(): 315 | row = stack.get_visible_child().row 316 | self.listbox.select_row(row) 317 | 318 | @log 319 | def _on_row_selected(self, listbox, row, _=None): 320 | if row: 321 | self.feed_stack.set_visible_child_name(row.feed['url']) 322 | 323 | @log 324 | def _on_button_release(self, w, event): 325 | selected_row = self.listbox.get_row_at_y(event.y) 326 | (_, button) = event.get_button() 327 | 328 | # Abort if the click is not in any row 329 | if not selected_row: 330 | return Gdk.EVENT_PROPAGATE 331 | 332 | # Left click 333 | if button is Gdk.BUTTON_PRIMARY: 334 | self.feed_stack.set_visible_child_name(selected_row.feed['url']) 335 | 336 | return Gdk.EVENT_PROPAGATE 337 | 338 | # Right click 339 | elif button is Gdk.BUTTON_SECONDARY: 340 | try: 341 | index = selected_row.get_index() 342 | 343 | menu = Gio.Menu() 344 | menu.append("Remove", "app.delete_channel(%s)" % index) 345 | 346 | popover = Gtk.Popover.new_from_model(selected_row, menu) 347 | popover.position = Gtk.PositionType.BOTTOM 348 | popover.show() 349 | 350 | except Exception as e: 351 | logger.warn("Error showing popover: %s" % str(e)) 352 | 353 | return Gdk.EVENT_STOP 354 | 355 | def sort_function(self, row1, row2, _=None): 356 | return row1.feed['title'] > row2.feed['title'] 357 | 358 | 359 | class StarredView(GenericFeedsView): 360 | def __init__(self, tracker): 361 | GenericFeedsView.__init__(self, tracker, 'starred', _("Starred")) 362 | 363 | # Setup a custom empty view 364 | self.remove(self._empty_view) 365 | 366 | self._empty_view = self._ui.get_object('empty-starred-view') 367 | self.add_named(self._empty_view, 'empty') 368 | 369 | self.tracker.connect('items-updated', self.update) 370 | 371 | @log 372 | def update(self, _=None): 373 | [self.flowbox.remove(old_feed) for old_feed in self.flowbox.get_children()] 374 | 375 | posts = self.tracker.get_post_sorted_by_date(starred=True) 376 | [self._add_a_new_preview(post) for post in posts] 377 | self.show_all() 378 | 379 | self.show_empty_view(len(posts) is 0) 380 | 381 | 382 | class SearchView(GenericFeedsView): 383 | 384 | __gproperties__ = { 385 | 'search-query': (str, 'Query', 'Search query', "", GObject.ParamFlags.READWRITE) 386 | } 387 | 388 | def __init__(self, tracker): 389 | GenericFeedsView.__init__(self, tracker, 'search') 390 | 391 | self.search_query = "" 392 | 393 | # Setup a custom empty view 394 | self.remove(self._empty_view) 395 | 396 | self._empty_view = self._ui.get_object('empty-search-view') 397 | self.add_named(self._empty_view, 'empty') 398 | 399 | @log 400 | def do_get_property(self, prop): 401 | if prop.name == 'search-query': 402 | return self.search_query 403 | else: 404 | raise AttributeError('Unknown property %s' % prop.name) 405 | 406 | @log 407 | def do_set_property(self, prop, value): 408 | if prop.name == 'search-query': 409 | self.search_query = value 410 | self.update_search() 411 | else: 412 | raise AttributeError('Unknown property %s' % prop.name) 413 | 414 | @log 415 | def update_search(self): 416 | [self.flowbox.remove(old_feed) for old_feed in self.flowbox.get_children()] 417 | 418 | if len(self.search_query) is 0: 419 | return 420 | 421 | posts = self.tracker.get_text_matches(self.search_query) 422 | [self._add_a_new_preview(post) for post in posts] 423 | self.show_all() 424 | 425 | self.show_empty_view(len(posts) is 0) 426 | --------------------------------------------------------------------------------