sakai-info 0.2.1 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # sakai-info Change History #
2
2
 
3
+ ## 0.3.0 ##
4
+
5
+ *Released 2012-02-26*
6
+
7
+ * Support for new object types: question-pool, quiz, quiz-section, quiz-item
8
+ * New CLI options for logging and trace-debugging
9
+ * New object abstraction patterns allow for --dbrow and --mod options
10
+
3
11
  ## 0.2.1 ##
4
12
 
5
13
  *Released 2012-02-25*
data/README.md CHANGED
@@ -10,7 +10,7 @@ tool or the libraries.
10
10
 
11
11
  ## Meta ##
12
12
 
13
- last updated: 2012-02-25
13
+ last updated: 2012-02-26
14
14
  author: David Adams (daveadams@gmail.com)
15
15
  github url: https://github.com/daveadams/sakai-info
16
16
 
@@ -26,7 +26,7 @@ Use `rake` to test and build the gem:
26
26
  $ rake gem:build
27
27
 
28
28
  The resulting gem will be saved to the working directory as
29
- `sakai-info-0.2.1.gem`.
29
+ `sakai-info-0.3.0.gem`.
30
30
 
31
31
  Cleanup built gems using:
32
32
 
@@ -75,22 +75,6 @@ PATH. For usage details, run:
75
75
 
76
76
  $ sakai-info help
77
77
 
78
- To look up information about a user, run:
79
-
80
- $ sakai-info user id
81
-
82
- For users, `id` can be either the user_id or the eid of the user you want
83
- details on.
84
-
85
- Similarly to look up information about a site, run:
86
-
87
- $ sakai-info site id
88
-
89
- For sites, `id` is the `site_id` of the desired site.
90
-
91
- Further details are available for both object types, see the corresponding
92
- help pages for more information.
93
-
94
78
  ## Library Usage ##
95
79
 
96
80
  To use the library in your own Ruby programs, simply specify:
data/ROADMAP.md CHANGED
@@ -1,10 +1,26 @@
1
1
  # sakai-info Roadmap #
2
2
 
3
- *Last updated 2012-02-24*
3
+ *Last updated 2012-02-26*
4
4
 
5
- ### 0.3 ###
5
+ ### 0.3.1 ###
6
6
 
7
- * CLI access to more objects, eg quizzes, tools, assignments, and groups
7
+ * CLI access to assignments
8
+
9
+ ### 0.3.2 ###
10
+
11
+ * CLI access to groups
12
+
13
+ ### 0.3.3 ###
14
+
15
+ * CLI access to pages and tools
16
+
17
+ ### 0.3.4 ###
18
+
19
+ * CLI access to forums
20
+
21
+ ### 0.4 ###
22
+
23
+ * Standardized abstraction for user and site to support --mod and --dbrow
8
24
  * Sqlite test infrastructure for a few basic objects
9
25
 
10
26
  ### 0.5 ###
@@ -12,6 +28,10 @@
12
28
  * Test fixtures and basic unit tests for all represented objects
13
29
  * RDoc coverage for every class
14
30
 
31
+ ### 0.6 ###
32
+
33
+ * Basic OSP support
34
+
15
35
  ------
16
36
 
17
37
  Other things on the wishlist for future releases:
@@ -36,4 +56,5 @@ Other things on the wishlist for future releases:
36
56
  * Additional tools
37
57
  * httpd log analysis helper
38
58
  * RPC client for Sakai-monitoring servlet
59
+ * schema analysis and generators
39
60
 
data/bin/sakai-info CHANGED
@@ -5,7 +5,7 @@
5
5
  # sakai-info library
6
6
  #
7
7
  # Created 2012-02-15 daveadams@gmail.com
8
- # Last updated 2012-02-24 daveadams@gmail.com
8
+ # Last updated 2012-02-26 daveadams@gmail.com
9
9
  #
10
10
  # https://github.com/daveadams/sakai-info
11
11
  #
@@ -17,14 +17,17 @@ include SakaiInfo
17
17
 
18
18
  require 'sakai-info/cli'
19
19
 
20
- ObjectModes = {
21
- "site" => Site,
22
- "user" => User
23
- }
24
-
25
20
  flags = []
26
21
  args = []
27
22
  db_name = nil
23
+ logfile = nil
24
+
25
+ __trace = proc { |event, file, line, id, binding, classname|
26
+ if %w(call raise return).include? event
27
+ t = Time.now
28
+ printf "%s.%06d %-8s %-25s %-10s .%-10s\n", t.strftime("%H:%M:%S"), t.usec, event, File.basename(file) + ":#{line}", classname, id
29
+ end
30
+ }
28
31
 
