solarsearch 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. data/.gitignore +23 -0
  2. data/.specification +294 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +17 -0
  5. data/Rakefile +76 -0
  6. data/Solarsearch.gemspec +176 -0
  7. data/VERSION +1 -0
  8. data/app/controllers/article_controller.rb +30 -0
  9. data/app/controllers/article_statuses_controller.rb +12 -0
  10. data/app/controllers/infosources_controller.rb +143 -0
  11. data/app/controllers/search_keywords_controller.rb +99 -0
  12. data/app/controllers/user_sessions_controller.rb +48 -0
  13. data/app/controllers/users_controller.rb +62 -0
  14. data/app/helpers/article_helper.rb +25 -0
  15. data/app/helpers/article_statuses_helper.rb +2 -0
  16. data/app/helpers/infosources_helper.rb +2 -0
  17. data/app/helpers/layout_helper.rb +22 -0
  18. data/app/helpers/search_keywords_helper.rb +2 -0
  19. data/app/helpers/site_helper.rb +2 -0
  20. data/app/helpers/user_sessions_helper.rb +2 -0
  21. data/app/helpers/users_helper.rb +2 -0
  22. data/app/models/article.rb +74 -0
  23. data/app/models/article_status.rb +20 -0
  24. data/app/models/infosource.rb +83 -0
  25. data/app/models/role.rb +2 -0
  26. data/app/models/roles_users.rb +2 -0
  27. data/app/models/search_keyword.rb +14 -0
  28. data/app/models/user.rb +132 -0
  29. data/app/models/user_mailer.rb +12 -0
  30. data/app/models/user_session.rb +2 -0
  31. data/config/locales/hu.yml +111 -0
  32. data/config/locales/sk.yml +111 -0
  33. data/init.rb +1 -0
  34. data/install.rb +1 -0
  35. data/lib/solarsearch.rb +9 -0
  36. data/lib/solarsearch/locales.rb +3 -0
  37. data/lib/solarsearch/routing.rb +31 -0
  38. data/rails/init.rb +1 -0
  39. data/solarsearch.gemspec +178 -0
  40. data/tasks/solarsearch_tasks.rake +4 -0
  41. data/test/blueprints.rb +34 -0
  42. data/test/blueprints/articles.rb +37 -0
  43. data/test/blueprints/infosources.rb +53 -0
  44. data/test/blueprints/infosources_files/pretty.html +17 -0
  45. data/test/blueprints/infosources_files/ugly.html +399 -0
  46. data/test/blueprints/search_keywords.rb +13 -0
  47. data/test/blueprints/users.rb +17 -0
  48. data/test/content_scrapper.rb +13 -0
  49. data/test/database.yml +7 -0
  50. data/test/functional/article_controller_test.rb +40 -0
  51. data/test/functional/email_controller_test.rb +9 -0
  52. data/test/functional/infosources_controller_test.rb +65 -0
  53. data/test/functional/restricted_logged_exceptions_controller_test.rb +38 -0
  54. data/test/functional/search_keywords_controller_test.rb +108 -0
  55. data/test/functional/user_sessions_controller_test.rb +39 -0
  56. data/test/functional/users_controller_test.rb +109 -0
  57. data/test/schema.rb +92 -0
  58. data/test/test_helper.rb +48 -0
  59. data/test/unit/article_test.rb +56 -0
  60. data/test/unit/helpers/article_helper_test.rb +20 -0
  61. data/test/unit/helpers/email_helper_test.rb +4 -0
  62. data/test/unit/helpers/user_sessions_helper_test.rb +4 -0
  63. data/test/unit/helpers/users_helper_test.rb +4 -0
  64. data/test/unit/infosource_test.rb +132 -0
  65. data/test/unit/role_test.rb +6 -0
  66. data/test/unit/roles_users_test.rb +6 -0
  67. data/test/unit/user_mailer_test.rb +24 -0
  68. data/test/unit/user_test.rb +103 -0
  69. data/uninstall.rb +1 -0
  70. metadata +297 -0
