autumn 3.1.8

Sign up to get free protection for your applications and to get access to all the features.
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