booklist 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/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: []