caboodle 0.1.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.
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