Permalink
Browse files

Big update - added importing, changed settings file location. WINDOWS…

… SUPPORT BROKEN (for now)
  • Loading branch information...
1 parent 92be571 commit 4b06089961417e3bb5aafec7f9d9e90588d3d12c @jphastings committed Apr 12, 2010
Showing with 161 additions and 50 deletions.
  1. +1 −1 VERSION
  2. +0 −6 config/settings.default.yaml
  3. +0 −18 config/settings.yaml
  4. +40 −15 lib/thimblr.rb
  5. +89 −0 lib/thimblr/importer.rb
  6. +3 −3 lib/thimblr/parser.rb
  7. +21 −1 public/assets/help.js
  8. +0 −1 public/assets/main.js
  9. +3 −1 public/index.html
  10. +4 −4 views/help.erb
View
@@ -1 +1 @@
-0.6.12
+0.8.0
@@ -2,12 +2,6 @@
Tumblr:
PostsPerPage: 10
-## Settings affecting Thimblr
-# The location of your theme files
-ThemesLocation: themes
-# The location of your data files
-DataLocation: data
-
# This allows the thimblr server to open your chosen editor to edit
# the theme you're currently viewing. There is a (very small!) risk
# that this could do malicious things, so you can disable it if you
View
@@ -1,18 +0,0 @@
-## Settings affecting Tumblr
-Tumblr:
- PostsPerPage: 10
-
-## Settings affecting Thimblr
-# The location of your theme files
-ThemesLocation: themes
-# The location of your data files
-DataLocation: data
-
-# This allows the thimblr server to open your chosen editor to edit
-# the theme you're currently viewing. There is a (very small!) risk
-# that this could do malicious things, so you can disable it if you
-# like
-AllowEditing: true
-# The editor you want to use for editing your themes. Below should
-# be what you'd use if you were launching it from the command line
-Editor: mate
View
@@ -5,18 +5,20 @@
require 'pathname'
require 'launchy'
require 'thimblr/parser'
+require 'thimblr/importer'
require 'rbconfig'
+require 'fileutils'
class Thimblr::Application < Sinatra::Base
Editors = {
'textmate' => {'command' => "mate",'platform' => "mac",'name' => "TextMate"},
'bbedit' => {'command' => "bbedit",'platform' => 'mac','name' => "BBEdit"},
'textedit' => {'command' => "open -a TextEdit.app",'platform' => 'mac','name' => "TextEdit"}
}
- Locations = [
- {"dir" => "~/Library/Application Support/Thimblr/", 'name' => "Application Support", 'platform' => "mac"},
- {'dir' => "~/.thimblr/",'name' => "Home directory", 'platform' => "nix"}
- ]
+ Locations = {
+ "mac" => {"dir" => "~/Library/Application Support/Thimblr/", 'name' => "Application Support", 'platform' => "mac"},
+ "nix" => {'dir' => "~/.thimblr/",'name' => "Home directory", 'platform' => "nix"}
+ }
case RbConfig::CONFIG['target_os']
when /darwin/i
@@ -28,8 +30,8 @@ class Thimblr::Application < Sinatra::Base
end
def self.parse_config(s)
- set :themes, File.expand_path((File.directory? s['ThemesLocation']) ? s['ThemesLocation'] : "./themes")
- set :data, File.expand_path((File.directory? s['DataLocation'] || "") ? s['DataLocation'] : "")
+ set :themes, File.expand_path(File.join(Locations[Platform]['dir'],"themes"))
+ set :data, File.expand_path(File.join(Locations[Platform]['dir'],"data"))
set :allowediting, (s['AllowEditing']) ? true : false
set :editor, s['Editor'] if s['Editor']
set :tumblr, Thimblr::Parser::Defaults.merge(s['Tumblr'] || {})
@@ -40,8 +42,25 @@ def self.parse_config(s)
set :root, File.join(File.dirname(__FILE__),"..")
Dir.chdir root
set :config, File.join(root,'config')
+ set :settingsfile, File.expand_path(File.join(Locations[Platform]['dir'],'settings.yaml'))
+
+ # Generate Data & Theme directories if required
+ if not File.directory?(File.expand_path(File.join(Locations[Platform]['dir'],"themes")))
+ FileUtils.cp_r(File.join(root,'themes'),File.expand_path(Locations[Platform]['dir']))
+ end
+
+ if not File.directory?(File.expand_path(File.join(Locations[Platform]['dir'],"data")))
+ FileUtils.mkdir_p(File.expand_path(File.join(Locations[Platform]['dir'],"data")))
+ FileUtils.cp(File.join(config,'demo.yaml'),File.expand_path(File.join(Locations[Platform]['dir'],'data','demo.yml')))
+ end
+
+ begin # Try to load the settings file, if it's crap then overwrite it with the defaults
+ s.parse_config(YAML::load(open(settingsfile)))
+ rescue
+ FileUtils.cp(File.join(config,'settings.default.yaml'),settingsfile)
+ retry
+ end
- s.parse_config(YAML::load(open(File.join(config,'settings.yaml'))))
enable :sessions
set :bind, '127.0.0.1'
@@ -83,7 +102,7 @@ def get_relative(path)
end
get '/data.set' do
- if File.exists?(File.join(settings.data,"#{params['data']}.yml")) or params['data'] == 'demo'
+ if File.exists?(File.join(settings.data,"#{params['data']}.yml"))
response.set_cookie('data',params['data'])
else
halt 404, "Not found"
@@ -95,7 +114,6 @@ def get_relative(path)
Dir.glob("#{settings.data}/*.yml").collect do |datum|
data[File.basename(datum,".yml")] = Digest::MD5.hexdigest(open(datum).read)
end
- data['demo'] = Digest::MD5.hexdigest(open(File.join(settings.config,"demo.yml")).read)
data.to_json
end
@@ -124,12 +142,11 @@ def get_relative(path)
get %r{/(tumblr)?settings.set} do |tumblr|
halt 501 if tumblr == "tumblr" # TODO: Tumblr settings save
+ params['AllowEditing'] = (params['AllowEditing'] == "on")
settings.parse_config(params)
- open(File.join(settings.config,"settings.yaml"),"w") do |f|
+ open(settings.settingsfile,"w") do |f|
f.write YAML.dump({
"Tumblr" => settings.tumblr,
- "ThemesLocation" => get_relative(settings.themes),
- "DataLocation" => get_relative(settings.data),
"AllowEditing" => settings.allowediting,
"Editor" => settings.editor,
"Port" => settings.port
@@ -139,9 +156,17 @@ def get_relative(path)
"Settings saved"
end
- # TODO: Downloads feed data from a tumblr site
- get '/import' do
- halt 501, "Sorry, I haven't written this bit yet!"
+ # Downloads feed data from a tumblr site
+ get %r{/import/([a-zA-Z0-9-]+)} do |username|
+ begin
+ data = Thimblr::Import.username(username)
+ open(File.join(settings.data,"#{username}.yml"),'w') do |f|
+ f.write data
+ end
+ rescue Exception => e
+ halt 404, e.message
+ end
+ "Imported as '#{username}'"
end
before do
View
@@ -0,0 +1,89 @@
+require 'open-uri'
+require 'nokogiri'
+require 'yaml'
+require 'uri'
+
+module Thimblr
+ class Import
+ def self.username(username)
+ data = {}
+ begin
+ xml = Nokogiri::XML(open("http://#{username}.tumblr.com/api/read"))
+ rescue OpenURI::HTTPError
+ raise "Username not found"
+ end
+
+ data['Title'] = xml.search('tumblelog')[0]['title']
+ data['Description'] = xml.search('tumblelog')[0].content
+
+ data['Posts'] = []
+ xml.search('posts post').each do |xpost|
+ post = {
+ 'PostId' => xpost['id'].to_i,
+ 'Permalink' => xpost['url'],
+ 'Type' => xpost['type'].capitalize,
+ 'Timestamp' => xpost['unix-timestamp'].to_i,
+ 'Tags' => xpost.search('tag').collect{ |tag| tag.content }
+ }
+
+ post['Type'] = "Text" if post['Type'] == "Regular"
+ post['Type'] = "Chat" if post['Type'] == "Conversation"
+
+ post.store('Title', xpost.search("#{xpost['type']}-title")[0].content) rescue nil
+
+ post.store('Caption',xpost.search("#{xpost['type']}-caption")[0].content) rescue nil
+
+ post.store('LinkURL',xpost.search("#{xpost['type']}-link-url")[0].content) rescue nil
+
+ post.store('Source',xpost.search("#{xpost['type']}-source")[0].content) rescue nil
+
+ case post['Type']
+ when "Photo"
+ xpost.search('photo-url').each do |photo|
+ post["PhotoURL-#{photo['max-width']}"] = photo.content
+ end
+ when "Link"
+ begin
+ post['Name'] = xpost.search("link-text")[0].content
+ rescue
+ end
+ when "Video"
+ post['Player'] = xpost.search("video-player")[0].content
+ when "Text"
+ post['Body'] = xpost.search("regular-body")[0].content
+ end
+
+ data['Posts'].push post
+ end
+
+ # Pages
+ begin
+ xml = Nokogiri::XML(open("http://#{username}.tumblr.com/api/pages"))
+ data['Pages'] = []
+
+ xml.search('pages').children.each do |re|
+ case re.name
+ when "redirect"
+ data['Pages'].push({
+ "Label" => re['link-title'],
+ "URL" => re['redirect-to']
+ })
+ when "page"
+ data['Pages'].push({
+ "Label" => re['link-title'],
+ "URL" => URI.split(re['url'])[5],
+ "Title" => re['title'],
+ "InTheme" => (re['render-in-theme'] == "true"),
+ "Body" => re.content
+ })
+ end
+ end
+ # Do pages
+ rescue OpenURI::HTTPError
+ # No pages
+ end
+
+ YAML::dump(data)
+ end
+ end
+end
View
@@ -41,9 +41,9 @@ def initialize(data_file,theme_file = nil,settings = {})
'Pagination' => (@posts.length > @settings['PostsPerPage'].to_i),
'SubmissionsEnabled' => template['SubmissionsEnabled'],
'AskEnabled' => !@constants['AskLabel'].empty?,
- 'HasPages' => @pages.length > 0,
- 'Following' => @following.length > 0,
- 'Followed' => @followed.length > 0,
+ 'HasPages' => (@pages.length > 0 rescue false),
+ 'Following' => (@following.length > 0 rescue false),
+ 'Followed' => (@followed.length > 0 rescue false),
'More' => true
}
View
@@ -16,12 +16,32 @@ $(document).ready(function(){
e.preventDefault();
})
+ $('#import').bind('submit',function(e) {
+ $('#TumblrUser').disabled = true
+ $.ajax({
+ url:'/import/'+$('#TumblrUser').val(),
+ success: function(d) {
+ $('#TumblrUser,#importinput').effect("highlight", {color:'#00ff00'}, 1000)
+ $('#TumblrUser').val('')
+ $('#TumblrUser').disabled = false
+ },
+ error: function(d) {
+ $('#TumblrUser,#importinput').effect("highlight", {color:'#ff0000'}, 2000)
+ $('#TumblrUser').val('')
+ $('#TumblrUser').disabled = false
+ }
+ })
+ })
+
$('table.settings a.preset').bind('click',function(e) {
e.preventDefault();
$('#'+$(this).parent().attr('rel')).val(this.rel).effect("highlight", {}, 500);
})
$('#settings input').bind('change',function(e) {
- $.get($('#settings').attr('action'),$('#settings').serialize())
+ $.get($('#settings').attr('action'),$('#settings').serialize(),function(d,status) {
+ $('#saved').effect("highlight", {}, 500);
+ $('#saved em').text(d)
+ })
})
})
View
@@ -34,7 +34,6 @@ $(document).ready(function(){
});
$('#data-selector').bind('click',function(e){
- alert('argh')
if (e.target.nodeName.toLowerCase() === 'option')
$('#data-select').trigger('submit');
});
View
@@ -1,5 +1,7 @@
<html>
-
+<head>
+ <title>Thimblr - A Tumblr Theme Editor</title>
+</head>
<frameset rows="32px,*" frameborder="no" framespacing="0" border="0">
<frame src="menu" />
View
@@ -83,7 +83,7 @@ Hope you guys don't mind… -->
</tr>
</table>
</form>
- <p><em>Changes are saved automatically</em></p>
+ <p id="saved"><em>Changes are saved automatically</em></p>
</div>
</div>
<div style="background-color: rgb(192, 205, 129);" id="right_column">
@@ -94,10 +94,10 @@ Hope you guys don't mind… -->
</div>
<div class="goody_container">
<h2>Import Data</h2>
- <p>Once I've gone outside for a while I'll write a script here that will download a tumblr user's posts here. Not ready yet tho, sorry :(</p>
- <form action="/import" id="import">
+ <p>Imports posts data from a specific tumblelog, so you can test themes with real-world data!</p>
+ <form action="/import/" id="import">
<label for="TumblrUser">Tumblr Username</label>
- <div style="margin-bottom: 5px;" class="goody_data">
+ <div style="margin-bottom: 5px;" class="goody_data" id="importinput">
<input type="text" value="" name="TumblrUser" id="TumblrUser" />
</div>
</form>

0 comments on commit 4b06089

Please sign in to comment.