athenaeum 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +28 -0
- data/README +19 -0
- data/Rakefile +128 -0
- data/bin/athenaeum +81 -0
- data/lib/athenaeum.rb +47 -0
- data/lib/athenaeum/borrower.rb +91 -0
- data/lib/athenaeum/item.rb +109 -0
- data/lib/athenaeum/itemtypes/book.rb +27 -0
- data/lib/athenaeum/itemtypes/game.rb +26 -0
- data/lib/athenaeum/itemtypes/movie.rb +27 -0
- data/lib/athenaeum/itemtypes/music.rb +27 -0
- data/lib/athenaeum/loan.rb +70 -0
- metadata +58 -0
data/LICENSE
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Copyright (c) 2007, LAIKA Inc. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
4
|
+
modification, are permitted provided that the following conditions are
|
5
|
+
met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright
|
8
|
+
notice, this list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
* Redistributions in binary form must reproduce the above copyright
|
11
|
+
notice, this list of conditions and the following disclaimer in the
|
12
|
+
documentation and/or other materials provided with the distribution.
|
13
|
+
|
14
|
+
* Neither the name of the LAIKA, Inc nor the names of its contributors
|
15
|
+
may be used to endorse or promote products derived from this software
|
16
|
+
without specific prior written permission.
|
17
|
+
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
19
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
20
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
21
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
22
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
24
|
+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
25
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
26
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
27
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
28
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= Athenaeum
|
2
|
+
|
3
|
+
Athenaeum is a small web application meant to read and display the items
|
4
|
+
checked out from your Delicious Library.
|
5
|
+
|
6
|
+
== Dependencies
|
7
|
+
|
8
|
+
* Delicious Library - http://www.delicious-monster.com
|
9
|
+
* RubyCocoa - http://rubycocoa.sf.net
|
10
|
+
* hpricot - http://code.whytheluckystiff.net/hpricot
|
11
|
+
* mongrel - http://mongrel.rubyforge.org
|
12
|
+
|
13
|
+
== Authors
|
14
|
+
|
15
|
+
* Ben Bleything - <mailto:bbleything@laika.com>
|
16
|
+
|
17
|
+
== License and Copyright
|
18
|
+
|
19
|
+
Athenaeum is copyright (c) 2007, LAIKA Inc. It is distributed under the terms of the BSD license.
|
data/Rakefile
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
##############################################################
|
2
|
+
# Copyright 2007, LAIKA, Inc. #
|
3
|
+
# #
|
4
|
+
# Based heavily on Ben Bleything's Rakefile for plist, which #
|
5
|
+
# is in turn based on Geoffrey Grosenbach's Rakefile for #
|
6
|
+
# gruff. #
|
7
|
+
# #
|
8
|
+
# Includes whitespace-fixing task based on code from Typo. #
|
9
|
+
# #
|
10
|
+
# Authors: #
|
11
|
+
# * Ben Bleything <bbleything@laika.com> #
|
12
|
+
##############################################################
|
13
|
+
|
14
|
+
require 'fileutils'
|
15
|
+
require 'rubygems'
|
16
|
+
require 'rake'
|
17
|
+
require 'rake/rdoctask'
|
18
|
+
require 'rake/packagetask'
|
19
|
+
require 'rake/gempackagetask'
|
20
|
+
require 'rake/contrib/rubyforgepublisher'
|
21
|
+
|
22
|
+
$:.unshift(File.dirname(__FILE__) + "/lib")
|
23
|
+
require 'athenaeum'
|
24
|
+
|
25
|
+
PKG_NAME = Athenaeum::NAME.downcase
|
26
|
+
PKG_VERSION = Athenaeum::VERSION
|
27
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
28
|
+
|
29
|
+
RELEASE_NAME = "REL #{PKG_VERSION}"
|
30
|
+
|
31
|
+
RUBYFORGE_PROJECT = "athenaeum"
|
32
|
+
RUBYFORGE_USER = ENV['RUBYFORGE_USER']
|
33
|
+
|
34
|
+
TEXT_FILES = %w( Rakefile README LICENSE )
|
35
|
+
LIB_FILES = Dir.glob('lib/**/*').delete_if { |item| item.include?( "\.svn" ) }
|
36
|
+
RELEASE_FILES = TEXT_FILES + LIB_FILES
|
37
|
+
|
38
|
+
task :default => [ :clean ]
|
39
|
+
|
40
|
+
desc "Clean pkg, coverage, and rdoc; remove .bak files"
|
41
|
+
task :clean => [ :clobber_rdoc, :clobber_package ] do
|
42
|
+
puts cmd = "find . -type f -name *.bak -delete"
|
43
|
+
`#{cmd}`
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Strip trailing whitespace and fix newlines for all release files"
|
47
|
+
task :fix_whitespace => [ :clean ] do
|
48
|
+
RELEASE_FILES.each do |filename|
|
49
|
+
next if File.directory? filename
|
50
|
+
|
51
|
+
File.open(filename) do |file|
|
52
|
+
newfile = ''
|
53
|
+
needs_love = false
|
54
|
+
|
55
|
+
file.readlines.each_with_index do |line, lineno|
|
56
|
+
if line =~ /[ \t]+$/
|
57
|
+
needs_love = true
|
58
|
+
puts "#{filename}: trailing whitespace on line #{lineno}"
|
59
|
+
line.gsub!(/[ \t]*$/, '')
|
60
|
+
end
|
61
|
+
|
62
|
+
if line.chomp == line
|
63
|
+
needs_love = true
|
64
|
+
puts "#{filename}: no newline on line #{lineno}"
|
65
|
+
line << "\n"
|
66
|
+
end
|
67
|
+
|
68
|
+
newfile << line
|
69
|
+
end
|
70
|
+
|
71
|
+
if needs_love
|
72
|
+
tempname = "#{filename}.new"
|
73
|
+
|
74
|
+
File.open(tempname, 'w').write(newfile)
|
75
|
+
File.chmod(File.stat(filename).mode, tempname)
|
76
|
+
|
77
|
+
FileUtils.ln filename, "#{filename}.bak"
|
78
|
+
FileUtils.ln tempname, filename, :force => true
|
79
|
+
File.unlink(tempname)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
desc "Copy documentation to rubyforge"
|
87
|
+
task :update_rdoc => [ :rdoc ] do
|
88
|
+
Rake::SshDirPublisher.new("#{RUBYFORGE_USER}@rubyforge.org", "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}", "rdoc").upload
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
### Genereate the RDoc documentation
|
93
|
+
Rake::RDocTask.new { |rdoc|
|
94
|
+
rdoc.rdoc_dir = 'rdoc'
|
95
|
+
rdoc.title = "#{Athenaeum::NAME} - #{Athenaeum::DESCRIPTION}"
|
96
|
+
rdoc.options << '-SNmREADME'
|
97
|
+
|
98
|
+
rdoc.rdoc_files.include TEXT_FILES
|
99
|
+
rdoc.rdoc_files.include LIB_FILES
|
100
|
+
rdoc.rdoc_files.include Dir.glob('docs/**').delete_if {|f| f.include? 'jamis' }
|
101
|
+
}
|
102
|
+
|
103
|
+
|
104
|
+
### Create compressed packages
|
105
|
+
spec = Gem::Specification.new do |s|
|
106
|
+
s.name = PKG_NAME
|
107
|
+
s.version = PKG_VERSION
|
108
|
+
|
109
|
+
s.summary = "#{Athenaeum::NAME} - #{Athenaeum::DESCRIPTION}"
|
110
|
+
s.description = Athenaeum::LONG_DESC
|
111
|
+
|
112
|
+
s.authors = "LAIKA, Inc."
|
113
|
+
s.homepage = "http://opensource.laika.com"
|
114
|
+
s.rubyforge_project = RUBYFORGE_PROJECT
|
115
|
+
|
116
|
+
s.has_rdoc = true
|
117
|
+
|
118
|
+
s.files = RELEASE_FILES
|
119
|
+
s.executables = 'athenaeum'
|
120
|
+
|
121
|
+
s.autorequire = 'athenaeum'
|
122
|
+
end
|
123
|
+
|
124
|
+
Rake::GemPackageTask.new(spec) do |p|
|
125
|
+
p.gem_spec = spec
|
126
|
+
p.need_tar = true
|
127
|
+
p.need_zip = true
|
128
|
+
end
|
data/bin/athenaeum
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Athenaeum
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# Athenaeum is a small web application meant to read and display the items
|
8
|
+
# checked out from your Delicious Library.
|
9
|
+
#
|
10
|
+
# == Authors
|
11
|
+
#
|
12
|
+
# * Ben Bleything <bbleything@laika.com>
|
13
|
+
#
|
14
|
+
# == Copyright
|
15
|
+
#
|
16
|
+
# Copyright (c) 2007 LAIKA, Inc
|
17
|
+
#
|
18
|
+
# == Version
|
19
|
+
#
|
20
|
+
# $Id: athenaeum 288 2007-08-01 22:35:03Z bbleything $
|
21
|
+
|
22
|
+
require 'athenaeum'
|
23
|
+
|
24
|
+
########################################################################
|
25
|
+
### S E T U P
|
26
|
+
########################################################################
|
27
|
+
|
28
|
+
# fetch the DL data from the running user's home directory
|
29
|
+
@xml = File.read( "/Users/#{`whoami`.strip}/Library/Application\ Support/Delicious\ Library/Library\ Media\ Data.xml" )
|
30
|
+
@doc = Hpricot.XML( @xml )
|
31
|
+
|
32
|
+
########################################################################
|
33
|
+
### B U I L D L I B R A R Y
|
34
|
+
########################################################################
|
35
|
+
|
36
|
+
# this query will get us all the top-level books, movies, music, and games
|
37
|
+
#from the item container. This prevents us from accidentally grabbing the
|
38
|
+
# recommendations and related items.
|
39
|
+
@doc.at( "/library/items" ).search( "/book | /movie | /music | /game" ) do |item|
|
40
|
+
Athenaeum::Item.create( item )
|
41
|
+
end
|
42
|
+
|
43
|
+
# fetches all the borrowers from the xml, creating Athenaeum::Borrower objects
|
44
|
+
# for each. This must happen *after* the Items are found, because
|
45
|
+
# Athenaeum::Borrower uses Athenaeum::Item's registry to build its internal
|
46
|
+
# registry.
|
47
|
+
@doc.search( "/library/borrowers/borrower" ).each do |b|
|
48
|
+
Athenaeum::Borrower.new( b )
|
49
|
+
end
|
50
|
+
|
51
|
+
########################################################################
|
52
|
+
### O U T P U T ! ! ! 1
|
53
|
+
########################################################################
|
54
|
+
|
55
|
+
Athenaeum::Item.types.sort_by {|k| k.type_name}.each do |type|
|
56
|
+
items = Athenaeum::Item.find_by_type( type )
|
57
|
+
next if items.empty?
|
58
|
+
|
59
|
+
type_name = type.type_name
|
60
|
+
type_name << 's' unless type_name == 'Music'
|
61
|
+
|
62
|
+
# +-----+
|
63
|
+
# | foo |
|
64
|
+
# +-----+----------------------------------------------------------------------+
|
65
|
+
puts "+-" + ( '-' * type_name.length ) + "-+"
|
66
|
+
puts "| #{type_name} |"
|
67
|
+
puts "+-" + ( '-' * type_name.length ) + "-+" + ( '-' * (79 - type_name.length - 6) ) + "+"
|
68
|
+
puts
|
69
|
+
|
70
|
+
# get the items of this type, sorted by title
|
71
|
+
items.sort_by {|item| item.title }.each do |item|
|
72
|
+
puts "- #{item.title} by #{item.creator}"
|
73
|
+
|
74
|
+
if loan = Athenaeum::Loan.find_by_item_uuid( item.uuid )
|
75
|
+
due_date = loan.due_date.strftime( '%B %d, %Y' )
|
76
|
+
puts " - loaned to #{loan.borrower.name} (#{loan.borrower.email}), due on #{due_date}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
puts # blank line for clarity
|
81
|
+
end
|
data/lib/athenaeum.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Athenaeum
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# Athenaeum is a small web application meant to read and display the items
|
8
|
+
# checked out from your Delicious Library.
|
9
|
+
#
|
10
|
+
# == Authors
|
11
|
+
#
|
12
|
+
# * Ben Bleything <bbleything@laika.com>
|
13
|
+
#
|
14
|
+
# == Copyright
|
15
|
+
#
|
16
|
+
# Copyright (c) 2007 LAIKA, Inc
|
17
|
+
#
|
18
|
+
# == Version
|
19
|
+
#
|
20
|
+
# $Id: athenaeum.rb 292 2007-08-02 21:56:18Z bbleything $
|
21
|
+
|
22
|
+
### standard library
|
23
|
+
require 'date'
|
24
|
+
|
25
|
+
### rubygems
|
26
|
+
require 'rubygems'
|
27
|
+
require 'hpricot'
|
28
|
+
|
29
|
+
### rubycocoa
|
30
|
+
require 'osx/cocoa'
|
31
|
+
|
32
|
+
module Athenaeum
|
33
|
+
NAME = "Athenaeum"
|
34
|
+
DESCRIPTION = "A small webapp to display the contents of your Delicious Library"
|
35
|
+
LONG_DESC = "Athenaeum is a collection of libraries to read and display the contents of your Delicious Library. It includes the ability to display what items are checked out, to whom, and when they are due."
|
36
|
+
VERSION = "1.0"
|
37
|
+
end
|
38
|
+
|
39
|
+
### athenaeum
|
40
|
+
require 'athenaeum/borrower'
|
41
|
+
require 'athenaeum/item'
|
42
|
+
require 'athenaeum/loan'
|
43
|
+
|
44
|
+
require 'athenaeum/itemtypes/book'
|
45
|
+
require 'athenaeum/itemtypes/game'
|
46
|
+
require 'athenaeum/itemtypes/movie'
|
47
|
+
require 'athenaeum/itemtypes/music'
|
@@ -0,0 +1,91 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Athenaeum::Borrower
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# Represents a person who has borrowed an item.
|
8
|
+
#
|
9
|
+
# Accepts a <borrower> record (as an Hpricot::Elem) and creates an object that
|
10
|
+
# represents that data.
|
11
|
+
#
|
12
|
+
# == Authors
|
13
|
+
#
|
14
|
+
# * Ben Bleything <bbleything@laika.com>
|
15
|
+
#
|
16
|
+
# == Copyright
|
17
|
+
#
|
18
|
+
# Copyright (c) 2007 LAIKA, Inc
|
19
|
+
#
|
20
|
+
# == Version
|
21
|
+
#
|
22
|
+
# $Id: borrower.rb 287 2007-08-01 22:15:57Z bbleything $
|
23
|
+
|
24
|
+
class Athenaeum::Borrower
|
25
|
+
# load the AddressBook framework from RubyCocoa
|
26
|
+
OSX.require_framework 'AddressBook'
|
27
|
+
|
28
|
+
attr_reader :email, :id, :name
|
29
|
+
|
30
|
+
# takes an Hpricot::Elem representing a borrower.
|
31
|
+
def initialize( info )
|
32
|
+
raise "Must provide an Hpricot::Elem object" unless
|
33
|
+
info.is_a? Hpricot::Elem
|
34
|
+
|
35
|
+
@id = info[ :id ]
|
36
|
+
|
37
|
+
if ab_record = fetch_ab_record( @id )
|
38
|
+
@name, @email = extract_data( ab_record )
|
39
|
+
else
|
40
|
+
@name = @email = 'Unknown'
|
41
|
+
end
|
42
|
+
|
43
|
+
info.search( "/loan" ).each {|loan| Athenaeum::Loan.new( self, loan ) }
|
44
|
+
end
|
45
|
+
|
46
|
+
# return an HTML representation of this borrower
|
47
|
+
def to_html
|
48
|
+
inner = if email !~ /unknown email address/
|
49
|
+
"<a href='mailto:#{self.email}'>#{self.name}</a>"
|
50
|
+
else
|
51
|
+
self.name
|
52
|
+
end
|
53
|
+
|
54
|
+
return "<span class='borrower'>#{inner}</span>"
|
55
|
+
end
|
56
|
+
|
57
|
+
########################################################################
|
58
|
+
private
|
59
|
+
########################################################################
|
60
|
+
|
61
|
+
# given a uuid, finds the record in the Address Book
|
62
|
+
def fetch_ab_record( id )
|
63
|
+
return OSX::ABAddressBook.sharedAddressBook.recordForUniqueId( id )
|
64
|
+
end
|
65
|
+
|
66
|
+
# fetches name and email from Address Book
|
67
|
+
def extract_data( ab_record )
|
68
|
+
return extract_name( ab_record ), extract_email( ab_record )
|
69
|
+
end
|
70
|
+
|
71
|
+
# fetches name from Address Book
|
72
|
+
def extract_name( ab_record )
|
73
|
+
first = ab_record.valueForProperty( 'First' )
|
74
|
+
last = ab_record.valueForProperty( 'Last' )
|
75
|
+
|
76
|
+
return "#{first} #{last}"
|
77
|
+
end
|
78
|
+
|
79
|
+
# fetches primary email from Address Book
|
80
|
+
def extract_email( ab_record )
|
81
|
+
if emails = ab_record.valueForProperty( 'Email' )
|
82
|
+
# emails is a multivalue list, so we need to find the primary
|
83
|
+
# identifier and then...
|
84
|
+
primary_id = emails.primaryIdentifier
|
85
|
+
# ... fetch the value associated with the primary id
|
86
|
+
return emails.valueAtIndex( emails.indexForIdentifier( primary_id ) ).to_s
|
87
|
+
else
|
88
|
+
return 'unknown email address'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Athenaeum::Item
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# Represents an item from your collection. This is the semi-abstract
|
8
|
+
# superclass from which the actual object types descend.
|
9
|
+
#
|
10
|
+
# == Authors
|
11
|
+
#
|
12
|
+
# * Ben Bleything <bbleything@laika.com>
|
13
|
+
#
|
14
|
+
# == Copyright
|
15
|
+
#
|
16
|
+
# Copyright (c) 2007 LAIKA, Inc
|
17
|
+
#
|
18
|
+
# == Version
|
19
|
+
#
|
20
|
+
# $Id: item.rb 290 2007-08-02 18:26:29Z bbleything $
|
21
|
+
|
22
|
+
class Athenaeum::Item
|
23
|
+
########################################################################
|
24
|
+
### I N I T I A L I Z E R S
|
25
|
+
########################################################################
|
26
|
+
|
27
|
+
# the initializer is not used directly, rather it is inherited by the
|
28
|
+
# subclasses and used in them.
|
29
|
+
def initialize( item )
|
30
|
+
item.attributes.keys.each do |name|
|
31
|
+
# add getter
|
32
|
+
(class << self ; self ; end).instance_eval {
|
33
|
+
attr_reader name.to_s.intern
|
34
|
+
}
|
35
|
+
|
36
|
+
# set ivar. Use raw_attributes because that's the only way to
|
37
|
+
# get the un-unescaped content.
|
38
|
+
instance_variable_set "@#{name}", item.raw_attributes[ name ]
|
39
|
+
end
|
40
|
+
|
41
|
+
@@registry ||= []
|
42
|
+
@@registry << self
|
43
|
+
end
|
44
|
+
|
45
|
+
# this is the initializer that actually gets used. Pass the appropriate
|
46
|
+
# kind of Hpricot::Elem object (representing an item in the xml) and it
|
47
|
+
# will give you the appropriate type of item back.
|
48
|
+
def self::create( item )
|
49
|
+
raise "Must provide an Hpricot::Elem object" unless
|
50
|
+
item.is_a? Hpricot::Elem
|
51
|
+
|
52
|
+
Athenaeum.const_get( item.etag.name.capitalize ).new( item )
|
53
|
+
end
|
54
|
+
|
55
|
+
########################################################################
|
56
|
+
### M A G I C H O O K S
|
57
|
+
########################################################################
|
58
|
+
|
59
|
+
# keep a registry of subclasses, for self::types, below
|
60
|
+
def self::inherited( klass )
|
61
|
+
@@subclasses ||= []
|
62
|
+
@@subclasses << klass
|
63
|
+
end
|
64
|
+
|
65
|
+
########################################################################
|
66
|
+
### I N T R O S P E C T I O N
|
67
|
+
########################################################################
|
68
|
+
|
69
|
+
# simple getter for the item registry
|
70
|
+
def self::registry
|
71
|
+
@@registry ||= []
|
72
|
+
return @@registry
|
73
|
+
end
|
74
|
+
|
75
|
+
# the name of this particular type... book, music, game, movie, etc
|
76
|
+
def self::type_name
|
77
|
+
self.to_s.split( /::/ ).last
|
78
|
+
end
|
79
|
+
|
80
|
+
# simple getter for the subclass registry
|
81
|
+
def self::types
|
82
|
+
@@subclasses || []
|
83
|
+
end
|
84
|
+
|
85
|
+
########################################################################
|
86
|
+
### F I N D E R S
|
87
|
+
########################################################################
|
88
|
+
|
89
|
+
# searches through the registry, finding all items of a given subclass
|
90
|
+
def self::find_by_type( type )
|
91
|
+
return @@registry.select {|item| item.is_a? type }
|
92
|
+
end
|
93
|
+
|
94
|
+
# searches through the registry, returning the item with the uuid
|
95
|
+
# specified
|
96
|
+
def self::find_by_uuid( uuid )
|
97
|
+
return @@registry.detect {|item| item.uuid == uuid }
|
98
|
+
end
|
99
|
+
|
100
|
+
########################################################################
|
101
|
+
### I N S T A N C E M E T H O D S
|
102
|
+
########################################################################
|
103
|
+
|
104
|
+
# returns a decent HTML representation of the item
|
105
|
+
def to_html
|
106
|
+
return "<span class='title'>#{self.title}</span> <span class='creator'>by #{self.creator}</span>"
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Athenaeum::Book
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# Represents a book from your collection.
|
8
|
+
#
|
9
|
+
# == Authors
|
10
|
+
#
|
11
|
+
# * Ben Bleything <bbleything@laika.com>
|
12
|
+
#
|
13
|
+
# == Copyright
|
14
|
+
#
|
15
|
+
# Copyright (c) 2007 LAIKA, Inc
|
16
|
+
#
|
17
|
+
# == Version
|
18
|
+
#
|
19
|
+
# $Id: book.rb 285 2007-08-01 21:38:27Z bbleything $
|
20
|
+
|
21
|
+
class Athenaeum::Book < Athenaeum::Item
|
22
|
+
# alias author to creator
|
23
|
+
def creator
|
24
|
+
creator = self.author rescue nil
|
25
|
+
return creator || 'Unknown Author'
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Athenaeum::Game
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# Represents a video game from your collection.
|
8
|
+
#
|
9
|
+
# == Authors
|
10
|
+
#
|
11
|
+
# * Ben Bleything <bbleything@laika.com>
|
12
|
+
#
|
13
|
+
# == Copyright
|
14
|
+
#
|
15
|
+
# Copyright (c) 2007 LAIKA, Inc
|
16
|
+
#
|
17
|
+
# == Version
|
18
|
+
#
|
19
|
+
# $Id: game.rb 284 2007-08-01 18:01:14Z bbleything $
|
20
|
+
|
21
|
+
class Athenaeum::Game < Athenaeum::Item
|
22
|
+
# alias publisher to creator
|
23
|
+
def creator
|
24
|
+
self.publisher
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Athenaeum::Movie
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# Represents a movie from your collection.
|
8
|
+
#
|
9
|
+
# == Authors
|
10
|
+
#
|
11
|
+
# * Ben Bleything <bbleything@laika.com>
|
12
|
+
#
|
13
|
+
# == Copyright
|
14
|
+
#
|
15
|
+
# Copyright (c) 2007 LAIKA, Inc
|
16
|
+
#
|
17
|
+
# == Version
|
18
|
+
#
|
19
|
+
# $Id: movie.rb 285 2007-08-01 21:38:27Z bbleything $
|
20
|
+
|
21
|
+
class Athenaeum::Movie < Athenaeum::Item
|
22
|
+
# alias director (or, failing that, publisher) to creator
|
23
|
+
def creator
|
24
|
+
creator = self.director rescue nil
|
25
|
+
return creator || 'Unknown Director'
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Athenaeum::Music
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# Represents an audio recording from your collection.
|
8
|
+
#
|
9
|
+
# == Authors
|
10
|
+
#
|
11
|
+
# * Ben Bleything <bbleything@laika.com>
|
12
|
+
#
|
13
|
+
# == Copyright
|
14
|
+
#
|
15
|
+
# Copyright (c) 2007 LAIKA, Inc
|
16
|
+
#
|
17
|
+
# == Version
|
18
|
+
#
|
19
|
+
# $Id: music.rb 285 2007-08-01 21:38:27Z bbleything $
|
20
|
+
|
21
|
+
class Athenaeum::Music < Athenaeum::Item
|
22
|
+
# alias artist to creator
|
23
|
+
def creator
|
24
|
+
creator = self.artist rescue nil
|
25
|
+
return creator || 'Unknown Artist'
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Athenaeum::Loan
|
4
|
+
#
|
5
|
+
# == Synopsis
|
6
|
+
#
|
7
|
+
# Encapsulates the relationship between a borrower and an item. Any instance
|
8
|
+
# of this class represented an item that has been loaned out to a particular
|
9
|
+
# person.
|
10
|
+
#
|
11
|
+
# == Authors
|
12
|
+
#
|
13
|
+
# * Ben Bleything <bbleything@laika.com>
|
14
|
+
#
|
15
|
+
# == Copyright
|
16
|
+
#
|
17
|
+
# Copyright (c) 2007 LAIKA, Inc
|
18
|
+
#
|
19
|
+
# == Version
|
20
|
+
#
|
21
|
+
# $Id: loan.rb 289 2007-08-01 23:17:06Z bbleything $
|
22
|
+
|
23
|
+
class Athenaeum::Loan
|
24
|
+
attr_reader :borrower, :item, :due_date
|
25
|
+
|
26
|
+
# take a borrower and a loan tag, and create an object to encapsulate
|
27
|
+
# them. Searches the Item registry for the item.
|
28
|
+
def initialize( borrower, loan )
|
29
|
+
raise "Must provide an Athenaeum::Borrower object" unless
|
30
|
+
borrower.is_a? Athenaeum::Borrower
|
31
|
+
|
32
|
+
raise "Must provide an Hpricot::Elem object" unless
|
33
|
+
loan.is_a? Hpricot::Elem
|
34
|
+
|
35
|
+
@item = Athenaeum::Item.find_by_uuid( loan[ :mediaID ] )
|
36
|
+
@borrower = borrower
|
37
|
+
@due_date = Date.strptime( loan[ :dueDate ], '%d-%m-%Y' )
|
38
|
+
|
39
|
+
@@registry ||= []
|
40
|
+
@@registry << self
|
41
|
+
end
|
42
|
+
|
43
|
+
########################################################################
|
44
|
+
### I N T R O S P E C T I O N
|
45
|
+
########################################################################
|
46
|
+
|
47
|
+
# simple getter for the loan registry
|
48
|
+
def self::registry
|
49
|
+
@@registry ||= []
|
50
|
+
return @@registry
|
51
|
+
end
|
52
|
+
|
53
|
+
########################################################################
|
54
|
+
### F I N D E R S
|
55
|
+
########################################################################
|
56
|
+
|
57
|
+
# searches the Loan registry and returns the loan for the item with the
|
58
|
+
# given uuid, if any.
|
59
|
+
def self::find_by_item_uuid( uuid )
|
60
|
+
@@registry ||= []
|
61
|
+
return @@registry.detect {|loan| loan.item.uuid == uuid }
|
62
|
+
end
|
63
|
+
|
64
|
+
# searches the Loan registry and returns all loans that belong to the
|
65
|
+
# specified borrower.
|
66
|
+
def self::find_by_borrower_id( id )
|
67
|
+
@@registry ||= []
|
68
|
+
return @@registry.select {|loan| loan.borrower.id == id }
|
69
|
+
end
|
70
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: athenaeum
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "1.0"
|
7
|
+
date: 2007-09-10 00:00:00 -07:00
|
8
|
+
summary: Athenaeum - A small webapp to display the contents of your Delicious Library
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email:
|
12
|
+
homepage: http://opensource.laika.com
|
13
|
+
rubyforge_project: athenaeum
|
14
|
+
description: Athenaeum is a collection of libraries to read and display the contents of your Delicious Library. It includes the ability to display what items are checked out, to whom, and when they are due.
|
15
|
+
autorequire: athenaeum
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- LAIKA, Inc.
|
31
|
+
files:
|
32
|
+
- Rakefile
|
33
|
+
- README
|
34
|
+
- LICENSE
|
35
|
+
- lib/athenaeum
|
36
|
+
- lib/athenaeum/borrower.rb
|
37
|
+
- lib/athenaeum/item.rb
|
38
|
+
- lib/athenaeum/itemtypes
|
39
|
+
- lib/athenaeum/itemtypes/book.rb
|
40
|
+
- lib/athenaeum/itemtypes/game.rb
|
41
|
+
- lib/athenaeum/itemtypes/movie.rb
|
42
|
+
- lib/athenaeum/itemtypes/music.rb
|
43
|
+
- lib/athenaeum/loan.rb
|
44
|
+
- lib/athenaeum.rb
|
45
|
+
test_files: []
|
46
|
+
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
extra_rdoc_files: []
|
50
|
+
|
51
|
+
executables:
|
52
|
+
- athenaeum
|
53
|
+
extensions: []
|
54
|
+
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
dependencies: []
|
58
|
+
|