New examples by Tony Ingraldi, using dns-lookup in stead of the funny interslip

module.
This commit is contained in:
Jack Jansen 1999-12-03 15:15:28 +00:00
parent 43fd1f75db
commit 2450a25fcd
12 changed files with 241 additions and 333 deletions

View file

@ -1,5 +1,6 @@
<HTML><HEAD><TITLE>Using python to create Macintosh applications, part one</TITLE></HEAD>
<BODY>
<H1>Using python to create Macintosh applications, part one</H1>
<HR>
@ -8,34 +9,26 @@ application using Python. We will glance at how to use dialogs and
resources. <p>
The example application we look at will be a simple program with a
dialog that allows you to control and monitor InterSLIP, a device
driver that connects your mac to the Internet via a modem connection.
<A HREF="example1/InterslipControl-1.py">Source</A> and resource file
(in binary and <A
HREF="example1/InterslipControl-1.rsrc.hqx">BinHex</A> form for
downloading) for this application are available in the <A
dialog that allows you to perform domain name lookups on IP addresses
and hostnames.
The <A HREF="example1/dnslookup-1.py">source code</A> and
<A HREF="example1/dnslookup-1.rsrc">resource file</A>
for this application are available in the <A
HREF="example1">example1</A> folder (which you will have to download
if you are reading this document over the net and if you want to look
at the resources). <p>
We will use a C extension module module "interslip" that allows a
Python program to control and monitor the behaviour of the low-level
driver, and we will create the user interface around that. If you want
to actually run the code, you will obvously need InterSLIP and the
interslip module. The latter is available as a dynamically loadable
extension for PowerPC/cfm68k Pythons, and may be compiled in your static 68K
Python. As of this writing there is still a slight
problem with the Python interslip module causing it to say "file not
found" if the driver is not loaded yet. The workaround is to load the
driver by starting InterSLIP Control and quitting it. <p>
We will use the builtin module "socket" that allows a
Python program to perform all sorts of networking functions, and we
will create the user interface around that. You should be able to run
the sample code with the standard Python distribution.<p>
<CITE>
If you are interested in building your own extensions to python you
should check out the companion document <A
HREF="plugins.html">Creating Macintosh Python C extensions</A>,
which tells you how to build your own C extension. Not completely
coincidental this document uses the interslip module that we will use
here as an example. <p>
which tells you how to build your own C extension.
<p>
</CITE>
<H2><A NAME="dialog-resources">Creating dialog resources</A></H2>
@ -62,19 +55,24 @@ conflicts arise: once you have opened your resource file any attempt
by the interpreter to open a dialog will also search your resource
file. <p>
Okay, let's have a look at InterslipControl-1.rsrc, our resource file.
Okay, let's have a look at dnslookup-1.rsrc, our resource file.
The DLOG and accompanying DITL resource both have number 512. Since
ResEdit creates both with default ID=128 you should take care to
change the number on both. The dialog itself is pretty basic: four
buttons (connect, disconnect, update status and quit), two labels and
two status fields. <p>
change the number on both. The dialog itself is pretty basic: two
buttons (Lookup and Quit), two labels and
two text entry areas, one of which is used for output only. Here's what
the dialog will look like at run time<p>
<div align=center>
<img width=324 height=189 src="example1/dnslookup-1.gif" alt="dialog image">
</div>
<p>
<H2><A NAME="modal-dialog">An application with a modal dialog</A></H2>
Next, we will have to write the actual application. For this example,
we will use a modal dialog. This means that we will put up the dialog
and go into a loop asking the dialog manager for events (buttons
pushed). We handle the actions requested by the user until the quit
pushed). We handle the actions requested by the user until the Quit
button is pressed, upon which we exit our loop (and the program). This
way of structuring your program is actually rather antisocial, since
you force the user to do whatever you, the application writer, happen
@ -86,8 +84,8 @@ answer because the data you needed was obscured by the dialog itself?
In the next example we will look at an application that does pretty
much the same as this one but in a more user-friendly way. <p>
On to the code itself, in file <A
HREF="example1/InterslipControl-1.py"> InterslipControl-1.py</A>. Have
The code itself is contained in the file <A
HREF="example1/dnslookup-1.py"> dnslookup-1.py</A>. Have
a copy handy before you read on. The file starts off with a
textstring giving a short description. Not many tools do anything with
this as yet, but at some point in the future we <EM>will</EM> have all
@ -122,39 +120,29 @@ as in <CODE>print Res.OpenResFile.__doc__</CODE>
Similarly, <A NAME="dlg"><CODE>Dlg</CODE></A> is an interface to the
Dialog manager (with Dialogs being implemented as python objects and
routines with Dialog arguments being methods). The sys module you
know, I hope. <A NAME="interslip"><CODE>Interslip</CODE></A>,
finally, is the module with the interface to the InterSLIP driver. We
use four calls from it:
know, I hope. The string module is an often used module that enables
you to perform many string related operations. In this case however, we
are only using the "digits" constant from the string module. We could
have simply defined "digits" as "0123456789". The socket module enables
us to perform the domain name lookups. We
use two calls from it:
<UL>
<LI> <CODE>open()</CODE>
opens the driver
<LI> <CODE>connect()</CODE>
asks it to initiate a connection procedure (without waiting)
<LI> <CODE>disconnect()</CODE>
asks it to initiate a disconnection procedure (without waiting)
<LI> <CODE>status()</CODE>
returns the current connection status in the form of an integer state,
an integer "message sequence number" and a message string.
<LI> <CODE>gethostbyaddr()</CODE>
returns the hostname associated with an IP address
<LI> <CODE>gethostbyname()</CODE>
returns the IP address associated with a hostname
</UL>
Next in the source file we get definitions for our dialog resource
number and for the item numbers in our dialog. These should match the
situation in our resource file InterslipControl-1.rsrc,
obviously. Then we get an array converting numeric state codes
returned by <CODE>interslip.status()</CODE> to textual messages. <p>
situation in our resource file dnslookup-1.rsrc,
obviously.<p>
On to the main program. We start off with opening our resource file,
which should live in the same folder as the python source. If we
cannot open it we use <CODE>EasyDialogs</CODE> to print a message and
exit. You can try it: just move the resource file somewhere else for a
moment. Then, we try to open the interslip driver, again catching an
error. All modules that raise <A NAME="macos-errors">MacOS error
exceptions</A> will pass a 2-tuple to the exception handler with the
first item being the numeric <CODE>OSErr</CODE> code and the second
one being an informative message. If no informative message is
available it will be the rather uninformative <CODE>"MacOS Error
-12345"</CODE>, but at least the second item will always be a
printable string. Finally we call do_dialog() to do the real work. <p>
moment. Then we call do_dialog() to do the real work. <p>
<CODE>Do_dialog()</CODE> uses <CODE>Dlg.GetNewDialog()</CODE> to open
a dialog window initialized from 'DLOG' resource ID_MAIN and putting
@ -166,13 +154,12 @@ slightly more complicated things also, like the user typing into
simple textfields, but it will <EM>not</EM> do things like updating
the physical appearance of radio buttons, etc. See Inside Mac or
another programming guide for how to handle this
yourself. Fortunately, our simple application doesn't have to bother
with this, since buttons are the only active elements we have. So, we
do a simple switch on item number and call the appropriate routine to
implement the action requested. Upon the user pressing "quit" we
simply leave the loop and, hence, <CODE>do_dialog()</CODE>. This will
cause the python dialog object <CODE>my_dlg</CODE> to be deleted and
the on-screen dialog to disappear. <p>
yourself. Fortunately, our simple application doesn't have to bother with this,
since buttons and textfields are the only active elements we have. So, we do a
simple switch on item number and call the appropriate routine to implement the
action requested. Upon the user pressing "Quit" we simply leave the loop and,
hence, <CODE>do_dialog()</CODE>. This will cause the python dialog object
<CODE>my_dlg</CODE> to be deleted and the on-screen dialog to disappear. <p>
<A NAME="dialog-warning">Time for a warning</A>: be very careful what
you do as long as a dialog is on-screen. Printing something, for
@ -183,8 +170,8 @@ may or may not work in this situation. I have also seen crashes in
such a situation, probably due to the multiple event loops involved or
some oversight in the interpreter. You have been warned. <p>
The implementation of the "update status" command can use a bit more
explaining: we get the new information with <CODE>do_status()</CODE>
The implementation of the "Lookup" command can use a bit more
explaining: we get the necessary information with <CODE>dnslookup()</CODE>
but now we have to update the on-screen dialog to present this
information to the user. The <CODE>GetDialogItem()</CODE> method of
the dialog returns three bits of information about the given item: its
@ -195,18 +182,12 @@ here that python programmers need not bother with the C-string versus
pascal-string controversy: the python glue module knows what is needed
and converts the python string to the correct type. <p>
Finally, the three implementation routines <CODE>do_connect()</CODE>,
<CODE>do_disconnect()</CODE> and <CODE>do_status()</CODE> are simply
boring wrappers around the corresponding interslip methods that will
put up a dialog in case of an error. <p>
And that concludes our first example of the use of resources and
dialogs. Next, you could have a look at the source of EasyDialogs for
some examples of using input fields and filterprocs. Or, go on with
reading the <A HREF="example2.html">second part</A> of this document
to see how to implement a better version of this application. Not only
will it allow the user to go back to the finder (or other apps) when
your application is running, it will also free her of the RSI-inducing
chore of pressing "update status" continuously... <p>
to see how to implement a better version of this application.<p>
</BODY>
</HTML>

View file

@ -1,92 +0,0 @@
"""Sample program handling InterSLIP control and showing off EasyDialogs,
Res and Dlg in the process"""
import EasyDialogs
import Res
import Dlg
import sys
import interslip
#
# Definitions for our resources
ID_MAIN=512
ITEM_CONNECT=1
ITEM_DISCONNECT=2
ITEM_UPDATE=3
ITEM_QUIT=4
ITEM_STATUS=5
ITEM_MESSAGE=6
status2text = ["<idle>", "<wait-modem>", "<dialling>", "<logging in>",
"<connected>", "<disconnecting>"]
def main():
"""Main routine: open resourcefile, open interslip, call dialog handler"""
try:
Res.OpenResFile("InterslipControl-1.rsrc")
except Res.Error, arg:
EasyDialogs.Message("Cannot open resource file InterslipControl-1.rsrc: "+
arg[1])
sys.exit(1)
try:
interslip.open()
except interslip.error, arg:
EasyDialogs.Message("Cannot open interslip: "+arg[1])
sys.exit(1)
do_dialog()
def do_dialog():
"""Post dialog and handle user interaction until quit"""
my_dlg = Dlg.GetNewDialog(ID_MAIN, -1)
while 1:
n = Dlg.ModalDialog(None)
if n == ITEM_CONNECT:
do_connect()
elif n == ITEM_DISCONNECT:
do_disconnect()
elif n == ITEM_UPDATE:
status, msg = do_status()
# Convert status number to a text string
try:
txt = status2text[status]
except IndexError:
txt = "<unknown state %d>"%status
# Set the status text field
tp, h, rect = my_dlg.GetDialogItem(ITEM_STATUS)
Dlg.SetDialogItemText(h, txt)
# Set the message text field
tp, h, rect = my_dlg.GetDialogItem(ITEM_MESSAGE)
Dlg.SetDialogItemText(h, msg)
elif n == ITEM_QUIT:
break
def do_connect():
"""Connect, posting error message in case of failure"""
try:
interslip.connect()
except interslip.error, arg:
EasyDialogs.Message("Cannot connect: "+arg[1])
def do_disconnect():
"""Disconnect, posting error message in case of failure"""
try:
interslip.disconnect()
except interslip.error, arg:
EasyDialogs.Message("Cannot disconnect: "+arg[1])
def do_status():
"""Get status as (state_index, message),
posting error message in case of failure"""
try:
status, msgnum, msg = interslip.status()
except interslip.error, arg:
EasyDialogs.Message("Cannot get status: "+arg[1])
return 0, ''
return status, msg
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1,61 @@
"""Sample program performing domain name lookups and showing off EasyDialogs,
Res and Dlg in the process"""
import EasyDialogs
import Res
import Dlg
import sys
import socket
import string
#
# Definitions for our resources
ID_MAIN=512
ITEM_LOOKUP_ENTRY=1
ITEM_RESULT=2
ITEM_LOOKUP_BUTTON=3
ITEM_QUIT_BUTTON=4
def main():
"""Main routine: open resource file, call dialog handler"""
try:
Res.OpenResFile("dnslookup-1.rsrc")
except Res.Error:
EasyDialogs.Message("Cannot open dnslookup-1.rsrc")
sys.exit(1)
do_dialog()
def do_dialog():
"""Post dialog and handle user interaction until quit"""
my_dlg = Dlg.GetNewDialog(ID_MAIN, -1)
while 1:
n = Dlg.ModalDialog(None)
if n == ITEM_LOOKUP_BUTTON:
tp, h, rect = my_dlg.GetDialogItem(ITEM_LOOKUP_ENTRY)
txt = Dlg.GetDialogItemText(h)
tp, h, rect = my_dlg.GetDialogItem(ITEM_RESULT)
Dlg.SetDialogItemText(h, dnslookup(txt))
elif n == ITEM_QUIT_BUTTON:
break
def dnslookup(str):
""" Perform DNS lookup on str. If first character of digit is numeric,
assume that str contains an IP address. Otherwise, assume that str
contains a hostname."""
if str == '': str = ' '
if str[0] in string.digits:
try:
value = socket.gethostbyaddr(str)[0]
except:
value = 'Lookup failed'
else:
try:
value = socket.gethostbyname(str)
except:
value = 'Lookup failed'
return value
main()

Binary file not shown.

View file

@ -6,52 +6,51 @@
In this document we rewrite the application of the <A
HREF="example1.html">previous example</A> to use modeless dialogs. We
will use an application framework, and we will have a look at creating
applets, standalone applications written in Python. <A
HREF="example2/InterslipControl-2.py">Source</A> and resource file (in
binary and <A HREF="example2/InterslipControl-2.rsrc.hqx">BinHex</A>
form for downloading) are available in the folder <A
HREF="example2">example2</A>. <p>
applets, standalone applications written in Python. The <A
HREF="example2/dnslookup-2.py">source code</A> and
<A HREF="example2/dnslookup-2.rsrc">resource file</A> are available in the folder
<A HREF="example2">example2</A>. <p>
Again, we start with ResEdit to create our dialogs. Not only do we
want a main dialog this time but also an "About" dialog, and we
provide the <A NAME="bundle">BNDL resource</A> and related stuff that
an application cannot be without. (Actually, a python applet can be
without, <A HREF="#no-bundle">see below</A>). "Inside Mac" or various
books on macintosh programming will help here. Also, you can refer to
want a main dialog this time but also an "About" dialog. This example is less
than complete since we do not provide a <A NAME="bundle">BNDL resource</A>
and related stuff that an application cannot be without. We are able to do this
when building a python applet since BuildApplet will substitute default resources
for BNDL, etc. when none are supplied (<A HREF="#no-bundle">See below</A>.)
"Inside Mac" or various
books on Macintosh programming will help here. Also, you can refer to
the resource files provided in the Python source distribution for some
of the python-specific points of BNDL programming: the
"appletbundle.rsrc" file is what is used for creating applets if you
don't provide your own resource file. <p>
Let's have a look at InterslipControl-2.rsrc, our resource file. First
off, there's the standard BNDL combo. I've picked 'PYTi' as signature
for the application. I tend to pick PYT plus one lower-case letter for
my signatures. The finder gets confused if you have two applications
with the same signature. This may be due to some incorrectness on the
side of "BuildApplet", I am not sure. There is one case when you
definitely need a unique signature: when you create an applet that has
its own data files and you want the user to be able to start your
When creating your own BNDL resouorces, keep in mind that the Finder gets
confused if you have more than one application with the same signature. This may be due
to some incorrectness on the side of "BuildApplet", I am not sure. There is one
case when you definitely need a unique signature: when you create an applet that
has its own data files and you want the user to be able to start your
applet by double-clicking one of the datafiles. <p>
There's little to tell about the BNDL stuff: I basically copied the
generic Python applet icons and pasted in the symbol for
InterSLIP. The two dialogs are equally unexciting: dialog 512 is our
main window which has four static text fields (two of which we will be
modifying during runtime, to show the status of the connection) and
two buttons "connect" and "disconnect". The "quit" and "update status"
buttons have disappeared, because they are handled by a menu choice
and automatically, respectively. <p>
Let's have a look at dnslookup-2.rsrc, our resource file. Dialog 512 is the
main window which has one button (Lookup), two labels and
two text entry areas, one of which is used for output only. The "Quit" and
button has disappeared, because its function is handled by a menu choice. Here's
what it will look like at run time:<p>
<div align=center>
<img width=324 height=205 src="example2/dnslookup-2.gif" alt="dialog image">
</div>
<p>
<H2>A modeless dialog application using FrameWork</H2>
On to the source code in <A
HREF="example2/InterslipControl-2.py">InterslipControl-2.py</A>. The
HREF="example2/dnslookup-2.py">dnslookup-2.py</A>. The
start is similar to our previous example program <A
HREF="example1/InterslipControl-1.py">InterSlipControl-1.py</A>, with
HREF="example1/dnslookup-1.py">dnslookup-1.py</A>, with
one extra module being imported. To make life more simple we will use
the <CODE>FrameWork</CODE> module, a nifty piece of code that handles
all the gory mac details of event loop programming, menubar
installation and all the other code that is the same for every mac
all the gory Mac details of event loop programming, menubar
installation and all the other code that is the same for every Mac
program in the world. Like most standard modules, FrameWork will run
some sample test code when you invoke it as a main program, so try it
now. It will create a menu bar with an Apple menu with the about box
@ -68,7 +67,7 @@ also continue with this document.
After the imports we get the definitions of resource-IDs in our
resource file, slightly changed from the previous version of our
program, and the state to string mapping. The main program is also
program. The main program is also
similar to our previous version, with one important exception: we
first check to see whether our resource is available before opening
the resource file. Why is this? Because later, when we will have
@ -77,13 +76,13 @@ the applet file and we don't need the separate resource file
anymore. <p>
Next comes the definition of our main class,
<CODE>InterslipControl</CODE>, which inherits
<CODE>DNSLookup</CODE>, which inherits
<CODE>FrameWork.Application</CODE>. The Application class handles the
menu bar and the main event loop and event dispatching. In the
<CODE>__init__</CODE> routine we first let the base class initialize
itself, then we create our modeless dialog and finally we jump into
the main loop. The main loop continues until we call <CODE>self._quit</CODE>,
which we will do when the user selects "quit". When we create
which we will do when the user selects "Quit". When we create
the instance of <CODE>MyDialog</CODE> (which inherits
<CODE>DialogWindow</CODE>, which inherits <CODE>Window</CODE>) we pass
a reference to the application object, this reference is used to tell
@ -104,31 +103,17 @@ familiar to you from the previous example program. That do_about is
called when the user selects About from the Apple menu is, again,
taken care of by the __init__ routine of Application. <p>
Our main object finally overrides <CODE>idle()</CODE>, the method
called when no event is available. It passes the call on to our dialog
object to give it a chance to update the status fields, if needed. <p>
The <CODE>MyDialog</CODE> class is the container for our main
window. Initialization is again done by first calling the base class
<CODE>__init__</CODE> function and finally setting two local variables
that are used by <CODE>updatestatus()</CODE> later. <p>
<CODE>__init__</CODE> function and finally setting the local variable
"parent." <p>
<CODE>Do_itemhit()</CODE> is called when an item is selected in this
dialog by the user. We are passed the item number (and the original
event structure, which we normally ignore). The code is similar to the
main loop of our previous example program: a switch depending on the
item selected. <CODE>Connect()</CODE> and <CODE>disconnect()</CODE>
are again quite similar to our previous example. <p>
<CODE>Updatestatus()</CODE> is different, however. It is now
potentially called many times per second instead of only when the
user presses a button we don't want to update the display every time
since that would cause some quite horrible flashing. Luckily,
<CODE>interslip.status()</CODE> not only provides us with a state and
a message but also with a message sequence number. If neither state
nor message sequence number has changed since the last call there is
no need to update the display, so we just return. For the rest,
nothing has changed. <p>
item selected. <CODE>Dnslookup()</CODE> is quite similar to our previous
example. <p>
<H2><IMG SRC="html.icons/mkapplet.gif"><A NAME="applets">Creating applets</A></H2>
@ -158,13 +143,8 @@ resources from that file will be copied to your applet too. If there
is no resource file for your script a set of default resources will be
used, and the applet will have the default creator 'Pyt0'. The latter
also happens if you do have a resource file but without the BNDL
combo. <A NAME="no-bundle">Actually</A>, for our example that would
have been the most logical solution, since our applet does not have
its own data files. It would have saved us hunting for an unused
creator code. The only reason for using the BNDL in this case is
having the custom icon, but that could have been done by pasting an
icon on the finder Info window, or by providing an custon icon in your
resource file and setting the "custom icon" finder bit. <p>
combo. <A NAME="no-bundle">Actually</A>, as in the present example.
<p>
If you need slightly more control over the BuildApplet process you can
double-click it, and you will get dialogs for source and
@ -178,3 +158,5 @@ interpreter still work. <p>
That's all for this example, you may now return to the <A HREF="index.html">
table of contents</A> to pick another topic. <p>
</BODY>
</HTML>

View file

@ -1,116 +0,0 @@
import FrameWork
import EasyDialogs
import Res
import Dlg
import sys
import interslip
#
# Definitions for our resources
ID_MAIN=512
ID_ABOUT=513
ITEM_CONNECT=1
ITEM_DISCONNECT=2
ITEM_STATUS=3
ITEM_MESSAGE=4
status2text = ["<idle>", "<wait-modem>", "<dialling>", "<logging in>",
"<connected>", "<disconnecting>"]
def main():
try:
interslip.open()
except interslip.error, arg:
EasyDialogs.Message("Cannot open interslip: "+arg[1])
sys.exit(1)
try:
dummy = Res.GetResource('DLOG', ID_MAIN)
except Res.Error:
try:
Res.OpenResFile("InterslipControl-2.rsrc")
except Res.error:
EasyDialogs.Message("Cannot open InterslipControl-2.rsrc: "+arg[1])
sys.exit(1)
InterslipControl()
class InterslipControl(FrameWork.Application):
"Application class for InterslipControl"
def __init__(self):
# First init menus, etc.
FrameWork.Application.__init__(self)
# Next create our dialog
self.main_dialog = MyDialog(self)
# Now open the dialog
self.main_dialog.open(ID_MAIN)
# Finally, go into the event loop
self.mainloop()
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
def quit(self, *args):
self._quit()
def do_about(self, *args):
f = Dlg.GetNewDialog(ID_ABOUT, -1)
while 1:
n = Dlg.ModalDialog(None)
if n == 1:
return
def idle(self, event):
"Idle routine - update status"
self.main_dialog.updatestatus()
class MyDialog(FrameWork.DialogWindow):
"Main dialog window for InterslipControl"
def __init__(self, parent):
FrameWork.DialogWindow.__init__(self, parent)
self.last_status = None
self.last_msgnum = None
def do_itemhit(self, item, event):
if item == ITEM_DISCONNECT:
self.disconnect()
elif item == ITEM_CONNECT:
self.connect()
def connect(self):
try:
interslip.connect()
except interslip.error, arg:
EasyDialogs.Message("Cannot connect: "+arg[1])
def disconnect(self):
try:
interslip.disconnect()
except interslip.error, arg:
EasyDialogs.Message("Cannot disconnect: "+arg[1])
def updatestatus(self):
try:
status, msgnum, msg = interslip.status()
except interslip.error, arg:
EasyDialogs.Message("Cannot get status: "+arg[1])
sys.exit(1)
if status == self.last_status and msgnum == self.last_msgnum:
return
self.last_status = status
self.last_msgnum = msgnum
if msgnum == 0:
msg = ''
try:
txt = status2text[status]
except IndexError:
txt = "<unknown state %d>"%status
tp, h, rect = self.wid.GetDialogItem(ITEM_STATUS)
Dlg.SetDialogItemText(h, txt)
tp, h, rect = self.wid.GetDialogItem(ITEM_MESSAGE)
Dlg.SetDialogItemText(h, msg)
main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1,92 @@
import FrameWork
import EasyDialogs
import Res
import Dlg
import sys
import socket
import string
#
# Definitions for our resources
ID_MAIN=512
ID_ABOUT=513
ITEM_LOOKUP_ENTRY=1
ITEM_RESULT=2
ITEM_LOOKUP_BUTTON=3
def main():
try:
dummy = Res.GetResource('DLOG', ID_MAIN)
except Res.Error:
try:
Res.OpenResFile("dnslookup-2.rsrc")
except Res.Error:
EasyDialogs.Message("Cannot open dnslookup-2.rsrc")
sys.exit(1)
DNSLookup()
class DNSLookup(FrameWork.Application):
"Application class for DNS Lookup"
def __init__(self):
# First init menus, etc.
FrameWork.Application.__init__(self)
# Next create our dialog
self.main_dialog = MyDialog(self)
# Now open the dialog
self.main_dialog.open(ID_MAIN)
# Finally, go into the event loop
self.mainloop()
def makeusermenus(self):
self.filemenu = m = FrameWork.Menu(self.menubar, "File")
self.quititem = FrameWork.MenuItem(m, "Quit", "Q", self.quit)
def quit(self, *args):
self._quit()
def do_about(self, *args):
f = Dlg.GetNewDialog(ID_ABOUT, -1)
while 1:
n = Dlg.ModalDialog(None)
if n == 1:
return
class MyDialog(FrameWork.DialogWindow):
"Main dialog window for DNSLookup"
def __init__(self, parent):
FrameWork.DialogWindow.__init__(self, parent)
self.parent = parent
def do_itemhit(self, item, event):
if item == ITEM_LOOKUP_BUTTON:
self.dolookup()
def dolookup(self):
"""Get text entered in the lookup entry area. Place result of the
call to dnslookup in the result entry area."""
tp, h, rect = self.wid.GetDialogItem(ITEM_LOOKUP_ENTRY)
txt = Dlg.GetDialogItemText(h)
tp, h, rect = self.wid.GetDialogItem(ITEM_RESULT)
Dlg.SetDialogItemText(h, self.dnslookup(txt))
def dnslookup(self, str):
""" Perform DNS lookup on str. If first character of digit is numeric,
assume that str contains an IP address. Otherwise, assume that str
contains a hostname."""
if str == '': str = ' '
if str[0] in string.digits:
try:
value = socket.gethostbyaddr(str)[0]
except:
value = 'Lookup failed'
else:
try:
value = socket.gethostbyname(str)
except:
value = 'Lookup failed'
return value
main()

Binary file not shown.