caboodle 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +21 -0
  5. data/Rakefile +64 -0
  6. data/VERSION +1 -0
  7. data/bin/caboodle +14 -0
  8. data/lib/.yardoc/checksums +2 -0
  9. data/lib/.yardoc/objects/Pago/App.dat +0 -0
  10. data/lib/.yardoc/objects/Pago/MenuItems.dat +0 -0
  11. data/lib/.yardoc/objects/Pago/Plugin/is_a_pago_plugin_c.dat +0 -0
  12. data/lib/.yardoc/objects/Pago/Plugin/load_all_c.dat +0 -0
  13. data/lib/.yardoc/objects/Pago/Plugin/menu_c.dat +0 -0
  14. data/lib/.yardoc/objects/Pago/Plugin/use_all_c.dat +0 -0
  15. data/lib/.yardoc/objects/Pago/Plugin.dat +0 -0
  16. data/lib/.yardoc/objects/Pago/Plugins.dat +0 -0
  17. data/lib/.yardoc/objects/Pago/Site.dat +0 -0
  18. data/lib/.yardoc/objects/Pago.dat +0 -0
  19. data/lib/.yardoc/objects/root.dat +0 -0
  20. data/lib/.yardoc/proxy_types +2 -0
  21. data/lib/caboodle/app/.gems +1 -0
  22. data/lib/caboodle/app/config/site.yml +4 -0
  23. data/lib/caboodle/app/config.ru +2 -0
  24. data/lib/caboodle/app/public/favicon.ico +0 -0
  25. data/lib/caboodle/app/public/images/favicon.ico +0 -0
  26. data/lib/caboodle/app/public/images/grid.png +0 -0
  27. data/lib/caboodle/app/public/js/application.js +0 -0
  28. data/lib/caboodle/app/public/stylesheets/ie.css +1 -0
  29. data/lib/caboodle/app/public/stylesheets/print.css +122 -0
  30. data/lib/caboodle/app/public/stylesheets/screen.css +196 -0
  31. data/lib/caboodle/app/stylesheets/_base.scss +49 -0
  32. data/lib/caboodle/app/stylesheets/_defaults.scss +257 -0
  33. data/lib/caboodle/app/stylesheets/ie.scss +10 -0
  34. data/lib/caboodle/app/stylesheets/print.scss +33 -0
  35. data/lib/caboodle/app/stylesheets/screen.scss +292 -0
  36. data/lib/caboodle/app/views/layout.haml +66 -0
  37. data/lib/caboodle/app.rb +35 -0
  38. data/lib/caboodle/command.rb +38 -0
  39. data/lib/caboodle/config.rb +12 -0
  40. data/lib/caboodle/kit.rb +148 -0
  41. data/lib/caboodle/kits/flickr/flickr.rb +65 -0
  42. data/lib/caboodle/kits/flickr/galleria.noconflict.min.js +18 -0
  43. data/lib/caboodle/kits/flickr/views/photography.haml +108 -0
  44. data/lib/caboodle/kits/github/github.rb +44 -0
  45. data/lib/caboodle/kits/github/views/_repo.haml +7 -0
  46. data/lib/caboodle/kits/github/views/github.haml +11 -0
  47. data/lib/caboodle/kits/identity/identity.rb +18 -0
  48. data/lib/caboodle/kits/identity/views/me.haml +22 -0
  49. data/lib/caboodle/kits/lazyload/lazyload.rb +6 -0
  50. data/lib/caboodle/kits/lazyload/public/jquery.lazyload.mini.js +12 -0
  51. data/lib/caboodle/kits/lazyload/public/lazyload.js +3 -0
  52. data/lib/caboodle/kits/linkedin/linkedin.rb +33 -0
  53. data/lib/caboodle/kits/linkedin/views/cv.haml +6 -0
  54. data/lib/caboodle/kits/onepage/card.html +220 -0
  55. data/lib/caboodle/kits/onepage/onepage.rb +16 -0
  56. data/lib/caboodle/kits/onepage/views/contact.haml +2 -0
  57. data/lib/caboodle/kits/page/page.rb +69 -0
  58. data/lib/caboodle/kits/page/views/page.haml +2 -0
  59. data/lib/caboodle/kits/portfolio/portfolio.rb +14 -0
  60. data/lib/caboodle/kits/portfolio/views/portfolio.haml +29 -0
  61. data/lib/caboodle/kits/posterous/posterous.rb +163 -0
  62. data/lib/caboodle/kits/posterous/views/_post.haml +29 -0
  63. data/lib/caboodle/kits/posterous/views/post.haml +14 -0
  64. data/lib/caboodle/kits/posterous/views/posts.haml +21 -0
  65. data/lib/caboodle/kits/soundcloud/soundcloud.rb +31 -0
  66. data/lib/caboodle/kits/soundcloud/views/soundcloud.haml +17 -0
  67. data/lib/caboodle/kits/twitter/public/images/ajax-loader.gif +0 -0
  68. data/lib/caboodle/kits/twitter/public/images/link.png +0 -0
  69. data/lib/caboodle/kits/twitter/twitter.rb +16 -0
  70. data/lib/caboodle/kits/twitter/views/twitter.haml +101 -0
  71. data/lib/caboodle/kits/typekit/public/typekit.js +1 -0
  72. data/lib/caboodle/kits/typekit/typekit.rb +10 -0
  73. data/lib/caboodle/scrape.rb +9 -0
  74. data/lib/caboodle.rb +3 -0
  75. data/test/helper.rb +10 -0
  76. data/test/test_caboodle.rb +7 -0
  77. metadata +348 -0