29
32
  while arg = ARGV.shift
30
33
  if arg =~ /^-/
@@ -32,6 +35,10 @@ while arg = ARGV.shift
32
35
  db_name = ARGV.shift
33
36
  elsif arg =~ /^--database=/
34
37
  db_name = arg.split("=")[1]
38
+ elsif arg =~ /^--log(file)?=/
39
+ logfile = arg.split("=")[1]
40
+ elsif arg == "--trace"
41
+ set_trace_func __trace
35
42
  else
36
43
  flags << arg
37
44
  end
@@ -99,7 +106,7 @@ when "test" then
99
106
 
100
107
  else
101
108
  # test to see if it's an accepted object mode
102
- if ObjectModes.keys.include? args[0]
109
+ if CLI::ObjectModes.keys.include? args[0]
103
110
  mode = args.shift
104
111
  id = args.shift
105
112
 
@@ -110,6 +117,19 @@ else
110
117
  end
111
118
  end
112
119
 
120
+ # set up a logger if specified
121
+ logger = nil
122
+ if not logfile.nil?
123
+ if logfile == "-"
124
+ logfile = STDOUT
125
+ end
126
+ logger = Logger.new(logfile)
127
+ logger.formatter = proc do |level, timestamp, progname, msg|
128
+ "#{timestamp.strftime("%Y-%m-%d %H:%M:%S")} #{msg}\n"
129
+ end
130
+ end
131
+ DB.logger = logger
132
+
113
133
  # load database config and set instance to the instance given on the command line
114
134
  DB.load_config
115
135
  if not db_name.nil?
@@ -117,12 +137,15 @@ if not db_name.nil?
117
137
  end
118
138
 
119
139
  if flags.include? "--all"
120
- serials = ObjectModes[mode].all_serializations
140
+ serials = CLI::ObjectModes[mode].all_serializations
141
+ elsif
142
+ flags.include? "--dbrow-only"
143
+ serials = [:dbrow]
121
144
  else
122
145
  serials = [:default] + flags.collect{|flag|flag.gsub(/^--/,'').to_sym}
123
146
  end
124
147
  begin
125
- puts ObjectModes[mode].find(id).to_yaml(serials)
148
+ puts CLI::ObjectModes[mode].find(id).to_yaml(serials)
126
149
  rescue ObjectNotFoundException
127
150
  STDERR.puts "ERROR: Could not find #{mode} with an ID of '#{id}'"
128
151
  exit 1
data/lib/sakai-info.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # Base library file
3
3
  #
4
4
  # Created 2012-02-15 daveadams@gmail.com
5
- # Last updated 2012-02-24 daveadams@gmail.com
5
+ # Last updated 2012-02-25 daveadams@gmail.com
6
6
  #
7
7
  # https://github.com/daveadams/sakai-info
8
8
  #
@@ -14,6 +14,7 @@ require 'json'
14
14
  require 'rexml/document'
15
15
  require 'base64'
16
16
  require 'sequel'
17
+ require 'logger'
17
18
 
18
19
  require 'sakai-info/version'
19
20
 
@@ -74,6 +75,7 @@ require 'sakai-info/database'
74
75
  # base objects
75
76
  require 'sakai-info/sakai_object'
76
77
  require 'sakai-info/sakai_xml_entity'
78
+ require 'sakai-info/mod_props'
77
79
 
78
80
  # sakai object classes
79
81
  require 'sakai-info/user'
@@ -85,5 +87,6 @@ require 'sakai-info/content'
85
87
  require 'sakai-info/gradebook'
86
88
  require 'sakai-info/group'
87
89
  require 'sakai-info/message'
88
- require 'sakai-info/samigo'
90
+ require 'sakai-info/quiz'
91
+ require 'sakai-info/question_pool'
89
92
 
@@ -2,7 +2,7 @@
2
2
  # - sakai-info command line tool support
3
3
  #
4
4
  # Created 2012-02-19 daveadams@gmail.com
5
- # Last updated 2012-02-23 daveadams@gmail.com
5
+ # Last updated 2012-02-26 daveadams@gmail.com
6
6
  #
7
7
  # https://github.com/daveadams/sakai-info
8
8
  #
@@ -11,3 +11,17 @@
11
11
 
12
12
  require 'sakai-info/cli/help'
13
13
 
14
+ module SakaiInfo
15
+ class CLI
16
+ ObjectModes = {
17
+ "site" => Site,
18
+ "user" => User,
19
+ "quiz" => Quiz,
20
+ "quiz-section" => QuizSection,
21
+ "quiz-item" => QuizItem,
22
+ "qpool" => QuestionPool,
23
+ "question-pool" => QuestionPool,
24
+ }
25
+ end
26
+ end
27
+
@@ -2,7 +2,7 @@
2
2
  # - sakai-info command line help
