autumn 3.1.8

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.
Files changed (111) hide show
  1. data/AUTHORS +11 -0
  2. data/CHANGELOG +567 -0
  3. data/MANIFEST +110 -0
  4. data/README +1114 -0
  5. data/README.textile +1153 -0
  6. data/Rakefile +75 -0
  7. data/autumn.gemspec +44 -0
  8. data/bin/autumn +11 -0
  9. data/lib/autumn.rb +8 -0
  10. data/lib/autumn/authentication.rb +238 -0
  11. data/lib/autumn/channel_leaf.rb +107 -0
  12. data/lib/autumn/coder.rb +166 -0
  13. data/lib/autumn/console_boot.rb +10 -0
  14. data/lib/autumn/ctcp.rb +250 -0
  15. data/lib/autumn/daemon.rb +207 -0
  16. data/lib/autumn/datamapper_hacks.rb +290 -0
  17. data/lib/autumn/foliater.rb +231 -0
  18. data/lib/autumn/formatting.rb +236 -0
  19. data/lib/autumn/generator.rb +231 -0
  20. data/lib/autumn/genesis.rb +190 -0
  21. data/lib/autumn/inheritable_attributes.rb +162 -0
  22. data/lib/autumn/leaf.rb +738 -0
  23. data/lib/autumn/log_facade.rb +49 -0
  24. data/lib/autumn/misc.rb +87 -0
  25. data/lib/autumn/resources/daemons/Anothernet.yml +3 -0
  26. data/lib/autumn/resources/daemons/AustHex.yml +29 -0
  27. data/lib/autumn/resources/daemons/Bahamut.yml +67 -0
  28. data/lib/autumn/resources/daemons/Dancer.yml +3 -0
  29. data/lib/autumn/resources/daemons/GameSurge.yml +3 -0
  30. data/lib/autumn/resources/daemons/IRCnet.yml +3 -0
  31. data/lib/autumn/resources/daemons/Ithildin.yml +7 -0
  32. data/lib/autumn/resources/daemons/KineIRCd.yml +56 -0
  33. data/lib/autumn/resources/daemons/PTlink.yml +6 -0
  34. data/lib/autumn/resources/daemons/QuakeNet.yml +20 -0
  35. data/lib/autumn/resources/daemons/RFC1459.yml +158 -0
  36. data/lib/autumn/resources/daemons/RFC2811.yml +16 -0
  37. data/lib/autumn/resources/daemons/RFC2812.yml +36 -0
  38. data/lib/autumn/resources/daemons/RatBox.yml +25 -0
  39. data/lib/autumn/resources/daemons/Ultimate.yml +24 -0
  40. data/lib/autumn/resources/daemons/Undernet.yml +6 -0
  41. data/lib/autumn/resources/daemons/Unreal.yml +110 -0
  42. data/lib/autumn/resources/daemons/_Other.yml +7 -0
  43. data/lib/autumn/resources/daemons/aircd.yml +33 -0
  44. data/lib/autumn/resources/daemons/bdq-ircd.yml +3 -0
  45. data/lib/autumn/resources/daemons/hybrid.yml +38 -0
  46. data/lib/autumn/resources/daemons/ircu.yml +67 -0
  47. data/lib/autumn/resources/daemons/tr-ircd.yml +8 -0
  48. data/lib/autumn/script.rb +74 -0
  49. data/lib/autumn/speciator.rb +165 -0
  50. data/lib/autumn/stem.rb +919 -0
  51. data/lib/autumn/stem_facade.rb +176 -0
  52. data/lib/autumn/tool/bin.rb +301 -0
  53. data/lib/autumn/tool/create.rb +48 -0
  54. data/lib/autumn/tool/project_creator.rb +110 -0
  55. data/lib/autumn/version.rb +3 -0
  56. data/lib/skel/Rakefile +163 -0
  57. data/lib/skel/config/global.yml +2 -0
  58. data/lib/skel/config/seasons/testing/database.yml +4 -0
  59. data/lib/skel/config/seasons/testing/leaves.yml +9 -0
  60. data/lib/skel/config/seasons/testing/season.yml +2 -0
  61. data/lib/skel/config/seasons/testing/stems.yml +10 -0
  62. data/lib/skel/leaves/administrator/README +20 -0
  63. data/lib/skel/leaves/administrator/controller.rb +67 -0
  64. data/lib/skel/leaves/administrator/views/autumn.txt.erb +1 -0
  65. data/lib/skel/leaves/administrator/views/reload.txt.erb +11 -0
  66. data/lib/skel/leaves/insulter/README +17 -0
  67. data/lib/skel/leaves/insulter/controller.rb +65 -0
  68. data/lib/skel/leaves/insulter/views/about.txt.erb +1 -0
  69. data/lib/skel/leaves/insulter/views/help.txt.erb +1 -0
  70. data/lib/skel/leaves/insulter/views/insult.txt.erb +1 -0
  71. data/lib/skel/leaves/scorekeeper/README +34 -0
  72. data/lib/skel/leaves/scorekeeper/config.yml +2 -0
  73. data/lib/skel/leaves/scorekeeper/controller.rb +104 -0
  74. data/lib/skel/leaves/scorekeeper/helpers/general.rb +64 -0
  75. data/lib/skel/leaves/scorekeeper/models/channel.rb +12 -0
  76. data/lib/skel/leaves/scorekeeper/models/person.rb +14 -0
  77. data/lib/skel/leaves/scorekeeper/models/pseudonym.rb +11 -0
  78. data/lib/skel/leaves/scorekeeper/models/score.rb +14 -0
  79. data/lib/skel/leaves/scorekeeper/tasks/stats.rake +17 -0
  80. data/lib/skel/leaves/scorekeeper/views/about.txt.erb +1 -0
  81. data/lib/skel/leaves/scorekeeper/views/change.txt.erb +5 -0
  82. data/lib/skel/leaves/scorekeeper/views/history.txt.erb +11 -0
  83. data/lib/skel/leaves/scorekeeper/views/points.txt.erb +5 -0
  84. data/lib/skel/leaves/scorekeeper/views/usage.txt.erb +1 -0
  85. data/lib/skel/log/README +1 -0
  86. data/lib/skel/script/console +28 -0
  87. data/lib/skel/script/destroy +48 -0
  88. data/lib/skel/script/generate +48 -0
  89. data/lib/skel/shared/README +1 -0
  90. data/lib/skel/tmp/README +1 -0
  91. data/spec/authentication_spec.rb +328 -0
  92. data/spec/channel_leaf_spec.rb +142 -0
  93. data/spec/coder_spec.rb +146 -0
  94. data/spec/ctcp_spec.rb +222 -0
  95. data/spec/daemon_spec.rb +202 -0
  96. data/spec/datamapper_hacks_spec.rb +164 -0
  97. data/tasks/authors.rake +30 -0
  98. data/tasks/changelog.rake +18 -0
  99. data/tasks/copyright.rake +21 -0
  100. data/tasks/doc.rake +7 -0
  101. data/tasks/gem.rake +23 -0
  102. data/tasks/gem_installer.rake +76 -0
  103. data/tasks/install_dependencies.rake +6 -0
  104. data/tasks/manifest.rake +4 -0
  105. data/tasks/rcov.rake +23 -0
  106. data/tasks/release.rake +52 -0
  107. data/tasks/reversion.rake +8 -0
  108. data/tasks/setup.rake +24 -0
  109. data/tasks/spec.rake +7 -0
  110. data/tasks/yard.rake +4 -0
  111. metadata +188 -0
