solarsearch 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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
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,2 @@
1
+ module ArticleStatusesHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module InfosourcesHelper
2
+ 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