my_wiki_generator 0.0.1

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 (103) hide show
  1. data/my_wiki/grep.txt +238 -0
  2. data/my_wiki/my_wiki_generator.rb +248 -0
  3. data/my_wiki/templates/POST_GENERATION_REMINDER +1 -0
  4. data/my_wiki/templates/app/controllers/application.rb +75 -0
  5. data/my_wiki/templates/app/controllers/content_history_controller.rb +49 -0
  6. data/my_wiki/templates/app/controllers/login_controller.rb +93 -0
  7. data/my_wiki/templates/app/controllers/my_wiki_admin_controller.rb +26 -0
  8. data/my_wiki/templates/app/controllers/my_wiki_controller.rb +250 -0
  9. data/my_wiki/templates/app/controllers/page_admin_controller.rb +51 -0
  10. data/my_wiki/templates/app/controllers/user_admin_controller.rb +34 -0
  11. data/my_wiki/templates/app/helpers/application_helper.rb +3 -0
  12. data/my_wiki/templates/app/helpers/content_history_helper.rb +2 -0
  13. data/my_wiki/templates/app/helpers/login_helper.rb +2 -0
  14. data/my_wiki/templates/app/helpers/my_wiki_admin_helper.rb +2 -0
  15. data/my_wiki/templates/app/helpers/my_wiki_helper.rb +94 -0
  16. data/my_wiki/templates/app/helpers/page_admin_helper.rb +2 -0
  17. data/my_wiki/templates/app/helpers/user_admin_helper.rb +2 -0
  18. data/my_wiki/templates/app/models/attachment.rb +55 -0
  19. data/my_wiki/templates/app/models/content.rb +32 -0
  20. data/my_wiki/templates/app/models/content_history.rb +49 -0
  21. data/my_wiki/templates/app/models/content_sweeper.rb +7 -0
  22. data/my_wiki/templates/app/models/my_wiki_mailer.rb +29 -0
  23. data/my_wiki/templates/app/models/role.rb +18 -0
  24. data/my_wiki/templates/app/models/setting.rb +7 -0
  25. data/my_wiki/templates/app/models/user.rb +60 -0
  26. data/my_wiki/templates/app/views/content_history/_form.rhtml +19 -0
  27. data/my_wiki/templates/app/views/content_history/edit.rhtml +9 -0
  28. data/my_wiki/templates/app/views/content_history/list.rhtml +27 -0
  29. data/my_wiki/templates/app/views/content_history/new.rhtml +8 -0
  30. data/my_wiki/templates/app/views/content_history/show.rhtml +21 -0
  31. data/my_wiki/templates/app/views/layouts/my_wiki.rhtml +105 -0
  32. data/my_wiki/templates/app/views/login/edit.rhtml +25 -0
  33. data/my_wiki/templates/app/views/login/login.rhtml +23 -0
  34. data/my_wiki/templates/app/views/login/logout.rhtml +10 -0
  35. data/my_wiki/templates/app/views/login/signup.rhtml +23 -0
  36. data/my_wiki/templates/app/views/login/welcome.rhtml +13 -0
  37. data/my_wiki/templates/app/views/my_wiki/_form.rhtml +11 -0
  38. data/my_wiki/templates/app/views/my_wiki/css.rhtml +224 -0
  39. data/my_wiki/templates/app/views/my_wiki/diff.rhtml +4 -0
  40. data/my_wiki/templates/app/views/my_wiki/edit.rhtml +34 -0
  41. data/my_wiki/templates/app/views/my_wiki/fileinfo.rhtml +22 -0
  42. data/my_wiki/templates/app/views/my_wiki/list.rhtml +1 -0
  43. data/my_wiki/templates/app/views/my_wiki/mails.rhtml +1 -0
  44. data/my_wiki/templates/app/views/my_wiki/new.rhtml +6 -0
  45. data/my_wiki/templates/app/views/my_wiki/recent.rhtml +3 -0
  46. data/my_wiki/templates/app/views/my_wiki/search.rhtml +5 -0
  47. data/my_wiki/templates/app/views/my_wiki/search_result.rhtml +10 -0
  48. data/my_wiki/templates/app/views/my_wiki/show.rhtml +31 -0
  49. data/my_wiki/templates/app/views/my_wiki_admin/index.rhtml +5 -0
  50. data/my_wiki/templates/app/views/my_wiki_admin/setting.rhtml +64 -0
  51. data/my_wiki/templates/app/views/my_wiki_mailer/inform.rhtml +3 -0
  52. data/my_wiki/templates/app/views/page_admin/_form.rhtml +22 -0
  53. data/my_wiki/templates/app/views/page_admin/edit.rhtml +9 -0
  54. data/my_wiki/templates/app/views/page_admin/list.rhtml +55 -0
  55. data/my_wiki/templates/app/views/page_admin/new.rhtml +8 -0
  56. data/my_wiki/templates/app/views/page_admin/show.rhtml +8 -0
  57. data/my_wiki/templates/app/views/user_admin/_form.rhtml +10 -0
  58. data/my_wiki/templates/app/views/user_admin/change_password.rhtml +9 -0
  59. data/my_wiki/templates/app/views/user_admin/list.rhtml +25 -0
  60. data/my_wiki/templates/app/views/user_admin/signup.rhtml +20 -0
  61. data/my_wiki/templates/components/admin/menu/menu.rhtml +5 -0
  62. data/my_wiki/templates/components/admin/menu_controller.rb +3 -0
  63. data/my_wiki/templates/components/list/list/list.rhtml +11 -0
  64. data/my_wiki/templates/components/list/list_controller.rb +11 -0
  65. data/my_wiki/templates/components/sidebar/sidebar/show.rhtml +7 -0
  66. data/my_wiki/templates/components/sidebar/sidebar_controller.rb +9 -0
  67. data/my_wiki/templates/config/routes.rb +35 -0
  68. data/my_wiki/templates/db/migrate/001_my_wiki_migration.rb +75 -0
  69. data/my_wiki/templates/lib/diff/lcs.rb +1105 -0
  70. data/my_wiki/templates/lib/diff/lcs/array.rb +21 -0
  71. data/my_wiki/templates/lib/diff/lcs/block.rb +51 -0
  72. data/my_wiki/templates/lib/diff/lcs/callbacks.rb +322 -0
  73. data/my_wiki/templates/lib/diff/lcs/change.rb +169 -0
  74. data/my_wiki/templates/lib/diff/lcs/hunk.rb +257 -0
  75. data/my_wiki/templates/lib/diff/lcs/ldiff.rb +226 -0
  76. data/my_wiki/templates/lib/diff/lcs/string.rb +19 -0
  77. data/my_wiki/templates/lib/login_system.rb +87 -0
  78. data/my_wiki/templates/lib/markup/simple_markup.rb +489 -0
  79. data/my_wiki/templates/lib/markup/simple_markup/fragments.rb +329 -0
  80. data/my_wiki/templates/lib/markup/simple_markup/inline.rb +338 -0
  81. data/my_wiki/templates/lib/markup/simple_markup/lines.rb +151 -0
  82. data/my_wiki/templates/lib/markup/simple_markup/preprocess.rb +68 -0
  83. data/my_wiki/templates/lib/markup/simple_markup/to_flow.rb +188 -0
  84. data/my_wiki/templates/lib/markup/simple_markup/to_html.rb +302 -0
  85. data/my_wiki/templates/lib/markup/simple_markup/to_latex.rb +333 -0
  86. data/my_wiki/templates/lib/my_wiki_plugin.rb +60 -0
  87. data/my_wiki/templates/lib/my_wiki_plugins/christel.rb +5 -0
  88. data/my_wiki/templates/lib/my_wiki_plugins/join.rb +3 -0
  89. data/my_wiki/templates/lib/my_wiki_plugins/link_to_attach.rb +17 -0
  90. data/my_wiki/templates/lib/my_wiki_plugins/recent.rb +8 -0
  91. data/my_wiki/templates/public/javascripts/my_wiki.js +8 -0
  92. data/my_wiki/templates/public/stylesheets/my_wiki/back.jpg +0 -0
  93. data/my_wiki/templates/public/stylesheets/my_wiki/back1.jpg +0 -0
  94. data/my_wiki/templates/public/stylesheets/my_wiki/back2.jpg +0 -0
  95. data/my_wiki/templates/public/stylesheets/my_wiki/foot.jpg +0 -0
  96. data/my_wiki/templates/public/stylesheets/my_wiki/h1.gif +0 -0
  97. data/my_wiki/templates/public/stylesheets/my_wiki/h1.jpg +0 -0
  98. data/my_wiki/templates/public/stylesheets/my_wiki/menu.jpg +0 -0
  99. data/my_wiki/templates/public/stylesheets/my_wiki/menu2.jpg +0 -0
  100. data/my_wiki/templates/public/stylesheets/my_wiki/menu_c.jpg +0 -0
  101. data/my_wiki/templates/public/stylesheets/my_wiki/my_wiki.css +336 -0
  102. data/my_wiki/templates/public/stylesheets/my_wiki/title.jpg +0 -0
  103. metadata +181 -0
