marley 0.5.0 → 0.6.0
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.
- data/README.rdoc +3 -8
- data/lib/marley.rb +27 -131
- data/lib/marley/controllers.rb +12 -7
- data/lib/marley/core_ext.rb +8 -0
- data/lib/marley/errors.rb +51 -0
- data/lib/marley/joint.rb +14 -19
- data/lib/marley/joints/forum.rb +88 -0
- data/lib/marley/joints/messages.rb +86 -0
- data/lib/marley/joints/section.rb +63 -0
- data/lib/marley/joints/tags.rb +99 -0
- data/lib/marley/joints/user.rb +120 -0
- data/lib/marley/plugin.rb +39 -0
- data/lib/marley/plugins/orm_rest_convenience.rb +92 -0
- data/lib/marley/plugins/rest_convenience.rb +28 -0
- data/lib/marley/reggae.rb +5 -2
- data/lib/marley/resources.rb +10 -0
- data/lib/marley/router.rb +61 -0
- data/lib/marley/test_helpers.rb +12 -1
- data/lib/marley/utils.rb +57 -25
- data/rdoc/example_joint.rb +33 -0
- data/rdoc/example_plugin.rb +20 -0
- data/rdoc/forum_joint.rb +50 -0
- data/rdoc/forum_joint.rdoc +19 -0
- data/rdoc/hello.rb +14 -0
- data/rdoc/hello.rdoc +14 -0
- data/rdoc/joints.rdoc +69 -0
- data/rdoc/messages_joint.rb +34 -0
- data/rdoc/messages_joint.rdoc +18 -0
- data/rdoc/messages_joint/private_messages.rdoc +59 -0
- data/rdoc/messages_joint/public_messages.rdoc +65 -0
- data/rdoc/orm_rest_convenience_plugin.rb +28 -0
- data/rdoc/orm_rest_convenience_plugin.rdoc +99 -0
- data/rdoc/plugins.rdoc +35 -0
- data/rdoc/reggae.rb +3 -0
- data/rdoc/reggae.rdoc +11 -0
- data/rdoc/reggae/generate.rdoc +13 -0
- data/rdoc/reggae/parse.rdoc +44 -0
- data/rdoc/section_joint.rb +13 -0
- data/rdoc/section_joint.rdoc +19 -0
- data/rdoc/tags_joint.rb +16 -0
- data/rdoc/tags_joint.rdoc +22 -0
- data/rdoc/tags_joint/announcements.rdoc +64 -0
- data/rdoc/tags_joint/secrets.rdoc +65 -0
- data/rdoc/user_joint.rb +62 -0
- data/rdoc/user_joint.rdoc +13 -0
- data/rdoc/user_joint/exiting_users.rdoc +120 -0
- data/rdoc/user_joint/no_auth_provided.rdoc +34 -0
- data/reggae.ebnf +1 -1
- metadata +45 -37
- data/Favicon.ico +0 -0
- data/Rakefile +0 -14
- data/TODO +0 -19
- data/examples/blog.rb +0 -26
- data/examples/empty.sqlite3 +0 -0
- data/examples/forum.css +0 -3
- data/examples/forum.js +0 -23
- data/examples/forum.rb +0 -20
- data/examples/forum.sql +0 -42
- data/examples/forum.sqlite3 +0 -0
- data/examples/forum_test.sqlite3 +0 -0
- data/examples/run.sh +0 -14
- data/lib/client/jamaica.css +0 -270
- data/lib/client/jamaica.js +0 -353
- data/lib/client/jamaica.rb +0 -38
- data/lib/client/jquery-1.6.2.js +0 -8981
- data/lib/client/jquery.form.js +0 -814
- data/lib/joints/basic_menu_system.rb +0 -41
- data/lib/joints/basic_messaging.rb +0 -88
- data/lib/joints/basic_user.rb +0 -51
- data/lib/joints/tagged_messaging.rb +0 -122
- data/lib/joints/tagging.rb +0 -56
- data/lib/sequel/plugins/rest_auth.rb +0 -53
- data/lib/sequel/plugins/rest_convenience.rb +0 -87
- data/marley-0.4.0.gem +0 -0
- data/marley.gemspec +0 -17
- data/test/empty.sqlite3 +0 -0
- data/test/menu_tests.rb +0 -9
- data/test/tagged_messaging_tests.rb +0 -289
- data/test/test.sqlite3 +0 -0
- data/test/test_include.rb +0 -16
- data/test/user_tests.rb +0 -72
@@ -1,41 +0,0 @@
|
|
1
|
-
|
2
|
-
module Marley
|
3
|
-
module Joints
|
4
|
-
class BasicMenuSystem < Joint
|
5
|
-
RestSection=Marley::Utils.rest_opts_mod('section',['name','title','description','navigation'],lambda {$request[:user].class})
|
6
|
-
def smoke
|
7
|
-
super
|
8
|
-
Sequel::Model.extend RestSection
|
9
|
-
end
|
10
|
-
module Resources
|
11
|
-
class Menu
|
12
|
-
include RestSection
|
13
|
-
def self.rest_get
|
14
|
-
new.rest_section
|
15
|
-
end
|
16
|
-
def self.requires_user?
|
17
|
-
! $request[:path].to_a.empty?
|
18
|
-
end
|
19
|
-
def initialize
|
20
|
-
@name='main'
|
21
|
-
if $request[:user].new?
|
22
|
-
u=$request[:user].to_a
|
23
|
-
u[1].merge!({:description => 'If you don\'t already have an account, please create one here:'})
|
24
|
-
@section_title="Welcome to #{$request[:opts][:app_name]}"
|
25
|
-
@section_description='Login or signup here.'
|
26
|
-
@section_navigation=[LOGIN_FORM,u]
|
27
|
-
else
|
28
|
-
@section_title = "#{$request[:opts][:app_name]} Main Menu"
|
29
|
-
@section_description="Welcome to #{$request[:opts][:app_name]}, #{$request[:user].name}"
|
30
|
-
@section_navigation=(MR.constants - [self.class.to_s.sub(/.*::/,'').to_sym]).map do |rn|
|
31
|
-
if (resource=MR.const_get(rn)).respond_to?(:rest_section) && (s=resource.rest_section) && s.title
|
32
|
-
[:link,{:title => s.title, :description =>s.description, :url => "#{resource.resource_name}/section" }]
|
33
|
-
end
|
34
|
-
end.compact
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
require 'sanitize'
|
2
|
-
|
3
|
-
module Marley
|
4
|
-
module Joints
|
5
|
-
class BasicMessaging < Joint
|
6
|
-
module Resources
|
7
|
-
class Message < Sequel::Model
|
8
|
-
plugin :single_table_inheritance, :message_type, :model_map => lambda{|v| v ? MR.const_get(v.to_s) : ''}, :key_map => lambda{|klass|klass.name.sub(/.*::/,'')}
|
9
|
-
# CHANGE NEEDED:tree is unnecessary, instead, select by thread_id, order by parent_id, inject [] for nesting. Should be much faster.
|
10
|
-
plugin :tree
|
11
|
-
many_to_one :author, :class => :'Marley::Resources::User'
|
12
|
-
@owner_col=:author_id
|
13
|
-
def rest_cols; [:id,:author_id,:message,:title,:parent_id]; end
|
14
|
-
def write_cols; new? ? rest_cols - [:id] : []; end
|
15
|
-
def required_cols; write_cols - [:parent_id]; end
|
16
|
-
def rest_schema
|
17
|
-
super << [:text,:author,RESTRICT_RO,author.to_s]
|
18
|
-
end
|
19
|
-
def authorize_rest_get(meth)
|
20
|
-
current_user_role && (meth.nil? || self.class.actions_get.include?(meth))
|
21
|
-
end
|
22
|
-
def authorize_rest_put(meth); false; end
|
23
|
-
def after_initialize
|
24
|
-
super
|
25
|
-
if new?
|
26
|
-
self.thread_id=parent ? parent.thread_id : Message.select(:max.sql_function(:thread_id).as(:tid)).all[0][:tid].to_i + 1
|
27
|
-
end
|
28
|
-
end
|
29
|
-
def before_save
|
30
|
-
self.message=Sanitize.clean(self.message,:elements => %w[blockquote em strong ul ol li p code])
|
31
|
-
end
|
32
|
-
def validate
|
33
|
-
validates_presence [:author,:message,:title]
|
34
|
-
validates_type MR::User, :author
|
35
|
-
end
|
36
|
-
def thread
|
37
|
-
children.length > 0 ? to_a << children.map{|m| m.thread} : to_a
|
38
|
-
end
|
39
|
-
end
|
40
|
-
class PrivateMessage < Message
|
41
|
-
@actions_get=['reply','reply_all']
|
42
|
-
def rest_cols; super << :recipients; end
|
43
|
-
def current_user_role
|
44
|
-
super || (recipients.match(/\b#{$request[:user][:name]}\b/) && "recipient")
|
45
|
-
end
|
46
|
-
def authorize_rest_get(meth)
|
47
|
-
super && ($request[:user]==author || self.recipients.match(/\b#{$request[:user].name}\b/))
|
48
|
-
end
|
49
|
-
def authorize_rest_post(meth)
|
50
|
-
meth.to_s > '' && (author_id==$request[:user][:id] || recipients.match(/\b#{$request[:user][:name]}\b/))
|
51
|
-
end
|
52
|
-
def self.authorize_rest_post(asdf)
|
53
|
-
true #may need to change this, for now auth is handled in validation
|
54
|
-
end
|
55
|
-
def reply
|
56
|
-
self.class.new({:parent_id => self[:id],:author_id => $request[:user][:id],:recipients => author.name, :title => "re: #{title}"})
|
57
|
-
end
|
58
|
-
def reply_all
|
59
|
-
foo=reply
|
60
|
-
foo.recipients="#{author.name},#{recipients}".gsub(/\b(#{$request[:user][:name]})\b/,'').sub(',,',',')
|
61
|
-
foo
|
62
|
-
end
|
63
|
-
def validate
|
64
|
-
super
|
65
|
-
validates_presence [:recipients]
|
66
|
-
self.recipients.split(',').each do |recipient|
|
67
|
-
if u=MR::User[:name => recipient]
|
68
|
-
errors.add(:recipients, "You may only send PM's to Admins or Mods. #{recipient} is neither of those") unless (['Admin','Moderator'].include?(MR::User[:name => recipient].user_type) || [MR::Admin,MR::Moderator].include?($request[:user].class))
|
69
|
-
else
|
70
|
-
errors.add(:recipients, "Invalid user: #{recipient}")
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
class Post < Message
|
76
|
-
@actions_get=['reply']
|
77
|
-
def current_user_role
|
78
|
-
super || 'reader'
|
79
|
-
end
|
80
|
-
def authorize_rest_post(meth);true;end
|
81
|
-
def reply
|
82
|
-
self.class.new({:parent_id => self[:id],:author_id => $request[:user][:id], :title => "re: #{title}"})
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
data/lib/joints/basic_user.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'digest/sha1'
|
2
|
-
LOGIN_FORM= [:instance,{:url => 'login',:description => 'Existing users please log in here:',:new_rec => true,:schema => [[:text,'name',RESTRICT_REQ],[:password,'password',RESTRICT_REQ]]}]
|
3
|
-
module Marley
|
4
|
-
module Joints
|
5
|
-
class BasicUser < Joint
|
6
|
-
module Resources
|
7
|
-
class User < Sequel::Model
|
8
|
-
set_dataset :users
|
9
|
-
plugin :single_table_inheritance, :user_type, :model_map => lambda{|v| MR.const_get(v.to_sym)}, :key_map => lambda{|klass|klass.name.sub(/.*::/,'')}
|
10
|
-
attr_reader :menus
|
11
|
-
attr_accessor :old_password,:password, :confirm_password
|
12
|
-
def self.requires_user?
|
13
|
-
! ($request[:verb]=='rest_post' || ($request[:verb]=='rest_get' && $request[:path][1]=='new'))
|
14
|
-
end
|
15
|
-
def self.rest_section
|
16
|
-
ReggaeSection.new( {:title => 'User Info', :name => self.to_s.sub(/.*::/,'').underscore, :navigation => []}) if $request[:user].class == self
|
17
|
-
end
|
18
|
-
def write_cols;[:name,:email,:password,:confirm_password,:old_password];end
|
19
|
-
def rest_schema
|
20
|
-
schema=super.delete_if {|c| [:pw_hash,:description,:active].include?(c[NAME_INDEX])}
|
21
|
-
schema.push([:password,:old_password,0]) unless new?
|
22
|
-
schema.push([:password,:password ,new? ? RESTRICT_REQ : 0],[:password,:confirm_password,new? ? RESTRICT_REQ : 0])
|
23
|
-
schema
|
24
|
-
end
|
25
|
-
def self.authenticate(credentials)
|
26
|
-
u=find(:name => credentials[0], :pw_hash => Digest::SHA1.hexdigest(credentials[1]))
|
27
|
-
u.respond_to?(:user_type) ? Marley::Resources.const_get(u[:user_type].to_sym)[u[:id]] : u
|
28
|
-
end
|
29
|
-
def validate
|
30
|
-
super
|
31
|
-
validates_presence [:name]
|
32
|
-
validates_unique [:name]
|
33
|
-
if self.new? || self.old_password.to_s + self.password.to_s + self.confirm_password.to_s > ''
|
34
|
-
errors[:password]=['Password must contain at least 8 characters'] if self.password.to_s.length < 8
|
35
|
-
errors[:confirm_password]=['Passwords do not match'] unless self.password==self.confirm_password
|
36
|
-
errors[:old_password]=['Old Password Incorrect'] if !self.new? && Digest::SHA1.hexdigest(self.old_password.to_s) != self.pw_hash
|
37
|
-
end
|
38
|
-
end
|
39
|
-
def before_save
|
40
|
-
if self.new? || self.old_password.to_s + self.password.to_s + self.confirm_password.to_s > ''
|
41
|
-
self.pw_hash=Digest::SHA1.hexdigest(self.password)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
def create_msg
|
45
|
-
[[:msg,{:title => 'Success!'},"Your login, '#{self.name}', has been sucessfully created. You can now log in."]]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,122 +0,0 @@
|
|
1
|
-
Sequel::Plugins::ValidationHelpers::DEFAULT_OPTIONS.merge!(:presence => {:message => 'is required'})
|
2
|
-
Sequel::Model.plugin :timestamps, :create => :date_created, :update => :date_updated
|
3
|
-
|
4
|
-
Marley.joint 'basic_user',{:resources => []}
|
5
|
-
Marley.joint 'tagging'
|
6
|
-
Marley.joint 'basic_messaging',{:resources => ['Message']}
|
7
|
-
module Marley
|
8
|
-
module Joints
|
9
|
-
class TaggedMessaging < Joint
|
10
|
-
def smoke
|
11
|
-
super
|
12
|
-
MR::Tag.tagging_for('PrivateMessage', 'User') if MR.constants.include?('PrivateMessage')
|
13
|
-
if MR.constants.include?('Post')
|
14
|
-
MR::Tag.tagging_for('Post', 'User')
|
15
|
-
MR::Tag.tagging_for('Post')
|
16
|
-
end
|
17
|
-
end
|
18
|
-
module MessagePlugin
|
19
|
-
module ClassMethods
|
20
|
-
def list(params={})
|
21
|
-
if associations.include?(:public_tags)
|
22
|
-
specified_tags=params.delete(:tags)
|
23
|
-
specified_user_tags=params.delete(:user_tags)
|
24
|
-
else
|
25
|
-
specified_user_tags=params.delete(:tags)
|
26
|
-
end
|
27
|
-
tag_ids=MR::PublicTag.filter(:tag => specified_tags.split(/\s*,\s*/)).select(:id) if specified_tags
|
28
|
-
user_tag_ids=$request[:user].user_tags_dataset.filter(:tag => specified_user_tags.split(/\s*,\s*/)).select(:id) if specified_user_tags
|
29
|
-
items=filter(params)
|
30
|
-
#would love to make the following line more generic...
|
31
|
-
items=filter("author_id=#{$request[:user][:id]} or recipients like('%#{$request[:user][:name]}%')".lit) if new.rest_cols.include?(:recipients)
|
32
|
-
items=items.join(:messages_tags,:message_id => :id).filter(:tag_id => tag_ids) if specified_tags
|
33
|
-
items=items.join(:messages_tags,:message_id => :id).filter(:tag_id => user_tag_ids) if specified_user_tags
|
34
|
-
items.group(:thread_id).order(:max.sql_function(:date_created).desc,:max.sql_function(:date_updated).desc).map{|t|self[:parent_id => nil, :thread_id => t[:thread_id]].thread} rescue []
|
35
|
-
end
|
36
|
-
end
|
37
|
-
module InstanceMethods
|
38
|
-
def rest_associations
|
39
|
-
if ! new?
|
40
|
-
[ respond_to?(:public_tags) ? :public_tags : nil, respond_to?(:user_tags) ? user_tags_dataset.current_user_dataset : nil].compact
|
41
|
-
end
|
42
|
-
end
|
43
|
-
def new_tags
|
44
|
-
[:instance,{:name => 'tags',:url => "#{url}tags", :new_rec => true, :schema => [['number','message_id',RESTRICT_HIDE,id],['text','tags',RESTRICT_REQ]]}]
|
45
|
-
end
|
46
|
-
def new_user_tags
|
47
|
-
[:instance,{:name => 'user_tags',:url => "#{url}user_tags", :new_rec => true, :schema => [['number','user_tags[message_id]',RESTRICT_HIDE,id],['text','user_tags[tags]',RESTRICT_REQ]]}]
|
48
|
-
end
|
49
|
-
def add_tags(tags,user=nil)
|
50
|
-
if respond_to?(:public_tags)
|
51
|
-
tags.to_s.split(',').each {|tag| add_public_tag(MR::PublicTag.find_or_create(:tag => tag))}
|
52
|
-
else
|
53
|
-
add_user_tags(tags,user)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
def add_user_tags(tags,user=nil) #does not conflict with add_user_tag
|
57
|
-
user||=$request[:user][:id]
|
58
|
-
if user.class==String
|
59
|
-
user.split(',').each {|u| add_user_tags(tags,MR::User[:name => u][:id])}
|
60
|
-
elsif user.class==Array
|
61
|
-
user.each {|u| add_user_tags(tags,u)}
|
62
|
-
elsif user.class==Fixnum
|
63
|
-
tags.to_s.split(',').each {|tag| add_user_tag(MR::UserTag.find_or_create(:user_id => user, :tag => tag))}
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
module Resources
|
69
|
-
class User < MJ::BasicUser::Resources::User
|
70
|
-
end
|
71
|
-
class Admin < User
|
72
|
-
def self.requires_user?;true;end
|
73
|
-
end
|
74
|
-
class Moderator < User
|
75
|
-
def self.requires_user?;true;end
|
76
|
-
end
|
77
|
-
class PrivateMessage < MJ::BasicMessaging::Resources::PrivateMessage
|
78
|
-
attr_accessor :tags
|
79
|
-
@actions_get= superclass.actions_get << 'new_tags'
|
80
|
-
@section_title='Private Messages'
|
81
|
-
@section_name='pms'
|
82
|
-
def self.section_navigation
|
83
|
-
$request[:user].user_tags.map{|t| [:link,{:url => "/private_message?private_message[tag]=#{t.tag}",:title => t.tag.humanize}]}.unshift(PrivateMessage.reggae_link('new'))
|
84
|
-
end
|
85
|
-
def rest_schema
|
86
|
-
super << [:text, :tags, 0,tags]
|
87
|
-
end
|
88
|
-
def reply
|
89
|
-
r=super
|
90
|
-
r.tags=(user_tags_dataset.current_user_dataset.map{|t|t.tag} - RESERVED_PM_TAGS).join(',')
|
91
|
-
r
|
92
|
-
end
|
93
|
-
def after_create
|
94
|
-
add_user_tags("inbox,#{tags}",recipients)
|
95
|
-
add_user_tags("sent,#{recipients.match(/\b#{author.name}\b/) ? '' : tags}",author_id)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
class Post < MJ::BasicMessaging::Resources::Post
|
99
|
-
attr_accessor :tags,:my_tags
|
100
|
-
@section_title='Public Posts'
|
101
|
-
@section_name='posts'
|
102
|
-
def self.section_navigation
|
103
|
-
MR::Tag.filter(:user_id => nil).map{|t| [:link,{:url => "/post?post[tag]=#{t.tag}",:title => t.tag.humanize}]}.unshift([:link,{:url => '/post?post[untagged]=true',:title => 'Untagged Messages'}]).unshift(Post.reggae_link('new'))
|
104
|
-
end
|
105
|
-
@actions_get=(superclass.actions_get << 'new_user_tags') << 'new_tags'
|
106
|
-
def rest_schema
|
107
|
-
(super << [:text, :tags, 0,tags] ) << [:text, :my_tags, 0,my_tags]
|
108
|
-
end
|
109
|
-
def reply
|
110
|
-
r=super
|
111
|
-
r.tags=self.tags
|
112
|
-
r
|
113
|
-
end
|
114
|
-
def after_create
|
115
|
-
add_tags(tags) if tags
|
116
|
-
add_user_tags(my_tags) if my_tags
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
data/lib/joints/tagging.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
module Marley
|
2
|
-
module Joints
|
3
|
-
class Tagging < Joint
|
4
|
-
module Resources
|
5
|
-
class Tag < Sequel::Model
|
6
|
-
def self.tagging_for(klass, user_class=nil,join_table=nil)
|
7
|
-
current_user_tags=Module.new do
|
8
|
-
def current_user_dataset
|
9
|
-
filter(:tags__user_id => $request[:user][:id])
|
10
|
-
end
|
11
|
-
end
|
12
|
-
tagged_class=Marley::Resources.const_get(klass.to_sym)
|
13
|
-
join_table||=:"#{tagged_class.table_name}_tags"
|
14
|
-
klass_key=:"#{tagged_class.table_name.to_s.singularize}_id"
|
15
|
-
tag_key=:tag_id
|
16
|
-
if user_class
|
17
|
-
UserTag.many_to_many klass.underscore.to_sym,:class => "Marley::Resources::#{klass}", :join_table => join_table,:left_key => tag_key,:right_key => klass_key,:extend => current_user_tags
|
18
|
-
tagged_class.many_to_many :user_tags, :class => 'Marley::Resources::UserTag',:join_table => join_table,:left_key => klass_key,:right_key => tag_key, :extend => [current_user_tags,Marley::RestActions]
|
19
|
-
Marley::Resources.const_get(user_class).one_to_many :user_tags, :class => 'Marley::Resources::UserTag'
|
20
|
-
UserTag.many_to_one user_class.underscore.to_sym,:class => "Marley::Resources::#{user_class}"
|
21
|
-
else
|
22
|
-
PublicTag.many_to_many klass.underscore.to_sym,:class => "Marley::Resources::#{klass}", :join_table => join_table,:left_key => tag_key,:right_key => klass_key
|
23
|
-
tagged_class.many_to_many :public_tags,:class => "Marley::Resources::PublicTag",:join_table => join_table,:left_key => klass_key,:right_key => tag_key, :extend => Marley::RestActions
|
24
|
-
end
|
25
|
-
end
|
26
|
-
def validate
|
27
|
-
validates_presence :tag
|
28
|
-
validates_unique [:tag,:user_id]
|
29
|
-
end
|
30
|
-
def before_save
|
31
|
-
super
|
32
|
-
self.tag.downcase!
|
33
|
-
self.tag.strip!
|
34
|
-
end
|
35
|
-
def after_save
|
36
|
-
super
|
37
|
-
assoc=methods.grep(/_id=$/) - ['user_id=']
|
38
|
-
assoc.each do |a|
|
39
|
-
if c=self.send(a.sub(/=$/,''))
|
40
|
-
send "add_#{a.sub(/_id=/,'')}", Marley::Resources.const_get(a.sub(/_id=/,'').camelize.to_sym)[c]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
class PublicTag < Tag
|
46
|
-
set_dataset DB[:tags].filter(:user_id => nil)
|
47
|
-
@actions_delete='remove_parent'
|
48
|
-
end
|
49
|
-
class UserTag < Tag
|
50
|
-
set_dataset DB[:tags].filter(~{:user_id => nil})
|
51
|
-
@actions_delete='remove_parent'
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
|
2
|
-
module Sequel::Plugins::RestAuthorization
|
3
|
-
module ClassMethods
|
4
|
-
attr_accessor :owner_col, :allowed_get_methods
|
5
|
-
def inherited(c)
|
6
|
-
super
|
7
|
-
c.owner_col=@owner_col
|
8
|
-
c.allowed_get_methods=@allowed_get_methods
|
9
|
-
end
|
10
|
-
def requires_user?(verb=nil,meth=nil);true;end
|
11
|
-
def authorize(meth)
|
12
|
-
if respond_to?(auth_type="authorize_#{$request[:verb]}")
|
13
|
-
send(auth_type,meth)
|
14
|
-
else
|
15
|
-
case $request[:verb]
|
16
|
-
when 'rest_put','rest_delete'
|
17
|
-
false
|
18
|
-
when 'rest_post'
|
19
|
-
new($request[:post_params][resource_name.to_sym]||{}).current_user_role=='owner' && meth.nil?
|
20
|
-
when 'rest_get'
|
21
|
-
methods=@allowed_get_methods || ['section','list','new']
|
22
|
-
(methods.class==Hash ? methods[$request[:user].class] : methods).include?(meth)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
module InstanceMethods
|
28
|
-
def after_initialize
|
29
|
-
super
|
30
|
-
send("#{self.class.owner_col}=",$request[:user][:id]) if $request && self.class.owner_col && new?
|
31
|
-
end
|
32
|
-
def requires_user?(verb=nil,meth=nil);true;end
|
33
|
-
def authorize(meth)
|
34
|
-
if respond_to?(auth_type="authorize_#{$request[:verb]}")
|
35
|
-
send(auth_type,meth)
|
36
|
-
else
|
37
|
-
current_user_role=='owner'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
def current_user_role
|
41
|
-
"owner" if owners.include?($request[:user])
|
42
|
-
end
|
43
|
-
def owners
|
44
|
-
if self.class.to_s.match(/User$/)||self.class.superclass.to_s.match(/User$/)
|
45
|
-
[self]
|
46
|
-
elsif @owner_col
|
47
|
-
[User[send(@owner_col)]]
|
48
|
-
else
|
49
|
-
self.class.association_reflections.select {|k,v| v[:type]==:many_to_one}.map {|a| self.send(a[0]) && self.send(a[0]).owners}.flatten.compact
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
|
2
|
-
module Sequel
|
3
|
-
module Plugins::RestConvenience
|
4
|
-
module ClassMethods
|
5
|
-
include Marley::RestActions
|
6
|
-
def controller
|
7
|
-
Marley::ModelController.new(self)
|
8
|
-
end
|
9
|
-
def resource_name
|
10
|
-
self.name.sub(/.*::/,'').underscore
|
11
|
-
end
|
12
|
-
def reggae_link(action=nil)
|
13
|
-
[:link,{:url => "/#{self.resource_name}/#{action}",:title => "#{action.humanize} #{self.resource_name.humanize}".strip}]
|
14
|
-
end
|
15
|
-
def list(params=nil)
|
16
|
-
user=$request[:user]
|
17
|
-
if user.respond_to?(otm=self.resource_name.pluralize)
|
18
|
-
if user.method(otm).arity==0
|
19
|
-
if (relationship=user.send(otm)).respond_to?(:filter)
|
20
|
-
relationship.filter($request[:get_params][resource_name.to_sym] || {}).all
|
21
|
-
else
|
22
|
-
user.send(otm)
|
23
|
-
end
|
24
|
-
else
|
25
|
-
user.send(otm,$request[:get_params][resource_name.to_sym])
|
26
|
-
end
|
27
|
-
else
|
28
|
-
raise Marley::AuthorizationError
|
29
|
-
end
|
30
|
-
end
|
31
|
-
def autocomplete(input_content)
|
32
|
-
filter(:name.like("#{input_content.strip}%")).map {|rec| [rec.id, rec.name]}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
module InstanceMethods
|
36
|
-
include Marley::RestActions
|
37
|
-
def edit; self; end
|
38
|
-
def rest_cols
|
39
|
-
columns.reject do |c|
|
40
|
-
if new?
|
41
|
-
c.to_s.match(/(^id$)|(_type$)|(date_(created|updated))/)
|
42
|
-
else
|
43
|
-
c.to_s.match(/_type$/)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
def hidden_cols
|
48
|
-
columns.select {|c| c.to_s.match(/(_id$)/)}
|
49
|
-
end
|
50
|
-
def write_cols
|
51
|
-
rest_cols.reject {|c| c.to_s.match(/(^id$)|(date_(created|updated))/)}
|
52
|
-
end
|
53
|
-
def required_cols;[];end
|
54
|
-
def rest_schema
|
55
|
-
rest_cols.map do |col_name|
|
56
|
-
db_spec=db_schema.to_hash[col_name]
|
57
|
-
col_type=db_spec ? db_spec[:db_type].downcase : col_name
|
58
|
-
restrictions=0
|
59
|
-
restrictions|=RESTRICT_HIDE if hidden_cols.include?(col_name)
|
60
|
-
restrictions|=RESTRICT_RO unless write_cols.include?(col_name)
|
61
|
-
restrictions|=RESTRICT_REQ if required_cols.include?(col_name) || (db_spec && !db_spec[:allow_null])
|
62
|
-
[col_type, col_name, restrictions,send(col_name)]
|
63
|
-
end
|
64
|
-
end
|
65
|
-
def to_s
|
66
|
-
respond_to?('name') ? name : id.to_s
|
67
|
-
end
|
68
|
-
def to_a
|
69
|
-
a=Marley::ReggaeInstance.new( {:name => self.class.resource_name,:url => url ,:new_rec => self.new?,:schema => rest_schema,:actions => self.class.rest_actions})
|
70
|
-
a.contents=self.class.associations.map do |assoc|
|
71
|
-
assoc=send("#{assoc}_dataset")
|
72
|
-
(assoc.respond_to?(:current_user_dataset) ? assoc.current_user_dataset : assoc).map{|instance| instance.to_a} if assoc.respond_to?(:rest_actions)
|
73
|
-
end.compact unless new?
|
74
|
-
a
|
75
|
-
end
|
76
|
-
def to_json(*args)
|
77
|
-
to_a.to_json
|
78
|
-
end
|
79
|
-
def url(action=nil)
|
80
|
-
"/#{self.class.resource_name}/#{self[:id]}/#{action}".sub('//','/')
|
81
|
-
end
|
82
|
-
def reggae_link(action=nil)
|
83
|
-
[:link,{:url => url,:title => "#{action.humanize}"}]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|