EliteJournal 1.9.400

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