booklist 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in panoptimon.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright 2013 Dafydd Crosby (dafydd@dafyddcrosby.com)
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
17
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ Booklist
2
+ ========
3
+
4
+ A simple command line tool for creating lists of books that you've read,
5
+ want to read, or simply enjoying right now.
data/bin/booklist ADDED
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright 2013 Dafydd Crosby (dafydd@dafyddcrosby.com)
3
+ # All rights reserved.
4
+
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+
8
+ # 1. Redistributions of source code must retain the above copyright notice, this
9
+ # list of conditions and the following disclaimer.
10
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+
14
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+
25
+ require 'optparse'
26
+ require 'ostruct'
27
+ require 'rubygems'
28
+ require 'active_record'
29
+ require 'yaml'
30
+ require 'pathname'
31
+
32
+ module Booklist
33
+ options = OpenStruct.new
34
+ STATES = { "read" => "Mark as read", "reading" => "Mark as currently reading", "toread" => "Mark as to-read" }
35
+ options.act_num = 0
36
+ usage = nil
37
+ OptionParser.new do |opts|
38
+ opts.banner = "Usage: booklist [options]"
39
+
40
+ opts.separator "Actions:"
41
+ opts.on("-a", "--add", "Add a book record", "(--title is required)") do
42
+ options.act_num += 1
43
+ options.action = :add
44
+ end
45
+
46
+ opts.on("-e", "--edit [ID]", Integer, "Edit a book record") do |id|
47
+ options.act_num += 1
48
+ options.id = id if id
49
+ options.action = :edit
50
+ end
51
+
52
+ opts.on("-d", "--delete [ID]", Integer, "Delete a book record") do |id|
53
+ options.act_num += 1
54
+ options.id = id if id
55
+ options.action = :delete
56
+ end
57
+
58
+ opts.on("-s", "--search", "Search for a book") do
59
+ options.act_num += 1
60
+ options.action = :search
61
+ end
62
+
63
+ opts.on("-r", "--read [ID]", Integer, "Show a book record's details") do |id|
64
+ options.act_num += 1
65
+ options.id = id if id
66
+ options.action = :read
67
+ end
68
+
69
+ opts.on("--list", "List all books in the database") do
70
+ options.act_num += 1
71
+ options.action = :list
72
+ end
73
+
74
+ opts.separator ""
75
+ opts.separator "Book details:"
76
+
77
+ # Book details
78
+ opts.on("--title TITLE", "Book title") do |title|
79
+ options.title = title
80
+ end
81
+
82
+ opts.on("--state STATE", "What state the book is in (read, to-read, reading, abandoned)") do |state|
83
+ options.state = state
84
+ end
85
+
86
+ opts.on("--author AUTHOR", "Book author") do |author|
87
+ options.author = author
88
+ end
89
+
90
+ opts.on("--addn_authors ADDN_AUTHORS", "Additional authors") do |aa|
91
+ options.addn_authors = aa
92
+ end
93
+
94
+ opts.on("--tags X,Y,Z", Array, "List of tags") do |tags|
95
+ options.tags = tags
96
+ end
97
+
98
+ opts.on("--id ID", Integer, "Book ID number") do |id|
99
+ options.id = id
100
+ end
101
+
102
+ opts.separator ""
103
+ opts.separator "Common options:"
104
+
105
+ # TODO - configurable booklist path
106
+ #opts.on("-c", "--config FILE", "Use configuration file") do |file|
107
+ # options.config_file = file
108
+ #end
109
+
110
+ opts.on("--debug", "Debug node") do
111
+ options.debug = true
112
+ end
113
+
114
+ opts.on("--updatedb", "Update the book database schema") do
115
+ options.update_schema = true
116
+ end
117
+
118
+ opts.on_tail("--version", "Get the booklist version") do
119
+ puts Booklist::version
120
+ exit
121
+ end
122
+
123
+ opts.on_tail("-h", "--help", "Show this message") do
124
+ puts opts
125
+ exit
126
+ end
127
+
128
+ usage = opts
129
+ end.parse!
130
+
131
+ if options.act_num > 1
132
+ puts "Please only use one action."
133
+ puts usage
134
+ exit
135
+ end
136
+
137
+ # TODO Create configuration directory if it doesn't exist
138
+ # mkdir ~/.booklist
139
+
140
+ # TODO configurable booklist path
141
+ booklist_db_path = File.join(Dir.home, '.booklist', 'booklist.db')
142
+
143
+ ActiveRecord::Base.establish_connection(
144
+ :adapter => 'sqlite3',
145
+ :database => booklist_db_path.to_s)
146
+ ActiveRecord::Base.logger = Logger.new(STDERR) if options.debug
147
+
148
+ if options.update_schema || !File.exist?(booklist_db_path)
149
+ ActiveRecord::Migrator.migrate('db/migrate')
150
+ end
151
+
152
+ class Book < ActiveRecord::Base
153
+ has_many :taggings
154
+ has_many :tags, through: :taggings #, source: "book_id"
155
+ validates :title, presence: true
156
+
157
+ def cli_display
158
+ puts "ID: #{id}\n"
159
+ puts "Title: #{title}\n"
160
+ puts "Author: #{author}\n" if author
161
+ puts "Additional authors: #{addn_authors}" if addn_authors
162
+ puts "State: #{state}" if state
163
+ puts "Tags: #{tag_list}\n" if tags.count > 0
164
+ puts "\n"
165
+ end
166
+
167
+ def tag_list
168
+ #put tags
169
+ tags.map(&:name).join(", ")
170
+ end
171
+
172
+ def tag_list=(names)
173
+ self.tags = names.map do |n|
174
+ Tag.where(name: n.strip).first_or_create!
175
+ end
176
+ end
177
+ end
178
+
179
+ class Tag < ActiveRecord::Base
180
+ has_many :taggings
181
+ has_many :books, through: :taggings #, source: "tag_id"
182
+ end
183
+
184
+ class Tagging < ActiveRecord::Base
185
+ belongs_to :tag
186
+ belongs_to :book
187
+ end
188
+
189
+ if options.act_num = 1
190
+ if options.action == :add
191
+ if !options.title || options.title == ""
192
+ puts "Please add a --title with the book name"
193
+ puts usage
194
+ exit
195
+ end
196
+ book = Book.new do |b|
197
+ b.title = options.title
198
+ b.author = options.author if options.author
199
+ b.addn_authors if options.addn_authors
200
+ b.state = options.state if options.state
201
+ b.tag_list = options.tags if options.tags
202
+ end
203
+ book.save
204
+ book.cli_display
205
+ elsif options.action == :edit
206
+ book = Book.find_by(id: options.id)
207
+ if book
208
+ book.title = options.title if options.title
209
+ book.author = options.author if options.author
210
+ book.addn_authors = options.addn_authors if options.addn_authors
211
+ book.state = options.state if options.state
212
+ book.tag_list = options.tags if options.tags
213
+ book.save
214
+ book.cli_display
215
+ else
216
+ puts "No book with ID of #{options.id} was found"
217
+ end
218
+ elsif options.action == :delete
219
+ book = Book.find_by(id: options.id)
220
+ book.destroy
221
+ elsif options.action == :read
222
+ book = Book.find_by(id: options.id)
223
+ if book
224
+ book.cli_display
225
+ else
226
+ puts "No book with ID of #{options.id} was found"
227
+ end
228
+ elsif options.action == :search
229
+ books = Book.where(["title LIKE ?", "%#{options.title}%"]) if options.title
230
+ # TODO - books << Book.where(["author LIKE ? or addn_authors LIKE ?", "%#{options.author}%", "%#{options.author}%"]) if options.author
231
+ # TODO show unique records
232
+ books.each { |b|
233
+ b.cli_display
234
+ }
235
+ elsif options.action == :list
236
+ books = Book.all
237
+ books.each{ |b|
238
+ b.cli_display
239
+ }
240
+ end
241
+ elsif options.act_num > 1
242
+ puts "Please only use one action."
243
+ puts usage
244
+ exit
245
+ end
246
+
247
+ end
data/booklist.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/booklist/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "booklist"
6
+ gem.authors = ["Dafydd Crosby"]
7
+ gem.description = %q{A book collection program}
8
+ gem.summary = %q{Booklist helps you keep a list of books you've read or want to read.}
9
+
10
+ gem.email = "dafydd@dafyddcrosby.com"
11
+ gem.homepage = "https://github.com/dafyddcrosby/booklist"
12
+
13
+ gem.license = 'bsd' # The (three-clause) BSD License
14
+
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.version = Booklist::VERSION
20
+ gem.required_ruby_version = '>= 1.9'
21
+ gem.add_dependency 'sqlite3'
22
+ gem.add_dependency 'activerecord', '~> 4.0.0'
23
+ end
@@ -0,0 +1,19 @@
1
+ class Initial < ActiveRecord::Migration
2
+ def up
3
+ connection.create_table :books do |t|
4
+ t.string :title, :author, :addn_authors, :state
5
+ t.timestamp :date_read
6
+ t.text :notes
7
+ t.timestamps
8
+ end
9
+
10
+ connection.create_table :tags do |t|
11
+ t.string :name
12
+ t.timestamps
13
+ end
14
+
15
+ connection.create_table :taggings do |t|
16
+ t.belongs_to :tag, :book
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Booklist
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: booklist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Dafydd Crosby
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sqlite3
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activerecord
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 4.0.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 4.0.0
46
+ description: A book collection program
47
+ email: dafydd@dafyddcrosby.com
48
+ executables:
49
+ - booklist
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - Gemfile
54
+ - LICENSE
55
+ - README.md
56
+ - bin/booklist
57
+ - booklist.gemspec
58
+ - db/migrate/001_initial.rb
59
+ - lib/booklist/version.rb
60
+ homepage: https://github.com/dafyddcrosby/booklist
61
+ licenses:
62
+ - bsd
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '1.9'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 1.8.24
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Booklist helps you keep a list of books you've read or want to read.
85
+ test_files: []