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
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