@@ -0,0 +1,51 @@
1
+ class PageAdminController < ApplicationController
2
+ layout "<%= file_name %>"
3
+ before_filter :must_be_admin
4
+
5
+ def index
6
+ list
7
+ render :action => 'list'
8
+ end
9
+
10
+ def list
11
+ @title = "Page list"
12
+ @content_pages, @contents = paginate :contents, :per_page => 10
13
+ end
14
+
15
+ def show
16
+ @content = Content.find(params[:id])
17
+ end
18
+
19
+ def new
20
+ @content = Content.new
21
+ end
22
+
23
+ def create
24
+ @content = Content.new(params[:content])
25
+ if @content.save
26
+ flash[:notice] = 'Content was successfully created.'
27
+ redirect_to :action => 'list'
28
+ else
29
+ render :action => 'new'
30
+ end
31
+ end
32
+
33
+ def edit
34
+ @content = Content.find(params[:id])
35
+ end
36
+
37
+ def update
38
+ @content = Content.find(params[:id])
39
+ if @content.update_attributes(params[:content])
40
+ flash[:notice] = 'Content was successfully updated.'
41
+ redirect_to :action => 'show', :id => @content
42
+ else
43
+ render :action => 'edit'
44
+ end
45
+ end
46
+
47
+ def destroy
48
+ Content.find(params[:id]).destroy
49
+ redirect_to :action => 'list'
50
+ end
51
+ end
@@ -0,0 +1,34 @@
1
+ class UserAdminController < ApplicationController
2
+ layout "<%= file_name %>"
3
+ before_filter :must_be_admin
4
+
5
+ def index
6
+ list
7
+ render :action => 'list'
8
+ end
9
+
10
+ def list
11
+ @title = "User List"
12
+ @user_pages, @users = paginate :users, :per_page => 10
13
+ end
14
+
15
+ def edit
16
+ @user = User.find(params[:id])
17
+ @title = "Edit: #{@user.login}"
18
+ end
19
+
20
+ def update
21
+ @user = User.find(params[:id])
22
+ if @user.update_attributes(params[:user])
23
+ flash[:notice] = 'User was successfully updated.'
24
+ redirect_to :action => 'list'
25
+ else
26
+ render :action => 'edit'
27
+ end
28
+ end
29
+
30
+ def destroy
31
+ User.find(params[:id]).destroy
32
+ redirect_to :action => 'list'
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ # Methods added to this helper will be available to all templates in the application.
2
+ module ApplicationHelper
3
+ end
@@ -0,0 +1,2 @@
1
+ module ContentHistoryHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module LoginHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module <%= class_name %>AdminHelper
2
+ end
@@ -0,0 +1,94 @@
1
+ module <%= class_name %>Helper
2
+ require 'markup/simple_markup'
3
+ require 'markup/simple_markup/inline'
4
+ require 'markup/simple_markup/to_html'
5
+
6
+ class RDocTemplate
7
+ def initialize(view=nil)
8
+ @view = view
9
+ end
10
+ def render(template, assigns)
11
+ SM::SimpleMarkup.new.convert template, SM::ToHtml.new
12
+ end
13
+ end
14
+
15
+ class WikiHtml < SM::ToHtml
16
+ attr_accessor :view
17
+
18
+ def handle_special_WIKIWORD(special)
19
+ @view.link_to special.text, {:controller=>"<%= file_name %>", :action=>"show", :title=>special.text}
20
+ end
21
+
22
+ def handle_special_HTTP(special)
23
+ if special.text =~ /.*\.(jpg|jpeg|png|gif)/i
24
+ "<img alt=\"#{special.text}\" src=\"#{special.text}\" />"
25
+ else
26
+ "<a href=\"#{special.text}\">#{special.text}</a>"
27
+ end
28
+ end
29
+
30
+ def handle_special_BRACKET(special)
31
+ bracketted = special.text[2..-3]
32
+ case bracketted
33
+ when /(.+?)\|(https?:.+\.(jpg|jpeg|png|gif))/i
34
+ "<img alt=\"#{$1}\" src=\"#{$2}\" />"
35
+ when /(.+?)\|(https?:.+)/
36
+ "<a href=\"#{$2}\">#{$1}</a>"
37
+ when /(.+?)\|(.+)/
38
+ @view.link_to $1, {:controller=>"<%= file_name %>", :action=>"show", :title=>$2}
39
+ #when /https?:.*\.(jpg|jpeg|png|gif)/
40
+ # "<img alt=\"#{bracketted}\" src=\"#{bracketted}\" />"
41
+ when /https?:.*/
42
+ "<a href=\"#{bracketted}\">#{bracketted}</a>"
43
+ when /(.+?):(.+)/
44
+ @view.link_to bracketted, {:controller=>"<%= file_name %>", :action=>"handle_interwiki", :server=>$1, :keyword=>$2}
45
+ else
46
+ @view.link_to bracketted, {:controller=>"<%= file_name %>", :action=>"show", :title=>bracketted}
47
+ end
48
+ end
49
+
50
+ def handle_special_PLUGIN(special)
51
+ plugin = special.text[2..-3].strip
52
+ plugin_name = plugin.sub(/(\(.*\)| .*)/, '').strip
53
+ plugin_args = plugin.sub(plugin_name, '').strip
54
+ if <%= class_name %>Plugin.plugin_method? plugin_name
55
+ if <%= class_name %>Plugin.valid_arguments? plugin_args
56
+ plugin_result = eval("<%= class_name %>Plugin.#{plugin}")
57
+ else
58
+ "{{invalid arguments: #{plugin}}}"
59
+ end
60
+ else
61
+ "{{no such plugin: #{plugin_name}}}"
62
+ end
63
+ rescue
64
+ "{{error occuered in #{plugin}: #{$!.to_s}}"
65
+ end
66
+ end
67
+
68
+ class NilView
69
+ def link_to(key, options)
70
+ "<a href=\"dummy/url/#{key}\">#{key}</a>"
71
+ end
72
+ end
73
+
74
+ class <%= class_name %>Template
75
+ def initialize(view=NilView.new)
76
+ @view = view
77
+ end
78
+
79
+ def comment_out(template)
80
+ template.gsub(%r|^//.*$|, '')
81
+ end
82
+
83
+ def render(template, assigns={:view=>NilView.new})
84
+ markup = SM::SimpleMarkup.new
85
+ markup.add_special(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD)
86
+ markup.add_special(/(https?:\/\/(\w+\.)*\w+\/?\S*)/, :HTTP)
87
+ markup.add_special(/(\[\[(.+?)\]\])/, :BRACKET)
88
+ markup.add_special(/(\{\{(.+?)\}\})/, :PLUGIN)
89
+ generator = WikiHtml.new
90
+ generator.view = assigns[:view]
91
+ markup.convert comment_out(template), generator
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,2 @@
1
+ module PageAdminHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module UserAdminHelper
2
+ end
@@ -0,0 +1,55 @@
1
+ MAX_BYTE = 1000000
2
+
3
+ class Attachment #< ActiveRecord::Base
4
+ attr_accessor :error_message
5
+
6
+ def self.new_with_params(params)
7
+ attached = params[:attached]
8
+ self.new attached[:id], attached[:file].original_filename, attached[:file]
9
+ end
10
+
11
+ def initialize(content_id, filename='', file=nil)
12
+ @dirname = "#{RAILS_ROOT}/public/attached/#{content_id.to_s}"
13
+ @filename = filename
14
+ @file = file
15
+ end
16
+
17
+ def save
18
+ Dir.mkdir(@dirname) unless File.exist? @dirname
19
+ File.open("#{@dirname}/#{@filename}", "wb") do |f|
20
+ f.write(@file.read)
21
+ end
22
+ end
23
+
24
+ def pathname
25
+ Pathname.new(File.join(@dirname, @filename))
26
+ end
27
+ alias :info :pathname
28
+
29
+ def destroy
30
+ pathname.delete
31
+ end
32
+
33
+ def self.destroy_all(content_id)
34
+ pathname = (self.new content_id).pathname
35
+ pathname.rmtree if pathname.exist?
36
+ end
37
+
38
+ def self.list(content_id)
39
+ pathname = (self.new content_id).pathname
40
+ if pathname.exist?
41
+ pathname.children
42
+ else
43
+ []
44
+ end
45
+ end
46
+
47
+ def validate
48
+ errors = []
49
+ errors << "Upload is canceled. '#{@filename}' has already exist." if pathname.exist?
50
+ errors << "Upload is canceled. '#{@filename}' is too big. It should be less than #{MAX_BYTE} byte." if MAX_BYTE < @file.size
51
+ errors << "Upload is canceled. The filetype of '#{@filename}' is not allowed." if pathname.extname =~ /(exe|html|htm|js)/i
52
+ @error_message = errors.join "<br/>\n"
53
+ errors.empty?
54
+ end
55
+ end
@@ -0,0 +1,32 @@
1
+ require 'attachment'
2
+
3
+ class Content < ActiveRecord::Base
4
+ validates_presence_of :title, :body
5
+ validates_uniqueness_of :title
6
+ belongs_to :user, :foreign_key => :updated_by
7
+
8
+ def self.find_by_id_or_title(params)
9
+ if params.has_key? :id then
10
+ find params[:id]
11
+ elsif params.has_key? :title then
12
+ find_by_title params[:title]
13
+ elsif params.has_key? :content and params[:content].has_key? :title then
14
+ find_by_title params[:content][:title]
15
+ else
16
+ nil
17
+ #raise "Couldn't find Content without an ID and an Title"
18
+ end
19
+ end
20
+
21
+ def self.title2id(title)
22
+ find_by_title(title).id
23
+ end
24
+
25
+ def self.id2title(id)
26
+ find_by_title(id).title
27
+ end
28
+
29
+ def attachments
30
+ Attachment.list id
31
+ end
32
+ end
@@ -0,0 +1,49 @@
1
+ class ContentHistory < ActiveRecord::Base
2
+ def self.find_by_id_or_title(params)
3
+ if params.has_key? :content_id then
4
+ ContentHistory.find_by_content_id_and_version params[:content_id], params[:version]
5
+ elsif params.has_key? :title then
6
+ ContentHistory.find :first, :conditions=>["title = ? and version = ? and deleted_at is null",
7
+ params[:title],
8
+ params[:version]]
9
+ else
10
+ nil
11
+ #raise "Couldn't find Content without an ID and an Title"
12
+ end
13
+ end
14
+
15
+ def self.create_for(content)
16
+ history = ContentHistory.new
17
+ history.content_id = content.id
18
+ history.content_updated_at = content.updated_at
19
+ history.title = content.title
20
+ history.body = content.body
21
+ history.updated_by = content.updated_by
22
+ #history.version = ContentHistory.next_version content.id
23
+ history.version = content.version
24
+ history.save
25
+ history
26
+ end
27
+
28
+ def self.next_version(content_id)
29
+ history = ContentHistory.find_by_sql(
30
+ ["select (max(version) + 1) as next_version " +
31
+ "from content_histories " +
32
+ "where content_id = :content_id",
33
+ {:content_id => content_id}])
34
+ history[0].next_version.nil? ? 1 : history[0].next_version
35
+ end
36
+
37
+ def self.max_version(content_id)
38
+ history = ContentHistory.find_by_sql(
39
+ ["select max(version) as max_version " +
40
+ "from content_histories " +
41
+ "where content_id = :content_id",
42
+ {:content_id => content_id}])
43
+ history[0].max_version.nil? ? FIRST_VERSION - 1 : history[0].max_version.to_i
44
+ end
45
+
46
+ def self.mark_as_deleted(content_id)
47
+ self.update_all ["deleted_at = ?", Time.now], ["content_id = ?", content_id]
48
+ end
49
+ end
@@ -0,0 +1,7 @@
1
+ class ContentSweeper < ActionController::Caching::Sweeper
2
+ observe Content
3
+ def after_update(content)
4
+ expire_action :action => "show", :id => content
5
+ expire_action :action => "show", :title => content.title
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ require 'nkf'
2
+
3
+ class <%= class_name %>Mailer < ActionMailer::Base
4
+ @@default_charset = 'iso-2022-jp'
5
+ @@encode_subject = false
6
+
7
+ def base64(text, charset="iso-2022-jp", convert=true)
8
+ if convert
9
+ if charset == "iso-2022-jp"
10
+ text = NKF.nkf('-j -m0', text)
11
+ end
12
+ end
13
+ text = [text].pack('m').delete("\r\n")
14
+ "=?#{charset}?B?#{text}?="
15
+ end
16
+
17
+ def create! (*)
18
+ super
19
+ @mail.body = NKF::nkf('-j', @mail.body)
20
+ return @mail
21
+ end
22
+
23
+ def inform(action, content)
24
+ @subject = '<%= class_name %> Information'
25
+ @body = {:action=>action, :title=>content.title}
26
+ @recipients = 'andyjpn@gmail.com'
27
+ @from = 'admin@mywiki.dummy.com'
28
+ end
29
+ end
@@ -0,0 +1,18 @@
1
+ class Role < ActiveRecord::Base
2
+
3
+ def normal?
4
+ id == 1
5
+ end
6
+
7
+ def not_normal?
8
+ !normal?
9
+ end
10
+
11
+ def super?
12
+ id == 2
13
+ end
14
+
15
+ def admin?
16
+ id == 3
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ class Setting < ActiveRecord::Base
2
+ def self.find_active_or_default
3
+ setting = find_by_active true
4
+ setting = find_by_label "default" if setting.nil?
5
+ setting
6
+ end
7
+ end
@@ -0,0 +1,60 @@
1
+ require 'digest/sha1'
2
+
3
+ # this model expects a certain database layout and its based on the name/login pattern.
4
+ class User < ActiveRecord::Base
5
+ belongs_to :role
6
+
7
+ # Please change the salt to something else,
8
+ # Every application should use a different one
9
+ @@salt = 'change-me'
10
+ cattr_accessor :salt
11
+
12
+ # Authenticate a user.
13
+ #
14
+ # Example:
15
+ # @user = User.authenticate('bob', 'bobpass')
16
+ #
17
+ def self.authenticate(login, pass)
18
+ find_first(["login = ? AND password = ?", login, sha1(pass)])
19
+ end
20
+
21
+
22
+ protected
23
+
24
+ # Apply SHA1 encryption to the supplied password.
25
+ # We will additionally surround the password with a salt
26
+ # for additional security.
27
+ def self.sha1(pass)
28
+ Digest::SHA1.hexdigest("#{salt}--#{pass}--")
29
+ end
30
+
31
+ before_create :crypt_password
32
+
33
+ # Before saving the record to database we will crypt the password
34
+ # using SHA1.
35
+ # We never store the actual password in the DB.
36
+ def crypt_password
37
+ write_attribute "password", self.class.sha1(password)
38
+ end
39
+
40
+ before_update :crypt_unless_empty
41
+
42
+ # If the record is updated we will check if the password is empty.
43
+ # If its empty we assume that the user didn't want to change his
44
+ # password and just reset it to the old value.
45
+ def crypt_unless_empty
46
+ if password.empty?
47
+ user = self.class.find(self.id)
48
+ self.password = user.password
49
+ else
50
+ write_attribute "password", self.class.sha1(password)
51
+ end
52
+ end
53
+
54
+ validates_uniqueness_of :login, :on => :create
55
+
56
+ validates_confirmation_of :password
57
+ validates_length_of :login, :within => 3..40
58
+ validates_length_of :password, :within => 5..40
59
+ validates_presence_of :login, :password, :password_confirmation
60
+ end