EliteJournal 1.9.400

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/AUTHORS +1 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +22 -0
  4. data/app/controllers/account_controller.rb +25 -0
  5. data/app/controllers/application.rb +83 -0
  6. data/app/controllers/atom_controller.rb +26 -0
  7. data/app/controllers/auth_controller.rb +23 -0
  8. data/app/controllers/backend_controller.rb +14 -0
  9. data/app/controllers/css_controller.rb +31 -0
  10. data/app/controllers/draft_controller.rb +62 -0
  11. data/app/controllers/image_controller.rb +11 -0
  12. data/app/controllers/journal_controller.rb +53 -0
  13. data/app/controllers/link_controller.rb +29 -0
  14. data/app/controllers/ping_controller.rb +44 -0
  15. data/app/controllers/post_controller.rb +131 -0
  16. data/app/controllers/rss_controller.rb +22 -0
  17. data/app/controllers/tags_controller.rb +74 -0
  18. data/app/controllers/user_controller.rb +30 -0
  19. data/app/controllers/users_controller.rb +13 -0
  20. data/app/helpers/account_helper.rb +2 -0
  21. data/app/helpers/application_helper.rb +117 -0
  22. data/app/helpers/atom_helper.rb +2 -0
  23. data/app/helpers/auth_helper.rb +2 -0
  24. data/app/helpers/backend_helper.rb +2 -0
  25. data/app/helpers/css_helper.rb +2 -0
  26. data/app/helpers/draft_helper.rb +2 -0
  27. data/app/helpers/image_helper.rb +2 -0
  28. data/app/helpers/journal_helper.rb +2 -0
  29. data/app/helpers/link_helper.rb +2 -0
  30. data/app/helpers/ping_helper.rb +5 -0
  31. data/app/helpers/post_helper.rb +2 -0
  32. data/app/helpers/rss_helper.rb +5 -0
  33. data/app/helpers/tags_helper.rb +7 -0
  34. data/app/helpers/user_helper.rb +2 -0
  35. data/app/helpers/users_helper.rb +2 -0
  36. data/app/models/blogger_api.rb +24 -0
  37. data/app/models/comment.rb +18 -0
  38. data/app/models/draft.rb +12 -0
  39. data/app/models/face.rb +24 -0
  40. data/app/models/feed_killer.rb +17 -0
  41. data/app/models/image.rb +7 -0
  42. data/app/models/link.rb +10 -0
  43. data/app/models/meta_weblog_api.rb +82 -0
  44. data/app/models/ping.rb +16 -0
  45. data/app/models/post.rb +30 -0
  46. data/app/models/stylesheet.rb +7 -0
  47. data/app/models/tag.rb +16 -0
  48. data/app/models/user.rb +35 -0
  49. data/app/views/account/info.rhtml +30 -0
  50. data/app/views/atom/feed.rxml +15 -0
  51. data/app/views/auth/login.rhtml +9 -0
  52. data/app/views/css/edit.rhtml +18 -0
  53. data/app/views/css/list.rhtml +24 -0
  54. data/app/views/css/new.rhtml +6 -0
  55. data/app/views/draft/edit.rhtml +9 -0
  56. data/app/views/draft/list.rhtml +22 -0
  57. data/app/views/draft/new.rhtml +9 -0
  58. data/app/views/journal/_comment.rhtml +10 -0
  59. data/app/views/journal/_post.rhtml +40 -0
  60. data/app/views/journal/_trackback.rhtml +4 -0
  61. data/app/views/journal/error.rhtml +1 -0
  62. data/app/views/journal/index.rhtml +1 -0
  63. data/app/views/journal/view.rhtml +15 -0
  64. data/app/views/layouts/application.rhtml +90 -0
  65. data/app/views/link/list.rhtml +19 -0
  66. data/app/views/link/new.rhtml +7 -0
  67. data/app/views/ping/trackback.rxml +4 -0
  68. data/app/views/post/_reply.rhtml +10 -0
  69. data/app/views/post/destroyxml.rxml +3 -0
  70. data/app/views/post/edit.rhtml +7 -0
  71. data/app/views/post/new.rhtml +13 -0
  72. data/app/views/post/postxml.rxml +7 -0
  73. data/app/views/post/reply.rhtml +33 -0
  74. data/app/views/post/replyxml.rxml +5 -0
  75. data/app/views/post/toggle_commentingxml.rxml +9 -0
  76. data/app/views/rss/index.rxml +15 -0
  77. data/app/views/tags/addxml.rxml +4 -0
  78. data/app/views/tags/index.rhtml +3 -0
  79. data/app/views/tags/no_completions.rhtml +1 -0
  80. data/app/views/tags/search.rhtml +10 -0
  81. data/app/views/tags/search_completer.rhtml +1 -0
  82. data/app/views/user/list.rhtml +21 -0
  83. data/app/views/user/new.rhtml +12 -0
  84. data/app/views/users/index.rhtml +6 -0
  85. data/config/app.yml +15 -0
  86. data/config/database.yml +17 -0
  87. data/config/environment.rb +58 -0
  88. data/config/environments/development.rb +5 -0
  89. data/config/environments/geminstall.rb +4 -0
  90. data/config/environments/production.rb +3 -0
  91. data/config/environments/shared.rb +17 -0
  92. data/config/environments/test.rb +3 -0
  93. data/db/db-mysql.sql +95 -0
  94. data/db/db-postgresql.sql +94 -0
  95. data/db/db-sqlite.sql +94 -0
  96. data/db/default_user.sql +1 -0
  97. data/db/development_structure.sql +257 -0
  98. data/elitejournal +132 -0
  99. data/lib/image_size.rb +277 -0
  100. data/lib/trackback.rb +45 -0
  101. data/public/404.html +6 -0
  102. data/public/500.html +6 -0
  103. data/public/dispatch.cgi +10 -0
  104. data/public/dispatch.fcgi +7 -0
  105. data/public/dispatch.rb +10 -0
  106. data/public/stylesheets/ej-layout.css +126 -0
  107. data/public/stylesheets/ej-style.css +105 -0
  108. data/public/stylesheets/undohtml.css +9 -0
  109. metadata +178 -0
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ Scott Barron <scott@elitists.net>
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2004 Scott Barron
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README ADDED
@@ -0,0 +1,22 @@
1
+ == Welcome to Elite Journal
2
+
3
+ Elite Journal is an online journal (or ``weblog'') package written in Ruby[1],
4
+ using the Ruby on Rails[2] framework.
5
+
6
+ The current feature set includes:
7
+ * Threaded comments
8
+ * Post categories
9
+ * Links sidebar
10
+ * News sidebar
11
+ * Post drafts
12
+ * TrackBack pings
13
+ * RSS2.0 feed
14
+ * Textile or Markdown, via RedCloth
15
+
16
+ To get started using Elite Journal see the INSTALL file for set up instructions.
17
+
18
+ The home page for Elite Journal is http://elitejournal.rubyforge.org.
19
+
20
+ The author's journal is at http://scott.elitists.net.
21
+
22
+ Please report any bugs or suggestions on the trac at http://dev.elitists.textdriven.com .
@@ -0,0 +1,25 @@
1
+ class AccountController < ApplicationController
2
+ model :user
3
+ before_filter :auth_required
4
+
5
+ def info
6
+ @user = current_user
7
+ if @request.post?
8
+ if valid_user_face?(@params['face']['picture'])
9
+ picture = @user.face || @user.build_face
10
+ picture.picture = @params['face']['picture'].read
11
+ picture.content_type = @params['face']['picture'].content_type
12
+ picture.save
13
+ # Need to update the headers so the newly updated image is displayed in the browser
14
+ @headers['Last-Modified'] = Time.now
15
+ end
16
+ @user = User.update(@params['id'], @params['user'])
17
+ start_user_session(@user)
18
+ end
19
+ end
20
+
21
+ private
22
+ def valid_user_face?(picture)
23
+ picture.content_type.include?('image') && picture.size <= @app_config['uploads']['max_face_size']
24
+ end
25
+ end
@@ -0,0 +1,83 @@
1
+ require_dependency 'user'
2
+
3
+ class ApplicationController < ActionController::Base
4
+ before_filter :configure_app, :except => [ :search, :face ]
5
+ before_filter :collect_info, :except => [ :search, :face ]
6
+
7
+ private
8
+ def current_user
9
+ @session['user']
10
+ end
11
+ helper_method :current_user
12
+
13
+ def current_user=(user)
14
+ @session['user'] = user
15
+ end
16
+
17
+ def logged_in?
18
+ @session['Elitist']
19
+ end
20
+ helper_method :logged_in?
21
+
22
+ def owns_post?(p)
23
+ logged_in? && (current_user.id == p.user_id)
24
+ end
25
+ helper_method :owns_post?
26
+
27
+ def user_page?
28
+ user_actions = ['view', 'reply', 'info']
29
+ ((@params['controller'] == 'users') && (@params['action'] != 'index')) || (user_actions.include? @params['action'])
30
+ end
31
+ helper_method :user_page?
32
+
33
+ def start_user_session(user)
34
+ @session['Elitist'] = true
35
+ self.current_user = user
36
+ end
37
+
38
+ def end_user_session
39
+ reset_session
40
+ end
41
+
42
+ def redirect_to_main
43
+ redirect_to :controller => 'journal', :action => 'index'
44
+ end
45
+
46
+ def redirect_to_user
47
+ redirect_to :controller => 'user', :action => 'index'
48
+ end
49
+
50
+ def redirect_to_draft
51
+ redirect_to :controller => 'draft', :action => 'index'
52
+ end
53
+
54
+ def redirect_to_link
55
+ redirect_to :controller => 'link', :action => 'index'
56
+ end
57
+
58
+ def redirect_to_login
59
+ redirect_to :controller => 'auth', :action => 'login'
60
+ end
61
+
62
+ def redirect_to_my_home
63
+ redirect_to :controller => 'users', :action => current_user.username
64
+ end
65
+
66
+ def configure_app
67
+ @app_config = YAML::load(File.open(File.dirname(__FILE__) + "/../../config/app.yml"))
68
+ end
69
+
70
+ def collect_info
71
+ @most_recent = Post.find_all(nil, 'created_at DESC', 25).collect {|p| p.user}.uniq
72
+ end
73
+
74
+ def auth_required
75
+ return true if logged_in?
76
+ redirect_to_login
77
+ end
78
+
79
+ def admin_required
80
+ return true if current_user.is_admin?
81
+ redirect_to_main
82
+ end
83
+ end
@@ -0,0 +1,26 @@
1
+ require 'time'
2
+
3
+ class AtomController < ApplicationController
4
+ layout nil
5
+ caches_page :feed
6
+
7
+ def feed
8
+ @posts = Post.find_all(nil, 'updated_at DESC', @app_config['main']['num_posts'])
9
+ @title = @app_config['main']['title']
10
+ @subtitle = @app_config['main']['subtitle']
11
+ end
12
+
13
+ # +method_missing+ provides the convenient /atom/username URLs to
14
+ # access a user's feed. If a non-existent user is passed, it will
15
+ # just return an empty feed.
16
+ def method_missing(method)
17
+ user = User.find_by_username(method.to_s)
18
+ @title = user.title
19
+ @subtitle = user.subtitle
20
+ @posts = user.posts.find_all(nil, 'created_at desc', @app_config['main']['num_posts']) rescue []
21
+
22
+ render_action 'feed'
23
+ cache_page if ActionController::Base.perform_caching
24
+ end
25
+
26
+ end
@@ -0,0 +1,23 @@
1
+ class AuthController < ApplicationController
2
+ def index
3
+ login
4
+ render_action 'login'
5
+ end
6
+
7
+ def login
8
+ if @request.post?
9
+ if user = User.authenticate(@params['username'], @params['password'])
10
+ start_user_session(user)
11
+ redirect_to_main
12
+ return
13
+ end
14
+ end
15
+ end
16
+
17
+ # logout() removes the session information set in login() and then deletes the
18
+ # session. The browser is then redirected to the log in form.
19
+ def logout
20
+ end_user_session
21
+ redirect_to_main
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ require 'xmlrpc/server'
2
+
3
+ class BackendController < ApplicationController
4
+ cache_sweeper :feed_killer
5
+
6
+ def xmlrpc
7
+ @server = XMLRPC::BasicServer.new
8
+ @server.add_handler('blogger', BloggerApi.new(@request))
9
+ @server.add_handler('metaWeblog', MetaWeblogApi.new(@request))
10
+
11
+ headers['Content-Type'] = 'text/xml'
12
+ render_text(@server.process(@request.raw_post))
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ class CssController < ApplicationController
2
+ before_filter :auth_required, :except => :getstyle
3
+
4
+ def getstyle
5
+ style = User.find(@params['id']).stylesheet.data rescue nil
6
+ render_text('', 404) and return unless style
7
+ response.headers['Content-type'] = 'text/css'
8
+ render_text style
9
+ end
10
+
11
+ def index
12
+ edit
13
+ render_action 'edit'
14
+ end
15
+
16
+ def edit
17
+ @lastpost = current_user.last_post
18
+ @stylesheet = current_user.stylesheet || current_user.build_stylesheet
19
+ end
20
+
21
+ def update
22
+ @stylesheet = current_user.stylesheet || current_user.build_stylesheet
23
+ @stylesheet.data = @params['stylesheet']['data']
24
+ if @stylesheet.save
25
+ flash['notice'] = 'Stylesheet was successfully updated.'
26
+ redirect_to_my_home
27
+ else
28
+ render_action 'edit'
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,62 @@
1
+ require_dependency 'trackback'
2
+
3
+ class DraftController < ApplicationController
4
+ before_filter :auth_required
5
+
6
+ def index
7
+ list
8
+ render_action 'list'
9
+ end
10
+
11
+ def list
12
+ @drafts = current_user.drafts.find_all(nil, 'created_at ASC')
13
+ end
14
+
15
+ def new
16
+ @draft = Draft.new
17
+ if @request.post?
18
+ @draft.attributes = @params['draft']
19
+ @draft.user = current_user
20
+ if @draft.save
21
+ flash['notice'] = "Draft was successfully saved."
22
+ return
23
+ end
24
+ end
25
+ end
26
+
27
+ def edit
28
+ begin
29
+ @draft = Draft.find(@params['id'])
30
+ rescue ActiveRecord::RecordNotFound
31
+ redirect_to_draft
32
+ return
33
+ end
34
+
35
+ if @request.post?
36
+ @draft.attributes = @params['draft']
37
+ if @draft.save
38
+ flash['notice'] = "Draft was successfully saved."
39
+ redirect_to_draft
40
+ end
41
+ end
42
+ end
43
+
44
+ def post
45
+ begin
46
+ draft = Draft.find(@params['id'])
47
+ post = current_user.posts.build
48
+ post.subject = draft.subject
49
+ post.body = draft.body
50
+ post.save
51
+ send_trackback(post, draft.tb_url, @app_config) unless draft.tb_url.empty?
52
+ draft.destroy
53
+ rescue ActiveRecord::RecordNotFound
54
+ end
55
+ redirect_to_draft
56
+ end
57
+
58
+ def destroy
59
+ Draft.find(@params['id']).destroy rescue nil
60
+ redirect_to_draft
61
+ end
62
+ end
@@ -0,0 +1,11 @@
1
+ require 'base64'
2
+
3
+ class ImageController < ApplicationController
4
+ def face
5
+ face = Face.find_first(["user_id = ?", @params['id']])
6
+ render_text("", 404) and return unless face
7
+ @headers['Content-type'] = face.content_type
8
+ @headers['Last-Modified'] = face.updated_at
9
+ render_text face.picture
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ class JournalController < ApplicationController
2
+ def index
3
+ @posts = Post.find_all(nil, 'created_at desc', @app_config['main']['num_posts'])
4
+ end
5
+
6
+ # View one specific post, using the post partial, and its comments using the comment
7
+ # partial.
8
+ def view
9
+ begin
10
+ @post = Post.find(@params['id'])
11
+ @user = @post.user
12
+ @comments = @post.find_all_in_comments("comment_id=0")
13
+ rescue
14
+ redirect_to_main
15
+ end
16
+ end
17
+
18
+ # This is used for fancy URL viewing with URLs of the format /year/month/day.
19
+ def range
20
+ unless @params['year']
21
+ @error = 'Invalid date.'
22
+ render 'journal/error'
23
+ return
24
+ end
25
+ if @params['day'] and !@params['month']
26
+ @error = 'Invalid date.'
27
+ render 'journal/error'
28
+ return
29
+ end
30
+
31
+ year = @params['year']
32
+ fmonth = @params['month'] || '01'
33
+ tmonth = @params['month'] ? fmonth : '12'
34
+ fday = @params['day'] || '01'
35
+ tday = @params['day'] ? fday : '31'
36
+
37
+
38
+ if @params['day']
39
+ tday = fday
40
+ else # I don't like this at all.
41
+ if tmonth == '02'
42
+ tday = '28'
43
+ elsif ['01', '03', '05', '07', '08', '10', '12'].include? tmonth
44
+ tday = '31'
45
+ else
46
+ tday = '30'
47
+ end
48
+ end
49
+
50
+ @posts = Post.find_all(["created_at BETWEEN '%s-%s-%s 00:00:00' AND '%s-%s-%s 23:59:59'", year, fmonth, fday, year, tmonth, tday], 'created_at DESC') rescue []
51
+ render_action 'index'
52
+ end
53
+ end
@@ -0,0 +1,29 @@
1
+ class LinkController < ApplicationController
2
+ before_filter :auth_required
3
+
4
+ def index
5
+ list
6
+ render_action 'list'
7
+ end
8
+
9
+ def list
10
+ @links = current_user.links || []
11
+ end
12
+
13
+ def new
14
+ @link = current_user.links.build
15
+ if @request.post?
16
+ @link.attributes = @params['link']
17
+ if @link.save
18
+ flash['notice'] = "Link was successfully saved."
19
+ redirect_to_link
20
+ return
21
+ end
22
+ end
23
+ end
24
+
25
+ def destroy
26
+ current_user.links.find(@params['id']).destroy rescue nil
27
+ redirect_to_link
28
+ end
29
+ end
@@ -0,0 +1,44 @@
1
+ class PingController < ApplicationController
2
+ layout nil
3
+
4
+ # This implements trackback functionality for other people tracking back to
5
+ # our elite journal. This method should have a post id passed in the url and
6
+ # the following are posted:
7
+ # title
8
+ # excerpt
9
+ # url
10
+ # blog_name
11
+ # Url is the only field we'll require, and we'll use that for title if title
12
+ # isn't passed in.
13
+ #
14
+ # Errors that we'll spew back in the faces of those unelite enough to send us garbage:
15
+ # 1 - They didn't send an ID or a URL, both are required.
16
+ # 2 - They tried to trackback to a BS post number.
17
+ # 3 - For whatever damn reason, the trackback didn't save in the db. Gnomes.
18
+ def trackback
19
+ @error = '0'
20
+ @message = nil
21
+
22
+ unless @params['id'] and @params['url']
23
+ @error = '1'
24
+ @message = 'Parameters missing.'
25
+ return
26
+ end
27
+
28
+ begin
29
+ post = Post.find(@params['id'])
30
+ ping = post.build_to_pings
31
+ ping.title = @params['title'] || @params['url']
32
+ ping.excerpt = @params['excerpt'] || ''
33
+ ping.url = @params['url']
34
+ ping.blog_name = @params['blog_name'] || ''
35
+ unless ping.save
36
+ @error = '3'
37
+ @message = 'TrackBack Ping not saved.'
38
+ end
39
+ rescue ActiveRecord::RecordNotFound, ActiveRecord::StatementInvalid
40
+ @error = '2'
41
+ @message = 'Post not found.'
42
+ end
43
+ end
44
+ end