[21884] trunk/base/portmgr/bots/port.rb

source_changes at macosforge.org source_changes at macosforge.org
Sat Feb 10 16:30:56 PST 2007


Revision: 21884
          http://trac.macosforge.org/projects/macports/changeset/21884
Author:   jberry at macports.org
Date:     2007-02-10 16:30:55 -0800 (Sat, 10 Feb 2007)

Log Message:
-----------
Add new commands to mpbot's port plugin:

 * port remember <nick> location <location>
    specifies physical location of a nick
 * port remember <nick> timezone <timezone>
    specifies timezone for a nick (relative to /usr/share/zoneinfo)
 * port forget <nick> email
    forgets email correspondance for nick
 * port forget <nick> location
    forgets location correspondance for nick
 * port forget <nick> timezone
    forgets timezone correspondance for nick
 * port whereis
 <nick>
    tells what it knows about <nick>'s location and timezone
 * port whois and the herald message also include some whereis info.

Modified Paths:
--------------
    trunk/base/portmgr/bots/port.rb

Modified: trunk/base/portmgr/bots/port.rb
===================================================================
--- trunk/base/portmgr/bots/port.rb	2007-02-10 23:48:14 UTC (rev 21883)
+++ trunk/base/portmgr/bots/port.rb	2007-02-11 00:30:55 UTC (rev 21884)
@@ -10,6 +10,10 @@
 #
 
 
+require 'fileutils.rb'
+require 'stringio'
+
+
 module Shuffle
 
 	def shuffle!
@@ -45,14 +49,78 @@
 		  when "herald"
 			return "herald enable|disable => enable or disable heralding by port"
 		  when "remember"
-			return "remember <nick> email <address> => remember what port maintainer email <nick> belongs to"
+			return "remember <nick> email <address> => remember what port maintainer email <nick> belongs to; " +
+					"remember <nick> timezone <timezone> => remember the local timezone for <nick>; " +
+					"remember <nick> location <location> => remember the physical location for <nick>"
 		  when "forget"
-			return "forget <nick> => forget email correspondance for <nick>"
+			return "forget <nick> => forget all information for <nick>; " +
+				"forget email <nick> => forget email correspondance for <nick>; " +
+				"forget timezone <nick> => forget local timezone for <nick>; " +
+				"forget location <nick> => forget physical location for <nick>"
+		  when "whois"
+		  	return "whois <nick> => give a summary of information for <nick>"
+		  when "whereis"
+		  	return "whereis <nick> => tell what is know about timezone and location of <nick>"
 		  else
-			return "port (MacPorts) commands: info, maintainer, version, herald, remember, forget, whois"
+			return "port (MacPorts) commands: info, maintainer, version, herald, remember, forget, whois, whereis"
 		end
 	end
 	
+	def runCmd(cmd, args, input=nil, output=nil, env={})
+		# Open pipes for stdin, and stdout
+		stdin,   inwrite = IO.pipe
+		outread, stdout  = IO.pipe
+	
+		# Fork the child
+		pid = fork {
+			# In child
+			
+			# Change the environment
+			ENV.update(env)
+	
+			# Redirect IO to the pipes
+			inwrite.close
+			$stdin.reopen(stdin)
+			stdin.close
+			
+			outread.close
+			$stdout.reopen(stdout)
+			$stderr.reopen(stdout)
+			stdout.close
+						
+			# Execute the command
+			exec(cmd, *args)
+			# shouldn't return
+		}
+		
+		# Close unneeded pipe-ends in this process
+		[stdin, stdout].each { |io| io.close }
+		
+		# In order to avoid deadlock, invoke a secondary process to write the input
+		open("|-", "w+") { |p|
+			if (p == nil)
+				# In child
+				FileUtils.copy_stream(input, inwrite) if !input.nil?
+				inwrite.close
+			end
+		}
+		
+		# Close remaining write pipe into command
+		inwrite.close
+	
+		# Read the stdout from the command, writing it to output
+		FileUtils.copy_stream(outread, output) if !output.nil?
+		
+		# Close remaining pipe ends
+		[outread].each { |io| io.close }
+		
+		# Collect the return code
+		pid, rc = Process.waitpid2(pid)
+		rc >>= 8
+		
+		return rc
+	end
+
 	def callPort(*args)
 		Utils.safe_exec("/opt/local/bin/port", *args)
 	end
@@ -90,19 +158,53 @@
 		m.okay
 	end
 	
-	def remember(m, params)
+	def rememberEmail(m, params)
 		nick = params[:nick]
 		email = params[:email]
 		@registry["email_#{nick}"] = email
 		m.reply "okay, #{nick} is #{email}"
 	end
 	
