persona 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in persona.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,5 @@
1
+ == Persona
2
+
3
+ Persona is a minimal personal content manager.
4
+ In this stage it's a work in progress, without much documentation.
5
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/bin/persona ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), "..", "lib", "tasks", "persona_tasks")
3
+
4
+
5
+ def create_site(name)
6
+ p Dir.new('.').entries
7
+ end
8
+
9
+ if (ARGV.length == 2 and ARGV[0] == 'create_site')
10
+ PersonaTasks.create_site Dir.new('.'), ARGV[1]
11
+ end
12
+
@@ -0,0 +1,24 @@
1
+ require 'yaml'
2
+
3
+ class File
4
+
5
+ def content_as_string
6
+ doc_started = false
7
+ metadata, data = '', ''
8
+ self.each_line do |line|
9
+ doc_started = true if line.chop == ''
10
+ if (doc_started)
11
+ data += line
12
+ else
13
+ metadata +=line
14
+ end
15
+ end
16
+ @metadata = YAML.parse(metadata)
17
+ return data
18
+ end
19
+
20
+ def metadata(name)
21
+ @metadata[name].value
22
+ end
23
+
24
+ end
@@ -0,0 +1,13 @@
1
+ class Page
2
+
3
+ attr_reader :content, :title, :author
4
+
5
+ def initialize(name)
6
+ f = File.open("./contents/pages/#{name}.txt","r")
7
+ @content = f.content_as_string
8
+ @title = f.metadata 'title'
9
+ @author = f.metadata 'author'
10
+ f.close
11
+ end
12
+
13
+ end
@@ -0,0 +1,38 @@
1
+ class Post
2
+
3
+ attr_reader :content, :title, :author, :url, :date, :excerpt, :is_excerpt
4
+
5
+ def initialize(file_name)
6
+ f = File.open("./contents/posts/#{file_name}","r")
7
+ @content = f.content_as_string
8
+ @title = f.metadata 'title'
9
+ @author = f.metadata 'author'
10
+ @date = Date.strptime(f.metadata('date'), '%Y/%m/%d')
11
+ @excerpt = create_excerpt(@content)
12
+
13
+ splits = /(\d{4}-\d{2}-\d{2})-([^\/]*)\.txt$/.match file_name
14
+ if splits
15
+ @url = splits[1].gsub(/[-]/, "/") + "/" + splits[2] + "/"
16
+ end
17
+
18
+ f.close
19
+ end
20
+
21
+ def self.from_url(y,m,d,name)
22
+ Post.new "#{y}-#{m}-#{d}-#{name}.txt"
23
+ end
24
+
25
+ private
26
+
27
+ MORE_TAG = '<!--more-->'
28
+
29
+ def create_excerpt(content)
30
+ if content.include? MORE_TAG
31
+ @is_excerpt = true
32
+ content.partition(MORE_TAG)[0] + "(... continued ...) "
33
+ else
34
+ content
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,3 @@
1
+ module Persona
2
+ VERSION = "0.0.1"
3
+ end
data/lib/persona.rb ADDED
@@ -0,0 +1,78 @@
1
+ require 'rubygems'
2
+ require 'erb'
3
+ require 'bundler'
4
+ require 'sinatra'
5
+ require 'builder'
6
+
7
+ require File.join(File.dirname(__FILE__), './persona', 'file')
8
+ autoload :Post, 'persona/post'
9
+ autoload :Page, 'persona/page'
10
+
11
+
12
+ #ROUTES
13
+
14
+ get '/' do
15
+ @posts = load_posts
16
+ erb :index
17
+ end
18
+
19
+ get '/feed/' do
20
+ builder do |xml|
21
+ xml.instruct! :xml, :version => '1.0'
22
+ xml.rss :version => "2.0" do
23
+ xml.channel do
24
+ xml.title ($config['site']['title'])
25
+ xml.description ($config['site']['description'])
26
+ xml.link ($config['site']['url'])
27
+
28
+ load_posts.first(10).each do |post|
29
+ xml.item do
30
+ xml.title post.title
31
+ xml.link(($config['site']['url'])+"/"+post.url)
32
+ xml.description post.content
33
+ xml.pubDate post.date.strftime("%a, %d %b %Y %H:%M:%S %z")
34
+ xml.guid(($config['site']['url'])+"/"+post.url)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ get '/feed' do
43
+ redirect '/feed/'
44
+ end
45
+
46
+ get '/:y/:m/:d/:name/' do
47
+ @page = Post.from_url params[:y], params[:m], params[:d], params[:name]
48
+ erb :post
49
+ end
50
+
51
+ get '/:y/:m/:d/:name' do #wrong link, but WP supports it
52
+ redirect "/#{params[:y]}/#{params[:m]}/#{params[:d]}/#{params[:name]}/"
53
+ end
54
+
55
+ get '/pages/:name' do
56
+ @page = Page.new params[:name]
57
+ erb :page
58
+ end
59
+
60
+ error do
61
+ erb :not_found
62
+ end
63
+
64
+ not_found do
65
+ erb :not_found
66
+ end
67
+
68
+
69
+ def load_posts
70
+ posts = Dir.entries('./contents/posts').sort.reverse.reject do |it|
71
+ not it.end_with? '.txt'
72
+ end
73
+
74
+ posts.map do |it|
75
+ Post.new it
76
+ end
77
+ end
78
+
@@ -0,0 +1,10 @@
1
+ require 'fileutils'
2
+
3
+ class PersonaTasks
4
+
5
+ def self.create_site(base_dir, site_name)
6
+ FileUtils.cp_r(File.join(File.dirname(__FILE__), "..", "..", "template"), site_name)
7
+ end
8
+
9
+
10
+ end
data/persona.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "persona/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "persona"
7
+ s.version = Persona::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Filippo Diotalevi"]
10
+ s.email = ["filippo.diotalevi@gmail.com"]
11
+ s.homepage = "https://github.com/fdiotalevi/persona-cms"
12
+ s.summary = %q{Minimal personal content manager}
13
+ s.description = %q{A minimal personal content manager}
14
+
15
+ s.add_dependency('sinatra', '>= 1.1.0')
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
data/template/Gemfile ADDED
@@ -0,0 +1 @@
1
+ require 'persona'
@@ -0,0 +1,4 @@
1
+ site:
2
+ title: Filippo Diotalevi
3
+ description: Startups, Technology and News
4
+ url: 'http://diotalevi.com'
@@ -0,0 +1,9 @@
1
+ require 'sinatra'
2
+ require 'yaml'
3
+ require 'persona'
4
+
5
+ set :environment, :production
6
+ disable :run
7
+
8
+ $config = YAML.load_file('./config/persona.yaml')
9
+ run Sinatra::Application
@@ -0,0 +1,5 @@
1
+ title: about page
2
+ author: John Doe
3
+ date: 1900/01/01
4
+
5
+ <h1>About John</h1>
@@ -0,0 +1,5 @@
1
+ title: hello world
2
+ author: John Doe
3
+ date: 1900/01/01
4
+
5
+ <p>Hello world</p>
@@ -0,0 +1,108 @@
1
+ html { margin: 20px }
2
+ body {
3
+ margin: 0 auto;
4
+ font-family: Georgia, 'Baskerville', Times, serif;
5
+ font-size: 18px;
6
+ line-height: 27px;
7
+ padding: 15px;
8
+ width: 780px;
9
+
10
+ }
11
+ header, footer, section, article {
12
+ display: block;
13
+ }
14
+
15
+ body > header {
16
+ height: 30px;
17
+ font-size: 16px;
18
+ vertical-align: top;
19
+ margin-bottom: 60px;
20
+ }
21
+
22
+ #content {
23
+ }
24
+ #by {
25
+ font-style: italic;
26
+ margin-right: 5px;
27
+ font-size: 28px;
28
+ }
29
+ #caption {
30
+ position: absolute;
31
+ font-size: 24px;
32
+ margin: -135px 0 0 70px;
33
+ }
34
+ #path {
35
+ color: #b53131;
36
+ }
37
+ .date {
38
+ font-style: italic;
39
+ line-height: 43px;
40
+ }
41
+ a {
42
+ color: #b83000;
43
+ }
44
+ h1 a {
45
+ color: black;
46
+ text-decoration: none;
47
+ }
48
+ a:hover {
49
+ text-decoration: underline;
50
+ }
51
+
52
+ .post header {
53
+ margin-bottom: 10px;
54
+ }
55
+ .post .body p:first-child {
56
+ margin-top: 0;
57
+ }
58
+ .post .body p:last-child {
59
+ margin-bottom: 0;
60
+ }
61
+ .post {
62
+ margin-bottom: 30px;
63
+ }
64
+ .post:last-child {
65
+ margin-bottom: 10px;
66
+ }
67
+ .post p {
68
+ margin: 10px 0;
69
+ }
70
+ .post .more {
71
+ margin-top: -10px;
72
+ margin-right: 30px;
73
+ font-style: italic;
74
+ text-align: right;
75
+ }
76
+ .more a {
77
+ text-decoration: none;
78
+ }
79
+ .more a:hover { text-decoration: underline }
80
+
81
+ .spaced {
82
+ margin-bottom: 50px;
83
+ }
84
+
85
+ h1, h2, h3, h4 {
86
+ margin: 0;
87
+ font-weight: normal;
88
+ }
89
+ ul, li {
90
+ list-style-type: none;
91
+ }
92
+ code {
93
+ font-family: 'Anonymous Pro', 'Bitstream Vera Sans', 'Monaco', Courier, mono;
94
+ }
95
+ pre {
96
+ padding: 20px;
97
+ }
98
+ blockquote {
99
+ font-style: italic;
100
+ }
101
+
102
+ body > footer {
103
+ text-align: left;
104
+ margin-left: 10px;
105
+ font-style: italic;
106
+ font-size: 18px;
107
+ color: #888;
108
+ }
@@ -0,0 +1,26 @@
1
+
2
+ <% @posts.first(3).each do |page| %>
3
+
4
+ <div class="spaced">
5
+ <h1><a href="<%= page.url %>"><%= page.title %></a></h1>
6
+ <div class="date">published on <%= page.date.strftime('%b %d, %Y') %> by <%= page.author %>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
7
+
8
+ <%= page.excerpt %>
9
+
10
+ <% if page.is_excerpt %>
11
+ <div class="date"><a href="<%= page.url %>">Read the complete post</a></div>
12
+ <% end %>
13
+ </div>
14
+
15
+ <% end %>
16
+
17
+ <h2>Older posts</h2>
18
+ <ul>
19
+ <% if @posts.size > 3%>
20
+ <% @posts[3..-1].each do |post| %>
21
+ <li>
22
+ <a href="<%= post.url %>"><%= post.title %></a>, published on <%= post.date.strftime('%b %d, %Y') %>
23
+ </li>
24
+ <%end%>
25
+ <%end%>
26
+ </ul>
@@ -0,0 +1,41 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <link rel="stylesheet" type="text/css" href="/css/main.css">
5
+ <link rel="alternate" type="application/atom+xml" title="feed" href="/feed/" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
7
+ <title>Filippo Diotalevi</title>
8
+ <meta name="keywords" content="startup,technology,java,ruby,rails,osgi">
9
+ <meta name="author" content="Filippo Diotalevi">
10
+
11
+ <script type="text/javascript">
12
+
13
+ var _gaq = _gaq || [];
14
+ _gaq.push(['_setAccount', 'UA-398358-5']);
15
+ _gaq.push(['_trackPageview']);
16
+
17
+ (function() {
18
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
19
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
20
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
21
+ })();
22
+
23
+ </script>
24
+
25
+
26
+ </head>
27
+ <body>
28
+ <header>
29
+ <a href='/'>Home</a> | <a href='/pages/about'>About</a>
30
+ </header>
31
+
32
+ <section>
33
+ <%= yield %>
34
+ </section>
35
+ <footer>
36
+ powered by Persona (unreleased yet), the minimal personal content manager
37
+ </footer>
38
+ </body>
39
+ </html>
40
+
41
+
@@ -0,0 +1,10 @@
1
+ <h1>Sorry, something went wrong</h1>
2
+ <p>
3
+ The page you request doesn't exist or couldn't be rendered.
4
+ <br/><br/>
5
+ </p>
6
+
7
+ <p>
8
+ <img src="http://dl.dropbox.com/u/1964762/diotalevi.com/images/404.jpg"/>
9
+
10
+ </p>
@@ -0,0 +1,4 @@
1
+ <h1><%= @page.title %></h1>
2
+ <div class="date">by <%= @page.author %></div>
3
+
4
+ <%= @page.content %>
@@ -0,0 +1,4 @@
1
+ <h1><%= @page.title %></h1>
2
+ <div class="date">published on <%= @page.date.strftime('%b %d, %Y') %> by <%= @page.author %>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
3
+
4
+ <%= @page.content %>
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: persona
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Filippo Diotalevi
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-26 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: sinatra
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 1
31
+ - 0
32
+ version: 1.1.0
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: A minimal personal content manager
36
+ email:
37
+ - filippo.diotalevi@gmail.com
38
+ executables:
39
+ - persona
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - .gitignore
46
+ - Gemfile
47
+ - README.rdoc
48
+ - Rakefile
49
+ - bin/persona
50
+ - lib/persona.rb
51
+ - lib/persona/file.rb
52
+ - lib/persona/page.rb
53
+ - lib/persona/post.rb
54
+ - lib/persona/version.rb
55
+ - lib/tasks/persona_tasks.rb
56
+ - persona.gemspec
57
+ - template/Gemfile
58
+ - template/config.ru
59
+ - template/config/persona.yaml
60
+ - template/contents/pages/about.txt
61
+ - template/contents/posts/1900-01-01-hello-world.txt
62
+ - template/public/css/main.css
63
+ - template/views/index.erb
64
+ - template/views/layout.erb
65
+ - template/views/not_found.erb
66
+ - template/views/page.erb
67
+ - template/views/post.erb
68
+ has_rdoc: true
69
+ homepage: https://github.com/fdiotalevi/persona-cms
70
+ licenses: []
71
+
72
+ post_install_message:
73
+ rdoc_options: []
74
+
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ requirements: []
94
+
95
+ rubyforge_project:
96
+ rubygems_version: 1.3.7
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Minimal personal content manager
100
+ test_files: []
101
+