3
3
  #
4
4
  # Created 2012-02-19 daveadams@gmail.com
5
- # Last updated 2012-02-19 daveadams@gmail.com
5
+ # Last updated 2012-02-26 daveadams@gmail.com
6
6
  #
7
7
  # https://github.com/daveadams/sakai-info
8
8
  #
@@ -19,20 +19,41 @@ sakai-info #{VERSION}
19
19
  Usage: sakai-info <command> [<id>] [<options>]
20
20
 
21
21
  Object commands:
22
- user Print information about a user or users
23
- site Print information about a site or sites
22
+ user User information
23
+ site Site information
24
+ quiz Quiz aka Assessment information, pending or published
25
+ quiz-section Quiz section information, pending or published
26
+ quiz-item Quiz item information, pending or published
27
+ question-pool Question Pool information
24
28
 
25
29
  Misc commands:
26
30
  test Tests configured database connections
27
31
  help Prints general help
28
32
  version Prints version
29
33
 
30
- Options that apply to most commands:
31
- -D <name>
34
+ Options that apply globally:
32
35
  --database=<name>
33
36
  Connect to database instance <name> as defined in ~/.sakai-info instead
34
37
  of the default (which is typically the first entry)
35
38
 
39
+ --log=<logfile>
40
+ Log actual SQL statements to <logfile> as they are executed. Use "-"
41
+ to log to STDOUT.
42
+
43
+ --trace
44
+ For development troubleshooting work, this outputs an extremely verbose
45
+ trace log to STDOUT.
46
+
47
+ Options that work on most object types:
48
+ --dbrow-only
49
+ Print only the raw database fields for the object requested.
50
+
51
+ --mod
52
+ Print creation and modification users and timestamps.
53
+
54
+ --all
55
+ Print all possible information (other than dbrow)
56
+
36
57
  Type 'sakai-info help <command>' for help on a specific command.
37
58
  EOF
38
59
 
@@ -94,6 +115,73 @@ sakai-info site
94
115
  --forums Print forum details
95
116
  --all Print all possible details
96
117
  EOF
118
+
119
+ "quiz" => <<EOF,
120
+ sakai-info quiz
121
+
122
+ Usage: sakai-info quiz <id> [<options>]
123
+
124
+ Prints information about the quiz ID specified. The quiz ID may represent
125
+ a pending quiz or a published quiz. Additional options may be passed to
126
+ include additional information:
127
+
128
+ --sections Print section summary list
129
+ --mod Print creation/modification info
130
+ --all Print all possible details
131
+ --dbrow Print the raw database fields
132
+
133
+ Not yet implemented:
134
+ --items Print summary of items on the quiz
135
+ --attempts Print summary of user quiz attempts (for published quizzes)
136
+ EOF
137
+
138
+ "quiz-section" => <<EOF,
139
+ sakai-info quiz-section
140
+
141
+ Usage: sakai-info quiz-section <id> [<options>]
142
+
143
+ Prints information about the quiz section ID specified. The ID may represent
144
+ a pending quiz section or a published quiz section. Additional options may be
145
+ passed to include additional information:
146
+
147
+ --items Print summary of items in the section
148
+ --mod Print creation/modification info
149
+ --all Print all possible details
150
+ --dbrow Print the raw database fields
151
+ EOF
152
+
153
+ "quiz-item" => <<EOF,
154
+ sakai-info quiz-item
155
+
156
+ Usage: sakai-info quiz-item <id> [<options>]
157
+
158
+ Prints information about the quiz item ID specified. The ID may represent
159
+ a pending quiz item or a published quiz item. Additional options may be
160
+ passed to include additional information:
161
+
162
+ --mod Print creation/modification info
163
+ --all Print all possible details
164
+ --dbrow Print the raw database fields
165
+ EOF
166
+
167
+ "question-pool" => <<EOF,
168
+ sakai-info question-pool
169
+
170
+ Usage: sakai-info qpool <id> [<options>]
171
+ sakai-info question-pool <id> [<options>]
172
+
173
+ Prints information about the question pool ID specified. Additional options
174
+ may be passed to include additional information:
175
+
176
+ --mod Print creation/modification info
177
+ --dbrow Print the raw database fields
178
+
179
+ Not yet implemented:
180
+ --items Print summary of items in the pool
181
+ --quizzes Print summary of quizzes that link to this pool
182
+ --all Print all possible details
183
+ EOF
184
+
97
185
  }
