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.
- data/.gitignore +23 -0
- data/.specification +294 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +76 -0
- data/Solarsearch.gemspec +176 -0
- data/VERSION +1 -0
- data/app/controllers/article_controller.rb +30 -0
- data/app/controllers/article_statuses_controller.rb +12 -0
- data/app/controllers/infosources_controller.rb +143 -0
- data/app/controllers/search_keywords_controller.rb +99 -0
- data/app/controllers/user_sessions_controller.rb +48 -0
- data/app/controllers/users_controller.rb +62 -0
- data/app/helpers/article_helper.rb +25 -0
- data/app/helpers/article_statuses_helper.rb +2 -0
- data/app/helpers/infosources_helper.rb +2 -0
- data/app/helpers/layout_helper.rb +22 -0
- data/app/helpers/search_keywords_helper.rb +2 -0
- data/app/helpers/site_helper.rb +2 -0
- data/app/helpers/user_sessions_helper.rb +2 -0
- data/app/helpers/users_helper.rb +2 -0
- data/app/models/article.rb +74 -0
- data/app/models/article_status.rb +20 -0
- data/app/models/infosource.rb +83 -0
- data/app/models/role.rb +2 -0
- data/app/models/roles_users.rb +2 -0
- data/app/models/search_keyword.rb +14 -0
- data/app/models/user.rb +132 -0
- data/app/models/user_mailer.rb +12 -0
- data/app/models/user_session.rb +2 -0
- data/config/locales/hu.yml +111 -0
- data/config/locales/sk.yml +111 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/solarsearch.rb +9 -0
- data/lib/solarsearch/locales.rb +3 -0
- data/lib/solarsearch/routing.rb +31 -0
- data/rails/init.rb +1 -0
- data/solarsearch.gemspec +178 -0
- data/tasks/solarsearch_tasks.rake +4 -0
- data/test/blueprints.rb +34 -0
- data/test/blueprints/articles.rb +37 -0
- data/test/blueprints/infosources.rb +53 -0
- data/test/blueprints/infosources_files/pretty.html +17 -0
- data/test/blueprints/infosources_files/ugly.html +399 -0
- data/test/blueprints/search_keywords.rb +13 -0
- data/test/blueprints/users.rb +17 -0
- data/test/content_scrapper.rb +13 -0
- data/test/database.yml +7 -0
- data/test/functional/article_controller_test.rb +40 -0
- data/test/functional/email_controller_test.rb +9 -0
- data/test/functional/infosources_controller_test.rb +65 -0
- data/test/functional/restricted_logged_exceptions_controller_test.rb +38 -0
- data/test/functional/search_keywords_controller_test.rb +108 -0
- data/test/functional/user_sessions_controller_test.rb +39 -0
- data/test/functional/users_controller_test.rb +109 -0
- data/test/schema.rb +92 -0
- data/test/test_helper.rb +48 -0
- data/test/unit/article_test.rb +56 -0
- data/test/unit/helpers/article_helper_test.rb +20 -0
- data/test/unit/helpers/email_helper_test.rb +4 -0
- data/test/unit/helpers/user_sessions_helper_test.rb +4 -0
- data/test/unit/helpers/users_helper_test.rb +4 -0
- data/test/unit/infosource_test.rb +132 -0
- data/test/unit/role_test.rb +6 -0
- data/test/unit/roles_users_test.rb +6 -0
- data/test/unit/user_mailer_test.rb +24 -0
- data/test/unit/user_test.rb +103 -0
- data/uninstall.rb +1 -0
- metadata +297 -0
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.6
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class ArticleController < ApplicationController
|
2
|
+
helper :application
|
3
|
+
|
4
|
+
access_control do
|
5
|
+
allow logged_in
|
6
|
+
end
|
7
|
+
|
8
|
+
def show
|
9
|
+
#TODO for admins should be able to fix a page, ie reload its content if the scrapper was fixed
|
10
|
+
@article = Article.find(params[:id])
|
11
|
+
@article.set_user_status(current_user, ArticleStatus::STATUS_VIEWED)
|
12
|
+
end
|
13
|
+
|
14
|
+
#TODO pop-downs for search queries, as the user types, reasonable query extensions appear
|
15
|
+
#TODO Slovak stemmer, I know Snowball stemmer now
|
16
|
+
#TODO Search result highlighting
|
17
|
+
def search
|
18
|
+
page = (params[:page] || 1).to_i
|
19
|
+
if params[:q]
|
20
|
+
query = params[:q]
|
21
|
+
search = Sunspot.search(Article) do
|
22
|
+
keywords query
|
23
|
+
paginate(:page => page)
|
24
|
+
order_by(:published_at, :desc)
|
25
|
+
end
|
26
|
+
@articles = search.results
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class ArticleStatusesController < ApplicationController
|
2
|
+
|
3
|
+
access_control do
|
4
|
+
allow logged_in
|
5
|
+
end
|
6
|
+
|
7
|
+
def index
|
8
|
+
@article_statuses = ArticleStatus.paginate_by_user_id(current_user,
|
9
|
+
:page => params[:page],
|
10
|
+
:order => 'updated_at DESC')
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'content_scrapper'
|
2
|
+
|
3
|
+
class InfosourcesController < ApplicationController
|
4
|
+
|
5
|
+
include InfosourcesHelper
|
6
|
+
|
7
|
+
access_control do
|
8
|
+
allow :admin
|
9
|
+
allow logged_in, :to => [:index, :show]
|
10
|
+
end
|
11
|
+
|
12
|
+
# GET /infosources
|
13
|
+
# GET /infosources.xml
|
14
|
+
def index
|
15
|
+
@infosources = Infosource.all
|
16
|
+
|
17
|
+
=begin
|
18
|
+
page = (params[:page] || 1).to_i
|
19
|
+
#OPTIMIZE this should be optimized for mysel perhaps, I suspect too much of data is read here,
|
20
|
+
#exploit limit in sql, index the necessary columns
|
21
|
+
@articles = Article.paginate(:order => 'created_at DESC',
|
22
|
+
:page => page)
|
23
|
+
=end
|
24
|
+
respond_to do |format|
|
25
|
+
format.html # index.html.erb
|
26
|
+
format.xml { render :xml => @infosources }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# TODO Fixer for all pages with empty content, the script goes through all page with empty content
|
31
|
+
# and tries to reload it from the original source, this should be realized with a worker method and
|
32
|
+
# email should be sent when the process finished
|
33
|
+
# Only for admins!!!
|
34
|
+
|
35
|
+
#TODO possibility to reload all of the articles' content, or with specific criteria (just for a source,..)
|
36
|
+
|
37
|
+
# simple tester page for the content cutting algorithm
|
38
|
+
def tester
|
39
|
+
@webpage_content = ContentScrapper.default.scrap_content(params[:url]) if params[:url]
|
40
|
+
end
|
41
|
+
|
42
|
+
# GET /infosources/1
|
43
|
+
# GET /infosources/1.xml
|
44
|
+
def show
|
45
|
+
@infosource = Infosource.find(params[:id])
|
46
|
+
|
47
|
+
#OPTIMIZE new articles for a specific Infosource selection
|
48
|
+
#perhaps db indexing or query optimization would help
|
49
|
+
#TODO the show for infosource should have different view than the one used from the article
|
50
|
+
page = (params[:page] || 1).to_i
|
51
|
+
@articles = Article.paginate_by_infosource_id(@infosource, :order => 'created_at DESC',
|
52
|
+
:page => page)
|
53
|
+
|
54
|
+
respond_to do |format|
|
55
|
+
format.html # show.html.erb
|
56
|
+
format.xml { render :xml => @infosource }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# GET /infosource/fetch/1
|
61
|
+
# GET /infosource/fetch/1.xml
|
62
|
+
def fetch
|
63
|
+
@infosource = Infosource.find(params[:id])
|
64
|
+
|
65
|
+
respond_to do |format|
|
66
|
+
#FIXME Should not wait for finishing the job, a worker process should start and
|
67
|
+
#email sent when the process is finished
|
68
|
+
items_fetched = @infosource.fetch_source
|
69
|
+
if !items_fetched.nil? and (items_fetched > 0)
|
70
|
+
flash[:notice] = t :infosource_fetched_flash, :item_fetched => items_fetched
|
71
|
+
format.html { redirect_to :action => :show }
|
72
|
+
format.xml { render :xml => @infosource, :status => :fetched, :location => @infosource }
|
73
|
+
else
|
74
|
+
flash[:notice] = t :nothing_was_fetched_flash
|
75
|
+
format.html { render :action => "show" }
|
76
|
+
format.xml { render :xml => @infosource.errors, :status => :unprocessable_entity }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
Sunspot.commit_if_dirty
|
80
|
+
end
|
81
|
+
|
82
|
+
# GET /infosources/new
|
83
|
+
# GET /infosources/new.xml
|
84
|
+
def new
|
85
|
+
@infosource = Infosource.new
|
86
|
+
|
87
|
+
respond_to do |format|
|
88
|
+
format.html # new.html.erb
|
89
|
+
format.xml { render :xml => @infosource }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# GET /infosources/1/edit
|
94
|
+
def edit
|
95
|
+
@infosource = Infosource.find(params[:id])
|
96
|
+
end
|
97
|
+
|
98
|
+
# POST /infosources
|
99
|
+
# POST /infosources.xml
|
100
|
+
def create
|
101
|
+
@infosource = Infosource.new(params[:infosource])
|
102
|
+
|
103
|
+
respond_to do |format|
|
104
|
+
if @infosource.save
|
105
|
+
flash[:notice] = t :infosource_creation_success_flash
|
106
|
+
format.html { redirect_to(@infosource) }
|
107
|
+
format.xml { render :xml => @infosource, :status => :created, :location => @infosource }
|
108
|
+
else
|
109
|
+
format.html { render :action => "new" }
|
110
|
+
format.xml { render :xml => @infosource.errors, :status => :unprocessable_entity }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# PUT /infosources/1
|
116
|
+
# PUT /infosources/1.xml
|
117
|
+
def update
|
118
|
+
@infosource = Infosource.find(params[:id])
|
119
|
+
|
120
|
+
respond_to do |format|
|
121
|
+
if @infosource.update_attributes(params[:infosource])
|
122
|
+
flash[:notice] = t :infosource_update_success_flash
|
123
|
+
format.html { redirect_to(@infosource) }
|
124
|
+
format.xml { head :ok }
|
125
|
+
else
|
126
|
+
format.html { render :action => "edit" }
|
127
|
+
format.xml { render :xml => @infosource.errors, :status => :unprocessable_entity }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# DELETE /infosources/1
|
133
|
+
# DELETE /infosources/1.xml
|
134
|
+
def destroy
|
135
|
+
@infosource = Infosource.find(params[:id])
|
136
|
+
@infosource.destroy
|
137
|
+
|
138
|
+
respond_to do |format|
|
139
|
+
format.html { redirect_to(infosources_url) }
|
140
|
+
format.xml { head :ok }
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
class SearchKeywordsController < ApplicationController
|
2
|
+
|
3
|
+
#FIXME The user interface for adding and editing search queries is almost unusable, fix for the user
|
4
|
+
|
5
|
+
access_control do
|
6
|
+
allow logged_in
|
7
|
+
end
|
8
|
+
|
9
|
+
def index
|
10
|
+
@search_keyword = SearchKeyword.new
|
11
|
+
if current_user.has_role?(:admin)
|
12
|
+
watched_user = params[:user_id] ? User.find_by_username(params[:user_id]) : current_user
|
13
|
+
else
|
14
|
+
watched_user = current_user
|
15
|
+
flash[:notice] = t :access_denied_flash \
|
16
|
+
if params[:user_id] and (current_user.username != params[:user_id])
|
17
|
+
end
|
18
|
+
@search_keyword.user = watched_user
|
19
|
+
@search_keywords = watched_user.search_keywords
|
20
|
+
end
|
21
|
+
|
22
|
+
def newsupdate
|
23
|
+
page = (params[:page] || 1).to_i
|
24
|
+
@articles = current_user.collect_recent_articles.paginate(:page => page, :per_page => Article.per_page)
|
25
|
+
end
|
26
|
+
|
27
|
+
def postnews
|
28
|
+
flash[:notice] = current_user.post_recent_news ? \
|
29
|
+
t(:news_were_posted_flash) : t(:no_news_were_posted_flash)
|
30
|
+
redirect_to :action => 'newsupdate'
|
31
|
+
end
|
32
|
+
|
33
|
+
def show
|
34
|
+
@search_keyword = get_keyword_for_current_user(params[:id])
|
35
|
+
if @search_keyword.nil? then
|
36
|
+
flash[:notice] = t :keyword_does_not_exist_flash
|
37
|
+
redirect_to :controller => 'site', :action => 'index'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def new
|
42
|
+
@search_keyword = SearchKeyword.new
|
43
|
+
@search_keyword.user = current_user
|
44
|
+
end
|
45
|
+
|
46
|
+
def create
|
47
|
+
@search_keyword = SearchKeyword.new(params[:search_keyword])
|
48
|
+
@search_keyword.user = current_user
|
49
|
+
if @search_keyword.save
|
50
|
+
flash[:notice] = t :keyword_creation_success_flash
|
51
|
+
redirect_to @search_keyword
|
52
|
+
else
|
53
|
+
render :action => 'new'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def edit
|
58
|
+
@search_keyword = get_keyword_for_current_user(params[:id])
|
59
|
+
if @search_keyword.nil?
|
60
|
+
flash[:notice] = t :keyword_update_denied_flash
|
61
|
+
redirect_to :controller => 'site', :action => 'index'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def update
|
66
|
+
@search_keyword = get_keyword_for_current_user(params[:id])
|
67
|
+
if @search_keyword.nil? then
|
68
|
+
flash[:notice] = t :keyword_update_denied_flash
|
69
|
+
redirect_to :controller => 'site', :action => 'index'
|
70
|
+
return
|
71
|
+
end
|
72
|
+
if @search_keyword.update_attributes(params[:search_keyword])
|
73
|
+
flash[:notice] = t :keyword_update_success_flash
|
74
|
+
redirect_to @search_keyword
|
75
|
+
else
|
76
|
+
render :action => 'edit'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def destroy
|
81
|
+
@search_keyword = get_keyword_for_current_user(params[:id])
|
82
|
+
if @search_keyword.nil? then
|
83
|
+
flash[:notice] = t :access_denied_flash
|
84
|
+
redirect_to :controller => 'site', :action => 'index'
|
85
|
+
else
|
86
|
+
@search_keyword.destroy
|
87
|
+
flash[:notice] = t :keyword_destroy_success_flash
|
88
|
+
redirect_to search_keywords_url
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def get_keyword_for_current_user(keyword_id)
|
95
|
+
keyword_to_show = SearchKeyword.find(keyword_id)
|
96
|
+
keyword_to_show.user === current_user ? SearchKeyword.find(params[:id]) : nil
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class UserSessionsController < ApplicationController
|
2
|
+
|
3
|
+
access_control do
|
4
|
+
allow logged_in, :except => :new
|
5
|
+
allow anonymous, :to => [:new, :create]
|
6
|
+
end
|
7
|
+
|
8
|
+
def new
|
9
|
+
@user_session = UserSession.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
user_session_plan = params[:user_session]
|
14
|
+
if /@/ =~ user_session_plan['username']
|
15
|
+
#we have email address instead of username
|
16
|
+
user = User.find_by_email(user_session_plan['username'])
|
17
|
+
user_session_plan['username'] = user.username unless user.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
@user_session = UserSession.new(user_session_plan)
|
21
|
+
if @user_session.save
|
22
|
+
flash[:notice] = t :login_successful_flash
|
23
|
+
redirect_to_forwarding_url
|
24
|
+
else
|
25
|
+
render :action => 'new'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def destroy
|
30
|
+
@user_session = UserSession.find
|
31
|
+
@user_session.destroy
|
32
|
+
flash[:notice] = t :logout_successful_flash
|
33
|
+
redirect_to login_url
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Redirect to the previously requested URL (if present).
|
39
|
+
def redirect_to_forwarding_url
|
40
|
+
if (redirect_url = session[:protected_page])
|
41
|
+
session[:protected_page] = nil
|
42
|
+
redirect_to redirect_url
|
43
|
+
else
|
44
|
+
redirect_to root_url
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class UsersController < ApplicationController
|
2
|
+
|
3
|
+
#TODO fificium can send notification about the forgot password to the user
|
4
|
+
|
5
|
+
access_control do
|
6
|
+
allow :admin
|
7
|
+
allow logged_in, :except => [:index, :new, :create]
|
8
|
+
end
|
9
|
+
|
10
|
+
def index
|
11
|
+
@users = User.paginate :page => params[:page]
|
12
|
+
end
|
13
|
+
|
14
|
+
def show
|
15
|
+
@user = get_user_from_params(params)
|
16
|
+
end
|
17
|
+
|
18
|
+
def new
|
19
|
+
@user = User.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def create
|
23
|
+
@user = User.new(params[:user])
|
24
|
+
if @user.save
|
25
|
+
flash[:notice] = t :registration_successful_flash
|
26
|
+
redirect_to root_path
|
27
|
+
else
|
28
|
+
render :action => 'new'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def edit
|
33
|
+
@user = get_user_from_params(params)
|
34
|
+
unless @user.can_be_modified_by(current_user)
|
35
|
+
flash[:notice] = t(:access_denied_flash)
|
36
|
+
@user.nil? ? redirect_to(root_path) : redirect_to("/users/#{@user.username}/edit")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def update
|
41
|
+
# dont you params here, should know the username
|
42
|
+
@user = User.find(params['id'])
|
43
|
+
if @user.can_be_modified_by(current_user)
|
44
|
+
if @user.update_attributes(params['user'])
|
45
|
+
flash[:notice] = t(:profil_change_success_flash)
|
46
|
+
redirect_to root_path
|
47
|
+
else
|
48
|
+
render :action => 'edit'
|
49
|
+
end
|
50
|
+
else
|
51
|
+
@user = current_user
|
52
|
+
flash[:notice] = t(:access_denied_flash)
|
53
|
+
render :action => 'edit'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def get_user_from_params(params)
|
60
|
+
User.find_by_username(params[:id]) || User.find(params[:id]) || current_user
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module ArticleHelper
|
2
|
+
|
3
|
+
MORE_CHARACTERS_TOLERANCE = 100
|
4
|
+
NUMBER_OF_CHARACTERS = 1200
|
5
|
+
|
6
|
+
def shorten_text(text, number_of_characters = NUMBER_OF_CHARACTERS, more_link = nil)
|
7
|
+
if !(text.nil? || text.empty?)
|
8
|
+
if text.length <= number_of_characters
|
9
|
+
shorter_text = text
|
10
|
+
else
|
11
|
+
punction_char_after_end = \
|
12
|
+
(text[number_of_characters..number_of_characters+MORE_CHARACTERS_TOLERANCE] =~ /\.|,|;/) || 0
|
13
|
+
shorter_text = text[0..number_of_characters + punction_char_after_end]
|
14
|
+
|
15
|
+
if more_link
|
16
|
+
shorter_text += more_link
|
17
|
+
end
|
18
|
+
end
|
19
|
+
else
|
20
|
+
shorter_text = ''
|
21
|
+
end
|
22
|
+
|
23
|
+
shorter_text
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# These helper methods can be called in your template to set variables to be used in the layout
|
2
|
+
# This module should be included in all views globally,
|
3
|
+
# to do so you may need to add this line to your ApplicationController
|
4
|
+
# helper :layout
|
5
|
+
module LayoutHelper
|
6
|
+
def title(page_title, show_title = true)
|
7
|
+
@content_for_title = page_title.to_s
|
8
|
+
@show_title = show_title
|
9
|
+
end
|
10
|
+
|
11
|
+
def show_title?
|
12
|
+
@show_title
|
13
|
+
end
|
14
|
+
|
15
|
+
def stylesheet(*args)
|
16
|
+
content_for(:head) { stylesheet_link_tag(*args) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def javascript(*args)
|
20
|
+
content_for(:head) { javascript_include_tag(*args) }
|
21
|
+
end
|
22
|
+
end
|