mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fca6132a0 | ||
|
|
137eba33c9 | ||
|
|
143699c0a4 | ||
|
|
0485403fff | ||
|
|
489fcb9666 | ||
|
|
7cc3b84ebc | ||
|
|
cb254f87d4 | ||
|
|
d4db98fd64 | ||
|
|
d14a6d8311 | ||
|
|
286c115167 | ||
|
|
6038b9e052 | ||
|
|
552082a36a | ||
|
|
5cea92d96d | ||
|
|
02b7b89b94 | ||
|
|
93697cf1f5 | ||
|
|
8daaee28c3 | ||
|
|
c32f608ec5 | ||
|
|
7b09029c5b | ||
|
|
6e1c414c84 | ||
|
|
e57976be99 | ||
|
|
a37e6a3f4c | ||
|
|
2dbe4064b2 | ||
|
|
2b0c0d467a | ||
|
|
40fa4516df | ||
|
|
5201c0cd14 | ||
|
|
61039dcd7e | ||
|
|
039ff4ee41 | ||
|
|
b40349805f | ||
|
|
d709d119ac | ||
|
|
8d2b6bdc12 | ||
|
|
ff78af2d56 | ||
|
|
ada53dba3b | ||
|
|
ba2f6c0f66 | ||
|
|
268869345c | ||
|
|
4b556bd3a9 | ||
|
|
6f10d35a4c | ||
|
|
33167fcdce | ||
|
|
e9c85b0e77 | ||
|
|
e521254600 | ||
|
|
a773d98400 | ||
|
|
ae066d3cd9 | ||
|
|
b5726fc0f3 | ||
|
|
4a056a0d27 | ||
|
|
7817431bce | ||
|
|
c02d2745c3 | ||
|
|
ee610ec800 | ||
|
|
6c0d585fef | ||
|
|
29417005b0 | ||
|
|
cf87fd8340 | ||
|
|
f1b85b0dde | ||
|
|
abef73d384 | ||
|
|
83f26cde53 |
@@ -1,3 +1,12 @@
|
||||
v 2.4.0
|
||||
- users were not able to change password or delete account
|
||||
- fix api key generation
|
||||
- feed entries can now be sorted alphabetically
|
||||
- fix facebook sharing
|
||||
- fix layout on iOS
|
||||
- postgresql driver update (fix for postgres 9.6)
|
||||
- various internationalization fixes
|
||||
- security fixes
|
||||
v 2.3.0
|
||||
- dropwizard upgrade 0.9.1
|
||||
- feed enclosures are hidden if they already displayed in the content
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
Sources for [CommaFeed.com](http://www.commafeed.com/).
|
||||
|
||||
Google Reader inspired self-hosted RSS reader, based on Dropwizard and AngularJS.
|
||||
CommaFeed is now considered feature-complete and is in maintenance mode.
|
||||
|
||||
## Related open-source projects
|
||||
|
||||
@@ -16,8 +17,8 @@ Browser extensions: [Chrome](https://github.com/Athou/commafeed-chrome) - [Firef
|
||||
### The very short version (download precompiled package)
|
||||
|
||||
mkdir commafeed && cd commafeed
|
||||
wget https://github.com/Athou/commafeed/releases/download/2.2.0/commafeed.jar
|
||||
wget https://raw.githubusercontent.com/Athou/commafeed/2.2.0/config.yml.example -O config.yml
|
||||
wget https://github.com/Athou/commafeed/releases/download/2.3.0/commafeed.jar
|
||||
wget https://raw.githubusercontent.com/Athou/commafeed/2.3.0/config.yml.example -O config.yml
|
||||
vi config.yml
|
||||
java -Djava.net.preferIPv4Stack=true -jar commafeed.jar server config.yml
|
||||
|
||||
@@ -123,7 +124,7 @@ Steps to configuring a development environment for CommaFeed may include, but ma
|
||||
|
||||
## Copyright and license
|
||||
|
||||
Copyright 2013-2015 CommaFeed.
|
||||
Copyright 2013-2016 CommaFeed.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this work except in compliance with the License.
|
||||
|
||||
@@ -28,6 +28,14 @@ app:
|
||||
smtpTls: false
|
||||
smtpUserName: user
|
||||
smtpPassword: pass
|
||||
|
||||
# Graphite Metric settings
|
||||
# Allows those who use Graphite to have CommaFeed send metrics for graphing (time in seconds)
|
||||
graphiteEnabled: false
|
||||
graphitePrefix: "test.commafeed"
|
||||
graphiteHost: "localhost"
|
||||
graphitePort: 2003
|
||||
graphiteInterval: 60
|
||||
|
||||
# wether this commafeed instance has a lot of feeds to refresh
|
||||
# leave this to false in almost all cases
|
||||
@@ -75,7 +83,7 @@ app:
|
||||
|
||||
database:
|
||||
driverClass: org.h2.Driver
|
||||
url: jdbc:h2:./target/example;mv_store=false
|
||||
url: jdbc:h2:./target/example
|
||||
user: sa
|
||||
password: sa
|
||||
properties:
|
||||
|
||||
@@ -29,6 +29,14 @@ app:
|
||||
smtpUserName:
|
||||
smtpPassword:
|
||||
smtpFromAddress:
|
||||
|
||||
# Graphite Metric settings
|
||||
# Allows those who use Graphite to have CommaFeed send metrics for graphing (time in seconds)
|
||||
graphiteEnabled: false
|
||||
graphitePrefix: "test.commafeed"
|
||||
graphiteHost: "localhost"
|
||||
graphitePort: 2003
|
||||
graphiteInterval: 60
|
||||
|
||||
# wether this commafeed instance has a lot of feeds to refresh
|
||||
# leave this to false in almost all cases
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#Maven download properties
|
||||
#Sat Jul 04 09:06:32 CEST 2015
|
||||
distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
|
||||
distributionUrl=https\://repository.apache.org/content/repositories/releases/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
|
||||
|
||||
21
pom.xml
21
pom.xml
@@ -4,14 +4,10 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.commafeed</groupId>
|
||||
<artifactId>commafeed</artifactId>
|
||||
<version>2.3.0</version>
|
||||
<version>2.4.0</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>CommaFeed</name>
|
||||
|
||||
<prerequisites>
|
||||
<maven>3.1.0</maven>
|
||||
</prerequisites>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
@@ -171,7 +167,7 @@
|
||||
<phase>compile</phase>
|
||||
<configuration>
|
||||
<nodeVersion>v0.10.39</nodeVersion>
|
||||
<npmVersion>2.12.1</npmVersion>
|
||||
<npmVersion>3.10.6</npmVersion>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
@@ -181,7 +177,7 @@
|
||||
</goals>
|
||||
<phase>compile</phase>
|
||||
<configuration>
|
||||
<arguments>install --loglevel info</arguments>
|
||||
<arguments>install</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
@@ -283,6 +279,11 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dropwizard.metrics</groupId>
|
||||
<artifactId>metrics-graphite</artifactId>
|
||||
<version>3.1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
@@ -328,7 +329,7 @@
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.0</version>
|
||||
<version>4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
@@ -417,7 +418,7 @@
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.190</version>
|
||||
<version>1.3.176</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
@@ -427,7 +428,7 @@
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>9.4-1205-jdbc42</version>
|
||||
<version>9.4.1212</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jtds</groupId>
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "إعادة انعاش",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc" : "الترتيب حسب التاريخ تصاعدي / تنازلي",
|
||||
"sort_by_abc_zyx" : "Sort alphabetically",
|
||||
"titles_only" : "العناوين فقط",
|
||||
"expanded_view" : "عرض موسع",
|
||||
"mark_all_as_read" : "اعتبر الكل مقروء",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Actualitzar",
|
||||
"refresh_all" : "Força l'actualització de tots els canals",
|
||||
"sort_by_asc_desc" : "Ordenar per data asc/desc",
|
||||
"sort_by_abc_zyx" : "Sort alphabetically",
|
||||
"titles_only" : "Només títols",
|
||||
"expanded_view" : "Vista ampliada",
|
||||
"mark_all_as_read" : "Marcar tots llegits",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh " : " Obnovit",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc " : " Seřadit podle nejnovějšího/nejstaršího",
|
||||
"sort_by_abc_zyx" : "Sort alphabetically",
|
||||
"titles_only " : " Zobrazit jenom titulky",
|
||||
"expanded_view " : " Rozšířený náhled",
|
||||
"mark_all_as_read " : " Označit vše jako přečtené",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Adnewyddu",
|
||||
"refresh_all" : "Gorfodi ail-lwytho pob ffrwd",
|
||||
"sort_by_asc_desc" : "Trefnu yn ôl dyddiad",
|
||||
"sort_by_abc_zyx" : "Sort alphabetically",
|
||||
"titles_only" : "Teitlau yn unig",
|
||||
"expanded_view" : "Golwg estynedig",
|
||||
"mark_all_as_read" : "Nodi'r cyfan fel wedi ei ddarllen",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Opdater",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc" : "Sorter efter dato ny/gammel",
|
||||
"sort_by_abc_zyx" : "Sort alphabetically",
|
||||
"titles_only" : "Kun titler",
|
||||
"expanded_view" : "Udvidet visning",
|
||||
"mark_all_as_read" : "Marker alle som læst",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Aktualisieren",
|
||||
"refresh_all" : "Erzwinge Aktualisierung aller Feeds",
|
||||
"sort_by_asc_desc" : "Nach Datum sortieren (auf-/absteigend)",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Nur Überschriften",
|
||||
"expanded_view" : "Ausgedehnte Ansicht",
|
||||
"mark_all_as_read" : "Alle Artikel als gelesen markieren",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Refresh",
|
||||
"refresh_all" : "Force refresh all my feeds",
|
||||
"sort_by_asc_desc" : "Sort by date asc/desc",
|
||||
"sort_by_abc_zyx" : "Sort alphabetically",
|
||||
"titles_only" : "Titles only",
|
||||
"expanded_view" : "Expanded view",
|
||||
"mark_all_as_read" : "Mark all as read",
|
||||
|
||||
@@ -40,9 +40,10 @@
|
||||
"all" : "Todos",
|
||||
"previous_entry" : "Entrada anterior",
|
||||
"next_entry" : "Entrada siguiente",
|
||||
"refresh" : "Atualizar",
|
||||
"refresh" : "Actualizar",
|
||||
"refresh_all" : "Forzar la actualización de todos mis canales.",
|
||||
"sort_by_asc_desc" : "Ordenar por fecha asc/desc.",
|
||||
"sort_by_abc_zyx" : "Ordenar alfabéticamente",
|
||||
"titles_only" : "Sólo títulos",
|
||||
"expanded_view" : "Vista expandida",
|
||||
"mark_all_as_read" : "Marcar todos como leído",
|
||||
@@ -94,7 +95,7 @@
|
||||
"website" : "Sitio web",
|
||||
"name" : "Nombre",
|
||||
"category" : "Categoría",
|
||||
"position" : "Posicióon",
|
||||
"position" : "Posición",
|
||||
"last_refresh" : "Última actualización",
|
||||
"message" : "Último mensaje de actualización",
|
||||
"next_refresh" : "Próxima actualización",
|
||||
@@ -105,7 +106,7 @@
|
||||
"unsubscribe_confirmation" : "¿Estás seguro de querer terminar tu suscripción a este canal?",
|
||||
"delete_category_confirmation" : "¿Estás seguro de querer eliminar esta categoría?",
|
||||
"category_details" : "Detalles de la categoría",
|
||||
"tag_details" : "Detalles de las etiuqetas ",
|
||||
"tag_details" : "Detalles de las etiquetas ",
|
||||
"parent_category" : "Categoría principal"
|
||||
},
|
||||
"profile" : {
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "تازهسازی",
|
||||
"refresh_all" : "مجبورکردن تازهسازی همهٔ خوراکها",
|
||||
"sort_by_asc_desc" : "مرتبکردن بر اساس تاریخ بهصورت صعودی/نزولی",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "فقط عنوانها",
|
||||
"expanded_view" : "نمای گسترشیافته",
|
||||
"mark_all_as_read" : "علامتگذاری تمامی مطالب بهعنوان خواندهشده",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Päivitä",
|
||||
"refresh_all" : "Pakota kaikkien syötteiden päivitys",
|
||||
"sort_by_asc_desc" : "Järjestä päivämäärän mukaan nousevasti/laskevasti",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Näytä vain otsikot",
|
||||
"expanded_view" : "Laajennettu näkymä",
|
||||
"mark_all_as_read" : "Merkitse kaikki luetuiksi",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Rafraîchir",
|
||||
"refresh_all" : "Rafraîchir tous les flux",
|
||||
"sort_by_asc_desc" : "Trier par date croissante/décroissante",
|
||||
"sort_by_abc_zyx" : "Trier par ordre alphabétique",
|
||||
"titles_only" : "Titres uniquement",
|
||||
"expanded_view" : "Vue étendue",
|
||||
"mark_all_as_read" : "Tout marquer comme lu",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Actualizar",
|
||||
"refresh_all" : "Forzar a actualización de todas as fontes ",
|
||||
"sort_by_asc_desc" : "Ordenar por data asc/desc",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Só títulos",
|
||||
"expanded_view" : "Vista expandida",
|
||||
"mark_all_as_read" : "Marcar todos como lidos",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "واجأری",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc" : "تاریخˇ سر دچئن",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "خالی تیتران",
|
||||
"expanded_view" : "واشاده نما",
|
||||
"mark_all_as_read" : "همهته مطالبه چاکون بخانده",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Frissítés",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc" : "Rendezés időrend szerint",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Csak cím",
|
||||
"expanded_view" : "Részletes nézet",
|
||||
"mark_all_as_read" : "Az összes megjelölése olvasottként",
|
||||
|
||||
183
src/main/app/i18n/id.js
Normal file
183
src/main/app/i18n/id.js
Normal file
@@ -0,0 +1,183 @@
|
||||
{
|
||||
"global" : {
|
||||
"save" : "Simpan",
|
||||
"cancel" : "Batal",
|
||||
"delete" : "Hapus",
|
||||
"required" : "Diminta",
|
||||
"download" : "Unduh",
|
||||
"link" : "Tautan",
|
||||
"bookmark" : "Penanda halaman buku",
|
||||
"close" : "Tutup",
|
||||
"tags" : "Penanda"
|
||||
},
|
||||
"tree" : {
|
||||
"subscribe" : "Berlangganan",
|
||||
"import" : "Impor",
|
||||
"new_category" : "Kategori Baru",
|
||||
"all" : "Semua",
|
||||
"starred" : "Diutamakan"
|
||||
},
|
||||
"subscribe" : {
|
||||
"feed_url" : "Umpan URL",
|
||||
"feed_name" : "Nama Umpan",
|
||||
"category" : "Kategori"
|
||||
},
|
||||
"import" : {
|
||||
"google_reader_prefix" : "Izinkan saya mengimpor umpan Anda dari kepunyaan Anda ",
|
||||
"google_reader_suffix" : " akun.",
|
||||
"google_download" : "Atau, unggah berkas subscriptions.xml Anda.",
|
||||
"google_download_link" : "Unggah dari sini.",
|
||||
"xml_file" : "Berkas OPML"
|
||||
},
|
||||
"new_category" : {
|
||||
"name" : "Nama",
|
||||
"parent" : "Induk"
|
||||
},
|
||||
"toolbar" : {
|
||||
"unread" : "Belum dibaca",
|
||||
"all" : "Semua",
|
||||
"previous_entry" : "Catatan sebelumnya",
|
||||
"next_entry" : "Catatan selanjutnya",
|
||||
"refresh" : "Segarkan",
|
||||
"refresh_all" : "Memaksa menyegarkan semua umpan saya",
|
||||
"sort_by_asc_desc" : "Urutkan menurut tanggal asc/desc",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Hanya Judul",
|
||||
"expanded_view" : "Penglihatan diperluas",
|
||||
"mark_all_as_read" : "Tandai semua sebagai telah dibaca",
|
||||
"mark_all_older_12_hours" : "Butir lebih lama 12 jam",
|
||||
"mark_all_older_day" : "Butir lebih lama sehari",
|
||||
"mark_all_older_week" : "Butir lebih lama seminggu",
|
||||
"mark_all_older_two_weeks" : "Butir lebih lama dua minggu",
|
||||
"settings" : "Pengaturan",
|
||||
"profile" : "Profil",
|
||||
"admin" : "Admin",
|
||||
"about" : "Tentang",
|
||||
"logout" : "Keluar",
|
||||
"donate" : "Donasi"
|
||||
},
|
||||
"view" : {
|
||||
"entry_source" : "dari ",
|
||||
"entry_author" : "oleh ",
|
||||
"error_while_loading_feed" : "Galat saat memuat umpan ini",
|
||||
"keep_unread" : "Tetapkan belum dibaca",
|
||||
"no_unread_items" : "Tidak ada yang butir yang belum dibaca.",
|
||||
"mark_up_to_here" : "Tandai sebagai dibaca di sini",
|
||||
"search_for" : "mencari: ",
|
||||
"no_search_results" : "Tidak ditemukan kata kunci yang sesuai dengan permintaan"
|
||||
},
|
||||
"feedsearch" : {
|
||||
"hint" : "Ketik sebuah langganan...",
|
||||
"help" : "Gunakan tombol enter untuk memilih dan tombol panah untuk navigasi.",
|
||||
"result_prefix" : "Langganan Anda:"
|
||||
},
|
||||
"settings" : {
|
||||
"general" : {
|
||||
"value" : "Umum",
|
||||
"language" : "Bahasa",
|
||||
"language_contribute" : "Kontribusi dengan terjemahan",
|
||||
"show_unread" : "Menampilkan umpan dan kategori tanpa catatan belum dibaca",
|
||||
"social_buttons" : "Menampilkan tombol sosial berbagi",
|
||||
"scroll_marks" : "Di penglihatan luas, menggulir melalui catatan menandakan sebagai telah dibaca"
|
||||
},
|
||||
"appearance" : "Penampilan",
|
||||
"scroll_speed" : "Kecepatan menggulir ketika menavigasi antar catatan (dalam milidetik)",
|
||||
"scroll_speed_help" : "setel ke 0 untuk menonaktifkan",
|
||||
"theme" : "Tema",
|
||||
"submit_your_theme" : "Mengajukan tema Anda",
|
||||
"custom_css" : "Ubah CSS"
|
||||
},
|
||||
"details" : {
|
||||
"feed_details" : "Rincian Umpan",
|
||||
"url" : "URL",
|
||||
"website" : "Situs",
|
||||
"name" : "Nama",
|
||||
"category" : "Kategori",
|
||||
"position" : "Posisi",
|
||||
"last_refresh" : "Penyegaran terakhir",
|
||||
"message" : "Menyegarkan pesan terakhir",
|
||||
"next_refresh" : "Penyegaran selanjutnya",
|
||||
"queued_for_refresh" : "Antri untuk penyegaran",
|
||||
"feed_url" : "Umpan URL",
|
||||
"filtering_expression" : "Penyaring ekspresi",
|
||||
"filtering_expression_help" : "Jika tidak kosong, sebuah ekspresi mengevaluasi ke 'benar' atau 'salah'. Jika salah, catatan baru untuk umpan ini akan ditandai sebagai telah dibaca secara otomatis. \nVariabel yang tersedia adalah 'judul', 'konten', 'url' 'penulis' dan 'kategori' dan konten mereka dikonversi dari huruf kecil ke perbandingan string yang mudah. \nContoh: url.contains('youtube') or (author eq 'athou' and title.contains('github'). \nSintaksis lengkap tersedia di <a href='http://commons.apache.org/proper/commons-jexl/reference/syntax.html' target='_blank'>here</a>.",
|
||||
"generate_api_key_first" : "Menghasilkan sebuah kunci API di profil Anda terlebih dahulu.",
|
||||
"unsubscribe" : "Berhenti berlangganan",
|
||||
"unsubscribe_confirmation" : "Apakah Anda yakin ingin berhenti berlangganan dari umpan ini?",
|
||||
"delete_category_confirmation" : "Apakah Anda yakin ingin menghapus dari kategori ini?",
|
||||
"category_details" : "rincian Kategori",
|
||||
"tag_details" : "rincian Penanda",
|
||||
"parent_category" : "kategori Induk"
|
||||
},
|
||||
"profile" : {
|
||||
"user_name" : "nama Pengguna",
|
||||
"email" : "Surel",
|
||||
"change_password" : "Ganti kata sandi",
|
||||
"confirm_password" : "Konfirmasi kata sandi",
|
||||
"minimum_6_chars" : "Minimal 6 karakter",
|
||||
"passwords_do_not_match" : "Kata sandi tidak sesuai",
|
||||
"api_key" : "kunci API",
|
||||
"api_key_not_generated" : "Belum menghasilkan",
|
||||
"generate_new_api_key" : "Hasilkan kunci API baru",
|
||||
"generate_new_api_key_info" : "Mengganti kata sandi akan menghasilkan sebuah kunci API baru",
|
||||
"opml_export" : "ekspor OPML",
|
||||
"delete_account" : "Hapus akun",
|
||||
"delete_account_confirmation" : "Hapus akun Anda? Hal ini tidak dapat dikembalikan!"
|
||||
},
|
||||
"about" : {
|
||||
"rest_api" : {
|
||||
"value" : "REST API",
|
||||
"line1" : "CommaFeed dibangun di atas JAX-RS dan AngularJS. Dengan demikian, tersedia sebuah REST API.",
|
||||
"link_to_documentation" : "Tautan menuju dokumentasi."
|
||||
},
|
||||
"keyboard_shortcuts" : "pintasan Papanketik",
|
||||
"version" : "versi CommaFeed",
|
||||
"line1_prefix" : "CommaFeed adalah suatu proyek open-source. Sumber di ",
|
||||
"line1_suffix" : ".",
|
||||
"line2_prefix" : "Jika Anda mengalami sebuah isu, silahkan laporkan pada halaman isu ",
|
||||
"line2_suffix" : " proyek.",
|
||||
"line3" : "Jika Anda menyukai proyek ini, silahkan mempertimbangkan suatu donasi untuk mendukung pengembang dan membantu menutupi biaya online situs ini.",
|
||||
"line4" : "Untuk Anda yang lebih suka bitcoin, alamatnya di sini",
|
||||
"goodies" : {
|
||||
"value" : "Bingkisan",
|
||||
"android_app" : "Android app",
|
||||
"subscribe_url" : "URL Langganan",
|
||||
"chrome_extension" : "ekstensi Chrome",
|
||||
"firefox_extension" : "ekstensi Firefox",
|
||||
"opera_extension" : "ekstensi Opera",
|
||||
"subscribe_bookmarklet" : "Tambahkan bookmarklet langganan(klik)",
|
||||
"subscribe_bookmarklet_asc" : "Terlama dahulu",
|
||||
"subscribe_bookmarklet_desc" : "Terbaru dahulu",
|
||||
"next_unread_bookmarklet" : "Butir bookmarklet selanjutnya yang belum dibaca (seret ke batang penanda halaman buku)"
|
||||
},
|
||||
"translation" : {
|
||||
"value" : "Terjemahan",
|
||||
"message" : "Kami membutuhkan bantuan Anda untuk menterjemahkan CommaFeed.",
|
||||
"link" : "Lihat bagaimana berkontribusi dengan terjemahan."
|
||||
},
|
||||
"announcements" : "Pengumuman",
|
||||
"shortcuts" : {
|
||||
"mouse_middleclick" : "klik tengah tetikus",
|
||||
"open_next_entry" : "buka catatan selanjutnya",
|
||||
"open_previous_entry" : "buka catatan sebelumnya",
|
||||
"spacebar" : "spasi/shift+spasi",
|
||||
"move_page_down_up" : "pindah halaman bawah/atas",
|
||||
"focus_next_entry" : "setel fokus pada catatan selanjutnya tanpa membukanya",
|
||||
"focus_previous_entry" : "setel fokus pada catatan sebelumnya tanpa membukanya",
|
||||
"open_next_feed" : "buka umpan atau kategori selanjutnya",
|
||||
"open_previous_feed" : "buka umpan atau kategori sebelumnya",
|
||||
"open_close_current_entry" : "buka/tutup catatan saat ini",
|
||||
"open_current_entry_in_new_window" : "buka catatan saat ini di sebuah jendela baru",
|
||||
"open_current_entry_in_new_window_background" : "buka catatan saat ini di sebuah jendela baru pada latar",
|
||||
"star_unstar" : "tanda bintang/tidak catatan saat ini",
|
||||
"mark_current_entry" : "tandai sebagai telah dibaca/belum catatan saat ini",
|
||||
"mark_all_as_read" : "tandai semua catatan sebagai telah dibaca",
|
||||
"open_in_new_tab_mark_as_read" : "buka catatan di tab baru dan tandai sebagai telah dibaca",
|
||||
"fullscreen" : "beralih modus layar penuh",
|
||||
"font_size" : "tingkatkan/turunkan ukuran huruf dari catatan saat ini",
|
||||
"go_to_all" : "menuju ke lihat Semua",
|
||||
"go_to_starred" : "menuju ke lihat Tanda Bintang",
|
||||
"feed_search" : "navigasi ke langganan dengan memasukkan nama langganan"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Aggiorna",
|
||||
"refresh_all" : "Forza l'aggiornamento di tutti i feed",
|
||||
"sort_by_asc_desc" : "Ordina per data crescente/decrescente",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Solo i titoli",
|
||||
"expanded_view" : "Espandi",
|
||||
"mark_all_as_read" : "Segna tutti come già letti",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "更新",
|
||||
"refresh_all" : "全てのフィードを更新",
|
||||
"sort_by_asc_desc" : "昇順/降順にソート",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "タイトルのみ",
|
||||
"expanded_view" : "拡張ビュー",
|
||||
"mark_all_as_read" : "全て既読にする",
|
||||
|
||||
@@ -4,23 +4,23 @@
|
||||
"cancel" : "취소",
|
||||
"delete" : "삭제",
|
||||
"required" : "필수",
|
||||
"download" : "Download ",
|
||||
"link" : "Link ",
|
||||
"bookmark" : "Bookmark ",
|
||||
"close" : "Close ",
|
||||
"tags" : "Tags "
|
||||
"download" : "다운로드",
|
||||
"link" : "링크",
|
||||
"bookmark" : "북마크",
|
||||
"close" : "닫기 ",
|
||||
"tags" : "태그 "
|
||||
},
|
||||
"tree" : {
|
||||
"subscribe" : "구독",
|
||||
"import" : "임포트",
|
||||
"import" : "가져오기",
|
||||
"new_category" : "새로운 카테고리",
|
||||
"all" : "전체",
|
||||
"starred" : "스타"
|
||||
"starred" : "중요 표시됨"
|
||||
},
|
||||
"subscribe" : {
|
||||
"feed_url" : "피드 URL",
|
||||
"feed_name" : "피드 이름",
|
||||
"category" : "카테로기"
|
||||
"category" : "카테고리"
|
||||
},
|
||||
"import" : {
|
||||
"google_reader_prefix" : "당신의 Google Reader",
|
||||
@@ -31,23 +31,24 @@
|
||||
},
|
||||
"new_category" : {
|
||||
"name" : "이름",
|
||||
"parent" : "카테고리 주소로 가기"
|
||||
"parent" : "부모 카테고리"
|
||||
},
|
||||
"toolbar" : {
|
||||
"unread" : "안읽음",
|
||||
"unread" : "읽지 않음",
|
||||
"all" : "전체",
|
||||
"previous_entry" : "Previous entry ",
|
||||
"next_entry" : "Next entry ",
|
||||
"refresh" : "리프래쉬",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc" : "Sort by date asc/desc ",
|
||||
"titles_only" : "Titles only ",
|
||||
"expanded_view" : "Expanded view ",
|
||||
"mark_all_as_read" : "읽음표시",
|
||||
"mark_all_older_12_hours" : "Items older than 12 hours ",
|
||||
"mark_all_older_day" : "Items older than a day ",
|
||||
"mark_all_older_week" : "Items older than a week ",
|
||||
"mark_all_older_two_weeks" : "Items older than two weeks ",
|
||||
"previous_entry" : "이전 항목",
|
||||
"next_entry" : "다음 항목",
|
||||
"refresh" : "새로고침",
|
||||
"refresh_all" : "모든 피드를 강제로 새로고침",
|
||||
"sort_by_asc_desc" : "날짜별 오름차/내림차순 정렬",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "제목만 표시하기",
|
||||
"expanded_view" : "Expanded View",
|
||||
"mark_all_as_read" : "읽음으로 표시",
|
||||
"mark_all_older_12_hours" : "12시간보다 오래된 항목",
|
||||
"mark_all_older_day" : "1일보다 오래된 항목",
|
||||
"mark_all_older_week" : "1주일보다 오래된 항목",
|
||||
"mark_all_older_two_weeks" : "2주일보다 오래된 항목",
|
||||
"settings" : "설정",
|
||||
"profile" : "프로필",
|
||||
"admin" : "괸리자",
|
||||
@@ -57,124 +58,124 @@
|
||||
},
|
||||
"view" : {
|
||||
"entry_source" : "from ",
|
||||
"entry_author" : "by ",
|
||||
"error_while_loading_feed" : "피드로딩중 에러",
|
||||
"keep_unread" : "안읽은것 저장",
|
||||
"no_unread_items" : " 읽지않은 항목이 없읍니다.",
|
||||
"mark_up_to_here" : "Mark as read up to here ",
|
||||
"search_for" : "searching for: ",
|
||||
"no_search_results" : "No match found for the requested keywords "
|
||||
"entry_author" : "by ",
|
||||
"error_while_loading_feed" : "피드 로딩중 에러",
|
||||
"keep_unread" : "항상 읽지 않음으로 표시",
|
||||
"no_unread_items" : " 읽지 않은 항목이 없습니다.",
|
||||
"mark_up_to_here" : "이 위로 읽음으로 표시",
|
||||
"search_for" : "검색: ",
|
||||
"no_search_results" : "검색 결과 없음"
|
||||
},
|
||||
"feedsearch" : {
|
||||
"hint" : "Type in a subscription... ",
|
||||
"help" : "Use the return key to select and arrow keys to navigate. ",
|
||||
"result_prefix" : "Your subscriptions: "
|
||||
"hint" : "구독 이름을 입력하세요",
|
||||
"help" : "화살표 키로 이동하고 엔터 키로 선택하세요.",
|
||||
"result_prefix" : "검색 결과:"
|
||||
},
|
||||
"settings" : {
|
||||
"general" : {
|
||||
"value" : "일반",
|
||||
"language" : "일반 언어",
|
||||
"language_contribute" : "번역 도움하기",
|
||||
"show_unread" : "안읽은 항목들이 있는 피드와 카테고리 보여주기",
|
||||
"social_buttons" : "소셜미디아 버튼들 보여주기",
|
||||
"scroll_marks" : "Expanded View에서 스크롤하면 항목들을 읽음으로 저장하기"
|
||||
"language" : "언어",
|
||||
"language_contribute" : "번역에 기여하기",
|
||||
"show_unread" : "안 읽은 항목들이 있는 피드와 카테고리 보여주기",
|
||||
"social_buttons" : "공유 버튼 표시하기",
|
||||
"scroll_marks" : "Expanded View에서 스크롤하면 항목들을 읽음으로 표시하기"
|
||||
},
|
||||
"appearance" : "Appearance ",
|
||||
"scroll_speed" : "Scrolling speed when navigating between entries (in milliseconds) ",
|
||||
"scroll_speed_help" : "set to 0 to disable ",
|
||||
"theme" : "Theme ",
|
||||
"submit_your_theme" : "Submit your theme ",
|
||||
"custom_css" : "커스톰 CSS"
|
||||
"appearance" : "외관",
|
||||
"scroll_speed" : "항목 사이를 이동할 때 스크롤 속도 (밀리초로 설정)",
|
||||
"scroll_speed_help" : "비활성화하려면 0으로 설정하세요",
|
||||
"theme" : "테마",
|
||||
"submit_your_theme" : "새 테마 업로드",
|
||||
"custom_css" : "커스텀 CSS"
|
||||
},
|
||||
"details" : {
|
||||
"feed_details" : "피드 세부",
|
||||
"url" : "유알엘",
|
||||
"website" : "Website ",
|
||||
"feed_details" : "피드 상세",
|
||||
"url" : "URL",
|
||||
"website" : "웹사이트",
|
||||
"name" : "이름",
|
||||
"category" : "카테고리",
|
||||
"position" : "Position ",
|
||||
"last_refresh" : "마지막 리프래쉬",
|
||||
"message" : "Last refresh message ",
|
||||
"next_refresh" : "Next refresh ",
|
||||
"queued_for_refresh" : "Queued for refresh ",
|
||||
"feed_url" : "피드 유알엘",
|
||||
"position" : "위치",
|
||||
"last_refresh" : "마지막 새로고침",
|
||||
"message" : "마지막 새로고침 메시지",
|
||||
"next_refresh" : "다음 새로고침",
|
||||
"queued_for_refresh" : "새로고침 대기중",
|
||||
"feed_url" : "피드 URL",
|
||||
"generate_api_key_first" : "당신의 프로필을 위해 API Key를 먼저 생성하세요.",
|
||||
"unsubscribe" : "주소 삭제",
|
||||
"unsubscribe_confirmation" : "Are you sure you want to unsubscribe from this feed? ",
|
||||
"delete_category_confirmation" : "Are you sure you want to delete this category? ",
|
||||
"category_details" : "카테고리 세부",
|
||||
"tag_details" : "Tag details ",
|
||||
"unsubscribe" : "구독 해제",
|
||||
"unsubscribe_confirmation" : "정말 이 피드를 구독 해제하시겠습니까?",
|
||||
"delete_category_confirmation" : "정말 이 카테고리를 삭제하시겠습니까?",
|
||||
"category_details" : "카테고리 상세",
|
||||
"tag_details" : "태그 상세",
|
||||
"parent_category" : "부모 카테고리"
|
||||
},
|
||||
"profile" : {
|
||||
"user_name" : "사용자 이름",
|
||||
"email" : "이메일",
|
||||
"change_password" : "비밀번호변경",
|
||||
"confirm_password" : "비밀번호확인",
|
||||
"minimum_6_chars" : "최소로 6자문자가 필요합니다.",
|
||||
"change_password" : "비밀번호 변경",
|
||||
"confirm_password" : "비밀번호 확인",
|
||||
"minimum_6_chars" : "최소 6개의 문자가 필요합니다.",
|
||||
"passwords_do_not_match" : "비밀번호가 일치하지 않습니다.",
|
||||
"api_key" : "API key",
|
||||
"api_key_not_generated" : "아직 API Key가 생성되지 않았습니다.",
|
||||
"generate_new_api_key" : "API Key 생성하기",
|
||||
"generate_new_api_key_info" : "비밀번호를 변경하면 새로운 API Key가 생성됩니다.",
|
||||
"opml_export" : "OPML export ",
|
||||
"delete_account" : "프로필삭제",
|
||||
"delete_account_confirmation" : "Delete your acount? There's no turning back! "
|
||||
"opml_export" : "OPML 내보내기",
|
||||
"delete_account" : "계정 삭제하기",
|
||||
"delete_account_confirmation" : "계정을 삭제하시겠습니까? 되돌릴 수 없어요!"
|
||||
},
|
||||
"about" : {
|
||||
"rest_api" : {
|
||||
"value" : "REST API",
|
||||
"line1" : "CommaFeed는 JAX-RS하고 AngularJS를 이용해서 만들었습니다. 그렇기 때문에 REST API를 사용할수있습니다.",
|
||||
"line1" : "CommaFeed는 JAX-RS와 AngularJS를 이용해 만들었습니다. 그렇기 때문에 REST API를 사용할수있습니다.",
|
||||
"link_to_documentation" : "문서 링크."
|
||||
},
|
||||
"keyboard_shortcuts" : "단축기",
|
||||
"version" : "CommaFeed version ",
|
||||
"line1_prefix" : "CommaFeed는 오픈 소스프로젝트입니다. 소스는",
|
||||
"keyboard_shortcuts" : "단축키",
|
||||
"version" : "CommaFeed 버전",
|
||||
"line1_prefix" : "CommaFeed는 오픈 소스 프로젝트입니다. 소스는",
|
||||
"line1_suffix" : "에 있습니다.",
|
||||
"line2_prefix" : "문제가 발생하는 경우",
|
||||
"line2_suffix" : " 프로젝트 문제페이지에 보고하십시요.",
|
||||
"line3" : "이 프로젝트를 좋아하시면 개발자를 지원하고 웹사이트 유지용비를 충당하는 데 도움이되는 기부금을 고려하시기 바랍니다.",
|
||||
"line4" : "For those of you who prefer bitcoin, here is the address ",
|
||||
"line2_suffix" : " 프로젝트 문제 페이지에 보고하십시오.",
|
||||
"line3" : "이 프로젝트를 좋아하시면 개발자를 지원하고 웹사이트 유지비용을 충당하는 데 도움이 되는 기부금을 고려하시기 바랍니다.",
|
||||
"line4" : "비트코인으로 기부하기",
|
||||
"goodies" : {
|
||||
"value" : "Goodies",
|
||||
"android_app" : "Android app ",
|
||||
"subscribe_url" : "Subscribe URL ",
|
||||
"chrome_extension" : "Chrome extension ",
|
||||
"firefox_extension" : "Firefox extension ",
|
||||
"opera_extension" : "Opera extension ",
|
||||
"subscribe_bookmarklet" : "Add subscription bookmarklet (click) ",
|
||||
"subscribe_bookmarklet_asc" : "Oldest first ",
|
||||
"subscribe_bookmarklet_desc" : "Newest first ",
|
||||
"next_unread_bookmarklet" : "Next unread item bookmarklet (drag to bookmark bar) "
|
||||
"android_app" : "안드로이드 앱",
|
||||
"subscribe_url" : "구독 URL",
|
||||
"chrome_extension" : "Chrome 확장 프로그램",
|
||||
"firefox_extension" : "Firefox 확장 기능",
|
||||
"opera_extension" : "Opera 확장 기능",
|
||||
"subscribe_bookmarklet" : "구독 북마크 추가 (클릭)",
|
||||
"subscribe_bookmarklet_asc" : "오래된 것 먼저",
|
||||
"subscribe_bookmarklet_desc" : "새로운 것 먼저",
|
||||
"next_unread_bookmarklet" : "안 읽은 항목 북마크 (북마크바에 끌기) "
|
||||
},
|
||||
"translation" : {
|
||||
"value" : "번역",
|
||||
"message" : "CommaFeed를 번역할려면 당신의 도움이 필요합니다.",
|
||||
"message" : "CommaFeed를 번역하는데 당신의 도움이 필요합니다.",
|
||||
"link" : "번역에 기여하기"
|
||||
},
|
||||
"announcements" : "공지",
|
||||
"shortcuts" : {
|
||||
"mouse_middleclick" : "마우시 미들클릭",
|
||||
"mouse_middleclick" : "마우스 미들클릭",
|
||||
"open_next_entry" : "다음 항목 열기",
|
||||
"open_previous_entry" : "이전 항목 열기",
|
||||
"spacebar" : "space/shift+space ",
|
||||
"move_page_down_up" : "moves the page down/up ",
|
||||
"focus_next_entry" : "set focus on next entry without opening it ",
|
||||
"focus_previous_entry" : "set focus on previous entry without opening it ",
|
||||
"open_next_feed" : "open next feed or category ",
|
||||
"open_previous_feed" : "open previous feed or category ",
|
||||
"move_page_down_up" : "페이지 아래/위로 이동 ",
|
||||
"focus_next_entry" : "열지 않고 다음 항목 보기",
|
||||
"focus_previous_entry" : "열지 않고 이전 항목 보기",
|
||||
"open_next_feed" : "다음 피드나 카테고리 열기",
|
||||
"open_previous_feed" : "이전 피드나 카테고리 열기",
|
||||
"open_close_current_entry" : "현재 항목 열기/닫기",
|
||||
"open_current_entry_in_new_window" : "새 창에서 현재 항목열기",
|
||||
"open_current_entry_in_new_window_background" : "open current entry in a new window in the background ",
|
||||
"star_unstar" : "현재 항목 스타/스타제거",
|
||||
"open_current_entry_in_new_window" : "새 창으로 현재 항목 열기",
|
||||
"open_current_entry_in_new_window_background" : "백그라운드에 새 창으로 현재 항목 열기",
|
||||
"star_unstar" : "현재 항목 중요 표시/중요 표시 제거",
|
||||
"mark_current_entry" : "현재 항목 읽음/안읽음 표시",
|
||||
"mark_all_as_read" : "모든 항목 읽음으로 표시",
|
||||
"open_in_new_tab_mark_as_read" : "읽음으로 표시하고 새로운 탭에서 열기",
|
||||
"fullscreen" : "toggle full screen mode ",
|
||||
"font_size" : "increase/decrease font size of the current entry ",
|
||||
"go_to_all" : "go to the All view ",
|
||||
"go_to_starred" : "go to the Starred view ",
|
||||
"feed_search" : "navigate to a subscription by entering the subscription name "
|
||||
"fullscreen" : "전체화면 켜기/끄기",
|
||||
"font_size" : "현재 항목의 글꼴 크기를 크게/작게",
|
||||
"go_to_all" : "모든 항목 보기",
|
||||
"go_to_starred" : "중요 표시한 항목 보기",
|
||||
"feed_search" : "구독 이름으로 구독 찾기"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Refresh",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc" : "Aturkan mengikut tarikh (baru/lama)",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Tajuk sahaja",
|
||||
"expanded_view" : "Wide view",
|
||||
"mark_all_as_read" : "Tanda kesemuanya telah dibaca",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Oppdater",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc" : "Sorter etter dato ny/gammel",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Kun titler",
|
||||
"expanded_view" : "Utvidet visning",
|
||||
"mark_all_as_read" : "Merk alle som lest",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Vernieuwen",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc" : "Sorteer op datum opl/afl",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Alleen titels",
|
||||
"expanded_view" : "Uitgebreide weergave",
|
||||
"mark_all_as_read" : "Markeer alles als gelezen",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Oppdater",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"sort_by_asc_desc" : "Sorter etter dato ny/gamal",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Berre titlar",
|
||||
"expanded_view" : "Utvida visning",
|
||||
"mark_all_as_read" : "Merk alle som lesne",
|
||||
|
||||
@@ -39,12 +39,13 @@
|
||||
"previous_entry" : "Poprzedni element",
|
||||
"next_entry" : "Następny element",
|
||||
"refresh" : "Odswież",
|
||||
"refresh_all" : "Force refresh all my feeds ",
|
||||
"refresh_all" : "Odśwież teraz wszystkie kanały ",
|
||||
"sort_by_asc_desc" : "Sortuj od najnowszego/najstarszego",
|
||||
"sort_by_abc_zyx" : "Sortuj alfabetycznie",
|
||||
"titles_only" : "Widok listy",
|
||||
"expanded_view" : "Widok rozwinięty",
|
||||
"mark_all_as_read" : "Oznacz wszystko jako przeczytane",
|
||||
"mark_all_older_12_hours" : "Items older than 12 hours ",
|
||||
"mark_all_older_12_hours" : "Elementy starsze niż 12 godzin ",
|
||||
"mark_all_older_day" : "Elementy starsze niż dzień",
|
||||
"mark_all_older_week" : "Elementy starsze niż tydzień",
|
||||
"mark_all_older_two_weeks" : "Elementy starsze niż dwa tygodnie",
|
||||
@@ -61,9 +62,9 @@
|
||||
"error_while_loading_feed" : "Wystąpił błąd podczas ładowania tego kanału.",
|
||||
"keep_unread" : "Pozostaw nieprzeczytane",
|
||||
"no_unread_items" : " nie ma nieprzeczytanych elementów.",
|
||||
"mark_up_to_here" : "Mark as read up to here ",
|
||||
"search_for" : "searching for: ",
|
||||
"no_search_results" : "No match found for the requested keywords "
|
||||
"mark_up_to_here" : "Oznacz jako przeczytane do tego elementu ",
|
||||
"search_for" : "wyszukiwanie dla: ",
|
||||
"no_search_results" : "Nie znaleziono wyników dla wyszukiwanej frazy "
|
||||
},
|
||||
"feedsearch" : {
|
||||
"hint" : "Wpisz subskrybcję...",
|
||||
@@ -80,8 +81,8 @@
|
||||
"scroll_marks" : "W widoku rozwiniętym przewijanie oznacza elementy jako przeczytane"
|
||||
},
|
||||
"appearance" : "Wygląd",
|
||||
"scroll_speed" : "Scrolling speed when navigating between entries (in milliseconds) ",
|
||||
"scroll_speed_help" : "set to 0 to disable ",
|
||||
"scroll_speed" : "Prędkość przewijania podczas nawigowania pomiędzy wpisami (w milisekundach) ",
|
||||
"scroll_speed_help" : "ustaw na 0 by wyłączyć ",
|
||||
"theme" : "Motyw",
|
||||
"submit_your_theme" : "Wyślij swój motyw",
|
||||
"custom_css" : "Własny styl CSS"
|
||||
@@ -89,21 +90,23 @@
|
||||
"details" : {
|
||||
"feed_details" : "Szczegóły kanału",
|
||||
"url" : "URL",
|
||||
"website" : "Website ",
|
||||
"website" : "Strona internetowa",
|
||||
"name" : "Nazwa",
|
||||
"category" : "Kategoria",
|
||||
"position" : "Pozycja",
|
||||
"last_refresh" : "Ostatnio odświeżony",
|
||||
"message" : "Last refresh message ",
|
||||
"message" : "Ostatnia odpowiedź odświeżenia",
|
||||
"next_refresh" : "Następne odświeżenie",
|
||||
"queued_for_refresh" : "W kolejce do odświeżenia",
|
||||
"feed_url" : "URL kanału",
|
||||
"filtering_expression" : "Wyrażenie filtrujące",
|
||||
"filtering_expression_help" : "Ustaw puste, by wyłączyć. W przeciwnym razie wyrażenie zwracające 'true' lub 'false'. Dla 'false' nowe elementy w kanale będą autmatycznie \noznaczane jako przeczytane. Dostępne zmienne to: 'title', 'content', 'url' 'author' and 'categories'. Ich zawartość jest konwertowana na małe litery \npodczas porówynywania tekstu. Przykład: url.contains('youtube') albo (author eq 'athou' and title.contains('github') \nPełna dostępna składnia jest dostępna pod <a href='http://commons.apache.org/proper/commons-jexl/reference/syntax.html' target='_blank'>tym</a> adresem.",
|
||||
"generate_api_key_first" : "Najpierw wygeneruj klucz API w swoim profilu.",
|
||||
"unsubscribe" : "Cofnij subskrypcje",
|
||||
"unsubscribe_confirmation" : "Are you sure you want to unsubscribe from this feed? ",
|
||||
"delete_category_confirmation" : "Are you sure you want to delete this category? ",
|
||||
"unsubscribe_confirmation" : "Czy na pewno chcesz cofnąć sybskrypcję tego kanału? ",
|
||||
"delete_category_confirmation" : "Czy na pewno chcesz usunąć tą kategorię? ",
|
||||
"category_details" : "Szczegóły kategorii",
|
||||
"tag_details" : "Tag details ",
|
||||
"tag_details" : "Szczegóły tagu ",
|
||||
"parent_category" : "Kategoria nadrzędna"
|
||||
},
|
||||
"profile" : {
|
||||
@@ -119,7 +122,7 @@
|
||||
"generate_new_api_key_info" : "Zmiana hasła spowoduje wygenerowanie nowego klucza API",
|
||||
"opml_export" : "Eksportuj do pliku OPML",
|
||||
"delete_account" : "Usuń konto",
|
||||
"delete_account_confirmation" : "Delete your acount? There's no turning back! "
|
||||
"delete_account_confirmation" : "Na pewno usunąć to konto? Nie można tego cofnąć! "
|
||||
},
|
||||
"about" : {
|
||||
"rest_api" : {
|
||||
@@ -143,8 +146,8 @@
|
||||
"firefox_extension" : "Dodatek do Firefoxa",
|
||||
"opera_extension" : "Dodatek do Opery",
|
||||
"subscribe_bookmarklet" : "Dodaj subskrybcje jako skryptozakładkę (kliknij)",
|
||||
"subscribe_bookmarklet_asc" : "Oldest first ",
|
||||
"subscribe_bookmarklet_desc" : "Newest first ",
|
||||
"subscribe_bookmarklet_asc" : "Najpierw najstarsze ",
|
||||
"subscribe_bookmarklet_desc" : "Najpierw najnowsze ",
|
||||
"next_unread_bookmarklet" : "Następny nieprzeczytany element jako skryptozakładka (przeciągnij na pasek zakładek)"
|
||||
},
|
||||
"translation" : {
|
||||
@@ -172,9 +175,9 @@
|
||||
"open_in_new_tab_mark_as_read" : "otwórz w nowej zakładce i oznacz jako przeczytane",
|
||||
"fullscreen" : "przełącz tryb pełnoekranowy",
|
||||
"font_size" : "zmień wielkość czcionki",
|
||||
"go_to_all" : "go to the All view ",
|
||||
"go_to_starred" : "go to the Starred view ",
|
||||
"go_to_all" : "przejdź do widoku Wszystkich elementów ",
|
||||
"go_to_starred" : "przejdź do Elementów oznaczonych gwiazdką ",
|
||||
"feed_search" : "przejdź do subskrybcji wpisując jej nazwę"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Atualizar",
|
||||
"refresh_all" : "Forçar atualização de todos os meus feeds",
|
||||
"sort_by_asc_desc" : "Ordenar por data cresc/decres",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Somente títulos",
|
||||
"expanded_view" : "Modo Expandido",
|
||||
"mark_all_as_read" : "Marcar tudo como lido",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Обновить",
|
||||
"refresh_all" : "Обновить все подписки вручную",
|
||||
"sort_by_asc_desc" : "Сначала новые/старые",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Только заголовки",
|
||||
"expanded_view" : "Развёрнутый вид",
|
||||
"mark_all_as_read" : "Отметить всё как прочитанное",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Obnoviť",
|
||||
"refresh_all" : "Vynútené obnovenie všetkých položiek",
|
||||
"sort_by_asc_desc" : "Zoradiť podľa najnovšieho/najstaršieho",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Náhľad titulkov",
|
||||
"expanded_view" : "Rozšírený náhľad",
|
||||
"mark_all_as_read" : "Označiť všetky ako prečítané",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Uppdatera",
|
||||
"refresh_all" : "Tvinga uppdatering av alla prenumerationer",
|
||||
"sort_by_asc_desc" : "Sortera efter datum stigande/fallande",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Endast titlar",
|
||||
"expanded_view" : "Expanderad vy",
|
||||
"mark_all_as_read" : "Markera alla som lästa",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "Yenile",
|
||||
"refresh_all" : "Tüm yayınları yenilemek için zorla",
|
||||
"sort_by_asc_desc" : "Tarihe göre sırala artan/azalan",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "Sadece başlıklar",
|
||||
"expanded_view" : "Genişletilmiş görünüm",
|
||||
"mark_all_as_read" : "Tümünü okundu işaretle",
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"refresh" : "刷新",
|
||||
"refresh_all" : "刷新所有订阅",
|
||||
"sort_by_asc_desc" : "按日期升序/降序排序",
|
||||
"sort_by_abc_zyx" : "Sort Alphabetically",
|
||||
"titles_only" : "仅显示标题",
|
||||
"expanded_view" : "显示内容",
|
||||
"mark_all_as_read" : "标记所有为已读",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
|
||||
|
||||
@@ -531,7 +531,11 @@ module.controller('ToolbarCtrl', [
|
||||
|
||||
$scope.toggleOrder = function() {
|
||||
var settings = $scope.settingsService.settings;
|
||||
settings.readingOrder = settings.readingOrder == 'asc' ? 'desc' : 'asc';
|
||||
settings.readingOrder = settings.readingOrder == 'desc' ? 'asc' : 'desc';
|
||||
};
|
||||
$scope.toggleAbcOrder = function() {
|
||||
var settings = $scope.settingsService.settings;
|
||||
settings.readingOrder = settings.readingOrder == 'abc' ? 'zyx' : 'abc';
|
||||
};
|
||||
|
||||
$scope.toAdmin = function() {
|
||||
|
||||
@@ -12,6 +12,7 @@ module.service('LangService', [function() {
|
||||
'gl': 'Galician',
|
||||
'glk': 'گیلکی',
|
||||
'hu': 'Magyar',
|
||||
'id': 'Indonesian',
|
||||
'ja': '日本語',
|
||||
'ko': '한국어',
|
||||
'nl': 'Nederlands',
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#loading-bar .bar {
|
||||
background: #2c3e50;
|
||||
height: 101px;
|
||||
top: -100px;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#loading-bar .peg {
|
||||
@@ -9,4 +12,4 @@
|
||||
#loading-bar-spinner .spinner-icon {
|
||||
border-top-color: #2c3e50;
|
||||
border-left-color: #2c3e50;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,26 +60,30 @@
|
||||
<div class="actions btn-group" id="toolbar-read-mode">
|
||||
<div ng-if="!MobileService.mobile || MobileService.rightMenu">
|
||||
<div class="btn-group read-mode">
|
||||
<button type="button" class="btn btn-default" ng-click="settingsService.settings.readingMode = 'unread'"
|
||||
ng-class="{'active': settingsService.settings.readingMode == 'unread'}">{{ 'toolbar.unread' | translate }}</button>
|
||||
<button type="button" class="btn btn-default" ng-click="settingsService.settings.readingMode = 'all'"
|
||||
ng-class="{'active': settingsService.settings.readingMode == 'all'}">{{ 'toolbar.all' | translate }}</button>
|
||||
<button type="button" class="btn btn-default" ng-click="settingsService.settings.readingMode = 'unread'" ng-class="{'active': settingsService.settings.readingMode == 'unread'}">{{
|
||||
'toolbar.unread' | translate }}</button>
|
||||
<button type="button" class="btn btn-default" ng-click="settingsService.settings.readingMode = 'all'" ng-class="{'active': settingsService.settings.readingMode == 'all'}">{{
|
||||
'toolbar.all' | translate }}</button>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" id="toolbar-read-order">
|
||||
<a type="button" class="btn btn-default" ng-click="toggleOrder()" title="{{ 'toolbar.sort_by_asc_desc' | translate }}">
|
||||
<i
|
||||
ng-class="{'icon-arrow-up' : settingsService.settings.readingOrder == 'asc', 'icon-arrow-down': settingsService.settings.readingOrder == 'desc'}"></i>
|
||||
<a type="button" class="btn btn-default" ng-click="toggleOrder()" title="{{ 'toolbar.sort_by_asc_desc' | translate }}"
|
||||
ng-class="{'active' : settingsService.settings.readingOrder == 'asc' || settingsService.settings.readingOrder == 'desc'}">
|
||||
<i ng-class="{'icon-arrow-up' : settingsService.settings.readingOrder == 'asc', 'icon-arrow-down': settingsService.settings.readingOrder != 'asc'}"></i>
|
||||
</a>
|
||||
<button type="button" class="btn btn-default" ng-click="toggleAbcOrder()" title="{{ 'toolbar.sort_by_abc_zyx' | translate }}"
|
||||
ng-class="{'active' : settingsService.settings.readingOrder == 'abc' || settingsService.settings.readingOrder == 'zyx'}">
|
||||
<i ng-class="{'icon-sort-by-alphabet' : settingsService.settings.readingOrder != 'zyx', 'icon-sort-by-alphabet-alt': settingsService.settings.readingOrder == 'zyx'}"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" id="toolbar-read-view-settings">
|
||||
<a type="button" class="btn btn-default" ng-click="settingsService.settings.viewMode = 'title'"
|
||||
ng-class="{'active': settingsService.settings.viewMode == 'title'}" title="{{ 'toolbar.titles_only' | translate }}">
|
||||
<a type="button" class="btn btn-default" ng-click="settingsService.settings.viewMode = 'title'" ng-class="{'active': settingsService.settings.viewMode == 'title'}"
|
||||
title="{{ 'toolbar.titles_only' | translate }}">
|
||||
<i class="icon-list"></i>
|
||||
</a>
|
||||
<a type="button" class="btn btn-default" ng-click="settingsService.settings.viewMode = 'expanded'"
|
||||
ng-class="{'active': settingsService.settings.viewMode == 'expanded'}" title="{{ 'toolbar.expanded_view' | translate }}">
|
||||
<a type="button" class="btn btn-default" ng-click="settingsService.settings.viewMode = 'expanded'" ng-class="{'active': settingsService.settings.viewMode == 'expanded'}"
|
||||
title="{{ 'toolbar.expanded_view' | translate }}">
|
||||
<i class="icon-th-list"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<span ng-switch-when="starred">{{ 'tree.starred' | translate }}</span>
|
||||
<span ng-switch-default>
|
||||
<span ng-hide="feedLink">{{name}}</span>
|
||||
<a ng-show="feedLink" href="{{feedLink}}" target="_blank">{{name}}</a>
|
||||
<a ng-show="feedLink" href="{{feedLink}}" target="_blank" rel="noreferrer">{{name}}</a>
|
||||
</span>
|
||||
</span>
|
||||
<span ng-show="name"> »</span>
|
||||
@@ -20,7 +20,7 @@
|
||||
<div ng-repeat="entry in entries" class="entry entry-font-size-{{font_size}}" id="entry_{{entry.id}}"
|
||||
ng-class="{unread: entry.read == false, current: current==entry, open: isOpen, closed: !isOpen }">
|
||||
<div class="entry-heading" ng-swipe-right="mark(entry, !entry.read)">
|
||||
<a href="{{entry.url}}" target="_blank" class="entry-heading-link" ng-click="noop($event)" ng-mouseup="entryClicked(entry, $event)">
|
||||
<a href="{{entry.url}}" target="_blank" rel="noreferrer" class="entry-heading-link" ng-click="noop($event)" ng-mouseup="entryClicked(entry, $event)">
|
||||
<span class="feed-name">
|
||||
<span class="star" ng-mouseup="star(entry, !entry.starred, $event)">
|
||||
<i ng-class="{'icon-star icon-star-yellow': entry.starred, 'icon-star-empty': !entry.starred}" class="pointer"></i>
|
||||
@@ -31,7 +31,7 @@
|
||||
<span class="entry-date">{{entry.date | entryDate}}</span>
|
||||
<span class="entry-name" ng-class="{shrink: true, rtl: entry.rtl}" ng-bind-html="entry.title | highlight:keywords | trustHtml"></span>
|
||||
</a>
|
||||
<a href="{{entry.url}}" target="_blank" class="entry-external-link" ng-click="mark(entry, true)">
|
||||
<a href="{{entry.url}}" target="_blank" rel="noreferrer" class="entry-external-link" ng-click="mark(entry, true)">
|
||||
<i class="icon-external-link"></i>
|
||||
</a>
|
||||
</div>
|
||||
@@ -39,7 +39,7 @@
|
||||
ng-mouseup="bodyClicked(entry, $event)" ng-class="{rtl: entry.rtl}">
|
||||
<div class="entry-header">
|
||||
<div class="entry-title">
|
||||
<a href="{{entry.url}}" target="_blank" ng-bind-html="entry.title | highlight:keywords | trustHtml"></a>
|
||||
<a href="{{entry.url}}" target="_blank" rel="noreferrer" ng-bind-html="entry.title | highlight:keywords | trustHtml"></a>
|
||||
<div class="entry-subtitle">
|
||||
<span class="entry-source" ng-if="selectedType == 'category'">
|
||||
<span class="entry-source-prefix">{{ 'view.entry_source' | translate }}</span>
|
||||
@@ -93,7 +93,7 @@
|
||||
title="Gmail" popup ng-if="settingsService.settings.gmail">
|
||||
<i class="icon-gmail"></i>
|
||||
</a>
|
||||
<a href="http://www.facebook.com/sharer.php?u=={{entry.url|escape}}" title="Facebook" popup ng-if="settingsService.settings.facebook">
|
||||
<a href="http://www.facebook.com/sharer.php?u={{entry.url|escape}}" title="Facebook" popup ng-if="settingsService.settings.facebook">
|
||||
<i class="icon-facebook"></i>
|
||||
</a>
|
||||
<a href="http://twitter.com/share?text={{entry.title|escape}}&url={{entry.url|escape}}" title="Twitter" popup
|
||||
|
||||
@@ -96,6 +96,12 @@ public class CommaFeedConfiguration extends Configuration {
|
||||
private String smtpPassword;
|
||||
private String smtpFromAddress;
|
||||
|
||||
private boolean graphiteEnabled;
|
||||
private String graphitePrefix;
|
||||
private String graphiteHost;
|
||||
private int graphitePort;
|
||||
private int graphiteInterval;
|
||||
|
||||
@NotNull
|
||||
@Valid
|
||||
private Boolean heavyLoad;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.commafeed;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -7,6 +9,10 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import com.codahale.metrics.graphite.Graphite;
|
||||
import com.codahale.metrics.graphite.GraphiteReporter;
|
||||
import com.codahale.metrics.MetricFilter;
|
||||
import com.commafeed.CommaFeedConfiguration.ApplicationSettings;
|
||||
import com.commafeed.CommaFeedConfiguration.CacheType;
|
||||
import com.commafeed.backend.cache.CacheService;
|
||||
import com.commafeed.backend.cache.NoopCacheService;
|
||||
@@ -54,5 +60,27 @@ public class CommaFeedModule extends AbstractModule {
|
||||
taskMultibinder.addBinding().to(OldEntriesCleanupTask.class);
|
||||
taskMultibinder.addBinding().to(OrphanedFeedsCleanupTask.class);
|
||||
taskMultibinder.addBinding().to(OrphanedContentsCleanupTask.class);
|
||||
|
||||
ApplicationSettings settings = config.getApplicationSettings();
|
||||
|
||||
if (settings.isGraphiteEnabled()) {
|
||||
final String graphitePrefix = settings.getGraphitePrefix();
|
||||
final String graphiteHost = settings.getGraphiteHost();
|
||||
final int graphitePort = settings.getGraphitePort();
|
||||
final int graphiteInterval = settings.getGraphiteInterval();
|
||||
|
||||
log.info("Graphite Metrics will be sent to host={}, port={}, prefix={}, interval={}sec", graphiteHost, graphitePort, graphitePrefix, graphiteInterval);
|
||||
|
||||
final Graphite graphite = new Graphite(new InetSocketAddress(graphiteHost, graphitePort));
|
||||
final GraphiteReporter reporter = GraphiteReporter.forRegistry(metrics)
|
||||
.prefixedWith(graphitePrefix)
|
||||
.convertRatesTo(TimeUnit.SECONDS)
|
||||
.convertDurationsTo(TimeUnit.MILLISECONDS)
|
||||
.filter(MetricFilter.ALL)
|
||||
.build(graphite);
|
||||
reporter.start(graphiteInterval, TimeUnit.SECONDS);
|
||||
} else {
|
||||
log.info("Graphite Metrics Disabled. Metrics will not be sent.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.commafeed.backend.FixedSizeSortedSet;
|
||||
import com.commafeed.backend.feed.FeedEntryKeyword;
|
||||
import com.commafeed.backend.feed.FeedEntryKeyword.Mode;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.FeedEntryContent;
|
||||
import com.commafeed.backend.model.FeedEntryStatus;
|
||||
import com.commafeed.backend.model.FeedEntryTag;
|
||||
import com.commafeed.backend.model.FeedSubscription;
|
||||
@@ -66,6 +67,19 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||
};
|
||||
|
||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = Ordering.from(STATUS_COMPARATOR_DESC).reverse();
|
||||
|
||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ABC = new Comparator<FeedEntryStatus>() {
|
||||
@Override
|
||||
public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
|
||||
CompareToBuilder builder = new CompareToBuilder();
|
||||
builder.append(o1.getEntry().getContent().getTitle(), o2.getEntry().getContent().getTitle());
|
||||
builder.append(o1.getId(), o2.getId());
|
||||
return builder.toComparison();
|
||||
}
|
||||
};
|
||||
|
||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ZYX = Ordering.from(STATUS_COMPARATOR_ABC).reverse();
|
||||
|
||||
|
||||
public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) {
|
||||
List<FeedEntryStatus> statuses = query().selectFrom(status).where(status.entry.eq(entry), status.subscription.eq(sub)).fetch();
|
||||
@@ -100,8 +114,12 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||
|
||||
if (order == ReadingOrder.asc) {
|
||||
query.orderBy(status.entryUpdated.asc(), status.id.asc());
|
||||
} else {
|
||||
} else if (order == ReadingOrder.desc){
|
||||
query.orderBy(status.entryUpdated.desc(), status.id.desc());
|
||||
} else if (order == ReadingOrder.abc) {
|
||||
query.orderBy(status.entry.content.title.asc(), status.id.desc());
|
||||
} else { //order == ReadingOrder.xyz
|
||||
query.orderBy(status.entry.content.title.desc(), status.id.desc());
|
||||
}
|
||||
|
||||
query.offset(offset).limit(limit);
|
||||
@@ -119,7 +137,7 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||
}
|
||||
|
||||
private HibernateQuery<FeedEntry> buildQuery(User user, FeedSubscription sub, boolean unreadOnly, List<FeedEntryKeyword> keywords,
|
||||
Date newerThan, int offset, int limit, ReadingOrder order, Date last, String tag) {
|
||||
Date newerThan, int offset, int limit, ReadingOrder order, FeedEntryStatus last, String tag) {
|
||||
|
||||
HibernateQuery<FeedEntry> query = query().selectFrom(entry).where(entry.feed.eq(sub.getFeed()));
|
||||
|
||||
@@ -163,17 +181,29 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||
|
||||
if (last != null) {
|
||||
if (order == ReadingOrder.desc) {
|
||||
query.where(entry.updated.gt(last));
|
||||
} else {
|
||||
query.where(entry.updated.lt(last));
|
||||
query.where(entry.updated.gt(last.getEntryUpdated()));
|
||||
} else if (order == ReadingOrder.asc) {
|
||||
query.where(entry.updated.lt(last.getEntryUpdated()));
|
||||
} else if (order == ReadingOrder.abc) {
|
||||
query.join(entry.content, content);
|
||||
query.where(content.title.lt(last.getEntry().getContent().getTitle()));
|
||||
} else { //order == ReadingOrder.zyx
|
||||
query.join(entry.content, content);
|
||||
query.where(content.title.gt(last.getEntry().getContent().getTitle()));
|
||||
}
|
||||
} else if (order != null && (order == ReadingOrder.abc || order == ReadingOrder.zyx)) {
|
||||
query.join(entry.content, content);
|
||||
}
|
||||
|
||||
|
||||
if (order != null) {
|
||||
if (order == ReadingOrder.asc) {
|
||||
query.orderBy(entry.updated.asc(), entry.id.asc());
|
||||
} else {
|
||||
} else if (order == ReadingOrder.desc) {
|
||||
query.orderBy(entry.updated.desc(), entry.id.desc());
|
||||
} else if (order == ReadingOrder.abc) {
|
||||
query.orderBy(content.title.asc(), entry.id.asc());
|
||||
} else { //order == ReadingOrder.zyx
|
||||
query.orderBy(content.title.desc(), entry.id.desc());
|
||||
}
|
||||
}
|
||||
if (offset > -1) {
|
||||
@@ -193,20 +223,36 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||
List<FeedEntryKeyword> keywords, Date newerThan, int offset, int limit, ReadingOrder order, boolean includeContent,
|
||||
boolean onlyIds, String tag) {
|
||||
int capacity = offset + limit;
|
||||
Comparator<FeedEntryStatus> comparator = order == ReadingOrder.desc ? STATUS_COMPARATOR_DESC : STATUS_COMPARATOR_ASC;
|
||||
|
||||
Comparator<FeedEntryStatus> comparator;
|
||||
if (order == ReadingOrder.desc) {
|
||||
comparator = STATUS_COMPARATOR_DESC;
|
||||
} else if (order == ReadingOrder.abc) {
|
||||
comparator = STATUS_COMPARATOR_ABC;
|
||||
} else if (order == ReadingOrder.zyx) {
|
||||
comparator = STATUS_COMPARATOR_ZYX;
|
||||
} else {
|
||||
comparator = STATUS_COMPARATOR_ASC;
|
||||
}
|
||||
|
||||
FixedSizeSortedSet<FeedEntryStatus> set = new FixedSizeSortedSet<FeedEntryStatus>(capacity, comparator);
|
||||
for (FeedSubscription sub : subs) {
|
||||
Date last = (order != null && set.isFull()) ? set.last().getEntryUpdated() : null;
|
||||
FeedEntryStatus last = (order != null && set.isFull()) ? set.last() : null;
|
||||
HibernateQuery<FeedEntry> query = buildQuery(user, sub, unreadOnly, keywords, newerThan, -1, capacity, order, last, tag);
|
||||
List<Tuple> tuples = query.select(entry.id, entry.updated, status.id).fetch();
|
||||
List<Tuple> tuples = query.select(entry.id, entry.updated, status.id, entry.content.title).fetch();
|
||||
|
||||
for (Tuple tuple : tuples) {
|
||||
Long id = tuple.get(entry.id);
|
||||
Date updated = tuple.get(entry.updated);
|
||||
Long statusId = tuple.get(status.id);
|
||||
|
||||
FeedEntryContent content = new FeedEntryContent();
|
||||
content.setTitle(tuple.get(entry.content.title));
|
||||
|
||||
FeedEntry entry = new FeedEntry();
|
||||
entry.setId(id);
|
||||
entry.setUpdated(updated);
|
||||
entry.setContent(content);
|
||||
|
||||
FeedEntryStatus status = new FeedEntryStatus();
|
||||
status.setId(statusId);
|
||||
|
||||
@@ -30,6 +30,10 @@ public abstract class GenericDAO<T extends AbstractModel> extends AbstractDAO<T>
|
||||
models.forEach(m -> persist(m));
|
||||
}
|
||||
|
||||
public void update(T model) {
|
||||
currentSession().merge(model);
|
||||
}
|
||||
|
||||
public T findById(Long id) {
|
||||
return get(id);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.hibernate.SessionFactory;
|
||||
@@ -135,9 +134,7 @@ public class FeedRefreshUpdater implements Managed {
|
||||
|
||||
if (subscriptions == null) {
|
||||
feed.setMessage("No new entries found");
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(subscriptions)) {
|
||||
} else if (!subscriptions.isEmpty()) {
|
||||
List<User> users = subscriptions.stream().map(s -> s.getUser()).collect(Collectors.toList());
|
||||
cache.invalidateUnreadCount(subscriptions.toArray(new FeedSubscription[0]));
|
||||
cache.invalidateUserRootCategory(users.toArray(new User[0]));
|
||||
|
||||
@@ -92,6 +92,7 @@ public class FeedUtils {
|
||||
whitelist.addProtocols("q", "cite", "http", "https");
|
||||
|
||||
whitelist.addEnforcedAttribute("a", "target", "_blank");
|
||||
whitelist.addEnforcedAttribute("a", "rel", "noreferrer");
|
||||
return whitelist;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ public class UserSettings extends AbstractModel {
|
||||
}
|
||||
|
||||
public enum ReadingOrder {
|
||||
asc, desc
|
||||
asc, desc, abc, zyx
|
||||
}
|
||||
|
||||
public enum ViewMode {
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
package com.commafeed.backend.service;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.internal.SessionFactoryImpl;
|
||||
|
||||
import com.commafeed.CommaFeedApplication;
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
@@ -31,7 +27,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class StartupService implements Managed {
|
||||
|
||||
@@ -50,17 +46,10 @@ public class StartupService implements Managed {
|
||||
}
|
||||
|
||||
private void updateSchema() {
|
||||
try {
|
||||
Connection connection = null;
|
||||
Session session = sessionFactory.openSession();
|
||||
session.doWork(connection -> {
|
||||
try {
|
||||
Thread currentThread = Thread.currentThread();
|
||||
ClassLoader classLoader = currentThread.getContextClassLoader();
|
||||
ResourceAccessor accessor = new ClassLoaderResourceAccessor(classLoader);
|
||||
|
||||
DataSource dataSource = getDataSource(sessionFactory);
|
||||
connection = dataSource.getConnection();
|
||||
JdbcConnection jdbcConnection = new JdbcConnection(connection);
|
||||
|
||||
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(jdbcConnection);
|
||||
|
||||
if (database instanceof PostgresDatabase) {
|
||||
@@ -73,17 +62,14 @@ public class StartupService implements Managed {
|
||||
database.setConnection(jdbcConnection);
|
||||
}
|
||||
|
||||
ResourceAccessor accessor = new ClassLoaderResourceAccessor(Thread.currentThread().getContextClassLoader());
|
||||
Liquibase liq = new Liquibase("migrations.xml", accessor, database);
|
||||
liq.update("prod");
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
session.close();
|
||||
}
|
||||
|
||||
private void initialData() {
|
||||
@@ -103,15 +89,4 @@ public class StartupService implements Managed {
|
||||
public void stop() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
private static DataSource getDataSource(SessionFactory sessionFactory) {
|
||||
if (sessionFactory instanceof SessionFactoryImpl) {
|
||||
ConnectionProvider cp = ((SessionFactoryImpl) sessionFactory).getConnectionProvider();
|
||||
if (cp instanceof DatasourceConnectionProviderImpl) {
|
||||
return ((DatasourceConnectionProviderImpl) cp).getDataSource();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public class CategoryREST {
|
||||
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
||||
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
||||
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
||||
@ApiParam(value = "date ordering", allowableValues = "asc,desc") @QueryParam("order") @DefaultValue("desc") ReadingOrder order,
|
||||
@ApiParam(value = "ordering", allowableValues = "asc,desc,abc,zyx") @QueryParam("order") @DefaultValue("desc") ReadingOrder order,
|
||||
@ApiParam(
|
||||
value = "search for keywords in either the title or the content of the entries, separated by spaces, 3 characters minimum") @QueryParam("keywords") String keywords,
|
||||
@ApiParam(value = "return only entry ids") @DefaultValue("false") @QueryParam("onlyIds") boolean onlyIds,
|
||||
|
||||
@@ -141,7 +141,7 @@ public class FeedREST {
|
||||
@ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan,
|
||||
@ApiParam(value = "offset for paging") @DefaultValue("0") @QueryParam("offset") int offset,
|
||||
@ApiParam(value = "limit for paging, default 20, maximum 1000") @DefaultValue("20") @QueryParam("limit") int limit,
|
||||
@ApiParam(value = "date ordering", allowableValues = "asc,desc") @QueryParam("order") @DefaultValue("desc") ReadingOrder order,
|
||||
@ApiParam(value = "ordering", allowableValues = "asc,desc,abc,zyx") @QueryParam("order") @DefaultValue("desc") ReadingOrder order,
|
||||
@ApiParam(
|
||||
value = "search for keywords in either the title or the content of the entries, separated by spaces, 3 characters minimum") @QueryParam("keywords") String keywords,
|
||||
@ApiParam(value = "return only entry ids") @DefaultValue("false") @QueryParam("onlyIds") boolean onlyIds) {
|
||||
|
||||
@@ -66,7 +66,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }) )
|
||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||
@Singleton
|
||||
public class UserREST {
|
||||
|
||||
@@ -217,7 +217,7 @@ public class UserREST {
|
||||
if (request.isNewApiKey()) {
|
||||
user.setApiKey(userService.generateApiKey(user));
|
||||
}
|
||||
userDAO.saveOrUpdate(user);
|
||||
userDAO.update(user);
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,18 @@ public class NextUnreadServlet extends HttpServlet {
|
||||
return;
|
||||
}
|
||||
|
||||
final ReadingOrder order = StringUtils.equals(orderParam, "asc") ? ReadingOrder.asc : ReadingOrder.desc;
|
||||
final ReadingOrder order = (StringUtils.equals(orderParam, "asc") ?
|
||||
ReadingOrder.asc :
|
||||
(
|
||||
StringUtils.equals(orderParam, "desc") ?
|
||||
ReadingOrder.desc :
|
||||
(
|
||||
StringUtils.equals(orderParam, "abc") ?
|
||||
ReadingOrder.abc :
|
||||
(ReadingOrder.zyx)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
FeedEntryStatus status = UnitOfWork.call(sessionFactory, () -> {
|
||||
FeedEntryStatus s = null;
|
||||
|
||||
Reference in New Issue
Block a user