visit_card 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +31 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/app/controllers/vcards_controller.rb +3 -0
- data/app/helpers/vcards_helper.rb +3 -0
- data/app/models/vcard.rb +3 -0
- data/app/models/vcard_adr.rb +3 -0
- data/app/models/vcard_categorization.rb +3 -0
- data/app/models/vcard_dictionary.rb +3 -0
- data/app/models/vcard_email.rb +3 -0
- data/app/models/vcard_tel.rb +3 -0
- data/app/views/visit_card/vcard_adrs/_form_fields.html.erb +38 -0
- data/app/views/visit_card/vcard_emails/_form_fields.html.erb +14 -0
- data/app/views/visit_card/vcard_tels/_form_fields.html.erb +14 -0
- data/app/views/visit_card/vcards/_form.html.erb +115 -0
- data/app/views/visit_card/vcards/_hcard.html.erb +1 -0
- data/app/views/visit_card/vcards/_static.html +39 -0
- data/app/views/visit_card/vcards/edit.html.erb +7 -0
- data/app/views/visit_card/vcards/index.html.erb +20 -0
- data/app/views/visit_card/vcards/new.html.erb +7 -0
- data/app/views/visit_card/vcards/show.html.erb +7 -0
- data/config/routes.rb +3 -0
- data/lib/generators/visit_card/vcard/templates/migration.rb +94 -0
- data/lib/generators/visit_card/vcard/templates/seeds.rb +14 -0
- data/lib/generators/visit_card/vcard/vcard_generator.rb +83 -0
- data/lib/generators/visit_card/views/views_generator.rb +63 -0
- data/lib/visit_card/controllers/vcards_controller.rb +65 -0
- data/lib/visit_card/helpers/vcards_helper.rb +66 -0
- data/lib/visit_card/models/vcard.rb +57 -0
- data/lib/visit_card/models/vcard_adr.rb +20 -0
- data/lib/visit_card/models/vcard_categorization.rb +18 -0
- data/lib/visit_card/models/vcard_dictionary.rb +25 -0
- data/lib/visit_card/models/vcard_email.rb +21 -0
- data/lib/visit_card/models/vcard_tel.rb +21 -0
- data/lib/visit_card.rb +33 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/visit_card_spec.rb +7 -0
- data/visit_card.gemspec +89 -0
- metadata +141 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Pavel Chipiga
|
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.
|
data/README.rdoc
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
= visit_card
|
2
|
+
|
3
|
+
Manage visit cards in your app.
|
4
|
+
VCard standart (RFC 2426) realization through Rails 3 Engines.
|
5
|
+
Supports export to hCard microformat.
|
6
|
+
|
7
|
+
== TODO
|
8
|
+
* Move out styles and javascript from views.
|
9
|
+
* Improve hCard microformat export. Move to Builder.
|
10
|
+
* Add I18n support.
|
11
|
+
* Add localized_country_select plugin support.
|
12
|
+
* Add phone gem support.
|
13
|
+
* Import/Export VCard.
|
14
|
+
* Test suite.
|
15
|
+
* Improve Generators. Add seeds generator.
|
16
|
+
* Do something with routes?
|
17
|
+
* Improve default views.
|
18
|
+
|
19
|
+
== Note on Patches/Pull Requests
|
20
|
+
|
21
|
+
* Fork the project.
|
22
|
+
* Make your feature addition or bug fix.
|
23
|
+
* Add tests for it. This is important so I don't break it in a
|
24
|
+
future version unintentionally.
|
25
|
+
* Commit, do not mess with rakefile, version, or history.
|
26
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
27
|
+
* Send me a pull request. Bonus points for topic branches.
|
28
|
+
|
29
|
+
== Copyright
|
30
|
+
|
31
|
+
Copyright (c) 2010 Pavel Chipiga. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "visit_card"
|
8
|
+
gem.summary = %Q{VCard implementation for Rails 3}
|
9
|
+
gem.description = %Q{Rails 3 engines plugin for VCard store and managment}
|
10
|
+
gem.email = "pavel.chipiga@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/chipiga/visit_card"
|
12
|
+
gem.authors = ["Pavel Chipiga"]
|
13
|
+
gem.add_dependency "bitmask-attribute", ">= 1.2.0"
|
14
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
+
end
|
27
|
+
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
+
spec.rcov = true
|
32
|
+
end
|
33
|
+
|
34
|
+
task :spec => :check_dependencies
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "visit_card #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/app/models/vcard.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
<fieldset class="inputs adr">
|
2
|
+
<legend>Address</legend>
|
3
|
+
<ol>
|
4
|
+
<li class="field">
|
5
|
+
<%= ff.check_box_collection :types, VcardAdr::TYPES %>
|
6
|
+
</li>
|
7
|
+
<li class="field">
|
8
|
+
<%= ff.label :post_office_box %>
|
9
|
+
<%= ff.text_field :post_office_box %>
|
10
|
+
</li>
|
11
|
+
<li class="field">
|
12
|
+
<%= ff.label :extended_address %>
|
13
|
+
<%= ff.text_field :extended_address %>
|
14
|
+
</li>
|
15
|
+
<li class="field">
|
16
|
+
<%= ff.label :street_address %>
|
17
|
+
<%= ff.text_field :street_address %>
|
18
|
+
</li>
|
19
|
+
<li class="field">
|
20
|
+
<%= ff.label :locality %>
|
21
|
+
<%= ff.text_field :locality %>
|
22
|
+
</li>
|
23
|
+
<li class="field">
|
24
|
+
<%= ff.label :region %>
|
25
|
+
<%= ff.text_field :region %>
|
26
|
+
</li>
|
27
|
+
<li class="field">
|
28
|
+
<%= ff.label :postal_code %>
|
29
|
+
<%= ff.text_field :postal_code %>
|
30
|
+
</li>
|
31
|
+
<li class="field">
|
32
|
+
<%= ff.label :country_name %>
|
33
|
+
<%= ff.text_field :country_name %> <!-- TODO select -->
|
34
|
+
</li>
|
35
|
+
</ol>
|
36
|
+
<%= ff.hidden_field :_destroy, :value => '' %>
|
37
|
+
<a href='#' class='remove'>Remove</a>
|
38
|
+
</fieldset>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<fieldset class="inputs email">
|
2
|
+
<legend>Email</legend>
|
3
|
+
<ol>
|
4
|
+
<li class="field">
|
5
|
+
<%= ff.check_box_collection :types, VcardEmail::TYPES %>
|
6
|
+
</li>
|
7
|
+
<li class="field">
|
8
|
+
<%= ff.label :value %>
|
9
|
+
<%= ff.email_field :value %>
|
10
|
+
</li>
|
11
|
+
</ol>
|
12
|
+
<%= ff.hidden_field :_destroy, :value => '' %>
|
13
|
+
<a href='#' class='remove'>Remove</a>
|
14
|
+
</fieldset>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<fieldset class="inputs tel">
|
2
|
+
<legend>Telephone</legend>
|
3
|
+
<ol>
|
4
|
+
<li class="field">
|
5
|
+
<%= ff.check_box_collection :types, VcardTel::TYPES %>
|
6
|
+
</li>
|
7
|
+
<li class="field">
|
8
|
+
<%= ff.label :value %>
|
9
|
+
<%= ff.telephone_field :value %>
|
10
|
+
</li>
|
11
|
+
</ol>
|
12
|
+
<%= ff.hidden_field :_destroy, :value => '' %>
|
13
|
+
<a href='#' class='remove'>Remove</a>
|
14
|
+
</fieldset>
|
@@ -0,0 +1,115 @@
|
|
1
|
+
<%= render 'static' %>
|
2
|
+
<%= form_for @vcard do |f| %>
|
3
|
+
<% if @vcard.errors.any? %>
|
4
|
+
<div id="errorExplanation">
|
5
|
+
<h2><%= "#{pluralize(@vcard.errors.count, "error")} prohibited this project from being saved:"%></h2>
|
6
|
+
<ul>
|
7
|
+
<% @vcard.errors.full_messages.each do |msg| %>
|
8
|
+
<li><%= msg %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<fieldset class="inputs">
|
15
|
+
<ol>
|
16
|
+
<li class="field required">
|
17
|
+
<%= f.label :family_name %>
|
18
|
+
<%= f.text_field :family_name %>
|
19
|
+
</li>
|
20
|
+
<li class="field required">
|
21
|
+
<%= f.label :given_name %>
|
22
|
+
<%= f.text_field :given_name %>
|
23
|
+
</li>
|
24
|
+
<li class="field">
|
25
|
+
<%= f.label :additional_name %>
|
26
|
+
<%= f.text_field :additional_name %>
|
27
|
+
</li>
|
28
|
+
<li class="field">
|
29
|
+
<%= f.label :honorific_prefix %>
|
30
|
+
<%= f.text_field :honorific_prefix, :size => 10, :maxlength => 10 %>
|
31
|
+
</li>
|
32
|
+
<li class="field">
|
33
|
+
<%= f.label :honorific_suffix %>
|
34
|
+
<%= f.text_field :honorific_suffix, :size => 10, :maxlength => 10 %>
|
35
|
+
</li>
|
36
|
+
<li class="field">
|
37
|
+
<%= f.label :nickname %>
|
38
|
+
<%= f.text_field :nickname %>
|
39
|
+
</li>
|
40
|
+
<li class="field">
|
41
|
+
<%= f.label :photo %>
|
42
|
+
<%= f.url_field :photo %>
|
43
|
+
</li>
|
44
|
+
<li class="field">
|
45
|
+
<%= f.label :bday %>
|
46
|
+
<%= f.date_select :bday, :start_year => Time.now.year - 80, :end_year => Time.now.year, :include_blank => true %>
|
47
|
+
</li>
|
48
|
+
|
49
|
+
<li class="field">
|
50
|
+
<%= f.label :tz %>
|
51
|
+
<%= f.time_zone_select :tz, nil, :include_blank => true %>
|
52
|
+
</li>
|
53
|
+
<li class="field">
|
54
|
+
<%= f.label :latitude %>
|
55
|
+
<%= f.number_field :latitude, :size => 10, :maxlength => 10 %>
|
56
|
+
</li>
|
57
|
+
<li class="field">
|
58
|
+
<%= f.label :longitude %>
|
59
|
+
<%= f.number_field :longitude, :size => 10, :maxlength => 10 %>
|
60
|
+
</li>
|
61
|
+
<li class="field">
|
62
|
+
<%= f.label :title %>
|
63
|
+
<%= f.text_field :title %>
|
64
|
+
</li>
|
65
|
+
<li class="field">
|
66
|
+
<%= f.label :role %>
|
67
|
+
<%= f.text_field :role %>
|
68
|
+
</li>
|
69
|
+
<li class="field">
|
70
|
+
<%= f.label :logo %>
|
71
|
+
<%= f.url_field :logo %>
|
72
|
+
</li>
|
73
|
+
<li class="field">
|
74
|
+
<%= f.label :agent %>
|
75
|
+
<%= f.select :agent_id, Vcard.except(params[:id]).collect {|v| [ v.fn, v.id ] }, :include_blank => true %>
|
76
|
+
</li>
|
77
|
+
<li class="field">
|
78
|
+
<%= f.label :org %>
|
79
|
+
<%= f.text_field :org %>
|
80
|
+
</li>
|
81
|
+
<li class="field">
|
82
|
+
<%= f.check_box_collection :vcard_categories, Hash[ *VcardDictionary.categories.collect { |d| [ d.id, d.name ] }.flatten ] %>
|
83
|
+
</li>
|
84
|
+
<li class="field">
|
85
|
+
<%= f.label :note %>
|
86
|
+
<%= f.text_area :note %>
|
87
|
+
</li>
|
88
|
+
<li class="field">
|
89
|
+
<%= f.label :url %>
|
90
|
+
<%= f.url_field :url %>
|
91
|
+
</li>
|
92
|
+
<li class="field">
|
93
|
+
<%= f.label :klass %>
|
94
|
+
<%= f.select :klass, Vcard::VCARD_KLASSES %>
|
95
|
+
</li>
|
96
|
+
|
97
|
+
<% %w{adrs tels emails extensions}.each do |item| %>
|
98
|
+
<li class="field <%= item %>">
|
99
|
+
<%= f.fields_for :"vcard_#{item}" do |ff| %>
|
100
|
+
<%= render "vcard_#{item}/form_fields", :ff => ff %>
|
101
|
+
<% end %>
|
102
|
+
<a href='#' class='add' title='<%= item.singularize %>'>Add <%= item.singularize.humanize %></a>
|
103
|
+
</li>
|
104
|
+
<% end %>
|
105
|
+
</ol>
|
106
|
+
</fieldset>
|
107
|
+
|
108
|
+
<fieldset class="buttons">
|
109
|
+
<ol>
|
110
|
+
<li class="actions">
|
111
|
+
<%= f.submit 'Save' %>
|
112
|
+
</li>
|
113
|
+
</ol>
|
114
|
+
</fieldset>
|
115
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= @vcard.to_hcard %>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<!-- TODO move to static files -->
|
2
|
+
<style>
|
3
|
+
li.field {clear: both;}
|
4
|
+
li.field > label {display: block;}
|
5
|
+
fieldset ol {list-style-type: none!important; padding: 0!important; margin: 0!important;}
|
6
|
+
fieldset.inputs, fieldset.vcard_categories {border: 1px solid #000000; padding: 10px;}
|
7
|
+
a.add, a.remove {float: right;}
|
8
|
+
.required label:after {content: ' * '; color: red;}
|
9
|
+
</style>
|
10
|
+
<script>
|
11
|
+
$(document).ready(function(){
|
12
|
+
$('a.remove').live('click', function(){
|
13
|
+
//$(this).prev().find('input[type$="hidden"]').val('1');
|
14
|
+
$(this).prev().val('1');
|
15
|
+
$(this).parent().slideUp('slow');
|
16
|
+
return false;
|
17
|
+
});
|
18
|
+
|
19
|
+
$('a.add').click(function(){
|
20
|
+
var from = $(this).parent().find('fieldset'+($(this).attr('title') ? '.'+$(this).attr('title') : '')+':last'); // source block
|
21
|
+
var id = parseInt(from.find('input:first').attr('id').split('_').sort().shift()) + 1; // parse id and increment
|
22
|
+
var to = from.clone().hide(); // copy block and hide
|
23
|
+
to.find('input,select').attr('id', function(){ // replace id param
|
24
|
+
return this.id.replace(/\d+/, id);
|
25
|
+
});
|
26
|
+
to.find('label').attr('for', function(){ // replace for param
|
27
|
+
return $(this).attr('for').replace(/\d+/, id);
|
28
|
+
});
|
29
|
+
to.find('input,select').attr('name', function(){ // replace name param
|
30
|
+
if ($(this).attr('type') != 'checkbox') { $(this).val(''); } // clear block fields values
|
31
|
+
else { $(this).removeAttr('checked'); } // clear checkboxes
|
32
|
+
return $(this).attr('name').replace(/\d+/, id);
|
33
|
+
});
|
34
|
+
$(this).before(to); // insert block before link
|
35
|
+
to.slideDown('slow'); // show block
|
36
|
+
return false;
|
37
|
+
});
|
38
|
+
});
|
39
|
+
</script>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<h1>Listing VCards</h1>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th>FN</th>
|
6
|
+
<th>ORG</th>
|
7
|
+
<th>Action</th>
|
8
|
+
</tr>
|
9
|
+
<% @vcards.each do |vcard| %>
|
10
|
+
<tr>
|
11
|
+
<td><%= link_to(vcard.fga, vcard) %></td>
|
12
|
+
<td><%= vcard.org %></td>
|
13
|
+
<td><%= link_to 'Edit', edit_vcard_path(vcard) %> | <%= link_to 'Destroy', vcard, :confirm => 'Are you sure?', :method => :delete %></td>
|
14
|
+
</tr>
|
15
|
+
<% end %>
|
16
|
+
</table>
|
17
|
+
|
18
|
+
<p>
|
19
|
+
<%= link_to 'New VCard', new_vcard_path %>
|
20
|
+
</p>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
class Create<%= table_name.camelize %>Tables < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table(:<%= table_name %>) do |t|
|
4
|
+
# t.references :user # additional field for multi-user system
|
5
|
+
t.references :agent
|
6
|
+
# t.boolean :primary # additional flag to set primary user contact
|
7
|
+
# t.string :type # uncomment this if you want use alternative vcard model name through STI
|
8
|
+
t.string :family_name
|
9
|
+
t.string :given_name
|
10
|
+
t.string :additional_name
|
11
|
+
t.string :honorific_prefix, :limit => 10
|
12
|
+
t.string :honorific_suffix, :limit => 10
|
13
|
+
t.string :nickname
|
14
|
+
t.text :photo
|
15
|
+
t.date :bday
|
16
|
+
t.string :tz
|
17
|
+
t.float :latitude
|
18
|
+
t.float :longitude
|
19
|
+
t.string :title
|
20
|
+
t.string :role
|
21
|
+
t.text :logo
|
22
|
+
t.string :org
|
23
|
+
t.text :note
|
24
|
+
t.string :url
|
25
|
+
t.string :klass
|
26
|
+
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
add_index :<%= table_name %>, :agent_id
|
30
|
+
add_index :<%= table_name %>, :klass
|
31
|
+
# add_index :<%= table_name %>, :user_id
|
32
|
+
# add_index :<%= table_name %>, :primary
|
33
|
+
add_index :<%= table_name %>, [:family_name, :given_name]
|
34
|
+
|
35
|
+
create_table(:vcard_adrs) do |t|
|
36
|
+
t.references :<%= table_name.singularize %>
|
37
|
+
t.integer :types, :default => 0
|
38
|
+
t.string :post_office_box
|
39
|
+
t.string :extended_address
|
40
|
+
t.string :street_address
|
41
|
+
t.string :locality
|
42
|
+
t.string :region
|
43
|
+
t.string :postal_code
|
44
|
+
t.string :country_name
|
45
|
+
end
|
46
|
+
add_index :vcard_adrs, :<%= table_name.singularize %>_id
|
47
|
+
|
48
|
+
create_table(:vcard_tels) do |t|
|
49
|
+
t.references :<%= table_name.singularize %>
|
50
|
+
t.integer :types, :default => 0
|
51
|
+
t.string :value
|
52
|
+
end
|
53
|
+
add_index :vcard_tels, :<%= table_name.singularize %>_id
|
54
|
+
|
55
|
+
create_table(:vcard_emails) do |t|
|
56
|
+
t.references :<%= table_name.singularize %>
|
57
|
+
t.integer :types, :default => 0
|
58
|
+
t.string :value
|
59
|
+
end
|
60
|
+
add_index :vcard_emails, :<%= table_name.singularize %>_id
|
61
|
+
|
62
|
+
create_table(:vcard_dictionaries) do |t|
|
63
|
+
t.string :klass
|
64
|
+
t.string :name
|
65
|
+
t.string :description
|
66
|
+
end
|
67
|
+
add_index :vcard_dictionaries, [:klass, :name], :unique => true
|
68
|
+
|
69
|
+
create_table(:vcard_categorizations) do |t|
|
70
|
+
t.references :<%= table_name.singularize %>
|
71
|
+
t.references :vcard_dictionary
|
72
|
+
end
|
73
|
+
add_index :vcard_categorizations, [:<%= table_name.singularize %>_id, :vcard_dictionary_id], :unique => true
|
74
|
+
|
75
|
+
create_table(:vcard_extensions) do |t|
|
76
|
+
t.references :<%= table_name.singularize %>
|
77
|
+
t.references :vcard_dictionary
|
78
|
+
t.integer :types, :default => 0
|
79
|
+
t.string :value
|
80
|
+
end
|
81
|
+
add_index :vcard_extensions, :<%= table_name.singularize %>_id
|
82
|
+
add_index :vcard_extensions, :vcard_dictionary_id
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.down
|
86
|
+
drop_table :<%= table_name %>
|
87
|
+
drop_table :vcard_adrs
|
88
|
+
drop_table :vcard_tels
|
89
|
+
drop_table :vcard_emails
|
90
|
+
drop_table :vcard_dictionaries
|
91
|
+
drop_table :vcard_categorizations
|
92
|
+
drop_table :vcard_extensions
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
VcardDictionary.create(:klass => 'category', 'name' => 'travel agent')
|
2
|
+
VcardDictionary.create(:klass => 'category', 'name' => 'internet')
|
3
|
+
VcardDictionary.create(:klass => 'category', 'name' => 'ietf')
|
4
|
+
VcardDictionary.create(:klass => 'category', 'name' => 'industry')
|
5
|
+
VcardDictionary.create(:klass => 'category', 'name' => 'information technology')
|
6
|
+
|
7
|
+
VcardDictionary.create(:klass => 'extension_type', 'name' => 'x-aim', 'description' => 'aim:#{value}')
|
8
|
+
VcardDictionary.create(:klass => 'extension_type', 'name' => 'x-icq', 'description' => 'icq:#{value}/') # http://www.icq.com/people/#{value}
|
9
|
+
VcardDictionary.create(:klass => 'extension_type', 'name' => 'x-xmpp', 'description' => 'xmpp:#{value}')
|
10
|
+
VcardDictionary.create(:klass => 'extension_type', 'name' => 'x-msn', 'description' => 'msn:#{value}')
|
11
|
+
VcardDictionary.create(:klass => 'extension_type', 'name' => 'x-yahoo', 'description' => 'yahoo:#{value}')
|
12
|
+
VcardDictionary.create(:klass => 'extension_type', 'name' => 'x-twitter', 'description' => 'http://twitter.com/#{value}')
|
13
|
+
VcardDictionary.create(:klass => 'extension_type', 'name' => 'x-skype', 'description' => 'skype:#{value}')
|
14
|
+
VcardDictionary.create(:klass => 'extension_type', 'name' => 'x-livejournal', 'description' => 'http://#{value}.livejournal.com/')
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'rails/generators/migration'
|
2
|
+
|
3
|
+
module VisitCard
|
4
|
+
module Generators
|
5
|
+
class VcardGenerator < Rails::Generators::NamedBase
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
namespace "visit_card"
|
10
|
+
|
11
|
+
desc "Generates a model with the given NAME (if one does not exist) with vcard " <<
|
12
|
+
"configuration plus a migration file and vcard routes." # TODO routes??
|
13
|
+
|
14
|
+
def self.orm_has_migration?
|
15
|
+
Rails::Generators.options[:rails][:orm] == :active_record
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.next_migration_number(path)
|
19
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
20
|
+
end
|
21
|
+
|
22
|
+
class_option :orm
|
23
|
+
class_option :migration, :type => :boolean, :default => orm_has_migration?
|
24
|
+
|
25
|
+
def invoke_orm_model
|
26
|
+
return unless behavior == :invoke
|
27
|
+
|
28
|
+
if model_exists?
|
29
|
+
say "* Model already exists. Adding Vcard behavior."
|
30
|
+
elsif options[:orm].present?
|
31
|
+
invoke "model", [name], :migration => false, :orm => options[:orm]
|
32
|
+
|
33
|
+
unless model_exists?
|
34
|
+
abort "Tried to invoke the model generator for '#{options[:orm]}' but could not find it.\n" <<
|
35
|
+
"Please create your model by hand before calling `rails g vcard #{name}`."
|
36
|
+
end
|
37
|
+
else
|
38
|
+
abort "Cannot create a vcard model because config.generators.orm is blank.\n" <<
|
39
|
+
"Please create your model by hand or configure your generators orm before calling `rails g vcard #{name}`."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def inject_vcard_config_into_model
|
44
|
+
vcard_class_setup = <<-CONTENT
|
45
|
+
|
46
|
+
include VisitCard::Models::Vcard
|
47
|
+
|
48
|
+
CONTENT
|
49
|
+
|
50
|
+
case options[:orm].to_s
|
51
|
+
when "mongoid"
|
52
|
+
inject_into_file model_path, vcard_class_setup, :after => "include Mongoid::Document\n"
|
53
|
+
when "data_mapper"
|
54
|
+
inject_into_file model_path, vcard_class_setup, :after => "include DataMapper::Resource\n"
|
55
|
+
when "active_record"
|
56
|
+
inject_into_class model_path, class_name, vcard_class_setup + <<-CONTENT
|
57
|
+
# Setup accessible (or protected) attributes for your model TODO
|
58
|
+
# attr_accessible :given_name, :last_name, :additional_name
|
59
|
+
CONTENT
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def copy_migration_template
|
64
|
+
return unless options.migration?
|
65
|
+
migration_template "migration.rb", "db/migrate/create_#{table_name}_tables"
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_vcard_routes
|
69
|
+
# route "vcard_for :#{table_name}"
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
|
74
|
+
def model_exists?
|
75
|
+
File.exists?(File.join(destination_root, model_path))
|
76
|
+
end
|
77
|
+
|
78
|
+
def model_path
|
79
|
+
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|