lifelog 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ LifeLog
2
+ =======
3
+
4
+ Install
5
+ -------
6
+
7
+ Do not install :-) or you may lose your data.
8
+ This is early alpha release.
9
+
10
+ If you're brave enough, try:
11
+
12
+ $ sudo gem install ramaze datamapper do_sqlite3
13
+ $ sudo gem install yhara-lifelog
14
+
15
+ How to use
16
+ ----------
17
+ $ lifelog \[options]
18
+
19
+ options:
20
+
21
+ * --config PATH : from where configuration is loaded
22
+ (default: ~/.lifelog.rb)
23
+ * --db PATH : where sqlite3 database is put
24
+ * --port N : port of server
25
+ * --version : show version
26
+ * --help : show information of options
27
+ * --from-001 : if you are using VERSION=0.0.1,
28
+ use this option for first time
29
+
30
+ then open [http://localhost:7012/](http://localhost:7012/)
31
+ in your browser.
32
+
33
+ Config file
34
+ -----------
35
+
36
+ Config file is put in ~/.lifelog.rb by default
37
+ (you can specify its path by --config option).
38
+
39
+ It's just a Ruby script file, so you can write
40
+ any code to change behavior of application.
41
+
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ begin
2
+ require 'jeweler'
3
+ rescue LoadError
4
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
5
+ end
6
+
7
+ Jeweler::Tasks.new do |gemspec|
8
+ gemspec.name = "lifelog"
9
+ gemspec.summary = "A lifelogging tool written in Ramaze"
10
+ gemspec.email = "yutaka.hara/at/gmail.com"
11
+ gemspec.homepage = "http://github.com/yhara/lifelog"
12
+ gemspec.description = gemspec.summary
13
+ gemspec.authors = ["Yutaka HARA"]
14
+ gemspec.add_dependency('ramaze', '= 2009.10')
15
+ gemspec.add_dependency('do_sqlite3', '= 0.10.0')
16
+ gemspec.add_dependency('dm-core', '= 0.10.1')
17
+ gemspec.add_dependency('dm-validations', '= 0.10.1')
18
+ gemspec.add_dependency('dm-aggregations', '= 0.10.1')
19
+ end
20
+
21
+ desc "install current source as gem"
22
+ task :dogfood => [:gemspec, :build] do
23
+ sh "sudo gem install pkg/lifelog-#{File.read("VERSION").chomp}.gem"
24
+ end
25
+
26
+ desc "uninstall temporary gem and install from github"
27
+ task :nodogfood do
28
+ sh "sudo gem uninstall lifelog"
29
+ sh "sudo gem install yhara-lifelog"
30
+ end
31
+
32
+ desc "check for gem to be built"
33
+ task :stalk do
34
+ sh "gemstalk yhara lifelog"
35
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,6 @@
1
+ class Controller < Ramaze::Controller
2
+ layout 'default'
3
+ engine :Etanni
4
+ end
5
+
6
+ require 'controller/main.rb'
@@ -0,0 +1,43 @@
1
+ class Main < Controller
2
+ map '/'
3
+ helper :paginate
4
+
5
+ trait :paginate => { :limit => 100, :var => "page" }
6
+
7
+ def index
8
+ @pager = paginate(Post.all(:order => [:posted_at.desc]))
9
+ end
10
+
11
+ def say
12
+ redirect_referer unless request.post?
13
+
14
+ post = Post.create({
15
+ :posted_at => Time.now,
16
+ :message => request.params["message"],
17
+ })
18
+ raise "failed to save post" if post.id.nil?
19
+
20
+ redirect '/'
21
+ end
22
+
23
+ def search(type, value)
24
+ case type
25
+ when "tag"
26
+ @pager = paginate(Post.all({
27
+ "taggings.tag_id" => Tag.first(:name => value).id,
28
+ :order => [:posted_at.desc]
29
+ }))
30
+ render_view :index
31
+ else
32
+ raise "unknown search type: #{type}"
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def format_message(msg)
39
+ msg.gsub(/#(\S+)/){
40
+ self.anchor("##{$1}", :search, :tag, $1)
41
+ }
42
+ end
43
+ end
@@ -0,0 +1,20 @@
1
+ <html>
2
+ <head>
3
+ <meta http-equiv="Content-Type",
4
+ content="text/html; charset=utf-8"/>
5
+ <title>LifeLog</title>
6
+ <!--<script type="text/javascript" src="/js/jquery.js"></script>
7
+ <style type='text/css'></style>-->
8
+ </head>
9
+ <body>
10
+ <div id="main">
11
+ <h1>
12
+ <a href="/">LifeLog</a>
13
+ </h1>
14
+ <div>
15
+ #{@content}
16
+ </div>
17
+ </div>
18
+ </body>
19
+ </html>
20
+
data/lifelog.gemspec ADDED
@@ -0,0 +1,71 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{lifelog}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Yutaka HARA"]
12
+ s.date = %q{2009-10-03}
13
+ s.description = %q{A lifelogging tool written in Ramaze}
14
+ s.email = %q{yutaka.hara/at/gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ "README.md",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "controller/init.rb",
23
+ "controller/main.rb",
24
+ "layout/default.xhtml",
25
+ "lifelog.gemspec",
26
+ "main.rb",
27
+ "model/init.rb",
28
+ "model/migrations.rb",
29
+ "model/post.rb",
30
+ "model/tag.rb",
31
+ "spec/helper.rb",
32
+ "spec/main.rb",
33
+ "spec/models.rb",
34
+ "view/index.xhtml"
35
+ ]
36
+ s.homepage = %q{http://github.com/yhara/lifelog}
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.5}
40
+ s.summary = %q{A lifelogging tool written in Ramaze}
41
+ s.test_files = [
42
+ "spec/helper.rb",
43
+ "spec/main.rb",
44
+ "spec/models.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<ramaze>, ["= 2009.10"])
53
+ s.add_runtime_dependency(%q<do_sqlite3>, ["= 0.10.0"])
54
+ s.add_runtime_dependency(%q<dm-core>, ["= 0.10.1"])
55
+ s.add_runtime_dependency(%q<dm-validations>, ["= 0.10.1"])
56
+ s.add_runtime_dependency(%q<dm-aggregations>, ["= 0.10.1"])
57
+ else
58
+ s.add_dependency(%q<ramaze>, ["= 2009.10"])
59
+ s.add_dependency(%q<do_sqlite3>, ["= 0.10.0"])
60
+ s.add_dependency(%q<dm-core>, ["= 0.10.1"])
61
+ s.add_dependency(%q<dm-validations>, ["= 0.10.1"])
62
+ s.add_dependency(%q<dm-aggregations>, ["= 0.10.1"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<ramaze>, ["= 2009.10"])
66
+ s.add_dependency(%q<do_sqlite3>, ["= 0.10.0"])
67
+ s.add_dependency(%q<dm-core>, ["= 0.10.1"])
68
+ s.add_dependency(%q<dm-validations>, ["= 0.10.1"])
69
+ s.add_dependency(%q<dm-aggregations>, ["= 0.10.1"])
70
+ end
71
+ end
data/main.rb ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'rubygems'
4
+ require 'ruby-station'; RubyStation.parse_argv
5
+ require 'ramaze'
6
+
7
+ $LOAD_PATH.unshift __DIR__("./")
8
+ require 'controller/init.rb'
9
+ require 'model/init.rb'
10
+
11
+ #module LifeLog
12
+ # VERSION = File.read(__DIR__("./VERSION"))
13
+ #end
14
+
15
+ Ramaze.start :port => RubyStation.port,
16
+ :root => __DIR__('./')
data/model/init.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'dm-core'
2
+ require 'dm-validations'
3
+ require 'dm-aggregates' # needed for #count in spec
4
+ db_path = RubyStation.data_path("lifelog.db")
5
+ DataMapper.setup(:default, "sqlite3://#{db_path}")
6
+
7
+ require __DIR__('./post.rb')
8
+ require __DIR__('./tag.rb')
9
+ require __DIR__('./migrations.rb')
10
+
11
+ #
12
+ # ramaze paginate for datamapper
13
+ #
14
+ require 'ramaze/helper/paginate'
15
+ class DataMapper::Collection
16
+ def paginate(page, limit)
17
+ DMCollectionPager.new(self, page, limit)
18
+ end
19
+
20
+ class DMCollectionPager < Ramaze::Helper::Paginate::Paginator::ArrayPager
21
+ def each(&block)
22
+ from = ((@page - 1) * @limit)
23
+ from = 0 if from < 0
24
+ to = from + @limit
25
+
26
+ a = @array[from...to] || []
27
+ a.each(&block)
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ # Note: decided not use migraion,
2
+ # until first beta release.
3
+ DataMapper.auto_upgrade!
data/model/post.rb ADDED
@@ -0,0 +1,57 @@
1
+ #require 'dm-timestamps'
2
+
3
+ class Post
4
+ include DataMapper::Resource
5
+
6
+ REXP_TAG = /#(\S+)/
7
+
8
+ property :id, Serial
9
+
10
+ property :posted_at, DateTime
11
+ validates_present :posted_at
12
+
13
+ property :message, String, :length => (1..420)
14
+
15
+ has n, :taggings
16
+ has n, :tags, :through => :taggings, :mutable => true
17
+
18
+ before :save, :create_tags
19
+ after :save, :add_tags
20
+
21
+ def time_str
22
+ self.posted_at.strftime("%Y-%m-%d %H:%M:%S")
23
+ end
24
+
25
+ def create_tags
26
+ if includes_tag?
27
+ scrape_tags.each do |tag_name|
28
+ if Tag.first(:name => tag_name).nil?
29
+ tag = Tag.create(:name => tag_name)
30
+ raise "failed to save tag" if tag.id.nil?
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def add_tags
37
+ if includes_tag?
38
+ scrape_tags.each do |tag_name|
39
+ tag = Tag.first(:name => tag_name)
40
+ raise "<BUG> tag not found" if tag.nil?
41
+
42
+ tagging = Tagging.create(:post => self, :tag => tag)
43
+ raise "failed to save tagging" if tagging.id.nil?
44
+ end
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def includes_tag?
51
+ REXP_TAG =~ self.message
52
+ end
53
+
54
+ def scrape_tags
55
+ self.message.scan(REXP_TAG).flatten
56
+ end
57
+ end
data/model/tag.rb ADDED
@@ -0,0 +1,29 @@
1
+ class Tag
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+
6
+ property :name, String, :length => (1..100)
7
+ validates_is_unique :name
8
+
9
+ has n, :taggings
10
+ has n, :post, :through => :taggings, :mutable => true
11
+ end
12
+
13
+ class Tagging
14
+ include DataMapper::Resource
15
+
16
+ property :id, Serial
17
+
18
+ belongs_to :post
19
+ belongs_to :tag
20
+
21
+ validates_with_block do
22
+ if Tagging.first(:post_id => post_id, :tag_id => tag_id)
23
+ [false, "Tagging for (#{post_id}, #{tag_id}) already exists"]
24
+ else
25
+ true
26
+ end
27
+ end
28
+
29
+ end
data/spec/helper.rb ADDED
@@ -0,0 +1 @@
1
+ require 'ramaze/spec/bacon'
data/spec/main.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'spec/helper.rb'
2
+ ARGV.concat ["--db", "test.db"]
3
+ load 'bin/lifelog'
4
+
5
+ describe Main do
6
+ behaves_like :rack_test
7
+
8
+ # index
9
+
10
+ it 'shows start page' do
11
+ get('/').status.should == 200
12
+ #last_response.should =~ /<h1>Welcome to Ramaze!<\/h1>/
13
+ end
14
+
15
+ # posting
16
+
17
+ it 'accepts a post' do
18
+ post('/say', :message => "This is test").status.should == 302
19
+ follow_redirect!
20
+ last_response.should =~ /This is test/
21
+ end
22
+
23
+ it 'should not create a post via GET method' do
24
+ lambda{
25
+ get('/say?message=test')
26
+ }.should.not.change{ Post.count }
27
+ end
28
+
29
+ # searching by tags
30
+
31
+ it 'searches tagged posts' do
32
+ post('/say', :message => "#foo test1")
33
+ post('/say', :message => "#foo test2")
34
+ post('/say', :message => "#bar test3")
35
+
36
+ get('/search/tag/foo')
37
+ last_response.should =~ /test1/
38
+ last_response.should =~ /test2/
39
+ last_response.should.not =~ /test3/
40
+ end
41
+ end
data/spec/models.rb ADDED
@@ -0,0 +1,48 @@
1
+ require 'spec/helper.rb'
2
+ module LifeLog
3
+ include Innate::Optioned
4
+
5
+ options.dsl do
6
+ o "Path of database file (for test)",
7
+ :db, "test.db"
8
+ end
9
+ end
10
+ require 'model/init.rb'
11
+
12
+ describe Post do
13
+ # init
14
+
15
+ it 'does not exist at first' do
16
+ Post.all.should == []
17
+ end
18
+
19
+ # instantiation
20
+
21
+ it 'should create instance for valid data' do
22
+ lambda{
23
+ Post.create({
24
+ :posted_at => Time.now,
25
+ :message => "test",
26
+ })
27
+ }.should.change{ Post.count }
28
+ end
29
+
30
+ it 'should make tags for tagged message' do
31
+ post = Post.create({
32
+ :posted_at => Time.now,
33
+ :message => "#foo #bar test",
34
+ })
35
+ foo = Tag.first(:name => "foo")
36
+ bar = Tag.first(:name => "bar")
37
+
38
+ [foo, bar].each{|tag| tag.should.not == nil}
39
+ post.tags.should == [foo, bar]
40
+ end
41
+ end
42
+
43
+ describe Tag do
44
+ it 'should check uniqueness' do
45
+ Tag.create(:name => "foo")
46
+ Tag.create(:name => "foo").id.should == nil
47
+ end
48
+ end
data/view/index.xhtml ADDED
@@ -0,0 +1,25 @@
1
+ <table>
2
+ <tr>
3
+ <td></td>
4
+ <td>
5
+ <form action="say" method="POST">
6
+ <input type="text" name="message" size="120" />
7
+ <input type="submit" value="add" />
8
+ </form>
9
+ </td>
10
+ </tr>
11
+
12
+ <?r @pager.each do |post| ?>
13
+ <tr>
14
+ <td class="time">#{h post.time_str}</td>
15
+ <td class="message">#{format_message(h post.message)}</td>
16
+ </tr>
17
+ <?r end ?>
18
+
19
+ </table>
20
+
21
+ <?r if @pager.needed? ?>
22
+ <div class="pager">
23
+ #{@pager.navigation}
24
+ </div>
25
+ <?r end ?>
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lifelog
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Yutaka HARA
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-03 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ramaze
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - !ruby/object:Gem::Version
23
+ version: "2009.10"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: do_sqlite3
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.10.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: dm-core
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.10.1
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: dm-validations
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.10.1
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: dm-aggregations
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - "="
62
+ - !ruby/object:Gem::Version
63
+ version: 0.10.1
64
+ version:
65
+ description: A lifelogging tool written in Ramaze
66
+ email: yutaka.hara/at/gmail.com
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - README.md
73
+ files:
74
+ - README.md
75
+ - Rakefile
76
+ - VERSION
77
+ - controller/init.rb
78
+ - controller/main.rb
79
+ - layout/default.xhtml
80
+ - lifelog.gemspec
81
+ - main.rb
82
+ - model/init.rb
83
+ - model/migrations.rb
84
+ - model/post.rb
85
+ - model/tag.rb
86
+ - spec/helper.rb
87
+ - spec/main.rb
88
+ - spec/models.rb
89
+ - view/index.xhtml
90
+ has_rdoc: true
91
+ homepage: http://github.com/yhara/lifelog
92
+ licenses: []
93
+
94
+ post_install_message:
95
+ rdoc_options:
96
+ - --charset=UTF-8
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: "0"
110
+ version:
111
+ requirements: []
112
+
113
+ rubyforge_project:
114
+ rubygems_version: 1.3.5
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: A lifelogging tool written in Ramaze
118
+ test_files:
119
+ - spec/helper.rb
120
+ - spec/main.rb
121
+ - spec/models.rb