@@ -0,0 +1,2 @@
1
+ module SearchKeywordsHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module SiteHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module UserSessionsHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module UsersHelper
2
+ end
@@ -0,0 +1,74 @@
1
+
2
+ require 'sunspot'
3
+ require 'sunspot/rails'
4
+
5
+ class Article < ActiveRecord::Base
6
+
7
+ cattr_reader :per_page
8
+ @@per_page = 10
9
+
10
+ before_validation :remove_illegal_characters
11
+
12
+ belongs_to :infosource
13
+ has_many :article_statuses
14
+
15
+ has_many :was_sent_to,
16
+ :through => :article_statuses,
17
+ :source => :user,
18
+ :conditions => "status = '#{ArticleStatus::STATUS_SENT}'",
19
+ :order => :created_at
20
+
21
+ has_many :viewed_by,
22
+ :through => :article_statuses,
23
+ :source => :user,
24
+ :conditions => "status ='#{ArticleStatus::STATUS_VIEWED}'",
25
+ :order => :created_at
26
+
27
+ searchable do
28
+ string :author
29
+ text :title
30
+ text :summary
31
+ text :body
32
+ string :url
33
+ time :published_at
34
+ dynamic_boolean :status do
35
+ article_statuses.inject({}) do |user_statuses_hash, article_status|
36
+ user_status_symbol = Article.give_user_status_symbol(article_status.user, article_status.status)
37
+ user_statuses_hash.merge(user_status_symbol => true)
38
+ end
39
+ end
40
+ end
41
+
42
+ validates_format_of :url, :with => URI::regexp(%w(http https)), :allow_nil => true
43
+ validates_uniqueness_of :guid, :allow_nil => true
44
+
45
+ def self.give_user_status_symbol(user, status)
46
+ "user#{user.object_id}_status#{status}".to_sym
47
+ end
48
+
49
+ def size
50
+ title.size + summary.size + body.size + url.size
51
+ end
52
+
53
+ def set_user_status(user, status)
54
+ article_status = ArticleStatus.find_by_user_id_and_article_id_and_status(user, self, status)
55
+ if article_status.nil?
56
+ article_status = ArticleStatus.new
57
+ article_status.user = user
58
+ article_status.article = self
59
+ article_status.status = status
60
+ article_status.save!
61
+ end
62
+ self.touch
63
+ end
64
+
65
+ def remove_illegal_characters
66
+ ugly_characters = "\x00-\x1F" #"\x00-\x08\x0B\x0C\x0E-\x1F"
67
+ exchange_character = ' '
68
+ author.tr!(ugly_characters, exchange_character) unless author.nil?
69
+ title.tr!(ugly_characters, exchange_character) unless title.nil?
70
+ summary.tr!(ugly_characters, exchange_character) unless summary.nil?
71
+ body.tr!(ugly_characters, exchange_character) unless body.nil?
72
+ url.tr!(ugly_characters, '') unless url.nil?
73
+ end
74
+ end
@@ -0,0 +1,20 @@
1
+ class ArticleStatus < ActiveRecord::Base
2
+
3
+ cattr_reader :per_page
4
+ @@per_page = 50
5
+
6
+ STATUS_SENT = 1
7
+ STATUS_VIEWED = 2
8
+
9
+ WORD_FOR_STATUS = { STATUS_SENT => I18n.t(:article_status_sent_word),
10
+ STATUS_VIEWED => I18n.t(:article_status_viewed_word) }
11
+
12
+ attr_accessible :article_id, :user_id, :status
13
+ belongs_to :article
14
+ belongs_to :user
15
+ validates_presence_of :user_id, :message => I18n.t(:user_not_set_validation_error)
16
+ validates_presence_of :article_id, :message => I18n.t(:article_not_set_validation_error)
17
+ validates_presence_of :status, :message => I18n.t(:status_not_set_validation_error)
18
+ validates_uniqueness_of :status, :scope => [:user_id, :article_id],
19
+ :message => I18n.t(:status_user_article_not_unique_validation_error)
20
+ end
@@ -0,0 +1,83 @@
1
+
2
+ require 'content_scrapper'
3
+ require 'content_scrapper/feedzirra'
4
+
5
+ class Infosource < ActiveRecord::Base
6
+
7
+ include InfosourcesHelper
8
+
9
+ MIN_SOURCENAME_SIZE = 3
10
+ MAX_SOURCENAME_SIZE = 40
11
+ RANGE_SOURCENAMESIZE = (3..40)
12
+
13
+ has_many :articles, :order => "published_at DESC"
14
+
15
+ validates_uniqueness_of :sourcename
16
+ validates_length_of :sourcename, :within => RANGE_SOURCENAMESIZE
17
+ validates_format_of :sourcefeed, :with => Regexp.new(URI::regexp(%w(http https)).to_s + '|^$'),
18
+ :allow_nil => true
19
+
20
+ def fetch_source
21
+ if has_sourcefeed?
22
+ begin
23
+ #TODO simulate Feedzirra collapse in tests
24
+ feed = Feedzirra::Feed.fetch_and_parse(self.sourcefeed)
25
+ rescue Exception
26
+ Rails.logger.error("Error occured during fetching infosource #{self.sourcename} (#{self.sourcefeed}): #{$!}")
27
+ end
28
+ if feed != 0
29
+ entries_count = add_entries(feed.entries)
30
+ Rails.logger.info "Infosource #{self.sourcename}'s fetched from feed #{self.sourcefeed}, #{entries_count} entries added."
31
+ else
32
+ entries_count = nil
33
+ Rails.logger.error "Infosource #{self.sourcename} count not be fetched. An error occured."
34
+ end
35
+ else
36
+ entries_count = nil
37
+ Rails.logger.info "Infosource #{self.sourcename} has not feed set, nothing fetched."
38
+ end
39
+ entries_count
40
+ end
41
+
42
+ #TODO updating feed using the Feedzirra, the feeds should be mapped to the articles model
43
+ def self.fetch_all_sources
44
+ Rails.logger.info "Starting to fetch feeds for #{Infosource.count} infosources."
45
+ begin
46
+ total_fetches = 0
47
+ Infosource.all.each do |infosource|
48
+ total_fetches += infosource.fetch_source || 0
49
+ end
50
+ rescue Exception
51
+ #TODO test for failed fetching
52
+ Rails.logger.error("Error occured during fetching all infosources: #{$!}")
53
+ ensure
54
+ Sunspot.commit_if_dirty
55
+ Rails.logger.info "#{total_fetches} articles were fetched. Harvesting finished."
56
+ end
57
+ total_fetches
58
+ end
59
+
60
+ private
61
+
62
+ def add_entries(entries)
63
+ new_entries = 0
64
+ entries.each do |entry|
65
+ unless Article.exists?(:guid => entry.id) then
66
+ article = Article.create!(:title => entry.title,
67
+ :summary => entry.summary,
68
+ :body => entry.scrap_content,
69
+ :url => entry.url,
70
+ :published_at => entry.published,
71
+ :guid => entry.id,
72
+ :infosource => self)
73
+ new_entries += 1
74
+ end
75
+ end
76
+ new_entries
77
+ end
78
+
79
+ def has_sourcefeed?
80
+ self.sourcefeed && !self.sourcefeed.empty?
81
+ end
82
+
83
+ end
@@ -0,0 +1,2 @@
1
+ class Role < ActiveRecord::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ class RolesUsers < ActiveRecord::Base
2
+ end
@@ -0,0 +1,14 @@
1
+
2
+ class SearchKeyword < ActiveRecord::Base
3
+
4
+ belongs_to :user
5
+
6
+ attr_accessible :query
7
+
8
+ MIN_QUERY_LENGTH = 3
9
+ MAX_QUERY_LENGTH = 120
10
+ RANGE_QUERY_LENGTH = (MIN_QUERY_LENGTH..MAX_QUERY_LENGTH)
11
+
12
+ validates_length_of :query, :within => RANGE_QUERY_LENGTH
13
+ end
14
+
@@ -0,0 +1,132 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ cattr_reader :per_page
4
+ @@per_page = 20
5
+
6
+ before_validation :strip_and_and_put_to_lowercase
7
+
8
+ has_many :search_keywords
9
+ has_many :article_statuses
10
+
11
+ has_many :sent_articles,
12
+ :through => :article_statuses,
13
+ :source => :article,
14
+ :conditions => "status = '#{ArticleStatus::STATUS_SENT}'",
15
+ :order => :created_at
16
+
17
+ has_many :viewed_articles,
18
+ :through => :article_statuses,
19
+ :source => :article,
20
+ :conditions => "status ='#{ArticleStatus::STATUS_VIEWED}'",
21
+ :order => :created_at
22
+
23
+ USERNAME_MIN_LENGTH = 4
24
+ USERNAME_MAX_LENGTH = 20
25
+ PASSWORD_MIN_LENGTH = 4
26
+ PASSWORD_MAX_LENGTH = 40
27
+ EMAIL_MAX_LENGTH = 50
28
+ USERNAME_RANGE = USERNAME_MIN_LENGTH..USERNAME_MAX_LENGTH
29
+ PASSWORD_RANGE = PASSWORD_MIN_LENGTH..PASSWORD_MAX_LENGTH
30
+ MAX_NUMBER_OF_ARTICLES_PER_NEWSUPDATE = 10
31
+ MAX_SIZE_OF_A_MAIL_IN_CHARACTERS = 10000
32
+ NEWSUPDATE_RECENT_NUMBER_OF_DAYS = 120
33
+
34
+ =begin
35
+ validates_uniqueness_of :username, :email
36
+ validates_confirmation_of :password
37
+ validates_length_of :username, :within => USERNAME_RANGE
38
+ validates_length_of :password, :within => PASSWORD_RANGE
39
+ validates_length_of :email, :maximum => EMAIL_MAX_LENGTH
40
+
41
+ validates_format_of :username,
42
+ :with => /^[a-z_][a-z0-9_]*$/,
43
+ :message => I18n.t(:given_username_is_not_correct_validation_error)
44
+ validates_format_of :email,
45
+ :with => /^[A-Z0-9._%-]+@([A-Z0-9-]+\.)+[A-Z]{2,4}$/i,
46
+ :message => I18n.t(:given_email_is_not_correct_validation_error)
47
+ =end
48
+
49
+ acts_as_authentic
50
+ acts_as_authorization_subject
51
+
52
+ #FIXME: is not unittested
53
+ def post_recent_news
54
+ recent_articles = collect_recent_articles do |article|
55
+ article.size <= User::MAX_SIZE_OF_A_MAIL_IN_CHARACTERS
56
+ end
57
+ recent_articles.each do |article|
58
+ UserMailer.deliver_newsupdate(self, article)
59
+ article.set_user_status(self, ArticleStatus::STATUS_SENT)
60
+ logger.info <<-EOF
61
+ Email notification about article #{article.title} was sent to #{self.username},
62
+ address #{self.email}
63
+ EOF
64
+ end
65
+ end
66
+
67
+ def self.post_recent_news_for_every_user
68
+ logger.info 'Starting to send the recent news for every user through email.'
69
+ User.all.each do |user|
70
+ user.post_recent_news
71
+ end
72
+ logger.info 'Sending recent news for every user finished.'
73
+ end
74
+
75
+ def collect_recent_articles(&article_condition)
76
+ Sunspot.commit_if_dirty
77
+ =begin
78
+ searchquery = search_keywords.map do |search_keyword|
79
+ "(#{search_keyword.query})"
80
+ end.join(' OR ')
81
+ search = Sunspot.search(Article) do
82
+ keywords searchquery
83
+ with(:published_at).greater_than Time.now - NEWSUPDATE_RECENT_NUMBER_OF_DAYS.day
84
+ dynamic :status do
85
+ without Article.give_user_status_symbol(self, ArticleStatus::STATUS_VIEWED), true
86
+ without Article.give_user_status_symbol(self, ArticleStatus::STATUS_SENT), true
87
+ end
88
+ order_by(:published_at, :desc)
89
+ paginate(:page => 1, :per_page => MAX_NUMBER_OF_ARTICLES_PER_NEWSUPDATE)
90
+ end
91
+ search.results
92
+ =end
93
+ set_all_articles = Set.new
94
+ search_keywords.each do |search_keyword|
95
+ article_update = recent_articles_for_search_keyword(search_keyword)
96
+ set_all_articles += article_update
97
+ end
98
+ arr_all_articles = set_all_articles.to_a
99
+ arr_all_articles = arr_all_articles.find_all { |article| article_condition.call(article) } if article_condition
100
+ arr_all_articles.sort! { |article1, article2| article2.published_at <=> article1.published_at }
101
+ arr_all_articles = arr_all_articles[0, MAX_NUMBER_OF_ARTICLES_PER_NEWSUPDATE]
102
+ arr_all_articles
103
+ end
104
+
105
+ def recent_articles_for_search_keyword(search_keyword)
106
+ searchquery = search_keyword.query
107
+ search = Sunspot.search(Article) do
108
+ keywords searchquery
109
+ with(:published_at).greater_than Time.now - NEWSUPDATE_RECENT_NUMBER_OF_DAYS.day
110
+ dynamic :status do
111
+ without Article.give_user_status_symbol(self, ArticleStatus::STATUS_VIEWED), true
112
+ without Article.give_user_status_symbol(self, ArticleStatus::STATUS_SENT), true
113
+ end
114
+ order_by(:published_at, :desc)
115
+ paginate(:page => 1, :per_page => MAX_NUMBER_OF_ARTICLES_PER_NEWSUPDATE)
116
+ end
117
+ search.results
118
+ end
119
+
120
+ def can_be_modified_by(user)
121
+ !user.nil? and (user==self or user.has_role?(:admin))
122
+ end
123
+
124
+ private
125
+
126
+ def strip_and_and_put_to_lowercase
127
+ self.email.strip!
128
+ self.email.downcase!
129
+ end
130
+
131
+ end
132
+
@@ -0,0 +1,12 @@
1
+
2
+ class UserMailer < ActionMailer::Base
3
+
4
+ #TODO the from email has to me moved to a configuration file
5
+ def newsupdate(user, article)
6
+ recipients user.email
7
+ from 'fificium@gmail.com'
8
+ subject I18n.t(:usermailer_newsupdate_subject)
9
+ content_type 'text/html'
10
+ @article = article
11
+ end
12
+ end
@@ -0,0 +1,2 @@
1
+ class UserSession < Authlogic::Session::Base
2
+ end
@@ -0,0 +1,111 @@
1
+ hu:
2
+ #controllers
3
+ access_denied_flash: 'Hozzáférés elutasítva'
4
+ login_please_flash: 'Jelentkezzen be'
5
+
6
+ infosource_fetched_flash: 'Az információforrás megújítva. {{items_fetched}} cikk letöltve.'
7
+ nothing_was_fetched_flash: 'Nincs cikk letöltve.'
8
+ infosource_creation_success_flash: 'Az információforrás sikeresen kialakítva.'
9
+ infosource_update_success_flash: 'Az információforrás módosítása sikeres.'
10
+
11
+ news_were_posted_flash: 'A legújabb hírek feladva.'
12
+ no_news_were_posted_flash: 'Nincsenek új hírek.'
13
+ keyword_does_not_exist_flash: 'Nem létező kulcsszó.'
14
+ keyword_creation_success_flash: 'A kulcsszó sikeresen kialakítva.'
15
+ keyword_update_denied_flash: 'A kulcsszó módosítása elutasítva.'
16
+ keyword_update_success_flash: 'A kulcsszó sikeresen módosítva.'
17
+ keyword_destroy_success_flash: 'A kulcsszó sikeresen eltávolítva.'
18
+
19
+ login_successful_flash: 'Sikeres bejelentkezés.'
20
+ logout_successful_flash: 'Sikeres kijelentkezés.'
21
+
22
+ registration_successful_flash: 'Sikeres regisztráció.'
23
+ profil_change_success_flash: 'A profil sikeresen módosítva.'
24
+
25
+ #models
26
+ article_status_sent_word: 'Elküldve'
27
+ article_status_viewed_word: 'Megjelenítve'
28
+
29
+ given_username_is_not_correct_validation_error: 'csak kisbetűket, számjegyeket és aláhúzást tartalmazhat "_"'
30
+ given_email_is_not_correct_validation_error: 'Hibás e-mail cím'
31
+ user_not_set_validation_error: 'Nincs felhasználó.'
32
+ article_not_set_validation_error: 'Nincs cikk.'
33
+ status_not_set_validation_error: 'Nincs állapot.'
34
+ status_user_article_not_unique_validation_error: 'A cikk, állapot és felhasználó hármas esetében csak egyetlen bejegyzés lehetséges.'
35
+
36
+ #views
37
+ unknown_infosource: 'ismeretlen forrás'
38
+ did_not_find_any_results_for_query: 'Nincs találat a "{{query}}" lekérdezésre'
39
+ search_summary_articles_from: 'Cikkek {{articles_from}}-tól/-től'
40
+ search_summary_articles_to: 'cikkek {{articles_to}}-ba/-be'
41
+ search_summary_number_of_articles: 'a {{articles_total}} összesített számból.'
42
+ pagination_previous_label: 'Előző'
43
+ pagination_next_label: 'Következő'
44
+ search_articles_button_label: 'Keresd a következő cikkekben'
45
+ article_search_view_title: 'Keresés'
46
+
47
+ article_statuses_view_title: 'Események'
48
+ article_status_line: '{{article_status}} a következő napon {{status_update_date}}:'
49
+
50
+ infosources_edit_view_title: 'Az információforrás megváltozott'
51
+ infosources_sourcename_form_field_label: 'Címke'
52
+ infosources_url_form_field_label: 'URL a következő hírcsatornára'
53
+ infosources_list_view_title: 'Információforrások listája'
54
+ infosources_new_view_title: 'Új információforrás'
55
+ infosources_show_view_title: 'Jelenítsd meg az információforrás részleteit'
56
+ infosources_unknown_source_text: 'Ismeretlen forrás'
57
+
58
+ infosources_change_action_label: 'Módosítás'
59
+ infosources_destroy_action_label: 'Törlés'
60
+ infosources_view_action_label: 'Megjelenítés'
61
+ infosources_back_to_the_list_action_label: 'Vissza a listához'
62
+ infosources_new_action_label: 'Új információforrás'
63
+ infosources_create_action_label: 'Létrehozás'
64
+ infosources_fetch_action_label: 'A forrás felújítása'
65
+ infosources_test_scrapper_for_page_label: 'Az oldal tartalmának kivágása'
66
+ infosources_empty_web_page_content_text: 'Üres tartalom'
67
+
68
+ search_keywords_submit_action_label: 'Megerősítés'
69
+ search_keywords_change_view_title: 'A kulcsszó megváltozott'
70
+ search_keywords_index_view_title: 'Kulcsszavak'
71
+ search_keywords_show_view_title: 'Kulcsszó'
72
+ search_keywords_change_action_label: 'Módosítás'
73
+ search_keywords_destroy_action_label: 'Mégse'
74
+ search_keywords_back_to_the_list_action_label: 'Vissza a listához'
75
+ search_keywords_view_action_label: 'Megjelenítés'
76
+ search_keywords_new_search_keyword_text: 'Új kulcsszó:'
77
+ search_keywords_my_search_keywords: 'Az én kulcsszavaim (a keresés során használt lekérdezések listája):'
78
+ search_keywords_new_view_title: 'Új kulcsszó'
79
+ search_keywords_my_news_view_title: 'Saját üzeneteim'
80
+ search_keywords_send_to_email_action_label: 'Küldés e-mailben'
81
+ search_keywords_query_text: 'Kérdés:'
82
+
83
+ this_page_shows_news_not_older_than_xy_days_text: "Ezen az oldalon {{days}} napnál nem régebbi üzenetek jelennek meg."
84
+ for_a_keyword_only_xy_results_are_listed: 'Egy kulcsszóra legtöbb {{results}} üzenet kerül megjelenítésre.'
85
+ news_which_were_viewed_through_the_web_and_were_of_your_interest_are_not_listed: 'Azok az üzenetek, amelyekről e-mail értesítést küldtünk és amelyeket megjelenített, nem szerepelnek a listán.'
86
+
87
+ user_sessions_login_view_title: 'Bejelentkezve'
88
+ user_sessions_username_form_field_label: 'Login:'
89
+ user_sessions_password_form_field_label: 'Jelszó:'
90
+ user_sessions_login_action_label: "Bejelentkezés"
91
+
92
+ users_username_form_field_label: 'Felhasználónév'
93
+ users_email_form_field_label: 'E-mail'
94
+ users_password_from_field_label: 'Jelszó'
95
+ users_password_confirmation_label: 'Jelszó megerősítése'
96
+ users_submit_form_action_label: 'Megerősítés'
97
+ users_change_profile_view_title: 'Profil módosítása'
98
+ users_registration_view_title: 'Regisztráció'
99
+
100
+ root_page_action_label: 'Főoldal'
101
+ my_profile_action_label: 'Saját kontó'
102
+ agent_action_label: 'Ügynök'
103
+ my_news_action_label: 'Saját hírek'
104
+ users_action_label: 'Felhasználók'
105
+ inforsources_list_action_label: 'Információforrások'
106
+ errors_and_exceptions_action_label: 'Hibák és kivételek'
107
+ logout_user_action_label: 'Kijelentkezés ({{username}})'
108
+ registration_action_label: 'Regisztráció'
109
+ login_action_label: 'Bejelentkezés'
110
+
111
+ are_you_sure_confirmation: 'Biztosan ezt akarja?'