lifelog 0.2.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.
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