daily pastebin goal
20%
SHARE
TWEET

Untitled

a guest Feb 22nd, 2019 61 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. def goodbye(name, adjective):
  2.     print("Goodbye, %s, it was %s to meet you." % (name, adjective))
  3.  
  4. import atexit
  5. atexit.register(goodbye, "Suzanne", "nice")
  6.      
  7. import bpy, socket, threading, atexit, platform, subprocess, os
  8. from xmlrpc.server import SimpleXMLRPCServer
  9. import xmlrpc.client
  10. bl_info = {
  11.     "name": "XMLRPC Server",
  12.     "author": "KristenH",
  13.     "version": (0, 5, 0, 1),
  14.     "blender": (2, 79, 0),
  15.     "category": "System"
  16. }
  17. print(os.path.dirname(os.path.abspath(__file__)))
  18.  
  19. def kill_process(pid):
  20.     if not(pid):
  21.         return
  22.     pid = str(pid)
  23.     current_os = platform.system()
  24.     if current_os == 'Windows':
  25.         cmd = ['taskkill', '/PID', pid]
  26.         # cmd = 'T:/apptools/bin/pskill.exe ' + pid
  27.         os.system(cmd)
  28.     else:
  29.         cmd = ['kill -9', '-ef', pid]
  30.         output = subprocess.check_output(cmd)
  31.         if self.debug:
  32.             print(output)
  33.  
  34. def goodbye(server):
  35.     print('goodbye')
  36.     server.stop()
  37.     kill_process(server._get_my_tid())
  38.     # kill_process(os.pid())
  39.  
  40. class SimpleServer(SimpleXMLRPCServer):
  41.     pass
  42.  
  43. def command(com):
  44.     com = 'import bpyn'+com
  45.     exec(com)
  46.     return com
  47.  
  48. def server_data():
  49.     return {
  50.         'hostname':socket.gethostname(),
  51.         'app_version':bpy.app.version_string,
  52.         'file_path':bpy.context.blend_data.filepath.replace('\', '/'),
  53.         'exe':os.path.basename(bpy.app.binary_path),
  54.         'scene_objects':bpy.data.objects.keys(),
  55.         'pid':os.getpid()
  56.         }
  57.  
  58. def pscan(host='localhost', port=8000):
  59.     # Setting up a socket
  60.     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  61.     proxy = (host, port)
  62.     try:
  63.         con = sock.connect(proxy)
  64.         return True
  65.     except:
  66.         pass
  67.  
  68. def _async_raise(tid, exctype):
  69.     '''Raises an exception in the threads with id tid'''
  70.     if not inspect.isclass(exctype):
  71.         raise TypeError("Only types can be raised (not instances)")
  72.     res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid),
  73.                                                      ctypes.py_object(exctype))
  74.     if res == 0:
  75.         raise ValueError("invalid thread id")
  76.     elif res != 1:
  77.         # "if it returns a number greater than one, you're in trouble,
  78.         # and you should call it again with exc=NULL to revert the effect"
  79.         ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), None)
  80.         raise SystemError("PyThreadState_SetAsyncExc failed")
  81.  
  82.  
  83. class ServerThread(threading.Thread):
  84.     '''A thread class that supports raising exception in the thread from
  85.        another thread.'''
  86.     def __init__(self, host='localhost', port=8000):
  87.         super(ServerThread, self).__init__()
  88.         self._stop_event = threading.Event()
  89.         self.proxy = (host, port)
  90.         self.server = SimpleServer(self.proxy)
  91.         self.port = port
  92.         self.host = host
  93.         threading.Thread.__init__(self)
  94.         self.server.register_introspection_functions()
  95.         self.server.register_function(command, "command")
  96.         self.server.register_function(server_data, "server_data")
  97.  
  98.     def _get_my_tid(self):
  99.         """determines this (self's) thread id
  100.  
  101.         CAREFUL : this function is executed in the context of the caller
  102.         thread, to get the identity of the thread represented by this
  103.         instance.
  104.         """
  105.         if not self.isAlive():
  106.             raise threading.ThreadError("the thread is not active")
  107.  
  108.         # do we have it cached?
  109.         if hasattr(self, "_thread_id"):
  110.             return self._thread_id
  111.  
  112.         # no, look for it in the _active dict
  113.         for tid, tobj in threading._active.items():
  114.             if tobj is self:
  115.                 self._thread_id = tid
  116.                 return tid
  117.  
  118.         # TODO: in python 2.6, there's a simpler way to do : self.ident
  119.  
  120.         raise AssertionError("could not determine the thread's id")
  121.  
  122.     def raiseExc(self, exctype):
  123.         """Raises the given exception type in the context of this thread.
  124.  
  125.         If the thread is busy in a system call (time.sleep(),
  126.         socket.accept(), ...), the exception is simply ignored.
  127.  
  128.         If you are sure that your exception should terminate the thread,
  129.         one way to ensure that it works is:
  130.  
  131.             t = ThreadWithExc( ... )
  132.             ...
  133.             t.raiseExc( SomeException )
  134.             while t.isAlive():
  135.                 time.sleep( 0.1 )
  136.                 t.raiseExc( SomeException )
  137.  
  138.         If the exception is to be caught by the thread, you need a way to
  139.         check that your thread has caught it.
  140.  
  141.         CAREFUL : this function is executed in the context of the
  142.         caller thread, to raise an excpetion in the context of the
  143.         thread represented by this instance.
  144.         """
  145.         _async_raise( self._get_my_tid(), exctype )
  146.  
  147.  
  148.     def stop(self):
  149.         self._stop_event.set()
  150.  
  151.     def stopped(self):
  152.         return self._stop_event.is_set()        
  153.  
  154.     # We must need this!!
  155.     def run(self):
  156.         try:
  157.             self.server.serve_forever()
  158.             self.server_thread.setDaemon(True)
  159.             # self.server. = mp.Process(target=register)
  160.             # self.server.proc.daemon = True
  161.             # self.server.proc.start()
  162.  
  163.         except Exception:
  164.             print("Exiting")
  165.             leaveBlender()
  166.  
  167.  
  168. class ServerPanel(bpy.types.Panel):
  169.     bl_label = "Server Panel"
  170.     bl_idname = "Object_PT_server"
  171.     bl_space_type = 'PROPERTIES'
  172.     bl_region_type = 'WINDOW'
  173.     bl_category = "Shortcuts"
  174.     #server = ServerThread()
  175.  
  176.     def draw(self, context):
  177.         # server = run_server()
  178.         layout = self.layout
  179.         layout.row().label(text="Server running on: {}:{}".format(server.host, server.port))
  180.  
  181.  
  182. server = None
  183. x=8000
  184. while(server is None):
  185.     con = pscan(port=x)
  186.     if con is not None:
  187.         print("Server found on: localhost:", x)
  188.         x += 1
  189.     else:
  190.         server = ServerThread(port=x)
  191.         server.start()
  192.         print("Started the server with:", server.host, ":", server.port, 'thread_id' ,server._get_my_tid())
  193.         atexit.register(goodbye,server)
  194.         print(dir(atexit))
  195.  
  196.  
  197.  
  198. # Enable server addon on Blender
  199. def register():
  200.     from bpy.utils import register_class
  201.     register_class(ServerPanel)
  202.  
  203. # Disable server addon form Blender
  204. def unregister():
  205.     print("Started the server with:", server.host, ":", server.port, 'thread_id' ,server._get_my_tid())
  206.     from bpy.utils import unregister_class
  207.     unregister_class(ServerPanel)
  208.  
  209.  
  210. if __name__ == "__main__":
  211.     register()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top