@@ -0,0 +1,38 @@
1
+ gem 'heroku'
2
+ require 'heroku'
3
+ require 'heroku/command'
4
+
5
+ module Caboodle
6
+ module Command
7
+ class << self
8
+ def run(command, args, retries=0)
9
+ case command
10
+ when "create"
11
+ puts `mkdir #{args.first}`
12
+ puts `cd #{args.first} && cp -r #{File.expand_path(File.join(File.dirname(__FILE__), 'app'))}/* .`
13
+ puts `cd #{args.first} && cp #{File.expand_path(File.join(File.dirname(__FILE__), 'app'))}/.gems .`
14
+ puts `cd #{args.first} && git init`
15
+ puts `cd #{args.first} && git add .`
16
+ puts `bundle install`
17
+ puts `cd #{args.first} && git commit -m"initial setup"`
18
+ puts `cd #{args.first} && heroku create #{args.first}`
19
+ puts `cd #{args.first} && git push heroku master`
20
+
21
+ when /kit:add/
22
+ unless Caboodle::Site.kits.include?(args.first.capitalize)
23
+ Caboodle::Kit.load_kit args.first.capitalize
24
+ Caboodle::Kit.dump_config
25
+ puts `git add .`
26
+ puts `git commit -m"kit:add #{args}" -a`
27
+ puts `git push heroku master`
28
+ end
29
+ when "deploy"
30
+ puts `git commit -m"deploy" -a`
31
+ puts `git push heroku master`
32
+ else
33
+ Heroku::Command.run(command,args,retries)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,12 @@
1
+ module Caboodle
2
+ MenuItems = []
3
+ Defaults = Hashie::Mash.new()
4
+ Site = Defaults.clone
5
+ RequiredSettings = Hashie::Mash.new()
6
+ Kits = []
7
+ Javascripts = []
8
+ Stylesheets = []
9
+ Site.required_settings = []
10
+ Site.kits = [] unless Site.kits
11
+ Defaults.merge!(Hashie::Mash.new(YAML.load_file(File.join( File.join(File.dirname(__FILE__), 'defaults.yml')))))
12
+ end
@@ -0,0 +1,148 @@
1
+ module Caboodle
2
+
3
+ class Kit < Sinatra::Base
4
+ #register Sinatra::Compass
5
+
6
+ set :app_file, __FILE__
7
+ set :logging, true
8
+ set :root, File.expand_path(File.join(File.dirname(__FILE__),"app"))
9
+ set :public, Proc.new { File.join(root, "public") }
10
+ set :haml, {:format => :html5 }
11
+
12
+ template :layout do
13
+ @@template ||= File.open(File.join(File.dirname(__FILE__),"app","views","layout.haml")).read
14
+ puts @@template.inspect
15
+ @@template
16
+ end
17
+
18
+ class << self
19
+ def is_a_caboodle_kit
20
+ true
21
+ end
22
+
23
+ def load_config p
24
+ loaded = YAML.load_file(p)
25
+ Hashie::Mash.new(loaded).each{ |k,v|
26
+ v.strip! if v.class == String
27
+ Caboodle::Site[k.to_s] = v } rescue puts "Warning! Skipping #{p}"
28
+ Caboodle::Site.kits.uniq!
29
+ end
30
+
31
+ def dump_config
32
+ p = File.expand_path(File.join(Caboodle::App.root,"site.yml"))
33
+ d = Caboodle::Site.clone
34
+ e = d.to_hash
35
+ e.delete("required_settings")
36
+ File.open(p, 'w') {|f| f.write(YAML::dump(e))}
37
+ end
38
+
39
+ def setup
40
+ require_all
41
+ use_all
42
+ end
43
+
44
+ def load_kit name
45
+ unless name.blank?
46
+ puts "Load kit #{name}"
47
+ kit_name = name.to_s.split("::").last || name
48
+ kit_name = kit_name.downcase
49
+ orig = Caboodle.constants
50
+ require "caboodle/kits/#{kit_name}/#{kit_name}" rescue puts "No such kit: #{kit_name}"
51
+ added = Caboodle.constants - orig
52
+ added.each do |d|
53
+ c = Caboodle.const_get(d)
54
+ if c.respond_to?(:is_a_caboodle_kit)
55
+ c.register
56
+ end
57
+ end
58
+ end
59
+ Caboodle::Kits
60
+ end
61
+
62
+ def register
63
+ required_settings.each do |r|
64
+ unless Caboodle::Site[r]
65
+ puts "Please set a value for #{r}:"
66
+ v = STDIN.gets
67
+ Caboodle::Site[r] = v
68
+ Caboodle::Kit.dump_config
69
+ end
70
+ end
71
+ Caboodle::Kits << self
72
+ end
73
+
74
+ def require_all
75
+ if(Caboodle::Site.kits)
76
+ Caboodle::Site.kits.each do |k|
77
+ puts "Load Kit: #{k}"
78
+ load_kit k
79
+ end
80
+ else
81
+ puts "Kits not registered"
82
+ end
83
+ end
84
+
85
+ def use_all
86
+ Caboodle::Kits.each do |p|
87
+ p.start
88
+ end
89
+ end
90
+
91
+ def menu display, link
92
+ Caboodle::MenuItems << {:display=>display, :link=>link}
93
+ end
94
+
95
+ def required keys
96
+ if keys.class == Array
97
+ keys.each do |k|
98
+ self.required_settings << k
99
+ end
100
+ else
101
+ self.required_settings << keys
102
+ end
103
+ end
104
+
105
+ def stylesheets array_of_css_files
106
+ array_of_css_files.each do |a|
107
+ Caboodle::Stylesheets << a
108
+ end
109
+ Caboodle::Stylesheets.uniq!
110
+ end
111
+
112
+ def javascripts array_of_js_files
113
+ array_of_js_files.each do |a|
114
+ Caboodle::Javascripts << a
115
+ end
116
+ Caboodle::Javascripts.uniq!
117
+ end
118
+
119
+ def defaults hash
120
+ if hash.class == Hash
121
+ hash.each {|k,v| Site[k] = v }
122
+ end
123
+ end
124
+
125
+ def required_settings
126
+ r = RequiredSettings[self.ancestors.first.to_s.split("::").last] ||= [:title, :description, :logo_url, :author]
127
+ RequiredSettings[self.ancestors.first.to_s.split("::").last]
128
+ end
129
+
130
+ def start
131
+ errors = []
132
+ self.required_settings.each do |s|
133
+ if Site[s].blank?
134
+ errors << " :#{s} has not been set"
135
+ end
136
+ end
137
+
138
+ if errors.empty?
139
+ Caboodle::App.use self
140
+ else
141
+ STDERR.puts " "
142
+ STDERR.puts "Warning - #{self.ancestors.first} is disabled because:"
143
+ STDERR.puts errors.join("\n")
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,65 @@
1
+ module Caboodle
2
+
3
+ class FlickrAPI < Weary::Base
4
+
5
+ def initialize(opts={})
6
+ self.defaults = {:api_key => Site.flickr_api_key}
7
+ end
8
+
9
+ declare "photosets" do |r|
10
+ r.url = "http://api.flickr.com/services/rest/?method=flickr.photosets.getList&api_key=#{Site.flickr_api_key}&user_id=#{Site.flickr_user_id}"
11
+ r.via = :get
12
+ end
13
+
14
+ declare "photoset" do |r|
15
+ r.url = "http://api.flickr.com/services/rest/"
16
+ r.with = [:api_key, :photoset_id]
17
+ r.requires = [:api_key, :photoset_id,:method]
18
+ r.via = :get
19
+ end
20
+
21
+ def self.photoset_info(id)
22
+ Caboodle.mash(new.photoset({:photoset_id=>id,:method=>"flickr.photosets.getInfo"})).rsp.photoset
23
+ end
24
+
25
+ def self.photoset_photos(id)
26
+ Caboodle.mash(new.photoset({:photoset_id=>id,:method=>"flickr.photosets.getPhotos"})).rsp.photoset.photo
27
+ end
28
+
29
+ def self.photosets
30
+ Caboodle.mash(new.photosets).rsp.photosets.photoset
31
+ end
32
+
33
+ end
34
+
35
+ class Flickr < Caboodle::Kit
36
+
37
+ set :views, File.join(File.dirname(__FILE__), "views")
38
+
39
+ def home
40
+ @photosets = FlickrAPI.photosets rescue []
41
+ @title = "Photography"
42
+ haml :photography
43
+ end
44
+
45
+ get "/photography" do
46
+ home
47
+ end
48
+
49
+ get "/photography/:set_id" do |set_id|
50
+ @photosets = FlickrAPI.photosets rescue []
51
+ @set_id = set_id
52
+ @photoset = Caboodle::FlickrAPI.photoset_info(@set_id) rescue nil
53
+ @title = "Photography: #{@photoset.title if @photoset.respond_to?(:title)}"
54
+ haml :photography
55
+ end
56
+
57
+ get "/galleria.js" do
58
+ send_file File.join(File.dirname(__FILE__),"galleria.noconflict.min.js")
59
+ end
60
+
61
+ required [:flickr_username, :flickr_user_id, :flickr_api_key]
62
+
63
+ menu "Photography", "/photography"
64
+ end
65
+ end
@@ -0,0 +1,18 @@
1
+ $j=jQuery.noConflict();$j(function(){var $$;$$=$j.fn.galleria=function($options){if(!$$.hasCSS()){return false;}
2
+ $j.historyInit($$.onPageLoad);var $defaults={insert:'.galleria_container',history:true,clickNext:true,onImage:function(image,caption,thumb){},onThumb:function(thumb){}};var $opts=$j.extend($defaults,$options);for(var i in $opts){if(i){$j.galleria[i]=$opts[i];}}
3
+ var _insert=($j($opts.insert).is($opts.insert))?$j($opts.insert):jQuery(document.createElement('div')).insertBefore(this);var _div=$j(document.createElement('div')).addClass('galleria_wrapper');var _span=$j(document.createElement('span')).addClass('caption');_insert.addClass('galleria_container').append(_div).append(_span);return this.each(function(){$j(this).addClass('galleria');$j(this).children('li').each(function(i){var _container=$j(this);var _o=$j.meta?$j.extend({},$opts,_container.data()):$opts;_o.clickNext=$j(this).is(':only-child')?false:_o.clickNext;var _a=$j(this).find('a').is('a')?$j(this).find('a'):false;var _img=$j(this).children('img').css('display','none');var _src=_a?_a.attr('href'):_img.attr('src');var _title=_a?_a.attr('title'):_img.attr('title');var _loader=new Image();if(_o.history&&(window.location.hash&&window.location.hash.replace(/\#/,'')==_src)){_container.siblings('.active').removeClass('active');_container.addClass('active');}
4
+ $j(_loader).load(function(){$j(this).attr('alt',_img.attr('alt'));var _thumb=_a?_a.find('img').addClass('thumb noscale').css('display','none'):_img.clone(true).addClass('thumb').css('display','none');if(_a){_a.replaceWith(_thumb);}
5
+ if(!_thumb.hasClass('noscale')){var w=Math.ceil(_img.width()/_img.height()*_container.height());var h=Math.ceil(_img.height()/_img.width()*_container.width());if(w<h){_thumb.css({height:'auto',width:_container.width(),marginTop:-(h-_container.height())/2});}else{_thumb.css({width:'auto',height:_container.height(),marginLeft:-(w-_container.width())/2});}}else{window.setTimeout(function(){_thumb.css({marginLeft:-(_thumb.width()-_container.width())/2,marginTop:-(_thumb.height()-_container.height())/2});},1);}
6
+ _thumb.attr('rel',_src);_thumb.attr('title',_title);_thumb.click(function(){$j.galleria.activate(_src);});_thumb.hover(function(){$j(this).addClass('hover');},function(){$j(this).removeClass('hover');});_container.hover(function(){_container.addClass('hover');},function(){_container.removeClass('hover');});_container.prepend(_thumb);_thumb.css('display','block');_o.onThumb(jQuery(_thumb));if(_container.hasClass('active')){$j.galleria.activate(_src);}
7
+ _img.remove();}).error(function(){_container.html('<span class="error" style="color:red">Error loading image: '+_src+'</span>');}).attr('src',_src);});});};$$.nextSelector=function(selector){return $j(selector).is(':last-child')?$j(selector).siblings(':first-child'):$j(selector).next();};$$.previousSelector=function(selector){return $j(selector).is(':first-child')?$j(selector).siblings(':last-child'):$j(selector).prev();};$$.hasCSS=function(){$j('body').append($j(document.createElement('div')).attr('id','css_test').css({width:'1px',height:'1px',display:'none'}));var _v=($j('#css_test').width()!=1)?false:true;$j('#css_test').remove();return _v;};$$.onPageLoad=function(_src){var _wrapper=$j('.galleria_wrapper');var _thumb=$j('.galleria img[rel="'+_src+'"]');if(_src){if($j.galleria.history){window.location=window.location.href.replace(/\#.*/,'')+'#'+_src;}
8
+ _thumb.parents('li').siblings('.active').removeClass('active');_thumb.parents('li').addClass('active');var _img=$j(new Image()).attr('src',_src).addClass('replaced');_wrapper.empty().append(_img);_wrapper.siblings('.caption').text(_thumb.attr('title'));$j.galleria.onImage(_img,_wrapper.siblings('.caption'),_thumb);if($j.galleria.clickNext){_img.css('cursor','pointer').click(function(){$j.galleria.next();});}}else{_wrapper.siblings().andSelf().empty();$j('.galleria li.active').removeClass('active');}
9
+ $j.galleria.current=_src;};$j.extend({galleria:{current:'',onImage:function(){},activate:function(_src){if($j.galleria.history){$j.historyLoad(_src);}else{$$.onPageLoad(_src);}},next:function(){var _next=$j($$.nextSelector($j('.galleria img[rel="'+$j.galleria.current+'"]').parents('li'))).find('img').attr('rel');$j.galleria.activate(_next);},prev:function(){var _prev=$j($$.previousSelector($j('.galleria img[rel="'+$j.galleria.current+'"]').parents('li'))).find('img').attr('rel');$j.galleria.activate(_prev);}}});});jQuery.extend({historyCurrentHash:undefined,historyCallback:undefined,historyInit:function(callback){jQuery.historyCallback=callback;var current_hash=location.hash;jQuery.historyCurrentHash=current_hash;if(jQuery.browser.msie){if(jQuery.historyCurrentHash===''){jQuery.historyCurrentHash='#';}
10
+ $j("body").prepend('<iframe id="jQuery_history" style="display: none;"></iframe>');var ihistory=$j("#jQuery_history")[0];var iframe=ihistory.contentWindow.document;iframe.open();iframe.close();iframe.location.hash=current_hash;}
11
+ else if($j.browser.safari){jQuery.historyBackStack=[];jQuery.historyBackStack.length=history.length;jQuery.historyForwardStack=[];jQuery.isFirst=true;}
12
+ jQuery.historyCallback(current_hash.replace(/^#/,''));setInterval(jQuery.historyCheck,100);},historyAddHistory:function(hash){jQuery.historyBackStack.push(hash);jQuery.historyForwardStack.length=0;this.isFirst=true;},historyCheck:function(){if(jQuery.browser.msie){var ihistory=$j("#jQuery_history")[0];var iframe=ihistory.contentDocument||ihistory.contentWindow.document;var current_hash=iframe.location.hash;if(current_hash!=jQuery.historyCurrentHash){location.hash=current_hash;jQuery.historyCurrentHash=current_hash;jQuery.historyCallback(current_hash.replace(/^#/,''));}}else if($j.browser.safari){if(!jQuery.dontCheck){var historyDelta=history.length-jQuery.historyBackStack.length;if(historyDelta){jQuery.isFirst=false;var i;if(historyDelta<0){for(i=0;i<Math.abs(historyDelta);i++){jQuery.historyForwardStack.unshift(jQuery.historyBackStack.pop());}}else{for(i=0;i<historyDelta;i++){jQuery.historyBackStack.push(jQuery.historyForwardStack.shift());}}
13
+ var cachedHash=jQuery.historyBackStack[jQuery.historyBackStack.length-1];if(cachedHash!==undefined){jQuery.historyCurrentHash=location.hash;jQuery.historyCallback(cachedHash);}}else if(jQuery.historyBackStack[jQuery.historyBackStack.length-1]===undefined&&!jQuery.isFirst){if(document.URL.indexOf('#')>=0){jQuery.historyCallback(document.URL.split('#')[1]);}else{current_hash=location.hash;jQuery.historyCallback('');}
14
+ jQuery.isFirst=true;}}}else{current_hash=location.hash;if(current_hash!=jQuery.historyCurrentHash){jQuery.historyCurrentHash=current_hash;jQuery.historyCallback(current_hash.replace(/^#/,''));}}},historyLoad:function(hash){var newhash;if(jQuery.browser.safari){newhash=hash;}
15
+ else{newhash='#'+hash;location.hash=newhash;}
16
+ jQuery.historyCurrentHash=newhash;if(jQuery.browser.msie){var ihistory=$j("#jQuery_history")[0];var iframe=ihistory.contentWindow.document;iframe.open();iframe.close();iframe.location.hash=newhash;jQuery.historyCallback(hash);}
17
+ else if(jQuery.browser.safari){jQuery.dontCheck=true;this.historyAddHistory(hash);var fn=function(){jQuery.dontCheck=false;};window.setTimeout(fn,200);jQuery.historyCallback(hash);location.hash=newhash;}
18
+ else{jQuery.historyCallback(hash);}}});
@@ -0,0 +1,108 @@
1
+ - if defined?(@photoset) && @photoset.nil?
2
+ .page
3
+ %h3
4
+ Sorry - there was a problem communicating with Flickr
5
+ - else
6
+
7
+ %script{:charset => "utf-8", :src => "/galleria.js", :type => "text/javascript"}
8
+
9
+ :javascript
10
+ jQuery(document).ready(function(){
11
+
12
+ var ifo = {
13
+ Api : '#{Caboodle::Site.flickr_api_key}', //flickr api
14
+ Set : '#{@set_id}', //photo set
15
+ fLink : 'http://www.flickr.com/photos/#{Caboodle::Site.flickr_username}/',
16
+ Cant : 24
17
+ };
18
+
19
+ var json_url = 'http://api.flickr.com/services/rest/?format=json&jsoncallback=?&api_key='+ifo.Api+'&method=flickr.photosets.getPhotos&photoset_id='+ifo.Set+'&per_page='+ifo.Cant;
20
+ jQuery.getJSON(json_url, function(Data){
21
+ if (Data.stat == "ok"){
22
+ console.log(Data);
23
+ for (var i=0; i<Data.photoset.photo.length; i++){
24
+ var photo = Data.photoset.photo[i];
25
+ var Thum = 'http://farm'+photo['farm']+'.static.flickr.com/'+photo['server']+'/'+photo['id']+'_'+photo['secret']+'_'+'s.jpg';
26
+ var Full = 'http://farm'+photo['farm']+'.static.flickr.com/'+photo['server']+'/'+photo['id']+'_'+photo['secret']+'.jpg';
27
+ var thumb_class = '';
28
+ if(i == 0)
29
+ {
30
+ thumb_class = 'active';
31
+ }
32
+
33
+ jQuery('.gallery ul').append('<li class="'+thumb_class+'"><a href="'+Full+'"><img src="'+Thum+'" alt="'+photo['title']+'" /></a></li>');
34
+
35
+ };
36
+ }
37
+
38
+
39
+
40
+ jQuery('.gallery ul').addClass('gallery_list'); // adds new class name to maintain degradability
41
+
42
+ jQuery('ul.gallery_list').galleria({
43
+ preload: 3,
44
+ transition: 'fade',
45
+ history : true, // activates the history object for bookmarking, back-button etc.
46
+ clickNext : true, // helper for making the image clickable
47
+ insert : '#main_image', // the containing selector for our main image
48
+ onImage : function(image,caption,thumb) { // let's add some image effects for demonstration purposes
49
+ // fade in the image & caption
50
+ //image.css('display','none').fadeIn(1000);
51
+ caption.css('display','none').fadeIn(1000);
52
+
53
+ // fetch the thumbnail container
54
+ var _li = thumb.parents('li');
55
+
56
+ // fade out inactive thumbnail
57
+ _li.siblings().children('img.selected').fadeTo(500,0.3);
58
+
59
+ // fade in active thumbnail
60
+ thumb.fadeTo('fast',1).addClass('selected');
61
+
62
+ // add a title for the clickable image
63
+ image.attr('title','Next image >>');
64
+ },
65
+ onThumb : function(thumb) { // thumbnail effects goes here
66
+
67
+ // fetch the thumbnail container
68
+ var _li = thumb.parents('li');
69
+
70
+ // if thumbnail is active, fade all the way.
71
+ var _fadeTo = _li.is('.active') ? '1' : '0.3';
72
+
73
+ // fade in the thumbnail when finished loading
74
+ thumb.css({display:'none',opacity:_fadeTo}).fadeIn(1500);
75
+
76
+ // hover effects
77
+ thumb.hover(
78
+ function() { thumb.fadeTo('fast',1); },
79
+ function() { _li.not('.active').children('img').fadeTo('fast',0.3); } // don't fade out if the parent is active
80
+ )
81
+ }
82
+ });
83
+ });
84
+ });
85
+
86
+ %section.subsection
87
+
88
+ %aside.submenu
89
+ %ul
90
+ - @photosets.each do |photoset|
91
+ %li
92
+ %a{:href=>"/photography/#{photoset.id}"}= photoset.title
93
+
94
+ %section.subpage
95
+ - if @set_id
96
+ #galleria_gallery
97
+ #main_image
98
+ #gallery.gallery
99
+ %ul
100
+ %p.nav
101
+ #gallery_description
102
+ = @photoset.description
103
+ - else
104
+ %h3
105
+ Choose a gallery &raquo;
106
+
107
+
108
+
@@ -0,0 +1,44 @@
1
+
2
+
3
+ module Caboodle
4
+ class Github < Caboodle::Kit
5
+
6
+ set :views, File.join(File.dirname(__FILE__), "views")
7
+ set :public, File.join(File.dirname(__FILE__), "public")
8
+
9
+ get "/code" do
10
+ @title = "Code"
11
+ @repos = GithubAPI.repositories
12
+
13
+ @repos.sort!{|a, b| a.watchers <=> b.watchers}.reverse!
14
+ @my_repos = @repos.clone
15
+ @my_repos.delete_if{|a| a.fork }
16
+
17
+ @forked_repos = @repos.clone
18
+ @forked_repos.delete_if{|a| !a.fork }
19
+
20
+ haml :github
21
+ end
22
+
23
+ menu "Code", "/code"
24
+
25
+ required [:github_username]
26
+
27
+ defaults []
28
+ end
29
+
30
+ class GithubAPI < Weary::Base
31
+
32
+ declare "repositories" do |r|
33
+ r.url = "http://github.com/api/v2/json/repos/show/#{Caboodle::Site.github_username}"
34
+ r.via = :get
35
+ end
36
+
37
+ def self.repositories
38
+ a = Hashie::Mash.new(GithubAPI.new.repositories.perform_sleepily.parse).repositories
39
+ puts a.inspect
40
+ a
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,7 @@
1
+ %dt.repository
2
+ %h3
3
+ %a{:href=>repo.url}
4
+ = repo.name
5
+ %dd
6
+ %p
7
+ = repo.description
@@ -0,0 +1,11 @@
1
+ #github.page
2
+ %h3
3
+ My projects
4
+ %dl.repositories.me
5
+ - @my_repos.each do |repo|
6
+ = haml :_repo, :locals=>{:repo=>repo}, :layout=>false
7
+ %h3
8
+ Forked projects
9
+ %dl.repositories.forked
10
+ - @forked_repos.each do |repo|
11
+ = haml :_repo, :locals=>{:repo=>repo}, :layout=>false
@@ -0,0 +1,18 @@
1
+ module Caboodle
2
+
3
+ class Identity
4
+
5
+ end
6
+
7
+ class IdentityApp < Caboodle::Kit
8
+
9
+ set :views, File.join(File.dirname(__FILE__), "views")
10
+
11
+ get "/me" do
12
+ @title = "About me"
13
+ haml :me, :locals=>{:identity=>Identity.new()}, :layout=>true
14
+ end
15
+
16
+ menu "Me", "/me"
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ .page
2
+ %p
3
+ Some info about me
4
+
5
+ / %p
6
+ / = "#{identity.first_name} is #{identity.descriptor}, currently working as #{identity.main_job} in #{identity.city_of_work}."
7
+ /
8
+ / %p
9
+ / In the past #{identity.first_name} #{identity.past_identities.first}. And before that #{identity.him_or_her} #{identity.past_identities[1]}.
10
+ /
11
+ / %p
12
+ / Three things you might find interesting about #{identity.him_or_her}:
13
+ /
14
+ / %ul#things_of_interest
15
+ / - identity.things_of_interest[0..2].each do |orly|
16
+ / %li.orly
17
+ / = orly
18
+ /
19
+ / %p
20
+ / = "In #{identity.his_or_hers} spare time #{identity.he_or_she}"
21
+ / = succeed(".") do
22
+ / = identity.spare_time_activities[0..4].join(",")
@@ -0,0 +1,6 @@
1
+ module Caboodle
2
+ class LazyLoad < Caboodle::Kit
3
+ set :public, File.join(File.dirname(__FILE__), "public")
4
+ javascripts ["jquery.lazyload.mini.js","lazyload.js"]
5
+ end
6
+ end
@@ -0,0 +1,12 @@
1
+
2
+ (function($){$.fn.lazyload=function(options){var settings={threshold:0,failurelimit:0,event:"scroll",effect:"show",container:window};if(options){$.extend(settings,options);}
3
+ var elements=this;if("scroll"==settings.event){$(settings.container).bind("scroll",function(event){var counter=0;elements.each(function(){if($.abovethetop(this,settings)||$.leftofbegin(this,settings)){}else if(!$.belowthefold(this,settings)&&!$.rightoffold(this,settings)){$(this).trigger("appear");}else{if(counter++>settings.failurelimit){return false;}}});var temp=$.grep(elements,function(element){return!element.loaded;});elements=$(temp);});}
4
+ this.each(function(){var self=this;if(undefined==$(self).attr("original")){$(self).attr("original",$(self).attr("src"));}
5
+ if("scroll"!=settings.event||undefined==$(self).attr("src")||settings.placeholder==$(self).attr("src")||($.abovethetop(self,settings)||$.leftofbegin(self,settings)||$.belowthefold(self,settings)||$.rightoffold(self,settings))){if(settings.placeholder){$(self).attr("src",settings.placeholder);}else{$(self).removeAttr("src");}
6
+ self.loaded=false;}else{self.loaded=true;}
7
+ $(self).one("appear",function(){if(!this.loaded){$("<img />").bind("load",function(){$(self).hide().attr("src",$(self).attr("original"))
8
+ [settings.effect](settings.effectspeed);self.loaded=true;}).attr("src",$(self).attr("original"));};});if("scroll"!=settings.event){$(self).bind(settings.event,function(event){if(!self.loaded){$(self).trigger("appear");}});}});$(settings.container).trigger(settings.event);return this;};$.belowthefold=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).height()+$(window).scrollTop();}else{var fold=$(settings.container).offset().top+$(settings.container).height();}
9
+ return fold<=$(element).offset().top-settings.threshold;};$.rightoffold=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).width()+$(window).scrollLeft();}else{var fold=$(settings.container).offset().left+$(settings.container).width();}
10
+ return fold<=$(element).offset().left-settings.threshold;};$.abovethetop=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).scrollTop();}else{var fold=$(settings.container).offset().top;}
11
+ return fold>=$(element).offset().top+settings.threshold+$(element).height();};$.leftofbegin=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).scrollLeft();}else{var fold=$(settings.container).offset().left;}
12
+ return fold>=$(element).offset().left+settings.threshold+$(element).width();};$.extend($.expr[':'],{"below-the-fold":"$.belowthefold(a, {threshold : 0, container: window})","above-the-fold":"!$.belowthefold(a, {threshold : 0, container: window})","right-of-fold":"$.rightoffold(a, {threshold : 0, container: window})","left-of-fold":"!$.rightoffold(a, {threshold : 0, container: window})"});})(jQuery);
@@ -0,0 +1,3 @@
1
+ $("img").lazyload({
2
+ effect : "fadeIn"
3
+ });
@@ -0,0 +1,33 @@
1
+ module Caboodle
2
+
3
+ class LinkedinAPI < Weary::Base
4
+ attr_accessor :data
5
+ attr_accessor :full
6
+
7
+ def initialize
8
+ @full = Caboodle.scrape(Caboodle::Site.linkedin_profile_url)
9
+ @full.css('.showhide-link').each{|a| @full.delete(a)}
10
+ @full = @full.css("#main").to_html.gsub("#{Caboodle::Site.linkedin_full_name}’s ","")
11
+ end
12
+ def method_missing(method_name)
13
+ @data.send(method_name.to_sym)
14
+ end
15
+ end
16
+
17
+ class Linkedin < Caboodle::Kit
18
+
19
+ set :views, File.join(File.dirname(__FILE__), "views")
20
+
21
+ get "/cv" do
22
+ @title = "Curriculum Vitae"
23
+
24
+ @linkedin = LinkedinAPI.new #rescue nil
25
+ #@linkedin.inspect
26
+ haml :cv
27
+ end
28
+
29
+ menu "CV", "/cv"
30
+
31
+ required [:linkedin_full_name, :linkedin_profile_url]
32
+ end
33
+ end
@@ -0,0 +1,6 @@
1
+ .page.linkedin
2
+ - if @linkedin
3
+ = @linkedin.full
4
+ - else
5
+ %h3
6
+ Sorry - there's a problem talking to Linkedin.com