Subversion Repositories HomeAutomation

Rev

Blame | Last modification | View Log | SVN | RSS feed

  1. #!/usr/bin/python
  2.  
  3. import select
  4. import can
  5.  
  6. class UncenJob:
  7.     version = "unknown"
  8.     name = "unknown"
  9.     listen = False
  10.  
  11.     job_name = None
  12.  
  13. # load/unload
  14.     def __init__( self, core, attr ):
  15.         self.job_init( core )
  16.  
  17.     def close( self ):
  18.         self.job_close()
  19.  
  20. # handlers
  21.     def getstatus( self ):
  22.         return "..."
  23.  
  24.     def termcmd( self, args ):
  25.         self.core.term.write( "Commands not accepted" )
  26.  
  27. # callbacks
  28.     def trigger( self, fd, eventmask ):
  29.         pass
  30.  
  31.     def can_recieve( self, cid, canp ):
  32.         pass
  33.  
  34.     def can_accept( self, sjid, cid ):
  35.         return False
  36.  
  37.     def can_close( self, cid ):
  38.         pass
  39.  
  40. # helpers
  41.     def can_accept_raw( self, sjid, cid ):
  42.         if not self.can_accept( sjid, cid ):
  43.             return False
  44.         self.can_connections[cid] = sjid
  45.         return True
  46.  
  47.     def can_close_raw( self, cid ):
  48.         self.can_close( cid )
  49.         self.can_connections.pop( cid, None )
  50.  
  51.     def can_connect( self, djid ):
  52.         djid = self.core.job_id( djid )
  53.         cid = self.core.can_connect( self.jid, djid )
  54.         if cid == None:
  55.             return None
  56.         self.can_connections[cid] = djid
  57.         return cid
  58.  
  59.     def can_disconnect( self, cid ):
  60.         del self.can_connections[cid]
  61.         return self.core.can_disconnect( self.jid, cid )
  62.  
  63.     def can_send( self, cid, canp ):
  64.         if not self.core.can_send( self.jid, cid, canp ):
  65.             self.can_close_raw( cid )
  66.  
  67.     def trigger_add( self, fd, eventmask = select.POLLIN | select.POLLPRI | select.POLLERR ):
  68.         self.trigger_fds.append( fd )
  69.         self.core.trigger_register( fd, self.trigger, eventmask )
  70.  
  71.     def trigger_del( self, fd ):
  72.         self.trigger_fds.remove( fd )
  73.         self.core.trigger_unregister( fd )
  74.  
  75.     def job_init( self, core ):
  76.         self.core = core
  77.         self.jid = self.core.job_register( self )
  78.         self.trigger_fds = []
  79.         self.can_connections = {}
  80.  
  81.     def job_close( self ):
  82.         for fd in self.trigger_fds:
  83.             self.core.trigger_unregister( fd )
  84.         cids = self.can_connections.keys()
  85.         for cid in cids:
  86.             self.can_disconnect( cid )
  87.         self.core.job_unregister( self.jid )
  88.  
  89. class UncenCore:
  90.     def __init__( self ):
  91.         self.jobs = {}
  92.  
  93.         self.connections = {}
  94.  
  95.         self.triggers = {}
  96.         self.poll = select.poll()
  97.         self.nextjid = 1
  98.         self.nextcid = 1
  99.  
  100.         self.term = None
  101.  
  102.         self.job_names = {}
  103.  
  104.         self.lastjob = 0
  105.  
  106.     def close( self ):
  107.         jids = self.jobs.keys()
  108.         for jid in jids:
  109.             self.jobs[jid].close()
  110.  
  111. # Jobs
  112.     def job_register( self, job ):
  113.         jid = self.nextjid
  114.         self.jobs[jid] = job
  115.         self.nextjid += 1
  116.         return jid
  117.  
  118.     def job_unregister( self, jid ):
  119.         jid = self.job_id( jid )
  120.         job = self.jobs.pop( jid, None )
  121.         if job is not None:
  122.             if job.job_name is not None:
  123.                 del self.job_names[job.job_name]
  124.         if self.lastjob == jid:
  125.             raise SystemExit()
  126.         return job
  127.  
  128.     def job_list( self ):
  129.         return self.jobs.keys()
  130.  
  131.     def job_get( self, jid ):
  132.         jid = self.job_id( jid )
  133.         return self.jobs[jid]
  134.  
  135.     def job_close( self, jid ):
  136.         jid = self.job_id( jid )
  137.         if self.jobs.has_key( jid ):
  138.             self.jobs[jid].close()
  139.  
  140.     def job_id( self, jname ):
  141.         s = str( jname )
  142.         if s.isdigit():
  143.             return int( s )
  144.         if self.job_names.has_key( s ):
  145.             return self.job_names[s]
  146.         return None
  147.  
  148.     def job_name( self, jid ):
  149.         jid = self.job_id( jid )
  150.         for name, id in self.job_names.items():
  151.             if jid == id:
  152.                 return name
  153.         return str( jid )
  154.  
  155.     def job_setname( self, jid, jname ):
  156.         jid = self.job_id( jid )
  157.         if self.job_names.has_key( jname ):
  158.             oldjid = self.job_names[jname]
  159.             if self.jobs.has_key( oldjid ):
  160.                 self.jobs[oldjid].job_name = None
  161.         if self.jobs.has_key( jid ):
  162.             self.job_names[jname] = jid
  163.             self.jobs[jid].job_name = jname
  164.  
  165.  
  166. # Triggers
  167.     def trigger_register( self, fd, callback, eventmask = select.POLLIN | select.POLLPRI | select.POLLERR ):
  168.         self.triggers[fd] = callback
  169.         self.poll.register( fd, eventmask )
  170.  
  171.     def trigger_unregister( self, fd ):
  172.         self.triggers.pop(fd,None)
  173.         self.poll.unregister( fd )
  174.  
  175.     def can_connect( self, sjid, djid ):
  176.         sjid = self.job_id( sjid )
  177.         djid = self.job_id( djid )
  178.         if self.jobs.has_key( djid ):
  179.             job = self.jobs[djid]
  180.             if job.listen:
  181.                 cid = self.nextcid
  182.                 self.nextcid += 1
  183.                 self.connections[cid] = (sjid, djid)
  184.                 if job.can_accept_raw( sjid, cid ):
  185.                     return cid
  186.                 else:
  187.                     del self.connections[cid]
  188.                     return None
  189.         return None
  190.  
  191.     def can_disconnect( self, sjid, cid ):
  192.         sjid = self.job_id( sjid )
  193.         if self.connections.has_key(cid):
  194.             jida, jidb = self.connections[cid]
  195.             if jida == sjid:
  196.                 djid = jidb
  197.             elif jidb == sjid:
  198.                 djid = jida
  199.             else:
  200.                 return False
  201.             if self.jobs.has_key( djid ):
  202.                 djob = self.jobs[ djid ]
  203.                 djob.can_close_raw( cid )
  204.                 self.connections.pop(cid, None)
  205.                 return True
  206.             else:
  207.                 del self.connections[cid]
  208.                 return False
  209.         else:
  210.             return False
  211.  
  212.     def can_send( self, sjid, cid, canp ):
  213.         sjid = self.job_id( sjid )
  214.         if self.connections.has_key(cid):
  215.             jida, jidb = self.connections[cid]
  216.             if jida == sjid:
  217.                 djid = jidb
  218.             elif jidb == sjid:
  219.                 djid = jida
  220.             else:
  221.                 return False
  222.             if self.jobs.has_key( djid ):
  223.                 djob = self.jobs[ djid ]
  224.                 djob.can_recieve( cid, canp )
  225.                 return True
  226.             else:
  227.                 del self.connections[cid]
  228.                 return False
  229.         else:
  230.             return False
  231.  
  232.     def set_lastjob( self, jid ):
  233.         jid = self.job_id( jid )
  234.         if jid==None:
  235.             raise SystemExit()
  236.         if not self.jobs.has_key( jid ):
  237.             raise SystemExit()
  238.         self.lastjob = jid
  239.  
  240. # Main loop
  241.     def do_poll( self, timeout=0 ):
  242.         events = self.poll.poll( timeout )
  243.         for fd, event in events:
  244.             self.triggers[fd]( fd, events )
  245.