98
186
 
99
187
  def self.help(topic = :default, io = STDOUT)
@@ -2,7 +2,7 @@
2
2
  # SakaiInfo::Database library
3
3
  #
4
4
  # Created 2012-02-19 daveadams@gmail.com
5
- # Last updated 2012-02-24 daveadams@gmail.com
5
+ # Last updated 2012-02-25 daveadams@gmail.com
6
6
  #
7
7
  # https://github.com/daveadams/sakai-info
8
8
  #
@@ -79,7 +79,8 @@ module SakaiInfo
79
79
  end
80
80
  else
81
81
  @@config[database_name]
82
- end)
82
+ end,
83
+ @@logger)
83
84
  end
84
85
  @@databases[database_name].connect
85
86
  end
@@ -87,11 +88,26 @@ module SakaiInfo
87
88
  def self.default_database=(database_name)
88
89
  @@default_database_name = database_name
89
90
  end
91
+
92
+ # set global logger
93
+ @@logger = nil
94
+ def self.logger=(logger)
95
+ @@logger = logger
96
+
97
+ # also force it on any existing database connections
98
+ @@databases.each do |name, dbconn|
99
+ puts "updating #{name}"
100
+ puts dbconn.class
101
+ dbconn.logger = @@logger
102
+ puts dbconn.connect.loggers.inspect
103
+ end
104
+ end
90
105
  end
91
106
 
92
107
  class Database
93
- def initialize(connection_string)
108
+ def initialize(connection_string, logger = nil)
94
109
  @connection_string = connection_string.to_s
110
+ @logger = logger
95
111
  end
96
112
 
97
113
  def connect
@@ -105,6 +121,17 @@ module SakaiInfo
105
121
  @connection = nil
106
122
  raise ConnectionFailureException.new("Could not connect: #{e}")
107
123
  end
124
+
125
+ if not @logger.nil?
126
+ @connection.logger = @logger
127
+ end
128
+
129
+ return @connection
130
+ end
131
+
132
+ def logger=(logger)
133
+ @logger = logger
134
+ @connection.logger = @logger
108
135
  end
109
136
 
110
137
  def alive?
@@ -0,0 +1,73 @@
1
+ # sakai-info/mod_props.rb
2
+ # SakaiInfo::ModProps library
3
+ #
4
+ # Created 2012-02-26 daveadams@gmail.com
5
+ # Last updated 2012-02-26 daveadams@gmail.com
6
+ #
7
+ # https://github.com/daveadams/sakai-info
8
+ #
9
+ # This software is public domain.
10
+ #
11
+
12
+ module SakaiInfo
13
+ module ModProps
14
+ def self.included(klass)
15
+ klass.class_eval {
16
+ # defaults based on User and Site objects
17
+ def get_created_at_key; :createdon; end
18
+ def get_created_by_key; :createdby; end
19
+ def get_modified_at_key; :modifiedon; end
20
+ def get_modified_by_key; :modifiedby; end
21
+
22
+ def self.created_at_key(newkey)
23
+ self.class_eval("def get_created_at_key; :#{newkey}; end")
24
+ end
25
+
26
+ def self.created_by_key(newkey)
27
+ self.class_eval("def get_created_by_key; :#{newkey}; end")
28
+ end
29
+
30
+ def self.modified_at_key(newkey)
31
+ self.class_eval("def get_modified_at_key; :#{newkey}; end")
32
+ end
33
+
34
+ def self.modified_by_key(newkey)
35
+ self.class_eval("def get_modified_by_key; :#{newkey}; end")
36
+ end
37
+
38
+ def created_by_id
39
+ @dbrow[self.get_created_by_key]
40
+ end
41
+
42
+ def created_by
43
+ User.find(self.created_by_id)
44
+ end
45
+
46
+ def created_at
47
+ @dbrow[self.get_created_at_key]
48
+ end
49
+
50
+ def modified_by_id
51
+ @dbrow[self.get_modified_by_key]
52
+ end
53
+
54
+ def modified_by
55
+ User.find(self.modified_by_id)
56
+ end
57
+
58
+ def modified_at
59
+ @dbrow[self.get_modified_at_key]
60
+ end
61
+
62
+ def mod_serialization
63
+ {
64
+ "created_by" => self.created_by.serialize(:summary),
65
+ "created_at" => self.created_at.strftime("%Y-%m-%d %H:%M:%S"),
66
+ "modified_by" => self.modified_by.serialize(:summary),
67
+ "modified_at" => self.modified_at.strftime("%Y-%m-%d %H:%M:%S")
68
+ }
69
+ end
70
+ }
71
+ end
72
+ end
73
+ end