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,220 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
+ <html xml:lang="en-us" xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <title>Stef Lewandowski (stef) on OnePage - interactive contact cards</title>
6
+
7
+ <link href="http://static.myonepage.com/css/onepage-1279966875.css" media="screen" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="http://static.myonepage.com/js/onepage-1277994110.js"></script>
8
+ <style type="text/css">
9
+ body { background-color: #61B4EF; } </style>
10
+ <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
11
+ <script type="text/javascript" src="/js/misc/more.js"></script>
12
+ <script type="text/javascript" src="/js/misc/email.v3.js"></script>
13
+ <script type="text/javascript" src="/js/misc/cardflip.v2.js"></script>
14
+ <script type="text/javascript" src="/js/misc/embed.js"></script>
15
+ <meta name="description" content="Create something every day." />
16
+ <meta name="keywords" content="OnePage, business card, social networks, card, stream, interactive, contact card, real-time" />
17
+ <link rel="icon" type="image/x-icon" href="/favicon.ico" />
18
+ <meta name="google-site-verification" content="NAsf4ohBOQ7O0hYPk__bpNxug11uA7luGiq6uk5dx-I" />
19
+ <script type="text/javascript">
20
+ //<![CDATA[
21
+ var _gaq = _gaq || [];
22
+ _gaq.push(['_setAccount', 'UA-10039160-2']);
23
+ _gaq.push(['_trackPageview']);
24
+ (function() {
25
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
26
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
27
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
28
+ })();
29
+ //]]>
30
+ </script>
31
+ </head>
32
+ <body>
33
+
34
+ <script type="text/javascript">
35
+ //<![CDATA[
36
+ var _kmq = _kmq || [];
37
+ (function(){function _kms(u,d){if(navigator.appName.indexOf("Microsoft")==0 && d)document.write("<scr"+"ipt defer='defer' async='true' src='"+u+"'></scr"+"ipt>");else{var s=document.createElement('script');s.type='text/javascript';s.async=true;s.src=u;(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(s);}}_kms('https://i.kissmetrics.com/i.js');_kms('http'+('https:'==document.location.protocol ? 's://s3.amazonaws.com/' : '://')+'scripts.kissmetrics.com/c94de5e9d21ab6ab8c6f9d4bd466739ab67f0645.1.js',1);})();
38
+ //]]>
39
+ </script>
40
+
41
+ <div id="container">
42
+ <div id="feedback"><a href="http://onepage.uservoice.com" title="Give us feedback using UserVoice">Feedback</a></div>
43
+ <div id="above-top-bar">
44
+ <div id="retweet_button">
45
+ <script type="text/javascript">
46
+ tweetmeme_style = 'compact';
47
+ tweetmeme_source = 'myonepage';
48
+ </script>
49
+ <script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
50
+ </div>
51
+ <div id="facebook_like"><iframe src="http://www.facebook.com/kits/like.php?href=http://myonepage.com/stef&layout=button_count&amp;show-faces=true&amp;width=200&amp;action=like&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width: 85px; height: 20px;"></iframe></div>
52
+ </div>
53
+ <div id="top-bar" class="roundedgradientshadow">
54
+ <h1 id="logo"><a href="/"><img src="http://static.myonepage.com/images/onepage-rez.png" alt="OnePage" /></a></h1>
55
+
56
+
57
+ <!-- start login bar -->
58
+
59
+ <div id="logged-in-bar">
60
+ <ul>
61
+ <li><a href="/stef">My OnePage</a></li>
62
+ <li><a href="/contacts">Contacts</a></li>
63
+ <li><a href="/settings">Edit OnePage</a></li>
64
+ <li><a href="/share">Share</a></li>
65
+ <li><a href="/account">Account</a></li>
66
+ <li><a href="/logout">Log Out</a></li>
67
+ </ul>
68
+ </div>
69
+ <!-- end login bar -->
70
+
71
+ </div>
72
+ <div class="imabadperson"></div>
73
+ <!-- start card -->
74
+ <div id="card">
75
+ <p id="edit-bar"><a id="edit-card" class="share right" href="/settings" title="Edit your OnePage"><img src="/images/silk-icons/pencil.png" /> Edit</a></p> <div id="card-container">
76
+ <ul id="hcard-Firstname-Lastname" class="vcard shadow">
77
+ <li class="avatar"><div id="photo"><img class="photo" src="http://static.myonepage.com/images/profiles/stef-thumb-1280252485.jpg" title="Photo of Stef Lewandowski" height="132" width="132"/></div></li>
78
+ <li class="fn limit"><strong>Stef Lewandowski</strong></li>
79
+ <li class="title limit">Chief Innovation Officer, All In Group</li>
80
+ <li class="note limit">Create something every day.</li> <li>
81
+ <ul id="details">
82
+
83
+
84
+ <li class="odd twitter">
85
+ <dl>
86
+ <dd title="Twitter">Twitter:</dd>
87
+ <dt title="stef" class="twitter"><a rel="784d6ba94b903ab5564a9bd3502b029b0aa88e83" rel="me" target="_blank" href="http://twitter.com/stef">stef</a></dt>
88
+ </dl>
89
+ </li>
90
+
91
+
92
+
93
+ <li class="website">
94
+ <dl>
95
+ <dd title="Website">Website:</dd>
96
+ <dt title="Stef Lewandowski | Create something every day" class="website"><a rel="046ca60a0b4c80ade5930c86aa2d67a4afef6233" rel="me" target="_blank" href="http://stef.io" class="url">Stef Lewandowski | Create something every day</a></dt>
97
+ </dl>
98
+ </li>
99
+
100
+
101
+
102
+ <li class="odd location">
103
+ <dl>
104
+ <dd title="Location">Location:</dd>
105
+ <dt title="London, UK" class="location locality">London, UK</dt>
106
+ </dl>
107
+ </li>
108
+
109
+
110
+
111
+ <li class="linkedin">
112
+ <dl>
113
+ <dd title="LinkedIn">LinkedIn:</dd>
114
+ <dt title="Stef Lewandowski" class="linkedin"><a rel="694e2380cb917dc817c26156f6496611e051f9ef" rel="me" target="_blank" href="http://www.linkedin.com/in/steflewandowski">Stef Lewandowski</a></dt>
115
+ </dl>
116
+ </li>
117
+
118
+
119
+
120
+ <li class="odd email">
121
+ <dl>
122
+ <dd title="Email">Email:</dd>
123
+ <dt title="Click to email Stef Lewandowski" class="email"><a rel="dc9b9d092c205be21ba35867cda6bb209a91825c" rel="me" target="_blank" href="/stef/email/dc9b9d092c205be21ba35867cda6bb209a91825c/1280252510">Click to email Stef Lewandowski</a></dt>
124
+ </dl>
125
+ </li>
126
+
127
+
128
+
129
+ <li class="flickr">
130
+ <dl>
131
+ <dd title="Flickr">Flickr:</dd>
132
+ <dt title="aeioux" class="flickr"><a rel="096b215e7861f3f03790f3413996a72086e437e5" rel="me" target="_blank" href="http://www.flickr.com/photos/aeioux">aeioux</a></dt>
133
+ </dl>
134
+ </li>
135
+
136
+ </ul>
137
+
138
+ </li>
139
+ <li class="imabadperson"></li>
140
+ </ul>
141
+ <div id="card-back" class="hidden">
142
+ <p></p>
143
+ </div>
144
+ </div>
145
+ <p id="card_share">
146
+ <a id="twitter_share" target="_blank" class="share" href="http://twitter.com/?status=Check out @stef's OnePage! http://myonepage.com/stef %23onepage" title="Share Stef Lewandowski's OnePage on Twitter"><img src="/images/services/twitter_16.png" /> Share</a>
147
+ <a id="facebook_share" name="fb_share" type="icon_link" class="share" href="http://www.facebook.com/sharer.php" title="Share Stef Lewandowski's OnePage on Facebook"></a><script src="http://static.ak.fbcdn.net/connect.php/js/FB.Share" type="text/javascript"></script>
148
+ <a id="random" class="share" href="/random" title="Jump to a random OnePage profile"><img src="/images/silk-icons/arrow_rotate_clockwise.png" /></a>
149
+ <a id="embed_contact" class="share right" href="/stef/embed" title="Embed Stef Lewandowski's OnePage"><img src="/images/silk-icons/tag.png" /> Embed</a>
150
+
151
+ </p>
152
+ </div>
153
+ <!-- end card -->
154
+ <div id="footer-clear"></div>
155
+ <div id="footer">
156
+ <ul class="roundedgradientshadow">
157
+ <li class="copyright">&copy; OnePage 2010</li>
158
+ <li><a href="/about" title="About OnePage">About Us</a></li>
159
+ <li><a href="/beta" title="Join the OnePage beta team">Beta Team</a></li>
160
+ <li><a href="/press" title="Press FAQs">Press FAQs</a></li>
161
+ <li><a href="http://blog.myonepage.com" title="Our blog about OnePage">Our Blog</a></li>
162
+ <li><a href="http://onepage.uservoice.com" title="Find help and support or make suggestions for OnePage">Support &amp; Suggestions</a></li>
163
+ <li><a href="/terms" title="Terms of use of OnePage">Terms</a></li>
164
+ <li><a href="/privacy" title="Your privacy on OnePage">Privacy</a></li>
165
+ </ul>
166
+ </div>
167
+ </div>
168
+ <script type="text/javascript">
169
+ //<![CDATA[
170
+ var uservoiceJsHost = ("https:" == document.location.protocol) ? "https://uservoice.com" : "http://cdn.uservoice.com";
171
+ document.write(unescape("%3Cscript src='" + uservoiceJsHost + "/javascripts/widgets/tab.js' type='text/javascript'%3E%3C/script%3E"))
172
+ var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
173
+ document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
174
+ document.write(unescape('%3Cscript id="ki_loader" src="http' + ((document.location.protocol == 'https:') ? 's' : '') + '://s3.amazonaws.com/j.kissinsights.com/1.0/load.js?site=myonepage.com" type="text/javascript"%3E%3C/script%3E'));
175
+ document.write(unescape("%3Cscript src='http://cdn.survey.io/embed/1.0/survey.js' type='text/javascript'%3E%3C/script%3E"));
176
+ var mp_protocol = (('https:' == document.location.protocol) ? 'https://' : 'http://');
177
+ document.write(unescape('%3Cscript src="' + mp_protocol + 'api.mixpanel.com/site_media/js/api/mixpanel.js" type="text/javascript"%3E%3C/script%3E'));
178
+ //]]>
179
+ </script>
180
+ <script type="text/javascript">
181
+ //<![CDATA[
182
+ UserVoice.Popin.setup({
183
+ key: 'onepage',
184
+ host: 'onepage.uservoice.com',
185
+ forum: 'general',
186
+ lang: 'en'
187
+ });
188
+ try{
189
+ var pageTracker = _gat._getTracker("UA-10039160-1");
190
+ pageTracker._setDomainName(".myonepage.com");
191
+ pageTracker._trackPageview();
192
+ } catch(err){}
193
+ KI.identify('stef');
194
+ Surveyio.init({
195
+ survey_id: "3c3fb",
196
+ token: "f6b868e63553196255abe8016123f694364a5310",
197
+ banner: {
198
+ x: "right",
199
+ y: "top",
200
+ color: "green"
201
+ }
202
+ });
203
+ Surveyio.set("username", "stef");
204
+ try{
205
+ var mpmetrics = new MixpanelLib('f147bce65eee669ec2c0d4bce26c535d');
206
+ }
207
+ catch(err){
208
+ null_fn = function () {};
209
+ var mpmetrics = {
210
+ track: null_fn,
211
+ track_funnel: null_fn,
212
+ register: null_fn,
213
+ register_once: null_fn,
214
+ register_funnel: null_fn
215
+ };
216
+ }
217
+ //]]>
218
+ </script>
219
+ </body>
220
+ </html>
@@ -0,0 +1,16 @@
1
+ module Caboodle
2
+
3
+ class Onepage < Caboodle::Kit
4
+
5
+ set :views, File.join(File.dirname(__FILE__), "views")
6
+
7
+ get "/contact" do
8
+ @title = "Contact"
9
+ haml :contact
10
+ end
11
+
12
+ menu "Contact", "/contact"
13
+
14
+ required [:onepage_username]
15
+ end
16
+ end
@@ -0,0 +1,2 @@
1
+ #onepage.page
2
+ %iframe#onepage{:scrolling=>"no",:src=>"http://myonepage.com/#{Caboodle::Site.onepage_username}/widget"}
@@ -0,0 +1,69 @@
1
+ require 'haml'
2
+
3
+ module Caboodle
4
+ Pages = []
5
+ class Page
6
+
7
+ attr_accessor :slug
8
+ attr_accessor :body
9
+ attr_accessor :file
10
+
11
+ def initialize slug
12
+ @slug = slug
13
+ end
14
+
15
+ def file
16
+ @file ||= File.new(Dir[File.join(File.dirname(__FILE__),"pages","#{@slug}.haml")].first)
17
+ end
18
+
19
+ def self.all
20
+ return Caboodle::Pages unless Caboodle::Pages.empty?
21
+ Dir[File.join(File.dirname(__FILE__),"pages","*.haml")].map do |a|
22
+ p = Page.new(a.split("/").last.gsub(".haml",""))
23
+ Caboodle::Pages << p
24
+ Caboodle::MenuItems << {:display=>p.title, :link=>p.link}
25
+ end
26
+
27
+ return Caboodle::Pages
28
+ end
29
+
30
+ def self.get slug
31
+ STDERR.puts "Get page: #{slug}"
32
+ return nil unless Caboodle::Pages.map{|a| a.slug}.include?(slug)
33
+ Page.new(slug.gsub(" ", "_"))
34
+ end
35
+
36
+ def body
37
+ @body ||= file.read
38
+ end
39
+
40
+ def to_html
41
+ Haml::Engine.new(body).render
42
+ end
43
+
44
+ def title
45
+ @slug.gsub("_","").capitalize
46
+ end
47
+
48
+ def link
49
+ "/#{slug}"
50
+ end
51
+
52
+ end
53
+
54
+ class PageApp < Caboodle::Kit
55
+
56
+ set :views, File.join(File.dirname(__FILE__), "views")
57
+
58
+ Caboodle::Site.pages = Caboodle::Page.all
59
+ Caboodle::Site.pages.each do |page|
60
+ get "/#{page.slug}" do
61
+ @page = Page.get(request.path_info.gsub("/",""))
62
+ pass if @page.blank?
63
+ @title = @page.title
64
+ haml :page, :locals => {:page => @page}
65
+ end
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,2 @@
1
+ .page
2
+ = page.to_html
@@ -0,0 +1,14 @@
1
+ module Caboodle
2
+
3
+ class PortfolioApp < Caboodle::Kit
4
+
5
+ set :views, File.join(File.dirname(__FILE__), "views")
6
+
7
+ get "/portfolio" do
8
+ @title = "Portfolio"
9
+ haml :portfolio
10
+ end
11
+
12
+ menu "Portfolio", "/portfolio"
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ - #todo - this should be a vcalendar
2
+ #portfolio.page
3
+ %dl
4
+ - if Caboodle::Site.portfolio_years.respond_to?(:sort)
5
+ - Caboodle::Site.portfolio_years.sort.reverse.each do |year,items|
6
+ %dt.year{:class=>year}
7
+ = year
8
+ %dd
9
+ %ul.portfolio_items
10
+ - if items.respond_to?(:each)
11
+ - items.each do |item|
12
+ %li.portfolio_item{:class=>item.tags}
13
+ %h3
14
+ - if item.link
15
+ %a{:href=>item.link}
16
+ = item.title
17
+ - else
18
+ = item.title
19
+ %p.role
20
+ = item.role
21
+ %p.description
22
+ = item.description
23
+
24
+
25
+ - if item.awards
26
+ %ul.awards
27
+ - item.awards.each do |award|
28
+ %li.award
29
+ = award
@@ -0,0 +1,163 @@
1
+ $: << File.expand_path(File.dirname(__FILE__))
2
+
3
+ require 'weary'
4
+ require 'nokogiri'
5
+
6
+ module Caboodle
7
+ class PosterousAPI < Weary::Base
8
+
9
+ def initialize(opts={})
10
+ Caboodle::Site.posterous_password ||= ENV["posterous_password"]
11
+ self.credentials(opts[:username] || Caboodle::Site.posterous_username, opts[:password] || Caboodle::Site.posterous_password)
12
+ sitename = opts[:sitename] || Caboodle::Site.posterous_sitename
13
+ unless defined?(Caboodle::Site.posterous_site_id)
14
+ sites = Hashie::Mash.new(getsites.perform_sleepily.parse).rsp.site
15
+
16
+ sites.each do |site|
17
+ if site.url.include?("http://#{Caboodle::Site.posterous_sitename}.posterous.com")
18
+ puts "GOT SITE ID: #{site.id}"
19
+ Caboodle::Site.posterous_site_id = site.id
20
+ end
21
+ end
22
+ end
23
+
24
+ self.defaults = {:site_id => Caboodle::Site.posterous_site_id}
25
+ end
26
+
27
+ declare "getsites" do |r|
28
+ r.url = "http://posterous.com/api/getsites"
29
+ r.via = :get
30
+ r.authenticates = true
31
+ r.headers = {'Accept' => 'application/xml'}
32
+ end
33
+
34
+ declare "all" do |r|
35
+ r.url = "http://posterous.com/api/readposts"
36
+ r.via = :get
37
+ r.with = [:site_id,:tag,:num_posts,:page]
38
+ r.requires = [:site_id]
39
+ r.authenticates = true
40
+ r.headers = {'Accept' => 'application/xml'}
41
+ end
42
+
43
+ end
44
+
45
+ class Post
46
+
47
+ attr_accessor :attributes
48
+
49
+ def initialize(res)
50
+ @attributes = res
51
+ end
52
+
53
+ def self.from_slug(slug)
54
+ doc = Caboodle.scrape("http://#{Caboodle::Site.posterous_sitename}.posterous.com/#{slug}")
55
+ opts = {}
56
+ opts["body"] = doc.css('div.bodytext').inner_html
57
+ opts["title"] = doc.css('title').inner_html.split(" - ").first
58
+ opts["link"] = "http://#{Caboodle::Site.posterous_sitename}.posterous.com/#{slug}"
59
+ perma = doc.css('.permalink').inner_html
60
+ STDERR.puts "Opts: #{opts.inspect}"
61
+ STDERR.puts "Perma: #{perma}"
62
+ opts["date"] = Date.parse(perma)
63
+ Post.new(opts)
64
+ end
65
+
66
+ def self.page(num)
67
+ raise "must be page 1 or more" if num.to_i < 1
68
+ Post.all(:page=>num.to_i)
69
+ end
70
+
71
+ def self.all(opts={})
72
+ r = []
73
+ STDERR.puts "All posts for: #{opts.inspect}"
74
+ p = PosterousAPI.new
75
+ opts[:site_id] = Caboodle::Site.posterous_site_id
76
+ rsp = p.all(opts).perform_sleepily.parse["rsp"]
77
+ rsp["post"].each{|a| r << Post.new(a)} if rsp["post"]
78
+ r
79
+ end
80
+
81
+ def self.get(slug)
82
+ Post.new(PosterousAPI.new.all().perform.parse)
83
+ end
84
+
85
+ def [] k
86
+ @attributes[k]
87
+ end
88
+
89
+ def []= l,v
90
+ @attributes = {} if @attributes.nil?
91
+ @attributes[l] = v
92
+ end
93
+
94
+ def method_missing arg
95
+ self[arg.to_s]
96
+ end
97
+
98
+ def tags
99
+ []
100
+ end
101
+
102
+ def semantic_tags
103
+ a = tags.collect{|t| "tag-#{t}"}
104
+ a << "slug-#{slug}"
105
+ a << "y#{date.year}"
106
+ a << "m#{date.month}"
107
+ a << "d#{date.day}"
108
+ end
109
+
110
+ def url
111
+ d = date
112
+ "/#{d.year}/#{d.month}/#{slug}"
113
+ end
114
+
115
+ def date
116
+ return @date if defined?(@date)
117
+ if attributes["date"].class == String
118
+ @date = Date.parse(attributes["date"])
119
+ else
120
+ @date = attributes["date"]
121
+ end
122
+ end
123
+
124
+ def full_url
125
+ Caboodle::Site.url_base.gsub(/\/$/, '') + url
126
+ end
127
+
128
+ def slug
129
+ self.link.split(".posterous.com/").last.split("/").last
130
+ end
131
+ end
132
+
133
+ class Posterous < Caboodle::Kit
134
+
135
+ set :views, File.join(File.dirname(__FILE__), "views")
136
+
137
+ get "/page/:page_number" do |page_number|
138
+ @posts = Post.page(page_number) rescue nil
139
+ not_found if @posts.class == Array && @posts.blank?
140
+ haml :posts
141
+ end
142
+
143
+ get "/:year/:month/:slug" do |year, month, slug|
144
+ STDERR.puts "Get a post"
145
+ post = Post.from_slug(slug) rescue nil
146
+ STDERR.puts "Slug not found: #{slug}"
147
+ not_found unless post
148
+ @title = post.title
149
+ haml :post, :locals => { :post => post }
150
+ end
151
+
152
+ get "/" do
153
+ @posts = Post.all(:page=>(params[:page] || 1))
154
+ haml :posts.to_sym
155
+ end
156
+
157
+ required [:posterous_sitename, :posterous_username, :posterous_password, :disqus]
158
+
159
+ stylesheets ["http://disqus.com/stylesheets/#{Caboodle::Site.disqus}/disqus.css?v=2.0"]
160
+ end
161
+ end
162
+
163
+ #Caboodle::Posterous.new #gets the ID set up
@@ -0,0 +1,29 @@
1
+ - post = locals[:post]
2
+
3
+ %article.post.hentry.publish{:class=>post.semantic_tags}
4
+ - if locals[:full]
5
+
6
+ - else
7
+ %h2.entry-title
8
+ %a{:href => post.url}= post.title
9
+
10
+ %section.entry-content
11
+ = post.body.gsub(/\n\n/m, "<br /><br />")
12
+ - if post.more?
13
+ %a{:href => post.url} Continue reading &raquo;
14
+
15
+ %aside.entry-meta
16
+ %span.meta-prep.meta-prep-author By
17
+ %span.author.vcard
18
+ %a.url.fn.n{:href => "/about", :title => "About the author"}= Caboodle::Site.author
19
+ %span.meta-sep.meta-sep-entry-date |
20
+ %span.meta-prep.meta-prep-entry-date Published:
21
+ %span.entry-date
22
+ %abbr.published{:title => post.date.strftime("%d")}= post.date.strftime("%b")
23
+ %small
24
+ %span.tag-links
25
+ = post.linked_tags
26
+ - if Caboodle::Site.disqus
27
+ |
28
+ %a{:href => "#{post.url}#disqus_thread"} comments
29
+
@@ -0,0 +1,14 @@
1
+ - if ENV["RACK_ENV"] == "development"
2
+ :javascript
3
+ var disqus_developer = true;
4
+
5
+ %div.posterous
6
+ = haml :_post, :locals=>{:post=>post, :full=>true}, :layout=>false
7
+ - if Caboodle::Site.disqus
8
+ #disqus_thread
9
+ %script{:src => "http://disqus.com/forums/#{Caboodle::Site.disqus}/embed.js", :type => "text/javascript"}
10
+ %noscript
11
+ %a{:href => "http://#{Caboodle::Site.disqus}.disqus.com/?url=ref"} View the discussion thread.
12
+ %a.dsq-brlink{:href => "http://disqus.com"}
13
+ blog comments powered by
14
+ %span.logo-disqus Disqus
@@ -0,0 +1,21 @@
1
+ %div.posterous
2
+ - if defined?(@posts) && @posts.nil?
3
+ %h3
4
+ Sorry, there's a problem communicating with Posterous.com
5
+ - else
6
+ - @posts.each do |post|
7
+ = haml :_post, :layout=>false, :locals=>{:post=>post}
8
+ #pagination
9
+ Pagination here
10
+ - if Caboodle::Site.disqus
11
+ :javascript
12
+ (function() {
13
+ var links = document.getElementsByTagName('a');
14
+ var query = '?';
15
+ for(var i = 0; i < links.length; i++) {
16
+ if(links[i].href.indexOf('#disqus_thread') >= 0) {
17
+ query += 'url' + i + '=' + encodeURIComponent(links[i].href) + '&';
18
+ }
19
+ }
20
+ document.write('<script type="text/javascript" src="http://disqus.com/forums/#{Caboodle::Site.disqus}/get_num_replies.js' + query + '"></' + 'script>');
21
+ })();
@@ -0,0 +1,31 @@
1
+ module Caboodle
2
+ class Soundcloud < Caboodle::Kit
3
+
4
+ set :views, File.join(File.dirname(__FILE__), "views")
5
+ set :public, File.join(File.dirname(__FILE__), "public")
6
+
7
+ get "/mixes" do
8
+ @title = "Mixes"
9
+ @mixes = SoundcloudAPI.sets
10
+ haml :soundcloud
11
+ end
12
+
13
+ menu "Mixes", "/mixes"
14
+
15
+ required [:soundcloud_query]
16
+ end
17
+
18
+ class SoundcloudAPI < Weary::Base
19
+
20
+ declare "sets" do |r|
21
+ r.url = "http://api.soundcloud.com/playlists?q=#{Site.soundcloud_query}"
22
+ r.via = :get
23
+ r.headers = {'Accept' => 'application/xml'}
24
+ end
25
+
26
+ def self.sets
27
+ Hashie::Mash.new(SoundcloudAPI.new.sets.perform_sleepily.parse).playlists
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ #soundcloud.page
2
+ %dl.mixes
3
+ - @mixes.each do |mix|
4
+ %dt
5
+ %h3
6
+ = mix.title
7
+ %dd
8
+ - url = "http%3A%2F%2Fsoundcloud.com%2F#{mix.user.permalink}%2Fsets%2F#{mix.permalink}"
9
+ - if Caboodle::Site.soundcloud_widget == "comments"
10
+ :plain
11
+ <object height="136" width="100%"> <param name="movie" value="http://player.soundcloud.com/player.swf?url=#{url}"></param> <param name="allowscriptaccess" value="always"></param> <embed allowscriptaccess="always" height="136" src="http://player.soundcloud.com/player.swf?url=#{url}" type="application/x-shockwave-flash" width="100%"></embed> </object>
12
+ - elsif Caboodle::Site.soundcloud_widget == "tiny"
13
+ :plain
14
+ <object height="18" width="100%"> <param name="movie" value="http://player.soundcloud.com/player.swf?url=#{url}&amp;auto_play=false&amp;player_type=tiny&amp;font=Arial&amp;color=0066cc"> <param name="allowscriptaccess" value="always"> <embed allowscriptaccess="always" height="18" src="http://player.soundcloud.com/player.swf?url=#{url}&amp;auto_play=false&amp;player_type=tiny&amp;font=Arial&amp;color=0066cc" type="application/x-shockwave-flash" width="100%"> </object>
15
+ - else Caboodle::Site.soundcloud_widget == "artwork"
16
+ :plain
17
+ <object height="200" width="200"> <param name="movie" value="http://player.soundcloud.com/player.swf?url=#{url}&amp;auto_play=false&amp;player_type=artwork&amp;color=0066cc"> <param name="allowscriptaccess" value="always"> <embed allowscriptaccess="always" height="200" src="http://player.soundcloud.com/player.swf?url=#{url}&amp;auto_play=false&amp;player_type=artwork&amp;color=0066cc" type="application/x-shockwave-flash" width="200"> </object>