@@ -0,0 +1,176 @@
1
+ # Defines the Autumn::StemFacade class, which provides additional convenience
2
+ # methods to Autumn::Stem.
3
+
4
+ module Autumn
5
+
6
+ # A collection of convenience methods that are added to the Stem class. These
7
+ # methods serve two purposes; one, to allow easier backwards compatibility
8
+ # with Autumn Leaves 1.0 (which had a simpler one-stem-per-leaf approach), and
9
+ # two, to make it easier or more Ruby-like to perform certain IRC actions.
10
+
11
+ module StemFacade
12
+
13
+ # Sends a message to one or more channels or nicks. If no channels or nicks
14
+ # are specified, broadcasts the message to every channel the stem is in. If
15
+ # you are sending a message to a channel you must prefix it correctly; the
16
+ # "#" will not be added before the channel name for you.
17
+ #
18
+ # message "Look at me!" # Broadcasts to all channels
19
+ # message "I love kitties", '#kitties' # Sends a message to one channel or person
20
+ # message "Learn to RTFM", '#help', 'NoobGuy' # Sends a message to two channels or people
21
+
22
+ def message(msg, *chans)
23
+ return if msg.nil? or msg.empty?
24
+ chans = channels if chans.empty?
25
+ if @throttle then
26
+ Thread.exclusive { msg.each_line { |line| privmsgt chans.to_a, line.strip unless line.strip.empty? } }
27
+ else
28
+ msg.each_line { |line| privmsg chans.to_a, line.strip unless line.strip.empty? }
29
+ end
30
+ end
31
+
32
+ # Sets the topic for one or more channels. If no channels are specified,
33
+ # sets the topic of every channel the stem is in.
34
+ #
35
+ # set_topic "Bots sure are fun!", 'bots', 'morebots'
36
+
37
+ def set_topic(motd, *chans)
38
+ return if motd.nil?
39
+ chans = chans.empty? ? channels : chans.map { |chan| normalized_channel_name chan }
40
+ chans.each { |chan| topic chan, motd }
41
+ end
42
+
43
+ # Joins a channel by name. If the channel is password-protected, specify the
44
+ # +password+ parameter. Of course, you could always just call the +join+
45
+ # method (since each IRC command has a method named after it), but the
46
+ # advantage to using this method is that it will also update the
47
+ # <tt>@channel_passwords</tt> instance variable. Internal consistency is a
48
+ # good thing, so please use this method.
49
+
50
+ def join_channel(channel, password=nil)
51
+ channel = normalized_channel_name(channel)
52
+ return if channels.include? channel
53
+ join channel, password
54
+ @channel_passwords[channel] = password if password
55
+ end
56
+
57
+ # Leaves a channel, specified by name.
58
+
59
+ def leave_channel(channel)
60
+ channel = normalized_channel_name(channel)
61
+ return unless channels.include? channel
62
+ part channel
63
+ end
64
+
65
+ # Changes this stem's IRC nick. Note that the stem's original nick will
66
+ # still be used by the logger.
67
+
68
+ def change_nick(new_nick)
69
+ nick new_nick
70
+ end
71
+
72
+ # Grants a privilege to a channel member, such as voicing a member. The stem
73
+ # must have the required privilege level to perform this command.
74
+ # +privilege+ can either be a symbol from the Daemon instance or a string
75
+ # with the letter code for the privilege.
76
+ #
77
+ # grant_user_privilege 'mychannel', 'Somedude', :operator
78
+ # grant_user_privilege '#mychannel', 'Somedude', 'oa'
79
+
80
+ def grant_user_privilege(channel, nick, privilege)
81
+ channel = normalized_channel_name(channel)
82
+ privcode = server_type.privilege.index(privilege).chr if server_type.privilege.value? privilege
83
+ privcode ||= privilege
84
+ mode channel, "+#{privcode}", nick
85
+ end
86
+
87
+ # Removes a privilege to a channel member, such as voicing a member. The
88
+ # stem must have the required privilege level to perform this command.
89
+ # +privilege+ can either be a symbol from the Daemon instance or a string
90
+ # with the letter code for the privilege.
91
+
92
+ def remove_user_privilege(channel, nick, privilege)
93
+ channel = normalized_channel_name(channel)
94
+ privcode = server_type.privilege.index(privilege).chr if server_type.privilege.value? privilege
95
+ privcode ||= privilege
96
+ mode channel, "-#{privcode}", nick
97
+ end
98
+
99
+ # Grants a usermode to an IRC nick, such as making a nick invisible.
100
+ # The stem must have the required privilege level to perform this command.
101
+ # (Generally, one can only change his own usermode unless he is a server
102
+ # op.) +mode+ can either be a symbol from the Daemon instance or a string
103
+ # with the letter code for the usermode.
104
+ #
105
+ # grant_usermode 'Spycloak', :invisible
106
+ # grant_usermode 'UpMobility', 'os'
107
+
108
+ def grant_usermode(nick, property)
109
+ propcode = server_type.usermode.index(property).chr if server_type.usermode.value? property
110
+ propcode ||= property
111
+ mode nick, "+#{property}"
112
+ end
113
+
114
+ # Revokes a usermode from an IRC nick, such as removing invisibility. The
115
+ # stem must have the required privilege level to perform this command.
116
+ # (Generally, one can only change his own usermode unless he is a server
117
+ # op.) +mode+ can either be a symbol from the Daemon instance or a string
118
+ # with the letter code for the usermode.
119
+
120
+ def remove_usermode(nick, property)
121
+ propcode = server_type.usermode.index(property).chr if server_type.usermode.value? property
122
+ propcode ||= property
123
+ mode nick, "-#{property}"
124
+ end
125
+
126
+ # Sets a property of a channel, such as moderated. The stem must have the
127
+ # required privilege level to perform this command. +property+ can either be
128
+ # a symbol from the Daemon instance or a string with the letter code for the
129
+ # property. If the property takes an argument (such as when setting a
130
+ # channel password), pass it as the +argument+ paramter.
131
+ #
132
+ # set_channel_property '#mychannel', :secret
133
+ # set_channel_property 'mychannel', :keylock, 'mypassword'
134
+ # set_channel_property '#mychannel', 'ntr'
135
+
136
+ def set_channel_property(channel, property, argument=nil)
137
+ channel = normalized_channel_name(channel)
138
+ propcode = server_type.channel_property.index(property).chr if server_type.channel_property.value? property
139
+ propcode ||= property
140
+ mode channel, "+#{propcode}", argument
141
+ end
142
+
143
+ # Removes a property of a channel, such as moderated. The stem must have the
144
+ # required privilege level to perform this command. +property+ can either be
145
+ # a symbol from the Daemon instance or a string with the letter code for the
146
+ # property. If the property takes an argument (such as when removing a
147
+ # channel password), pass it as the +argument+ paramter.
148
+
149
+ def unset_channel_property(channel, property, argument=nil)
150
+ channel = normalized_channel_name(channel)
151
+ propcode = server_type.channel_property.index(property).chr if server_type.channel_property.value? property
152
+ propcode ||= property
153
+ mode channel, "-#{propcode}", argument
154
+ end
155
+
156
+ # Returns an array of nicks for users that are in a channel.
157
+
158
+ def users(channel)
159
+ channel = normalized_channel_name(channel)
160
+ @chan_mutex.synchronize { @channel_members[channel] && @channel_members[channel].keys }
161
+ end
162
+
163
+ # Returns the privilege level of a channel member. The privilege level will
164
+ # be a symbol from the Daemon instance. Returns nil if the channel member
165
+ # doesn't exist or if the bot is not on the given channel. Returns an array
166
+ # of privileges if the server supports multiple privileges per user, and the
167
+ # user has more than one privilege.
168
+ #
169
+ # +user+ can be a nick or a sender hash.
170
+
171
+ def privilege(channel, user)
172
+ user = user[:nick] if user.kind_of? Hash
173
+ @chan_mutex.synchronize { @channel_members[channel] && @channel_members[channel][user] }
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,301 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ ### This module offers the functionality to start, stop, restart, create,
4
+ ### Check status, or run a console of an autumn application
5
+ ### see autumn -h for usage
6
+ module Autumn
7
+ module Tool
8
+ module Bin
9
+ module Helpers # Helper methods {{{
10
+
11
+ def default_pidfile # {{{
12
+ return @default_pidfile if @default_pidfile
13
+ al_root
14
+ pn = Pathname.new(AL_ROOT)
15
+ @default_pidfile = (pn.expand_path.join("tmp", pn.basename.to_s + ".pid")).strip
16
+ end # }}}
17
+
18
+ # We're really only concerned about win32ole, so we focus our check on its
19
+ # ability to load that
20
+ def is_windows? # {{{
21
+ return @is_win if @is_win
22
+ begin
23
+ require "win32ole"
24
+ rescue LoadError
25
+ end
26
+ @is_win ||= Object.const_defined?("WIN32OLE")
27
+ end # }}}
28
+
29
+ def is_running?(pid) # {{{
30
+ if is_windows?
31
+ wmi = WIN32OLE.connect("winmgmts://")
32
+ processes, ours = wmi.ExecQuery("select * from win32_process where ProcessId = #{pid}"), []
33
+ processes.each { |process| ours << process.Name }
34
+ ours.first.nil?
35
+ else
36
+ begin
37
+ prio = Process.getpriority(Process::PRIO_PROCESS, pid)
38
+ true
39
+ rescue Errno::ESRCH
40
+ false
41
+ end
42
+ end
43
+ end # }}}
44
+
45
+ def check_running?(pid_file) # {{{
46
+ return false unless File.file?(pid_file)
47
+ is_running?(File.read(pid_file).to_i)
48
+ end # }}}
49
+
50
+ def find_pid(pid_file) # {{{
51
+ if pid_file.nil? or not File.file?(pid_file)
52
+ pid_file = default_pidfile
53
+ end
54
+ unless File.file?(pid_file)
55
+ $stderr.puts "Could not find running process id."
56
+ return false
57
+ end
58
+ pid_file
59
+ end # }}}
60
+ end # End helper methods }}}
61
+
62
+ class Cmd # This class contains the command methods {{{
63
+ include Helpers
64
+ attr_accessor :command
65
+
66
+ def initialize(args = nil)
67
+ args ||= ARGV
68
+ raise "arguments must be an array!" unless args.respond_to?(:detect)
69
+ @ourargs = args.dup
70
+ @command = args.detect { |arg| arg.match(/^(?:--?)?(?:start|stop|restart|create|h(?:elp)?|v(?:ersion)?|console|status)/) }
71
+ if command.nil?
72
+ @command = ""
73
+ else
74
+ args.delete(@command)
75
+ end
76
+ ARGV.replace(args)
77
+ end
78
+
79
+ # {{{ #run is called when we're interactive ($0 == __FILE__)
80
+ def self.run(args = nil)
81
+ cmd = new(args)
82
+ case cmd.command
83
+ when /^(?:--?)?status$/
84
+ cmd.status(cmd.command)
85
+ when /^(?:--?)?restart$/
86
+ cmd.stop(cmd.command)
87
+ cmd.start
88
+ when /^(?:--?)?start$/
89
+ cmd.start
90
+ when /^(?:--?)?create$/
91
+ cmd.create(cmd.command)
92
+ when /^(?:--?)?stop$/
93
+ if cmd.stop(cmd.command)
94
+ puts "Autumn session has ended."
95
+ $stdout.flush
96
+ else
97
+ puts "Autumn failed to stop (or was not running)"
98
+ end
99
+ when /^(?:--?)?console$/
100
+ require "irb"
101
+ require "irb/completion"
102
+ cmd.include_autumn
103
+ require "lib/genesis"
104
+ IRB.start
105
+ puts "Autumn session has ended."
106
+ when /^(?:--?)?h(elp)?$/
107
+ puts cmd.usage
108
+ when /^(?:--?)?v(ersion)?$/
109
+ cmd.include_autumn
110
+ puts Autumn::VERSION
111
+ exit
112
+ when /^$/
113
+ puts "Must supply a valid command"
114
+ puts cmd.usage
115
+ exit 1
116
+ else
117
+ puts "#{command} not implemented"
118
+ puts cmd.usage
119
+ exit 1
120
+ end
121
+ end # }}}
122
+
123
+ def include_autumn # {{{
124
+ begin
125
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '/../lib')
126
+ require 'autumn'
127
+ rescue LoadError
128
+ $LOAD_PATH.shift
129
+
130
+ begin
131
+ require 'rubygems'
132
+ rescue LoadError
133
+ end
134
+ require 'autumn'
135
+ end
136
+ end # }}}
137
+
138
+ def usage # {{{
139
+ txt = [
140
+ "\n Usage:",
141
+ "autumn <start|stop|restart|status|create|console> PROJECT [options]\n",
142
+ "Commands:\n",
143
+ " start - Starts an instance of this application.\n",
144
+ " stop - Stops a running instance of this application.\n",
145
+ " restart - Stops running instance of this application, then starts it back up. Pidfile",
146
+ " (if supplied) is used for both stop and start.\n",
147
+ " status - Gives status of a running autumn instance\n",
148
+ " create - Creates a new prototype Autumn application in a directory named PROJECT in",
149
+ " the current directory. autumn create foo would make ./foo containing an",
150
+ " application prototype.\n",
151
+ " console - Starts an irb console with autumn (and irb completion) loaded.",
152
+ " ARGV is passed on to IRB.\n\n"
153
+ ].join("\n\t")
154
+
155
+ txt << "* All commands take PROJECT as the directory the autumn bot lives in.\n\n"
156
+ txt << start_options.to_s << "\n"
157
+ txt << create_options.to_s << "\n"
158
+ #if is_windows?
159
+ #txt << %x{ruby #{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
160
+ #else
161
+ #txt << %x{#{rackup_path} --help}.split("\n").reject { |line| line.match(/^Usage:/) }.join("\n\t")
162
+ #end
163
+ end # }}}
164
+
165
+ def start_options
166
+ @start_opts ||= OptionParser.new do |o|
167
+ o.banner = "Start/Restart Options"
168
+ o.on("-D", "--daemonize", "Daemonize the process") { |daem| @daemonize = true }
169
+ end
170
+ end
171
+
172
+ def al_root
173
+ require "pathname"
174
+ dir = nil
175
+ if ARGV.size == 1
176
+ dir = Pathname.new(ARGV.shift)
177
+ elsif ARGV.size > 1
178
+ $stderr.puts "Unknown options given #{ARGV.join(" ")}"
179
+ puts usage
180
+ exit 1
181
+ end
182
+ if dir.nil? or not dir.directory?
183
+ dir = Pathname.new(ENV["PWD"]).expand_path
184
+ $stderr.puts "Path to autumn tree not given or invalid, using #{dir}"
185
+ end
186
+ Object.const_set("AL_ROOT", dir.expand_path.to_s)
187
+ Dir.chdir(AL_ROOT)
188
+ end
189
+
190
+ ### Methods for commands {{{
191
+ def start # {{{
192
+ start_options.parse!(ARGV)
193
+ al_root
194
+
195
+ # Find the name of this app
196
+ puts "starting autumn"
197
+ if @daemonize
198
+ require "daemons"
199
+ Daemons.run_proc(Pathname.new(AL_ROOT).basename, :ARGV => ["start"], :dir_mode => :normal, :dir => "tmp", :multiple => false) do
200
+ start_autumn
201
+ end
202
+ puts "Autumn started in the background"
203
+ else
204
+ start_autumn
205
+ end
206
+ end # }}}
207
+
208
+ def start_autumn
209
+ require "autumn/genesis"
210
+ puts "Loading Autumn #{Autumn::VERSION}"
211
+ Autumn::Genesis.new.boot!
212
+ end
213
+
214
+ def create_options(opts = {})
215
+ @create_opts ||= OptionParser.new do |o|
216
+ o.banner = "Create Options"
217
+ o.on("-f", "--force", "Force creation if dir already exists") { |yn| opts[:force] = true }
218
+ o.on("-a", "--amend", "Update a tree") { |yn| opts[:amend] = true }
219
+ end
220
+ end
221
+
222
+ def create(command) # {{{
223
+ create_options(opts = {}).parse!(ARGV)
224
+ unless ARGV.size == 1
225
+ $stderr.puts "Invalid options given: #{ARGV.join(" ")}"
226
+ exit 1
227
+ end
228
+ project_name = ARGV.shift
229
+ if project_name.nil?
230
+ $stderr.puts "Must supply a valid project name, you gave none."
231
+ puts usage
232
+ exit 1
233
+ end
234
+ include_autumn
235
+ require 'autumn/tool/create'
236
+ Autumn::Tool::Create.create(project_name, opts)
237
+ end # }}}
238
+
239
+ def stop(command) # {{{
240
+ al_root
241
+ require "daemons"
242
+ Daemons.run_proc(Pathname.new(AL_ROOT).basename, :ARGV => ["stop"], :dir_mode => :normal, :dir => "tmp", :multiple => false) do
243
+ start_autumn
244
+ end
245
+ end # }}}
246
+
247
+ def status(command) # {{{
248
+ al_root
249
+ pn = Pathname.new(AL_ROOT)
250
+ unless pid_file = find_pid(pn.join("tmp", pn.basename.to_s + ".pid"))
251
+ $stderr.puts "No pid_file found! Autumn may not be started."
252
+ exit 1
253
+ end
254
+ puts "Pid file #{pid_file} found, PID is #{pid = File.read(pid_file).chomp}"
255
+ unless is_running?(pid.to_i)
256
+ $stderr.puts "PID #{pid} is not running"
257
+ exit 1
258
+ end
259
+ if is_windows?
260
+ wmi = WIN32OLE.connect("winmgmts://")
261
+ processes, ours = wmi.ExecQuery("select * from win32_process where ProcessId = #{pid}"), []
262
+ processes.each { |p| ours << [p.Name, p.CommandLine, p.VirtualSize, p.CreationDate, p.ExecutablePath, p.Status ] }
263
+ puts "Autumn is running!\n\tName: %s\n\tCommand Line: %s\n\tVirtual Size: %s\n\tStarted: %s\n\tExec Path: %s\n\tStatus: %s" % ours.first
264
+ else
265
+ require "pathname"
266
+ # Check for /proc
267
+ if File.directory?(proc_dir = Pathname.new("/proc"))
268
+ proc_dir = proc_dir.join(pid)
269
+ # If we have a "stat" file, we'll assume linux and get as much info
270
+ # as we can
271
+ if stat_file = proc_dir.join("stat") and stat_file.file?
272
+ stats = File.read(stat_file).split
273
+ puts "Autumn is running!\n\tCommand Line: %s\n\tVirtual Size: %s\n\tStarted: %s\n\tExec Path: %s\n\tStatus: %s" % [
274
+ File.read(proc_dir.join("cmdline")).split("\000").join(" "),
275
+ "%s k" % (stats[22].to_f / 1024),
276
+ File.mtime(proc_dir),
277
+ File.readlink(proc_dir.join("exe")),
278
+ stats[2]
279
+ ]
280
+ exit
281
+ end
282
+ end
283
+ # Fallthrough status, just print a ps
284
+ puts "Autumn process #{pid} is running!"
285
+ begin
286
+ puts %x{ps l #{pid}}
287
+ rescue
288
+ puts "No further information available"
289
+ end
290
+ end
291
+ end # }}}
292
+
293
+ ### End of command methods }}}
294
+ end # }}}
295
+ end
296
+ end
297
+ end
298
+
299
+ if $0 == __FILE__
300
+ Autumn::Tool::Bin::Cmd.run(ARGV)
301
+ end