+	def rememberTimeZone(m, params)
+		nick = params[:nick]
+		timezone = params[:timezone]
+		@registry["timezone_#{nick}"] = timezone
+		m.reply "okay, #{nick} is in timezone #{timezone}"
+	end
+	
+	def rememberLocation(m, params)
+		nick = params[:nick]
+		location = params[:location].join(' ')
+		@registry["location_#{nick}"] = location
+		m.reply "okay, #{nick} is in #{location}"
+	end
+	
 	def forget(m, params)
 		nick = params[:nick]
 		@registry.delete("email_#{nick}")
 		m.okay
 	end
 
+	def forgetEmail(m, params)
+		nick = params[:nick]
+		@registry.delete("email_#{nick}")
+		@registry.delete("timezone_#{nick}")
+		@registry.delete("location_#{nick}")
+		m.okay
+	end
+
+	def forgetTimeZone(m, params)
+		nick = params[:nick]
+		@registry.delete("timezone_#{nick}")
+		m.okay
+	end
+
+	def forgetLocation(m, params)
+		nick = params[:nick]
+		@registry.delete("location_#{nick}")
+		m.okay
+	end
+
 	def whois(m, params)
 		nick = params[:nick]
 		email = @registry["email_#{nick}"]
@@ -113,6 +215,47 @@
 		end
 	end
 	
+	def localTimeInTimeZone(timeZone)
+		localTime = nil
+		StringIO.open("", "r+") { |o|
+			runCmd("/bin/date", "+%a %H:%M %Z", nil, o, { "TZ" => timeZone } )
+			o.close_write
+			localTime = o.string
+		}
+		return localTime
+	end
+	
+	def whereisNick(nick)
+		location = @registry["location_#{nick}"]
+		timeZone = @registry["timezone_#{nick}"]
+		
+		localTime = nil
+		if timeZone
+			localTime = localTimeInTimeZone(timeZone)
+		end
+		
+		if location && localTime
+			whereis = "is in #{location}; local time is #{localTime}"
+		elsif location
+			whereis = "is in #{location}"
+		elsif localTime
+			whereis = "is at local time #{localTime}"
+		else
+			whereis = nil
+		end
+	end
+	
+	def whereis(m, params)
+		nick = params[:nick]
+		
+		where = whereisNick(nick)
+		if where
+			m.reply "#{nick} #{where}"
+		else
+			m.reply "I don't know where #{nick} is"
+		end
+	end
+	
 	def textEnumeration(a)
 		sz = a.size
 		case sz
@@ -137,16 +280,25 @@
 				showMax = 4
 				somePorts = ports.extend(Shuffle).shuffle!.slice(0, showMax)
 				
+				msg = nil;
+				
 				if (portCount == 0)
-					@bot.say where, "#{nick} is #{email}"
+					msg = "#{nick} is #{email}"
 				elsif (portCount <= showMax)
-					@bot.say where, "#{nick} is #{email} and maintainer of " +
+					msg = "#{nick} is #{email} and maintainer of " +
 						textEnumeration(somePorts)
 				else
-					@bot.say where, "#{nick} is #{email} and maintainer of " +
+					msg = "#{nick} is #{email} and maintainer of " +
 						textEnumeration(somePorts) +
 						" (of #{portCount} total)"
-				end	
+				end
+				
+				whereis = whereisNick(nick)
+				if whereis
+					msg = msg + " and #{whereis}"
+				end
+				
+				@bot.say where, msg
 			end
 		end
 	end
@@ -198,6 +350,12 @@
 
 plugin.map 'port herald enable', :action => 'herald_enable'
 plugin.map 'port herald disable', :action => 'herald_disable'
-plugin.map 'port remember :nick email :email', :action => 'remember'
+plugin.map 'port remember :nick timezone :timezone', :action => 'rememberTimeZone'
+plugin.map 'port remember :nick email :email', :action => 'rememberEmail'
+plugin.map 'port remember :nick location *location', :action => 'rememberLocation'
 plugin.map 'port forget :nick', :action => 'forget'
+plugin.map 'port forget :nick email', :action => 'forgetEmail'
+plugin.map 'port forget :nick timezone', :action => 'forgetTimeZone'
+plugin.map 'port forget :nick location', :action => 'forgetLocation'
 plugin.map 'port whois :nick', :action => 'whois'
+plugin.map 'port whereis :nick', :action => 'whereis'

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20070210/e2fda2b9/attachment.html


More information about the macports-changes mailing list