Annotation of micropolis/micropolisactivity.py, revision 1.1

1.1     ! root        1: # -*- mode: python; tab-width: 4 -*-
        !             2: #
        !             3: # Micropolis, Unix Version.  This game was released for the Unix platform
        !             4: # in or about 1990 and has been modified for inclusion in the One Laptop
        !             5: # Per Child program.  Copyright (C) 1989 - 2007 Electronic Arts Inc.  If
        !             6: # you need assistance with this program, you may contact:
        !             7: #   http://wiki.laptop.org/go/Micropolis  or email  [email protected].
        !             8: # 
        !             9: # This program is free software: you can redistribute it and/or modify
        !            10: # it under the terms of the GNU General Public License as published by
        !            11: # the Free Software Foundation, either version 3 of the License, or (at
        !            12: # your option) any later version.
        !            13: # 
        !            14: # This program is distributed in the hope that it will be useful, but
        !            15: # WITHOUT ANY WARRANTY; without even the implied warranty of
        !            16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            17: # General Public License for more details.  You should have received a
        !            18: # copy of the GNU General Public License along with this program.  If
        !            19: # not, see <http://www.gnu.org/licenses/>.
        !            20: # 
        !            21: #             ADDITIONAL TERMS per GNU GPL Section 7
        !            22: # 
        !            23: # No trademark or publicity rights are granted.  This license does NOT
        !            24: # give you any right, title or interest in the trademark SimCity or any
        !            25: # other Electronic Arts trademark.  You may not distribute any
        !            26: # modification of this program using the trademark SimCity or claim any
        !            27: # affliation or association with Electronic Arts Inc. or its employees.
        !            28: # 
        !            29: # Any propagation or conveyance of this program must include this
        !            30: # copyright notice and these terms.
        !            31: # 
        !            32: # If you convey this program (or any modifications of it) and assume
        !            33: # contractual liability for the program to recipients of it, you agree
        !            34: # to indemnify Electronic Arts for any liability that those contractual
        !            35: # assumptions impose on Electronic Arts.
        !            36: # 
        !            37: # You may not misrepresent the origins of this program; modified
        !            38: # versions of the program must be marked as such and not identified as
        !            39: # the original program.
        !            40: # 
        !            41: # This disclaimer supplements the one included in the General Public
        !            42: # License.  TO THE FULLEST EXTENT PERMISSIBLE UNDER APPLICABLE LAW, THIS
        !            43: # PROGRAM IS PROVIDED TO YOU "AS IS," WITH ALL FAULTS, WITHOUT WARRANTY
        !            44: # OF ANY KIND, AND YOUR USE IS AT YOUR SOLE RISK.  THE ENTIRE RISK OF
        !            45: # SATISFACTORY QUALITY AND PERFORMANCE RESIDES WITH YOU.  ELECTRONIC ARTS
        !            46: # DISCLAIMS ANY AND ALL EXPRESS, IMPLIED OR STATUTORY WARRANTIES,
        !            47: # INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY, SATISFACTORY QUALITY,
        !            48: # FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT OF THIRD PARTY
        !            49: # RIGHTS, AND WARRANTIES (IF ANY) ARISING FROM A COURSE OF DEALING,
        !            50: # USAGE, OR TRADE PRACTICE.  ELECTRONIC ARTS DOES NOT WARRANT AGAINST
        !            51: # INTERFERENCE WITH YOUR ENJOYMENT OF THE PROGRAM; THAT THE PROGRAM WILL
        !            52: # MEET YOUR REQUIREMENTS; THAT OPERATION OF THE PROGRAM WILL BE
        !            53: # UNINTERRUPTED OR ERROR-FREE, OR THAT THE PROGRAM WILL BE COMPATIBLE
        !            54: # WITH THIRD PARTY SOFTWARE OR THAT ANY ERRORS IN THE PROGRAM WILL BE
        !            55: # CORRECTED.  NO ORAL OR WRITTEN ADVICE PROVIDED BY ELECTRONIC ARTS OR
        !            56: # ANY AUTHORIZED REPRESENTATIVE SHALL CREATE A WARRANTY.  SOME
        !            57: # JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF OR LIMITATIONS ON IMPLIED
        !            58: # WARRANTIES OR THE LIMITATIONS ON THE APPLICABLE STATUTORY RIGHTS OF A
        !            59: # CONSUMER, SO SOME OR ALL OF THE ABOVE EXCLUSIONS AND LIMITATIONS MAY
        !            60: # NOT APPLY TO YOU.
        !            61: 
        !            62: import gtk
        !            63: import os
        !            64: import signal
        !            65: import tempfile
        !            66: import logging
        !            67: import sys
        !            68: import time
        !            69: import subprocess
        !            70: import thread
        !            71: import fcntl
        !            72: 
        !            73: from sugar.activity import activity
        !            74: from sugar.activity.activity import get_bundle_path
        !            75: from sugar import profile
        !            76: from gettext import gettext as _
        !            77: from glob import glob
        !            78: 
        !            79: try:
        !            80:     import pygame.mixer
        !            81:     pygame.mixer.init()
        !            82: except: pass
        !            83: 
        !            84: try:
        !            85:     from sugar.presence import presenceservice
        !            86: except ImportError:
        !            87:     from sugar.presence import PresenceService as presenceservice
        !            88: 
        !            89: 
        !            90: def QuoteTCL(s):
        !            91:     return s.replace('"', '\\"')
        !            92: 
        !            93: 
        !            94: class MicropolisActivity(activity.Activity):
        !            95: 
        !            96:     def __init__(self, handle):
        !            97: 
        !            98:         activity.Activity.__init__(self, handle)
        !            99:     
        !           100:         self.set_title(_('Micropolis Activity'))
        !           101:         self.connect('destroy', self._destroy_cb)
        !           102:         self.connect('focus-in-event', self._focus_in_cb)
        !           103:         self.connect('focus-out-event', self._focus_out_cb)
        !           104: 
        !           105:         signal.signal(signal.SIGCHLD, self._sigchild_handler)
        !           106: 
        !           107:         self._bundle_path = get_bundle_path()
        !           108: 
        !           109:         if False:
        !           110:             # FIXME: Plug Micropolis's window into a gtk socket.
        !           111:             # Doesn't work yet, but it would be cool if it did. 
        !           112:             socket = gtk.Socket()
        !           113:             try:
        !           114:                 self.set_canvas(socket)
        !           115:             except AttributeError:
        !           116:                 self.add(socket)
        !           117:             socket.show()
        !           118:             socket.connect('plug-added', self._plug_added_cb)
        !           119:             socket.connect('plug-removed', self._plug_removed_cb)
        !           120: 
        !           121:             win = socket.get_id()
        !           122: 
        !           123:         command = os.path.join(
        !           124:             self._bundle_path,
        !           125:             'Micropolis')
        !           126: 
        !           127:         args = [
        !           128:             command,
        !           129:             #'-R', str(win), # Set root window to socket window id
        !           130:             '-t', # Interactive tty mode, so we can send it commands.
        !           131:         ]
        !           132: 
        !           133:         logging.debug("CWD: " + self._bundle_path)
        !           134:         logging.debug("Micropolis ARGS: " + repr(args))
        !           135: 
        !           136:         self._process = subprocess.Popen(
        !           137:             args,
        !           138:             stdin=subprocess.PIPE,
        !           139:             stdout=subprocess.PIPE,
        !           140:             close_fds=True,
        !           141:             cwd=self._bundle_path,
        !           142:             preexec_fn=lambda: os.chdir(self._bundle_path))
        !           143: 
        !           144:         logging.debug("STARTING THREAD... " + str(self._stdout_thread_function))
        !           145:         t = None
        !           146:         try:
        !           147:             t = thread.start_new(
        !           148:                 self._stdout_thread_function,
        !           149:                 ())
        !           150:         except Exception, e:
        !           151:             logging.debug("EXCEPTION " + str(e))
        !           152:         self._stdout_thread = t
        !           153:         logging.debug("STARTED THREAD. " + str(t))
        !           154: 
        !           155:         uri = handle.uri or ''
        !           156:         logging.debug("Micropolis SUGARSTARTUP URI " + repr(uri))
        !           157:         self.send_process(
        !           158:             'SugarStartUp "' + QuoteTCL(uri) + '"\n')
        !           159: 
        !           160:         nick = profile.get_nick_name() or ''
        !           161:         logging.debug("Micropolis SUGARNICKNAME NICK " + repr(nick))
        !           162:         self.send_process(
        !           163:             'SugarNickName "' + QuoteTCL(nick) + '"\n')
        !           164: 
        !           165:         #logging.debug("started Micropolis, pid " + repr(self._pid))
        !           166: 
        !           167:         ps = presenceservice.get_instance()
        !           168: 
        !           169:         for buddy in ps.get_buddies():
        !           170:             self._buddy_appeared_cb(ps, buddy)
        !           171: 
        !           172:         ps.connect("buddy-appeared", self._buddy_appeared_cb)
        !           173:         ps.connect("buddy-disappeared", self._buddy_disappeared_cb)
        !           174: 
        !           175: 
        !           176:     def _stdout_thread_function(self, *args, **keys):
        !           177:         logging.debug("_stdout_thread_function BEGIN " + repr(args) + " " + repr(keys))
        !           178:         f = self._process.stdout
        !           179:         fcntl.fcntl(f.fileno(), fcntl.F_SETFD, 0)
        !           180:         while True:
        !           181:             line = 'XXX'
        !           182:             try:
        !           183:                 line = f.readline()
        !           184:             except Exception, e:
        !           185:                 logging.debug("READLINE EXCEPTION " + str(e))
        !           186:                 break
        !           187:             logging.debug("LINE: " + repr(line))
        !           188:             line = line.strip()
        !           189:             if not line:
        !           190:                 continue
        !           191:             words = line.strip().split(' ')
        !           192:             command = words[0]
        !           193:             if command == 'PlaySound':
        !           194:                 logging.debug("PLAYSOUND " + " ".join(words[1:]))
        !           195:                 self.play_sound(words[1])
        !           196:             else:
        !           197:                 pass # logging.debug(">>> " + line)
        !           198:         logging.debug("_stdout_thread_function END")
        !           199: 
        !           200: 
        !           201:     def play_sound(self, name):
        !           202:         fileName = os.path.join(
        !           203:             self._bundle_path,
        !           204:             'res/sounds',
        !           205:             name.lower() + '.wav')
        !           206:         print "PLAY_SOUND " + fileName
        !           207:         try:
        !           208:             sound = pygame.mixer.Sound(fileName)
        !           209:             sound.play()
        !           210:         except Exception, e:
        !           211:             print "Can't play sound: " + fileName + " " + str(e)
        !           212:             pass
        !           213: 
        !           214: 
        !           215:     def send_process(self, message):
        !           216:         logging.debug("SEND_PROCESS " + message)
        !           217:         self._process.stdin.write(message)
        !           218: 
        !           219: 
        !           220:     def share(self):
        !           221:         logging.debug("SHARE")
        !           222:         Activity.share(self)
        !           223:         self.send_process(
        !           224:             'SugarShare\n')
        !           225: 
        !           226: 
        !           227:     def quit_process(self):
        !           228:         logging.debug("QUIT_PROCESS")
        !           229:         self.send_process(
        !           230:             'SugarQuit\n')
        !           231:         time.sleep(10)
        !           232: 
        !           233: 
        !           234:     def _plug_added_cb(self, sock):
        !           235:         logging.debug("Micropolis window opened")
        !           236:         return False
        !           237: 
        !           238: 
        !           239:     def _plug_removed_cb(self, sock):
        !           240:         logging.debug("Micropolis window closed")
        !           241:         self.destroy()
        !           242:         return False
        !           243: 
        !           244:     
        !           245:     def _destroy_cb(self, window):
        !           246:         logging.debug("Micropolis activity destroyed %r" % window)
        !           247:         self.quit_process()
        !           248: 
        !           249:         
        !           250:     def _focus_in_cb(self, window, event):
        !           251:         logging.debug("Micropolis activated %r %r" % (window, event))
        !           252:         self.send_process(
        !           253:             'SugarActivate\n')
        !           254: 
        !           255: 
        !           256:     def _focus_out_cb(self, window, event):
        !           257:         logging.debug("Micropolis deactivated %r %r" % (window, event))
        !           258:         self.send_process(
        !           259:             'SugarDeactivate\n')
        !           260: 
        !           261: 
        !           262:     def _buddy_appeared_cb(self, ps, buddy):
        !           263: 
        !           264:         try:
        !           265:             key = buddy.props.key or ''
        !           266:             nick = buddy.props.nick or ''
        !           267:             color = buddy.props.color or ''
        !           268:             address = buddy.props.ip4_address or ''
        !           269:         except AttributeError:
        !           270:             key = buddy.get_name() or ''
        !           271:             nick = buddy.get_name() or ''
        !           272:             color = buddy.get_color() or ''
        !           273:             address = buddy.get_ip4_address() or ''
        !           274: 
        !           275:         logging.debug("Micropolis _BUDDY_APPEARED_CB KEY " + repr(key) + " NICK " + repr(nick) + " COLOR " + repr(color) + " ADDRESS " + repr(address))
        !           276: 
        !           277:         logging.debug("Buddy appeared " + repr(buddy.props.nick))
        !           278: 
        !           279:         self.send_process(
        !           280:             'SugarBuddyAdd "' +
        !           281:             QuoteTCL(key) + '" "' +
        !           282:             QuoteTCL(nick) + '" "' +
        !           283:             QuoteTCL(color) + '" "' +
        !           284:             QuoteTCL(address) + '"\n')
        !           285: 
        !           286:     def _buddy_disappeared_cb(self, ps, buddy):
        !           287: 
        !           288:         try:
        !           289:             key = buddy.props.key or ''
        !           290:             nick = buddy.props.nick or ''
        !           291:             color = buddy.props.color or ''
        !           292:             address = buddy.props.ip4_address or ''
        !           293:         except AttributeError:
        !           294:             key = buddy.get_name() or ''
        !           295:             nick = buddy.get_name() or ''
        !           296:             color = buddy.get_color() or ''
        !           297:             address = buddy.get_ip4_address() or ''
        !           298: 
        !           299:         logging.debug("Micropolis _BUDDY_DISAPPEARED_CB KEY " + repr(key) + " NICK " + repr(nick) + " COLOR " + repr(color) + " ADDRESS " + repr(address))
        !           300: 
        !           301:         logging.debug("Buddy disappeared " + repr(buddy.props.nick))
        !           302: 
        !           303:         self.send_process(
        !           304:             'SugarBuddyDel "' +
        !           305:             QuoteTCL(key) + '" "' +
        !           306:             QuoteTCL(nick) + '" "' +
        !           307:             QuoteTCL(color) + '" "' +
        !           308:             QuoteTCL(address) + '"\n')
        !           309: 
        !           310:     def _sigchild_handler(self, signum, frame):
        !           311:         logging.debug("got signal %i %r %r" % (signum, frame, self._process))
        !           312:         sys.exit(0)
        !           313: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.