diff --git a/app/models/profile.rb b/app/models/profile.rb
index e1b029e7c..c3d196843 100644
--- a/app/models/profile.rb
+++ b/app/models/profile.rb
@@ -5,8 +5,14 @@
class Profile < ActiveRecord::Base
require File.join(Rails.root, 'lib/diaspora/webhooks')
include Diaspora::Webhooks
+ include Diaspora::Taggable
include ROXML
+ attr_accessor :tag_string
+
+ acts_as_taggable_on :tags
+ extract_tags_from :tag_string
+
xml_attr :diaspora_handle
xml_attr :first_name
xml_attr :last_name
diff --git a/app/models/status_message.rb b/app/models/status_message.rb
index f44a345f4..445819847 100644
--- a/app/models/status_message.rb
+++ b/app/models/status_message.rb
@@ -4,11 +4,14 @@
class StatusMessage < Post
include Diaspora::Socketable
+ include Diaspora::Taggable
+
include YoutubeTitles
require File.join(Rails.root, 'lib/youtube_titles')
include ActionView::Helpers::TextHelper
acts_as_taggable_on :tags
+ extract_tags_from :raw_message
validates_length_of :text, :maximum => 1000, :text => "please make your status messages less than 1000 characters"
xml_name :status_message
@@ -45,15 +48,6 @@ class StatusMessage < Post
self.format_tags(mentioned_message, opts)
end
- def format_tags(text, opts={})
- return text if opts[:plain_text]
- regex = /(^|\s)#(\w+)/
- form_message = text.gsub(regex) do |matched_string|
- "#{$~[1]}##{ERB::Util.h($~[2])}"
- end
- form_message
- end
-
def format_mentions(text, opts = {})
people = self.mentioned_people
regex = /@\{([^;]+); ([^\}]+)\}/
@@ -102,22 +96,6 @@ class StatusMessage < Post
identifiers.empty? ? [] : Person.where(:diaspora_handle => identifiers)
end
- def build_tags
- self.tag_list = tag_strings
- end
-
- def tag_strings
- regex = /(?:^|\s)#(\w+)/
- matches = self.raw_message.scan(regex).map do |match|
- match.last
- end
- unique_matches = matches.inject(Hash.new) do |h,element|
- h[element.downcase] = element unless h[element.downcase]
- h
- end
- unique_matches.values
- end
-
def to_activity
<<-XML
diff --git a/app/views/profiles/_edit.html.haml b/app/views/profiles/_edit.html.haml
index 33ebf82f5..c7d9f1f39 100644
--- a/app/views/profiles/_edit.html.haml
+++ b/app/views/profiles/_edit.html.haml
@@ -29,6 +29,10 @@
= select_date profile.birthday, :prompt => true,
:default => true, :order => t('date.order'), :start_year => 2000, :end_year => 1930, :prefix => 'profile[date]'
+ %h4
+ = t('profiles.edit.your_tags')
+ = text_field_tag 'profile[tags]', profile.tags, :placeholder => t('.your_tags_placeholder')
+
%h4
= t('profiles.edit.your_bio')
= text_area_tag 'profile[bio]', profile.bio, :rows => 5, :placeholder => t('fill_me_out')
diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml
index cda1016c5..2cd0cbd22 100644
--- a/config/locales/diaspora/en.yml
+++ b/config/locales/diaspora/en.yml
@@ -409,6 +409,8 @@ en:
last_name: "Last name"
your_gender: "Your gender"
your_birthday: "Your birthday"
+ your_tags: "You: in 5 tags"
+ your_tags_placeholder: "i.e. #ironing #knitting #kittens #knees #doors"
your_bio: "Your bio"
your_photo: "Your photo"
update_profile: "Update Profile"
diff --git a/lib/diaspora/taggable.rb b/lib/diaspora/taggable.rb
new file mode 100644
index 000000000..cf5c955d2
--- /dev/null
+++ b/lib/diaspora/taggable.rb
@@ -0,0 +1,50 @@
+# Copyright (c) 2010, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+module Diaspora
+ module Taggable
+ def self.included(model)
+ model.class_eval do
+
+ cattr_reader :field_with_tags
+
+ def self.extract_tags_from sym
+ puts "extract_tags_from"
+ pp self
+ @field_with_tags = sym
+ end
+ def self.field_with_tags_setter
+ @field_with_tags_setter = "#{@field_with_tags}=".to_sym
+ end
+ end
+ end
+
+ def build_tags
+ self.tag_list = tag_strings
+ end
+
+ def tag_strings
+ regex = /(?:^|\s)#(\w+)/
+ puts "tag strings"
+ pp self
+ matches = self.send(self.class.field_with_tags).scan(regex).map do |match|
+ match.last
+ end
+ unique_matches = matches.inject(Hash.new) do |h,element|
+ h[element.downcase] = element unless h[element.downcase]
+ h
+ end
+ unique_matches.values
+ end
+
+ def format_tags(text, opts={})
+ return text if opts[:plain_text]
+ regex = /(^|\s)#(\w+)/
+ form_message = text.gsub(regex) do |matched_string|
+ "#{$~[1]}##{ERB::Util.h($~[2])}"
+ end
+ form_message
+ end
+ end
+end
diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb
index 28461e091..2fae00b1e 100644
--- a/spec/controllers/profiles_controller_spec.rb
+++ b/spec/controllers/profiles_controller_spec.rb
@@ -34,7 +34,6 @@ describe ProfilesController do
end
end
-
describe '#update' do
it "sets the flash" do
put :update, :profile => {
@@ -45,6 +44,15 @@ describe ProfilesController do
flash[:notice].should_not be_empty
end
+ it 'sets tags' do
+ params = { :id => @user.person.id,
+ :profile =>
+ { :tags => '#apples #oranges'}}
+
+ put :update, params
+ @user.person(true).profile.tags.should =~ ['apples', 'oranges']
+ end
+
context 'with a profile photo set' do
before do
@params = { :id => @user.person.id,
diff --git a/spec/models/profile_spec.rb b/spec/models/profile_spec.rb
index c7ebb1eab..372a98694 100644
--- a/spec/models/profile_spec.rb
+++ b/spec/models/profile_spec.rb
@@ -146,6 +146,13 @@ describe Profile do
end
end
+ describe 'tags' do
+ before do
+ @object = Factory.build(:profile)
+ end
+ it_should_behave_like 'it is taggable'
+ end
+
describe '#receive' do
it 'updates the profile in place' do
diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb
index e98a7c693..06a110824 100644
--- a/spec/models/status_message_spec.rb
+++ b/spec/models/status_message_spec.rb
@@ -4,7 +4,6 @@
require 'spec_helper'
-
describe StatusMessage do
include ActionView::Helpers::UrlHelper
include Rails.application.routes.url_helpers
@@ -174,60 +173,14 @@ STR
end
end
end
+
describe 'tags' do
before do
- @sm = Factory.build(:status_message)
- end
- describe '#format_tags' do
- before do
- @str = '#what #hey'
- @sm.text = @str
- @sm.build_tags
- @sm.save
- @sm.reload
- end
- it 'links the tag to /p' do
- link = link_to('#what', posts_path(:tag => 'what'), :class => 'tag')
- @sm.format_tags(@str).should include(link)
- end
- it 'responds to plain_text' do
- @sm.format_tags(@str, :plain_text => true).should == @str
- end
- end
- describe '#build_tags' do
- it 'builds the tags' do
- @sm.text = '#what'
- @sm.build_tags
- @sm.tag_list.should == ['what']
- lambda {
- @sm.save
- }.should change{@sm.tags.count}.by(1)
- end
- end
- describe '#tag_strings' do
- it 'returns a string for every #thing' do
- str = '#what #hey #that"smybike. #@hey ##boo # #THATWASMYBIKE #hey#there #135440we #abc/23 ###'
- arr = ['what', 'hey', 'that', 'THATWASMYBIKE', '135440we', 'abc']
-
- @sm.text = str
- @sm.tag_strings.should =~ arr
- end
- it 'returns no duplicates' do
- str = '#what #what #what #whaaaaaaaaaat'
- arr = ['what','whaaaaaaaaaat']
-
- @sm.text = str
- @sm.tag_strings.should =~ arr
- end
- it 'is case insensitive' do
- str = '#what #wHaT #WHAT'
- arr = ['what']
-
- @sm.text = str
- @sm.tag_strings.should =~ arr
- end
+ @object = Factory.build(:status_message)
end
+ it_should_behave_like 'it is taggable'
end
+
describe "XML" do
before do
@message = Factory.create(:status_message, :text => "I hate WALRUSES!", :author => @user.person)
diff --git a/spec/shared_behaviors/taggable.rb b/spec/shared_behaviors/taggable.rb
new file mode 100644
index 000000000..9c7248fd5
--- /dev/null
+++ b/spec/shared_behaviors/taggable.rb
@@ -0,0 +1,60 @@
+# Copyright (c) 2010, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe Diaspora::Taggable do
+ shared_examples_for "it is taggable" do
+ describe '#format_tags' do
+ before do
+ @str = '#what #hey'
+ @object.send(@object.class.field_with_tags_setter, @str)
+ @object.build_tags
+ @object.save
+ @object.reload
+ end
+ it 'links the tag to /p' do
+ link = link_to('#what', posts_path(:tag => 'what'), :class => 'tag')
+ @object.format_tags(@str).should include(link)
+ end
+ it 'responds to plain_text' do
+ @object.format_tags(@str, :plain_text => true).should == @str
+ end
+ end
+ describe '#build_tags' do
+ it 'builds the tags' do
+ @object.send(@object.class.field_with_tags_setter, '#what')
+ @object.build_tags
+ @object.tag_list.should == ['what']
+ lambda {
+ @object.save
+ }.should change{@object.tags.count}.by(1)
+ end
+ end
+ describe '#tag_strings' do
+ it 'returns a string for every #thing' do
+ str = '#what #hey #that"smybike. #@hey ##boo # #THATWASMYBIKE #hey#there #135440we #abc/23 ###'
+ arr = ['what', 'hey', 'that', 'THATWASMYBIKE', '135440we', 'abc']
+
+ @object.send(@object.class.field_with_tags_setter, str)
+ @object.tag_strings.should =~ arr
+ end
+ it 'returns no duplicates' do
+ str = '#what #what #what #whaaaaaaaaaat'
+ arr = ['what','whaaaaaaaaaat']
+
+ @object.send(@object.class.field_with_tags_setter, str)
+ @object.tag_strings.should =~ arr
+ end
+ it 'is case insensitive' do
+ str = '#what #wHaT #WHAT'
+ arr = ['what']
+
+ @object.send(@object.class.field_with_tags_setter, str)
+ @object.tag_strings.should =~ arr
+ end
+ end
+ end
+end
+
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 66275fd2b..3a19f50f2 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -24,6 +24,10 @@ support_files = Dir["#{File.dirname(__FILE__)}/support/**/*.rb"] - [fixture_buil
support_files.each {|f| require f }
require fixture_builder_file
+Dir["#{File.dirname(__FILE__)}/shared_behaviors/**/*.rb"].each do |f|
+ require f
+end
+
RSpec.configure do |config|
config.include Devise::TestHelpers, :type => :controller
config.mock_with :rspec