Migrate FGFSDemo.py, FlightGear.py, demo.py and nasal_api_doc.py to Python 3
Also apply minor changes to FGFSDemo.py and demo.py: add python3 shebang, make the scripts executable, improve an error message. This closes ticket #224: <https://sourceforge.net/p/flightgear/flightgear/merge-requests/224/>.
This commit is contained in:
parent
8e3274a7c2
commit
31f434d3ad
4 changed files with 49 additions and 42 deletions
scripts/python
32
scripts/python/FGFSDemo.py
Normal file → Executable file
32
scripts/python/FGFSDemo.py
Normal file → Executable file
|
@ -1,9 +1,14 @@
|
|||
import Tix
|
||||
from Tkconstants import *
|
||||
#! /usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from tkinter import tix as Tix
|
||||
from FlightGear import FlightGear
|
||||
|
||||
import sys
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
|
||||
PROGNAME = os.path.basename(sys.argv[0])
|
||||
|
||||
class PropertyField:
|
||||
def __init__(self, parent, prop, label):
|
||||
|
@ -20,14 +25,14 @@ class PropertyField:
|
|||
val = fgfs[self.prop]
|
||||
self.field.entry.delete(0,'end')
|
||||
self.field.entry.insert(0, val)
|
||||
|
||||
|
||||
class PropertyPage(Tix.Frame):
|
||||
def __init__(self,parent,fgfs):
|
||||
Tix.Frame.__init__(self,parent)
|
||||
self.fgfs = fgfs
|
||||
self.pack( side=Tix.TOP, padx=2, pady=2, fill=Tix.BOTH, expand=1 )
|
||||
self.fields = []
|
||||
|
||||
|
||||
def addField(self, prop, label):
|
||||
f = PropertyField(self, prop, label)
|
||||
self.fields.append(f)
|
||||
|
@ -143,7 +148,7 @@ class FGFSDemo(Tix.Frame):
|
|||
page.addField("/velocities/speed-down-fps", "Descent speed (fps):")
|
||||
|
||||
self.nb.pack( expand=1, fill=Tix.BOTH, padx=5, pady=5, side=Tix.TOP )
|
||||
|
||||
|
||||
self.QUIT = Tix.Button(self)
|
||||
self.QUIT['text'] = 'Quit'
|
||||
self.QUIT['command'] = self.quitcmd
|
||||
|
@ -163,23 +168,24 @@ class FGFSDemo(Tix.Frame):
|
|||
|
||||
def main():
|
||||
if len(sys.argv) != 3:
|
||||
print 'Usage: %s host port' % sys.argv[0]
|
||||
print('Usage: {} host port'.format(PROGNAME))
|
||||
sys.exit(1)
|
||||
|
||||
host = sys.argv[1]
|
||||
try:
|
||||
port = int( sys.argv[2] )
|
||||
except ValueError, msg:
|
||||
print 'Error: expected a number for port'
|
||||
except ValueError:
|
||||
print('Error: expected a number for the port argument, not {!r}'
|
||||
.format(sys.argv[2]))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
fgfs = None
|
||||
try:
|
||||
fgfs = FlightGear( host, port )
|
||||
except socket.error, msg:
|
||||
print 'Error connecting to flightgear:', msg[1]
|
||||
except socket.error as msg:
|
||||
print('Error connecting to flightgear:', msg.strerror)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
root = Tix.Tk()
|
||||
app = FGFSDemo( fgfs, root )
|
||||
app.mainloop()
|
||||
|
|
|
@ -2,7 +2,6 @@ from telnetlib import Telnet
|
|||
import sys
|
||||
import socket
|
||||
import re
|
||||
from string import split, join
|
||||
import time
|
||||
|
||||
__all__ = ["FlightGear"]
|
||||
|
@ -12,8 +11,7 @@ CRLF = '\r\n'
|
|||
class FGTelnet(Telnet):
|
||||
def __init__(self,host,port):
|
||||
Telnet.__init__(self,host,port)
|
||||
self.prompt = []
|
||||
self.prompt.append( re.compile('/[^>]*> ') )
|
||||
self.prompt = [re.compile('/[^>]*> '.encode('utf-8'))]
|
||||
self.timeout = 5
|
||||
#Telnet.set_debuglevel(self,2)
|
||||
|
||||
|
@ -64,16 +62,16 @@ class FGTelnet(Telnet):
|
|||
|
||||
# Internal: send one command to FlightGear
|
||||
def _putcmd(self,cmd):
|
||||
cmd = cmd + CRLF;
|
||||
Telnet.write(self, cmd)
|
||||
cmd = cmd + CRLF
|
||||
Telnet.write(self, cmd.encode('utf-8'))
|
||||
return
|
||||
|
||||
# Internal: get a response from FlightGear
|
||||
def _getresp(self):
|
||||
(i,match,resp) = Telnet.expect(self, self.prompt, self.timeout)
|
||||
(_i,_match,resp) = Telnet.expect(self, self.prompt, self.timeout)
|
||||
# Remove the terminating prompt.
|
||||
# Everything preceding it is the response.
|
||||
return split(resp, '\n')[:-1]
|
||||
return resp.decode('utf-8').split('\n')[:-1]
|
||||
|
||||
class FlightGear:
|
||||
"""FlightGear interface class.
|
||||
|
@ -97,20 +95,20 @@ class FlightGear:
|
|||
def __init__( self, host = 'localhost', port = 5500 ):
|
||||
try:
|
||||
self.telnet = FGTelnet(host,port)
|
||||
except socket.error, msg:
|
||||
except socket.error as msg:
|
||||
self.telnet = None
|
||||
raise socket.error, msg
|
||||
raise msg
|
||||
|
||||
def __del__(self):
|
||||
# Ensure telnet connection is closed cleanly.
|
||||
self.quit();
|
||||
self.quit()
|
||||
|
||||
def __getitem__(self,key):
|
||||
"""Get a FlightGear property value.
|
||||
Where possible the value is converted to the equivalent Python type.
|
||||
"""
|
||||
s = self.telnet.get(key)[0]
|
||||
match = re.compile( '[^=]*=\s*\'([^\']*)\'\s*([^\r]*)\r').match( s )
|
||||
match = re.compile( r'[^=]*=\s*\'([^\']*)\'\s*([^\r]*)\r').match( s )
|
||||
if not match:
|
||||
return None
|
||||
value,type = match.groups()
|
||||
|
@ -142,10 +140,10 @@ class FlightGear:
|
|||
self.telnet = None
|
||||
|
||||
def view_next(self):
|
||||
#move to next view
|
||||
"""Move to next view."""
|
||||
self.telnet.set( "/command/view/next", "true")
|
||||
|
||||
def view_prev(self):
|
||||
#move to next view
|
||||
"""Move to next view."""
|
||||
self.telnet.set( "/command/view/prev", "true")
|
||||
|
||||
|
|
7
scripts/python/demo.py
Normal file → Executable file
7
scripts/python/demo.py
Normal file → Executable file
|
@ -1,3 +1,6 @@
|
|||
#! /usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from FlightGear import FlightGear
|
||||
import time
|
||||
|
||||
|
@ -9,13 +12,13 @@ def main():
|
|||
if fg['/sim/time/elapsed-sec'] > 5:
|
||||
break
|
||||
time.sleep(1.0)
|
||||
print fg['/sim/time/elapsed-sec']
|
||||
print(fg['/sim/time/elapsed-sec'])
|
||||
|
||||
|
||||
# parking brake on
|
||||
fg['/controls/parking-brake'] = 1
|
||||
|
||||
heading = fg['/orientation/heading-deg']
|
||||
# heading = fg['/orientation/heading-deg']
|
||||
|
||||
# Switch to external view for for 'walk around'.
|
||||
fg.view_next()
|
||||
|
|
|
@ -37,7 +37,7 @@ def get_files(nasal_dir):
|
|||
try:
|
||||
os.stat(nasal_dir)
|
||||
except:
|
||||
print "The path does not exist"
|
||||
print("The path does not exist")
|
||||
sys.exit()
|
||||
fgroot_dir = nasal_dir.rstrip('/').replace('Nasal','')
|
||||
f_version = open(fgroot_dir+'version','rb')
|
||||
|
@ -55,10 +55,10 @@ def get_files(nasal_dir):
|
|||
top_level.sort()
|
||||
modules.sort()
|
||||
if len(top_level) ==0:
|
||||
print "This does not look like the correct $FGROOT/Nasal path"
|
||||
print("This does not look like the correct $FGROOT/Nasal path")
|
||||
sys.exit()
|
||||
if len(modules)==0:
|
||||
print "Warning: could not find any submodules"
|
||||
print("Warning: could not find any submodules")
|
||||
for f in top_level:
|
||||
namespace=f.replace(".nas","")
|
||||
functions=parse_file(nasal_dir + f)
|
||||
|
@ -136,7 +136,7 @@ def output_text(top_namespaces,modules,version):
|
|||
buf+='<hr/>'
|
||||
else:
|
||||
tempComment = comment.replace('#','').replace('<','<').replace('>','>')
|
||||
if string.strip(tempComment)!="":
|
||||
if tempComment.strip()!="":
|
||||
buf+= '<div class="comments">'+tempComment+'</div><br/>\n'
|
||||
buf+='</div>\n'
|
||||
if namespace[0] not in done2:
|
||||
|
@ -152,7 +152,7 @@ def parse_file(filename):
|
|||
retval=[]
|
||||
classname=""
|
||||
for line in content:
|
||||
match=re.search('^var\s+([A-Za-z0-9_-]+)\s*=\s*func\s*\(?([A-Za-z0-9_\s,=.\n-]*)\)?',line)
|
||||
match=re.search(r'^var\s+([A-Za-z0-9_-]+)\s*=\s*func\s*\(?([A-Za-z0-9_\s,=.\n-]*)\)?',line)
|
||||
if match!=None:
|
||||
func_name=match.group(1)
|
||||
comments=[]
|
||||
|
@ -172,7 +172,7 @@ def parse_file(filename):
|
|||
j-=1
|
||||
count+=1
|
||||
continue
|
||||
if re.search('^\s*#',content[j])!=None:
|
||||
if re.search(r'^\s*#',content[j])!=None:
|
||||
comments.append(content[j].rstrip('\n'))
|
||||
j-=1
|
||||
else:
|
||||
|
@ -183,7 +183,7 @@ def parse_file(filename):
|
|||
i+=1
|
||||
continue
|
||||
|
||||
match3=re.search('^var\s*([A-Za-z0-9_-]+)\s*=\s*{\s*(\n|})',line)
|
||||
match3=re.search(r'^var\s*([A-Za-z0-9_-]+)\s*=\s*{\s*(\n|})',line)
|
||||
if match3!=None:
|
||||
classname=match3.group(1)
|
||||
|
||||
|
@ -198,7 +198,7 @@ def parse_file(filename):
|
|||
j-=1
|
||||
count+=1
|
||||
continue
|
||||
if re.search('^\s*#',content[j])!=None:
|
||||
if re.search(r'^\s*#',content[j])!=None:
|
||||
comments.append(content[j].rstrip('\n'))
|
||||
j-=1
|
||||
else:
|
||||
|
@ -209,7 +209,7 @@ def parse_file(filename):
|
|||
i+=1
|
||||
continue
|
||||
|
||||
match2=re.search('^\s*([A-Za-z0-9_-]+)\s*:\s*func\s*\(?([A-Za-z0-9_\s,=.\n-]*)\)?',line)
|
||||
match2=re.search(r'^\s*([A-Za-z0-9_-]+)\s*:\s*func\s*\(?([A-Za-z0-9_\s,=.\n-]*)\)?',line)
|
||||
if match2!=None:
|
||||
func_name=match2.group(1)
|
||||
comments=[]
|
||||
|
@ -229,7 +229,7 @@ def parse_file(filename):
|
|||
j-=1
|
||||
count+=1
|
||||
continue
|
||||
if re.search('^\s*#',content[j])!=None:
|
||||
if re.search(r'^\s*#',content[j])!=None:
|
||||
comments.append(content[j].rstrip('\n'))
|
||||
j-=1
|
||||
else:
|
||||
|
@ -242,7 +242,7 @@ def parse_file(filename):
|
|||
i+=1
|
||||
continue
|
||||
|
||||
match4=re.search('^([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]+)\s*=\s*func\s*\(?([A-Za-z0-9_\s,=\n.-]*)\)?',line)
|
||||
match4=re.search(r'^([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]+)\s*=\s*func\s*\(?([A-Za-z0-9_\s,=\n.-]*)\)?',line)
|
||||
if match4!=None:
|
||||
classname=match4.group(1)
|
||||
func_name=match4.group(2)
|
||||
|
@ -263,7 +263,7 @@ def parse_file(filename):
|
|||
j-=1
|
||||
count+=1
|
||||
continue
|
||||
if re.search('^\s*#',content[j])!=None:
|
||||
if re.search(r'^\s*#',content[j])!=None:
|
||||
comments.append(content[j].rstrip('\n'))
|
||||
j-=1
|
||||
else:
|
||||
|
@ -281,7 +281,7 @@ def parse_file(filename):
|
|||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) <2:
|
||||
print 'Usage: nasal_api_doc.py parse [path to $FGROOT/Nasal/]'
|
||||
print('Usage: nasal_api_doc.py parse [path to $FGROOT/Nasal/]')
|
||||
sys.exit()
|
||||
else:
|
||||
if sys.argv[1]=='parse':
|
||||
|
@ -291,5 +291,5 @@ if __name__ == "__main__":
|
|||
nasal_path=sys.argv[2]
|
||||
get_files(nasal_path)
|
||||
else:
|
||||
print 'Usage: nasal_api_doc.py parse [path to $FGROOT/Nasal/]'
|
||||
print('Usage: nasal_api_doc.py parse [path to $FGROOT/Nasal/]')
|
||||
sys.exit()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue