System Information and Operations (Python on Symbian)
From Symbian Developer Community
Original Authors: Pankaj Nathani and Mike Jipping
Now that we are familiar with Python's basic conventions and coding syntax, it's time to start learning PyS60. This chapter describes how to access device and application information, how to perform system operations, and how to work with files and time values.
Contents |
Introduction
The methods described in this chapter are frequently used in PyS60 applications, including many of the examples in this book.
This chapter first introduces the PyS60 modules that are used to discover information about the device and the current application: sysinfo and e32. In addition to providing information about the device, the e32 module contains utilities that allow developers to perform "system operations" - running new scripts, setting the device time, pausing the current script.
Lastly, the chapter discusses core functionality inherited from standard Python: how to perform operations related to time, and how to manipulate files. It covers Symbian file naming and handling conventions, and shows how Python handles files in ways similar to other programming languages.
System Information Module
The sysinfo module can be used to access device information, including: IMEI, signal strength, battery strength, firmware version, OS version, screen display resolution, current profile, current ringing type, RAM and ROM drive size and the amount of available available free RAM, ROM and disk drive space.
The module is easy to use. For example, the following two lines in the interactive PyS60 console return the IMEI of the device:
>>>import sysinfo
>>>sysinfo.imei()
u’2174027202720292’
| Note Every mobile device on a GSM network is identified by a unique number called its IMEI (International Mobile Equipment Identity). The IMEI of the device can be retrieved manually by dialing *#06#. |
The following code snippets show methods used to obtain the information and their return types.
# Battery strength as an integer. This value ranges from 0 (empty) to 100 (full).
>>> sysinfo.battery()
42
# Signal strength as an integer. This value ranges from 0 (no signal) to 7 (strong signal).
>>> sysinfo.signal_bars()
7
# Network signal strength in dBm (integer)
>>> sysinfo.signal_dbm()
81
# IMEI code of the device as a Unicode string
>>> sysinfo.imei()
u'354829024755443'
# Software version as a Unicode string. This is the same version number that a device shows when *#0000# is dialled from it.
>>> sysinfo.sw_version()
u'V 20.0.016 28-2-08 RM-320 N95(c)NMP'
# Width and height of the display (current orientation) in pixels
>>> sysinfo.display_pixels()
(240, 320)
# Current profile name as a string ('general', 'silent', 'meeting', 'outdoor', 'pager', 'offline', etc). If a custom profile is selected - it returns 'user <profile value>'
>>> sysinfo.active_profile()
'general'
# Ringing type as a string - 'normal', 'ascending', 'ring_once', 'beep', or 'silent'
>>> sysinfo.ring_type()
'normal'
# Os version as a tuple
>>> sysinfo.os_version()
(2, 0, 1540)
| Note As the Emulator is not a device, not all values have "real" values. Instead dummy values are returned:
|
Symbian devices usually have an internal disk (C:) and a memory card (E:); there are exceptions - devices which use E drive for "internal" mass memory and which have additional drives. The Random access memory (RAM) drive is mapped to D drive; while Z drive indicates the Read only memory (ROM) drive. The amount of ROM, RAM and disk space varies across devices.
sysinfo can also return information about the device memory, as shown below:
# Free RAM in bytes
>>> sysinfo.free_ram()
81838080
# Total RAM in bytes
>>> sysinfo.total_ram()
125501440
# Total ROM in bytes
>>> sysinfo.total_rom()
8716288
# Free disk space in bytes. Drive can be C: or E:
>>> sysinfo.free_drivespace()['C:']
16207872
Note that the e32 module provides drive_list() to get the list of drives, as discussed in the following section.
e32 Module
The e32 module contains a useful and varied collection of utilities. The utilities range from those which give access to information about the device and current application, though to methods that allow an application to pause the current script or reset the device inactivity timer. There are even methods to copy files and folders.
The e32 module provides the following "system" information (complementary to that provided in sysinfo):
- Version of Python runtime
- Version of Symbian device runtime
- List of available drives
- Application platform security capabilities
- Length of time since the last user activity
- Whether or not the current thread is a UI thread
- Whether or not the application/script is running on an emulator
The code snippet below shows the methods used to obtain the above information.
# pyS60 version - tuple of version number: major, minor, micro and release tag,
>>> e32.pys60_version()
(1, 9, 7, 'svn2793')
# pyS60 version - tuple of major, minor, micro, release tag, and serial.
>>> e32.pys60_version_info()
(1, 9, 7, 'svn2793', 0)
# Symbian platform device version - tuple of major and minor version
>>> e32.s60_version_info()
(3, 0)
# List of available memory drives. For example: [u'C:',u'D:',u'E:',u'Z:']
>>>e32.drive_list()
[u'C:',u'D:',u'E:',u'F:',u'Z:']
# Time in seconds since the last user activity
>>> e32.inactivity()
3
# Platform security capabilities granted to the application, returned as a tuple
>>> e32.get_capabilities()
('ReadUserData','WriteUserData')
# Test if application has been granted the specified platform security capabilities. Returns True or False.
# querying single capability
>>> e32.has_capabilities('WriteUserData')
True
# querying two capabilities
>>> e32.has_capabilities('WriteUserData','ReadUserData')
True
# Test if the calling script is running in the context of a UI thread. Returns True or False
>>> e32.is_ui_thread()
True
# Test whether or not the application/script is running in an emulator. Returns 1 if yes, 0 if no.
>>>e32.in_emulator()
1
The e32 module contains the following "system operations".
Set device time
The set_home_time() function sets the device system time to given time (for e.g. user_time in the example below). The device system time can be retrieved through the time module as explained in next section.
import e32
import time
# current time
user_time = time.time()
# modify the user_time
user_time -= 10.0
e32.set_home_time(user_time)
| Note The WriteDeviceData capability is required when using this function. For more information, refer to Chapter 16. |
Copy files
The file_copy() function can be used for copying files from one folder to another.
>>> source_path=u"C:\\Python\\myimage.jpg"
>>> destination_path=u"C:\\Data\\Images\\myimage.jpg"
>>> e32.file_copy(destination_path,source_path)
For copying all the files in the source folder '*.*' is appended in the source path following is used.
>>> source_path=u"C:\\Python\\*.*"
>>> destination_path=u"C:\\Data"
>>> e32.file_copy(destination_path,source_path)
This copies all the files in C:\Python directory to the C:\Data directory.
Note
|
Launch an application
The start_exe() method can be used to launch a specified executable (.exe) file:
>>> e32.start_exe(exe_filename, command,wait_time)
The parameter command passes command line arguments to the executable; if no arguments are required it may be set as NULL or an empty string. The parameter wait_time is optional parameter, as described below.
The following statement is used to launch the Web browser with the default URL. Here the command parameter is passed an empty string.
>>> application_exe='BrowserNG.exe'
>>> a=e32.start_exe(application_exe, "")
In order to open the web browser application with a particular URL we pass it as a command, as shown below.
>>> url="http://symbian.org"
>>> application_exe='BrowserNG.exe'
>>> e32.start_exe(application_exe, ' "%s"' %url)
In both the previous examples the browser is launched asynchronously. We can use the optional wait_time integer parameter to launch an application synchronously.
If a non-zero value is specified for a non-zero value for wait_time then start_exe() will launch the application and wait for it to exit. It will then return 0 if the application exited normally or 2 if the application was terminated abnormally.
>>> wait_time=1
>>> url="4 http://symbian.org"
>>> exit_type=e32.start_exe(application_exe,' "%s"' %url , wait_time)
>>> print exit_type
The '4 ' prefixed in the url parameter indicates that the browser should launch the url specified. Other predefined prefixes for the parameter are shown below:
- Start/Continue the browser and nothing is specified (the default case): Parameter = <Any text>
- Start/Continue the browser specifying a Bookmark: Parameter = “1”+”<Space>“+”<Uid of the Bookmark>”
- Start/Continue the browser specifying a Saved deck: Parameter = “2”+” <Space>“+”<Uid of the Saved deck>”
- Start/Continue the browser specifying a URL: Parameter = “4”+” <Space>“+”<Url>”
- Start/Continue the browser specifying a URL and an Access Point: Parameter = “4”+”<Space>“+”<Url>”+”<Space>“+”<Uid of Ap>”
- Start/Continue the browser with the start page. (Used when starting the browser with a long press of “0” in the Idle state of the phone): Parameter = “5”
- Start/Continue the browser specifying a Bookmark folder: Parameter = “6”+” <Space>“+”<Uid of the Folder>”
The start_exe() function can also be used to launch other native and third party applications.
Launch a python script as a server
A python script can be launched in the background (as a server script) by using the start_server() function.
>>> server_script.py=u"C:\\Data\\Python\\myscript.py"
>>> e32.start_server(server_script)
Reset Inactivity
The reset_inactivity() method can be used to programmatically reset the inactivity timer.
>>> e32.reset_inactivity()
Reseting the inactivity timer at regular intervals prevents the device from entering a low power mode during periods of user inactivity. This can be useful if an application needs to remain visible even if the user isn't "doing anything" - for example when using an in-car hands-free navigation system. See also inactivity() to get the current value of the inactivity timer.
Wait/Sleep
The ao_sleep() method can be used to introduce a delay between the execution of statements, or to call a specified method after a given interval.
For example, the following code causes the script to wait for two seconds:
print "Waiting for 2 seconds"
e32.ao_sleep(2) #sleeps for 2 seconds
print "Wait over"
An optional call back function could be used with ao_sleep(). In the example below, the function foo is called after waiting for 3 seconds.
def foo():
print "In function"
e32.ao_sleep(3,foo)
ao_yield and ao_callgate
Calling ao_yield gives control back to the active scheduler - allowing any active object based code with priority above normal to run. In practice, this keeps an application responsive to menu and softkey events even while performing other long running events. For example, the following code fragment displays notes within a continuous while loop. The use of e32.ao_yield ensures that we can exit the loop (and application) by pressing the right soft key. Without e32.ao_yield in the loop, the active scheduler would never get to run the event handling code.
def quit():
global running
running=0
appuifw.app.set_exit()
appuifw.app.exit_key_handler=quit
running=1
while running:
appuifw.note(u"hello")
e32.ao_yield())
The ao_callgate is an object that queues the calls and parameters made, and when activated, calls the given function as many times as there are calls in the queue, with the parameters that were given, in the context of the thread where the ao_callgate was created.
The ao_callgate is simply an active object that has a queue of calls and that runs all the calls in the queue in its RunL method.
| Note Active objects are used extensively in Symbian C++ to provide co-operative multitasking to applications and other code. The concept has been used to implement some of Python's core platform-specific behaviour - for example "under the hood" menus are implemented as active objects. Active objects are discussed in detail in Active Objects (Fundamentals of Symbian C++) |
import e32
def fun():
print "Hello"
foo = e32.ao_callgate(fun)
foo()
Ao_lock and Ao_timer
In addition to the above operational functions, Ao_lock and Ao_timer are the two important classes defined in the e32 module. As these are classes and not module level functions, they can be used only after they are instantiated.
Ao_lock is a Symbian active object based synchronization service, that is the heart of the UI Structure of a Python Application. It is used by creating an instance of Ao_lock, adding a number of active objects to it, and then calling wait() on the thread, as shown below:
#Creating instance of Ao_lock
app_lock = e32.Ao_lock()
# Add active objects here - e.g. menu callbacks
#Wait for application lock to be signaled
app_lock.wait()
Script execution is halted at the wait, but any active objects that are already running will be serviced. As menus are implemented "behind the scenes" as active objects, your menu callbacks will still be called and the UI will remain responsive.
When you're ready to continue execution of the script you call signal(). Note however that as the script execution is halted at the wait() you need to do this through a menu callback. It is a convention to release the waiter in the quit function:
#Signals the lock and releases the waiter
def quit():
app_lock.signal()
It is important to remember that wait() can only be called in the thread that created the lock object and only one waiter is allowed (so care should be taken while using it in a loop).
Ao_timer is a Symbian active object based timer service. Like Ao_lock, it can be used in the main thread without blocking the handling of UI events. The following code snippet creates an instance of Ao_timer and illustrates use of its after() and cancel() methods.
#Creating instance of Ao_timer
timer = e32.Ao_timer()
#Sleeps for the 1 second without blocking the active scheduler and calls the callback_function() - user defined callback function
timer.after(1, callback_function)
#Cancels the 'after' call.
timer.cancel()
While using the after method the callback function is optional - if it is not specified the thread simply sleeps for the specified time.
The cancel() method can be used to cancel a pending after() request. It is important to cancel pending timer calls before exiting the application; if you forget your application will panic on exit.
| Tip Use Ao_timer instead of ao_sleep where possible, both because a pending ao_sleep cannot be canceled and because the user can exit the application while the application is sleeping (which would cause a panic). |
Time Operations
Python's concept of time comes from the Unix operating system. Unix measures time as the number of seconds since "the epoch", which started on January 1, 1970 at 00:00:00 UTC (Coordinated Universal Time, also known as Greenwich Mean Time). For example, midnight on 1 January 2010, is 1,262,304,000 seconds since the Unix epoch. France's Bastille Day in 2010 at 8:00 in the morning is 1,279,094,400 seconds in Unix time.
| Tip Generally speaking you don't need to think about the number of seconds! Python provides methods to allow you to convert to more friendly units. If you did need to do a manual conversion, there are several sites on the Internet that will convert them for you: |
There are several system functions that let you display and manipulate system time. Before we do that, however, we should review the possible values accepted for time values. There are two sets of values:
- float values represent seconds since the epoch as described above (the float data type must be used because this number of seconds is large).
- time structure values are nine integers that correspond to specific time components, as shown in the table below:
| Python Name | Description |
|---|---|
| tm_year | four digit value depicting the year |
| tm_mon | integer in the range 1 to 12 depicting the month |
| tm_mday | integer in the range 1 to 31 depicting the day of the month |
| tm_hour | integer in the range 0 to 23 depicting the hour |
| tm_min | integer in the range 0 to 59 depicting the minute |
| tm_msec | integer in the range 0 to 61 depicting the second (the 60th and 61st values account for leap and double leap seconds) |
| tm_wday | integer in the range 0 to 6 depicting the day of the week (Monday has the value 0) |
| tm_yday | integer in the range 0 to 365 depicting the day of the year (accommodating for leap year) |
| tm_isdst | integer in the range 0 to 1 depicting a boolean value to determine Daylight Savings Time (can be -1, see mktime() below, |
For example, consider the code below, where time.localtime() returns the time structure values as a tuple:
import time
(a,b,c,d,e,f,g,h,i) = time.localtime()
If this code were executed on 8 September 2009, at 9:15:38 am, then the variables would have the following values:
a = 2009 b = 9 c = 8 d = 9 e = 15 f = 38 g = 1 h = 251 i = 1
Let's briefly overview the functions in the time module:
- time.asctime([t]) converts the time - either the current time, if the parameter is absent, or the time represented by the optional tuple representing a time structure value - to a string that depicts the time described.
- time.clock() returns the current processor time as a float in seconds. You cannot really depend on this value for anything other than comparative uses.
- time.ctime([secs]) converts a time value in seconds since the epoch to a time structure value UTC. For this conversion, the dst flag is always zero, which means adjustment for Daylight Savings Time is not done. If secs is not provided or is None, the current time as returned by time() is used.
- time.gmtime([secs]) converts a time expressed in seconds since the epoch to a time structure value in UTC in which the dst flag is always zero. If secs is not provided or None, the current time is used.
- time.localtime([secs]) converts to local time, returning a time structure value. If secs is not provided or is None, the current time is used.
- time.mktime(t) can be viewed as the inverse function of localtime(). Its argument is tuple depicting a time strructure value which expresses the time in local time, not UTC. It returns a floating point number of seconds since the epoch. If the input value cannot be represented as a valid time, either OverflowError or ValueError will be raised.
- time.sleep(secs) suspends execution of the current program for the given number of seconds. This number may be a floating point number to indicate a precise sleep time.
- time.strftime(format[, t]) converts a tuple representing a time structure value to a string as specified by the format argument. If t is not provided, the current time is used. format must be a string. A ValueError exception is raised if any field in t is outside of the allowed range. More on this function will be described later.
- time.strptime(string[, format]) parses a string representing a time according to a format. The return value is a time structure value. The format follows the same directives as strftime(), described below.
- time.time() returns the time as a floating point number expressed in seconds since the epoch, in UTC.
- time.tzset() resets the time conversion rules used by the library routines. The environment variable TZ specifies how this is done.
The strftime() and strptime() functions use special directives embedded in a format string. These directives are shown below:
| Directive | Description |
|---|---|
| %a | abbreviated weekday name |
| %A | full weekday name |
| %b | abbreviated month name |
| %B | full month name |
| %c | date and time representation appropriate for region |
| %d | day of the month as an integer |
| %H | hour as an integer on the 24-hour clock |
| %I | hour as an integer on the 12-hour clock |
| %j | day of the year as an integer |
| %m | month as an integer |
| %M | minute as an integer |
| %p | AM or PM as a string |
| %S | seconds as an integer |
| %U | week number of the year as an integer (with Sunday considered the first day of the week) |
| %w | weekday as an integer (Sunday is day numbered 0) |
| %W | week number of the year as an integer (with Monday considered the first day of the week) |
| %x | date representation as a string |
| %X | time representation as a string |
| %y | year as an integer without century |
| %Y | year as in integer with century |
| %Z | time zone name (no characters if no time zone exists) |
Let's look at a couple of examples to clarify this. Consider the following code:
time.strftime("Now is %a, %d %b %Y at %H:%M:%S", time.gmtime())
Notice how the format string combines regular text with time specifiers. It also gets the time value from time.gmtime(). This code will produce the output:
'Now is Wed, 09 Sep 2009 at 13:58:37'
Now consider this code:
thedate = "31 Dec 08"
t = time.strptime(thedate, "%d %b %y")
if t[7] == 366:
print thedate, "was in a leap year"
else:
print thedate, "was not in a leap year"
In the above example, the results showed that 2008 was a leap year, because "31 Dec 08" was day number 366 in the year. Notice that the format string for time.strptime() describes the way that the first string depicting the date is formatted.
There are also some variables represented in the time module. These are
- time.accept2dyear is a boolean value indicating whether two-digit year values will be accepted.
- time.altzone represents the offset of the local DST timezone, in seconds west of UTC, if one is defined.
- time.daylight is nonzero if a DST timezone is defined.
- time.timezone is the offset of the local timezone, in seconds west of UTC.
- time.tzname is a tuple of two strings. The first is the name of the local timezone; the second is the name of the local DST timezone.
| Does this look familiar? These calls and variables might look familiar. Python is based heavily in C and C++, so you might have recognized these methods as Unix system calls. The time structure values are also taken from Unix system calls. In fact, there is one more method - struct_time() - that works with the time values in the C struct time structure (see the struct values in the table above). While you do not need it, most time methods will accept a structure in the C form, much like this: time.struct_time(tm_year=2010, tm_mon=0, tm_mday=0, |
The description here is of the system time module. There are other modules that provide a less primitive, more object-oriented approach to dates and times. The datetime module generally handles dates and times. The locale module implements internationalization services; its settings can alter the return values for some of the functions above. The calendar module implements calendar related functions.
Finally, there is one more system function we should look at: e32.set_home_time(). This call comes from the e32 module and is used to set the current time for the device. The parameter to the function is the time to be set in Unix "seconds past the epoch" format. For example:
import e32
e32.set_home_time(1262304000)
This code would set the global device time to midnight on 1 January 2010.
To execute this code, the application needs WriteDeviceData capability (capabilities are discussed in Chapter 16).
File Operations
The idea of files is a familiar one: storage containers of data that are managed by the operating system. As we discussed in Chapter 2: Basic Python Elements, a file is a built-in data type for Python. Python handles files in ways similar to other programming languages. There are also some extended file operations in the modules unique to Python on the Symbian platform. We also cover operations from the os module that apply to file operations.
We should start by noting the file naming conventions for the Symbian platform. Symbian uses conventions similar to those used in Microsoft Windows. Drive letters are used to indicate storage units, such as memory or SD cards. The common use of the hierarchy of directories and files is used here, with pathname components separated by backslashes.
The file object is a built-in data type of Python. The table below outlines some of the common file operations provided by the language:
| Operation | Description |
|---|---|
| log=open("C:\logfile2.txt", "w") | Create a new file (the "w" flag is for writing) |
| inlog = open("C:\images\logfile.txt") | Open the file for reading(the "r" flag, for reading, is the default flag) |
| contents = inlog.read() | Read the entire contents of a file into a single string variable |
| bytes = inlog.read(count) | Read "count" bytes into a string |
| line = inlog.readline() | Read a single line into a string (includes end-of-line marker) |
| linelist = inlog.readlines() | Read the entire contents of a file into a list of strings, each holding a line |
| log.write(someContent) | Write a string into a file |
| log.writeLines(stringList) | Write a sequence of strings to the file (does not add end-of-line markers) |
| log.flush() | Flush the buffer holding data for a file into that file |
| log.truncate() | Cut off the file at the current position, discarding all data after that position |
| log.seek(position) | Move the current position in a file to "position" |
| log.close() | Close a file |
Most of these operations are common to those used in other languages. Many operations are streamlined from ones you may have used, because of the way Python organizes data objects. The readlines() and writelines() functions, for example, make reading or writing a large amount of content quite easy. For example, consider this code:
html = ["<HEAD>"]
## ... generate HTML and append it to the list using "html.append(...)"
htmlfile = open("E:\Images\announce.html", "w")
htmlfile.writelines(html)
htmlfile.close()
Other languages like Java would require each line of HTML to be written separately to a file, probably using a for loop. Here, however, one statement writes all lines to the file.
Note that data is always retrieved from files as a string -- even non-readable data. This means that if you need data in another form, say numbers, you have to convert the data from strings to the form you need. Likewise, writing data to a file is always done using strings. Even if you want to write integers or floats, you must format the data into a string first, then write that string to a file.
For example:
line = str(10) + "," + str(data) + "," + str(value) + "\n"
out.write(line)
This code builds three data items into a single string for writing. Likewise, we might read this data like
line = input.readline()
pieces = line.split(',')
data1 = int(pieces[0])
data2 = int(pieces[1])
converter = float(pieces[2])
Here, we read a comma separated line, split it into pieces and convert the individual strings into the type of data we need.
We can also use some string formatting to construct the line we need for a file. Consider this example, which rewrites the example above:
line = "%d,%d,%f\n" % (10, data, value)
out.write(line)
The above works for simple data types, but native Python objects might be harder to convert to strings and back. This is where the pickle module comes in. The pickle module contains methods that allow almost any Python object to be written to a file, with no conversion to and from strings. Consider the example below:
import pickle
dict = {'one': 1, 'two': 2, 'three': 3, 'four': 4}
dictFile = open('dictfile', 'w')
pickle.dump(dict, dictFile)
dictFile.close()
This allows the data store in the dictionary dict to be stored in the file "dictfile" as a native Python dictionary. We could get the dictionary back using the code below:
infile = open('dictfile')
newdict = pickle.load(infile)
infile.close()
Now, the variables dict and newdict have the same value.
In addition to these basic file operations, the os module has many file descriptor and directory operations. The file descriptor operations reveal the Unix operating system method of dealing with files. Unix uses integers to keep track of files at the system level (really indexes into a file table) and there are several primitive operations that work with these descriptors. The useful operations get status information for files from the operating system. You can get more information at the PyS60 Web page (http://pys60.garage.maemo.org/doc/lib/os-fd-ops.html) on file descriptors.
The operations from the os module on directory operations are a bit more useful. Again, many deal with system level manipulation of the file system, but some can prove useful in general use. A few are listed below:
- chdir(path) changes the current working directory of your program. This is useful, for example, when many files will be manipulated and long pathnames are undesirable.
- getcwd() will tell your program what the current working directory is.
- chmod(path, mode) changes the mode of the path given. The mode of a file is a set of permission flags kept by the operating system. Please refer to the list of permissions on the Web page to understand everything you can change for a file.
- listdir(path) returns a list of names for the files and directories in the directory given as the parameter.
- mkdir(path[, mode]) will create a directory with the pathname given and the (optional) permissions given by mode. Without the permissions given, the directory is created with all permissions for all users.
- remove(path) deletes the file specified by path. If you specify a directory here, you will raise an exception.
- rename(src, dst) will rename src to dst.
- rmdir(path) removes the directory given by path.
- stat(path) returns a lot of information about the path specified. See the Web page for the list of information.
- tempnam([dir[, prefix]]) will return a unique path name that can be used for creating a temporary file. Often, such a temporary file is useful for generating data -- then for using the temporary data to build useful data in a "real" file.
As if all these facilities were not enough, there are several more calls available in the e32 and sysinfo modules that can be useful - as discussed in the e32 Module section. The calls that relate to file operations are listed in the table below:
| System Call | Module | Description |
|---|---|---|
| drive_list() | e32 | Returns a list of visible, accessible drives |
| file_copy(target_name, source_name) | e32 | Copies a file from target_name to source_name |
| free_drivespace() | sysinfo | Returns the amount of free space left on drives as a dictionary object using drive/space pairs |
More information can be found at: http://pys60.garage.maemo.org/doc/s60/node10.html and http://pys60.garage.maemo.org/doc/s60/module-sysinfo.html.
Summary
This chapter described the system operations and information provided by two basic PyS60 modules: e32 and sysinfo, how to perform operations related to time, and how to work with files and directories. To do so we've used some rather simplistic examples, however believe these are still very illustrative!
These features are combined with other ingredients of PyS60 in many of the examples in forthcoming chapters. We suggest you to use this chapter as a reference and come back to it whenever you need to apply these concepts in practice.
Comments
Contents |
Bogdan said…
Croozeus said…
Hi Hamish and Bogdan,
Thanks for your comments and suggestions!
I have now integrated the comments of both (sysinfo and e32 sections). Please let me know incase, I might have still missed out something. Hamish, thanks for wording the introduction and sysinfo text and making it more readable, it looks good to me.
Regarding the system operations section (description of each methods) - I think this is required, since they have a elaborated description with examples. It would be difficult to show these in a grouped snippet like the previous system info section, where only return values and sample statements can be shown collectively within a code snippet the approach is fine. Let me know if it is fine?
Please feel free to do any changes that would improve the presentation.
--Croozeus 03:15, 9 February 2010 (UTC)
Hamishwillee said…
Hi Croozeus
Thanks very much. This is improved a lot.
Below are further comments in response to changes:
- Launch an application
<HamishW - removed my comments here - addressed>
- ao_yield and ao_callgate
- Explanation of ao_yield didn't make much sense to me. What is yeilding (giving way) to what. In the example you say that "For example, in the following example the code execution would move ahead after the import of the CustomModule returns.". However if you removed the yielding line the code would still move ahead - so in this case the example doesn't really do anything. I think you need a new example.
- ao_callgate - I'm not sure about this. Are you saying that all the functions are run in the one RunL? I think to make it clearer we need to:
- in the example queue up a number of functions
- show a function afterwards being called (with a comment on the ao_callgate that all the functions in list are run in order, and a comment on the function afterwards that it runs immediately
- Discuss why doing this might be useful - ie when is a callgate something you might use
- Wait/Sleep
- We still don't mention time.sleep(secs) - I think its worth doing, at least as a note.
- We say "While using the after method the callback function is optional."
- what if you don't declare it? Does nothing happen?
- We say "Use of Ao_timer is recommended ao_sleep because ao_sleep cannot be interrupted and the user can exit the application while the application is sleeping - this would cause a panic."</blue>
- When you say canot be interrupted, do you mean that it freezes the thread and the UI isn't responsive? If not, what do you mean? If so, then how can they exit the application if the UI is unresponsive?
- Documents should have a Summary. I've added the heading, but would be good if you could add the text.
I've also added a note link to Active objects information, and restructured the section on application locks/wait. The main reason I did this is that from the example the signal would never be called because the wait was active. I needed to somehow explain that once waiting, the only actions are those from callbacks of existing active objects. I think this works, but please check.
Cheers H
--Hamishwillee 02:12, 10 February 2010 (UTC) </div>
Frethop said…
I have made the changes you commented on. I have a few notes:
1. I'm feeling stupid here, but I have always used single backslashes with Symbian and it works fine in the Python I wrote. So I left them...
--Frethop 11:40, 19 February 2010 (UTC)
Sign in to comment…




Very well written chapter.
I fixed two small typos: In the first paragraph: its -> it's In the note about appuifw: python -> Python
Hamish has already made plenty of useful suggestions (more that I would have been able to come up with) so once those are implemented it should be perfect. I can only insist that there be a healthy discussion about e32.Ao_timer - it's important.
Unrelated to the contents of the chapter, I noticed that on Internet Explorer 8 the image in the tip called "Does this look familiar?" overlaps the text. Just thought I'd mention it so maybe you can reproduce it and fix it.
Once again, you've done a great job with this chapter.
--Bogdan 11:06, 5 February 2010 (UTC)