Scripts

Differences between revisions 5 and 18 (spanning 13 versions)
Revision 5 as of 2012-04-30 23:02:47
Size: 2830
Comment:
Revision 18 as of 2012-05-01 14:47:44
Size: 7357
Comment:
Deletions are marked like this. Additions are marked like this.
Line 5: Line 5:
[[Accomplishments/CreatingGuide/AccomplishmentFile|<-- Previous page (Creating .accomplishment files)]] - - - - - [[Accomplishments|Next page (blah) --->]]

'''This page is under construction. This guide is not yet complete!'''
[[Accomplishments/CreatingGuide/AccomplishmentFile|<-- Previous page (Creating .accomplishment files)]] - - - - - [[Accomplishments/CreatingGuide/SetStructure|Next page (Accomplishments sets structure) --->]]
Line 30: Line 27:
Also, if your script has to use some '''extra-information''', it can use Accomplishments Daemon API to get it - details below.  Also, if your script has to use some '''extra-information''', it can use Accomplishments Daemon API to get it - details below.
Line 32: Line 29:
Everything your script prints will land in daemon's log - which is available at ~/.cache/accomplishments/daemon.log Remember, that if your accomplishment collection uses scripts that import some unusual libraries, you will need to setup appropriate dependencies, when publishing it as a .deb package.

For testing, you can `print` something with your scripts, but remember to remove such statements before publishing your accomplishments. ''When your script is run by the Accomplishments Daemon, all what your script `print`s will land in ~/.cache/accomplishments/logs/daemon.log''
Line 37: Line 36:
{{{
##!/usr/bin/python
{{{#!python
#!/usr/bin/python
Line 62: Line 61:
Scripts for global accomplishments are slightly more complicated. Also, they may use Accomplishments Daemon API to get extra-information easily.

===== Example =====
{{{#!python
#!/usr/bin/python
import traceback, sys

from accomplishments.daemon import dbusapi

try:
    import sys, os, pwd, subprocess
    from launchpadlib.launchpad import Launchpad

    # Connect to the daemon to get extra-information.
    api = dbusapi.Accomplishments()
    f = api.get_extra_information("ubuntu-community", "launchpad-email")
    if bool(f[0]["launchpad-email"]) == False:
        sys.exit(4)
    else:
        email = f[0]["launchpad-email"]

    # Get count of bugs reported by user from Launchpad, using email to identify user
    l = Launchpad.login_anonymously(
        'ubuntu-community accomplishments', 'production')
    me = l.people.getByEmail(email=email)
    if me == None:
        # User of such e-mail does not exist...
        sys.exit(1)
    else:
        ubuntu=l.projects['ubuntu']
        # Search for bugs of any status reported by this user in Ubuntu...
        bugs_reported = ubuntu.searchTasks(bug_reporter=me,
            status=['New', 'Incomplete', 'Invalid', 'Confirmed', 'Triaged',
                    'In Progress', 'Fix Committed', 'Fix Released', 'Opinion',
                    "Won't Fix"])
        if len(bugs_reported) > 0:
            # Success! Accomplishment completed!
            sys.exit(0)
        else:
            # No such bugs were found...
            sys.exit(1)
except SystemExit, e:
    sys.exit(e.code)
except:
    traceback.print_exc()
    sys.exit(2)

}}}

This example is an actual code for '''Filed First Bug''' accomplishment from previous chapter. It uses `launchpadlib` to connect to Launchpad, and check bugs that given person reported in Ubuntu. There are few lines of special interest, that are worth explaining:

{{{
    from accomplishments.daemon import dbusapi
    api = dbusapi.Accomplishments()
}}}

The above used to connect to Accomplishments Daemon.

{{{
    f = api.get_extra_information("ubuntu-community", "launchpad-email")
    if bool(f[0]["launchpad-email"]) == False:
        sys.exit(4)
    else:
        email = f[0]["launchpad-email"]
}}}

`get_extra_information` is used to ask for `launchpad-email` in this example. Note that set's name (`ubuntu-comunity` in this case) has to be passed too. The following `if` statement is used to determine if getting extra-information was successful, if not, the script should return ''4'', in other case we store requested e-mail to a variable.
Line 63: Line 130:

Testing scripts is very easy, and can be done without installing accomplishments to your system, and it is recommended to test them before installing, because this way it's easier to hunt bugs. Simply run your script: `python script.py`. If you want to check exit code of your script, the simplest trick is to run: `python script.py; echo $?`

'''Remember''': To test scripts which use extra-information, you need to be running the daemon first. You can start it by launching Accomplishments Viewer, or with `twistd -y /usr/bin/accomplishments-daemon`.

'''Note:''' If you test your scripts before installing them, you need to setup required extra-information manually. After installing your accomplishment, the Accomplishment Viewer will ask user for required credentials. To set that data manually, use e.g. `echo user@mail.com | cat > ~/.local/share/accomplishments/trophies/.extrainformation/launchpad-email`

<<BR>>
Now you should be able to write your own accomplishment script, as well as an .accomplishment file. This should be enough if you want to contribute to one of existing accomplishment collections.

The next chapter will teach you how accomplishment collections are organised, how to make your accomplishments available in multiple languages, how to install them to your system, and how to prepare an installation script.

[[Accomplishments/CreatingGuide/AccomplishmentFile|<-- Previous page (Creating .accomplishment files)]] - - - - - [[Accomplishments/CreatingGuide/SetStructure|Next page (Accomplishments sets structure) --->]]

The Guide to Creating Your Accomplishments

Creating accomplishment scripts

<-- Previous page (Creating .accomplishment files) - - - - - Next page (Accomplishments sets structure) --->

Every single accomplishment requires a script, that is executed to determine whether the user has completed this accomplishment. Usually these scripts are not larger then the .accomplishment file, so no great programming skills are needed to prepare one.

Currently only Python scripts are supported. We hope to allow developers to prepare scripts in other languages too, but that's not our priority, while writing them in Python is simple and quick.

Returning values

The Accomplishments System will run scripts on it's own. The only thing the script has to do is to check if the accomplishment is complete, and report result by returning a number.

The exit codes are:

  • 0 - The accomplishment has been completed.

  • 1 - The accomplishment has not been completed.

  • 2 - There was an error while checking for completion.

  • 4 - There was an error while getting extra-information.

The easiest way to return such value is to use sys.exit(n).


While this should be enough for you to create scripts, there are some tips and examples for you, to make everything clearer.

  • Also, if your script has to use some extra-information, it can use Accomplishments Daemon API to get it - details below.

Remember, that if your accomplishment collection uses scripts that import some unusual libraries, you will need to setup appropriate dependencies, when publishing it as a .deb package.

For testing, you can print something with your scripts, but remember to remove such statements before publishing your accomplishments. When your script is run by the Accomplishments Daemon, all what your script prints will land in ~/.cache/accomplishments/logs/daemon.log

Local accomplishment scripts

Example

   1 #!/usr/bin/python
   2 import traceback, sys
   3 try:
   4     try:
   5         #open the highscores file...
   6         highscoresfile = open("/var/games/gnomine.Small.scores")
   7     except IOError as e:
   8         # it seems that the file does not exist
   9         sys.exit(1)
  10     bestscore = highscoresfile.readline()
  11     if not bestscore:
  12         #the file is empty
  13         sys.exit(1)
  14     #the file is not empty
  15     sys.exit(0)
  16 except:
  17     traceback.print_exc()
  18     sys.exit(2)

This is a working script for Begginer Minesweeper from previous chapter. It is intended to check if the user has ever completed a Small game in Gnomine. This is done by reading the highscores file, and checking whether it contains at least one entry. If so, we return 0, otherwise 1. All that is within a global try block, to react in case of unhandled errors (that does not make much sense here, but may be useful in your scripts, so it's just as an example).

Global accomplishment scripts

Scripts for global accomplishments are slightly more complicated. Also, they may use Accomplishments Daemon API to get extra-information easily.

Example

   1 #!/usr/bin/python
   2 import traceback, sys
   3 
   4 from accomplishments.daemon import dbusapi
   5 
   6 try:
   7     import sys, os, pwd, subprocess
   8     from launchpadlib.launchpad import Launchpad
   9 
  10     # Connect to the daemon to get extra-information.
  11     api = dbusapi.Accomplishments()
  12     f = api.get_extra_information("ubuntu-community", "launchpad-email")
  13     if bool(f[0]["launchpad-email"]) == False:
  14         sys.exit(4)
  15     else:
  16         email = f[0]["launchpad-email"]
  17 
  18     # Get count of bugs reported by user from Launchpad, using email to identify user
  19     l = Launchpad.login_anonymously(
  20         'ubuntu-community accomplishments', 'production')
  21     me = l.people.getByEmail(email=email)
  22     if me == None:
  23         # User of such e-mail does not exist...
  24         sys.exit(1)
  25     else:
  26         ubuntu=l.projects['ubuntu']
  27         # Search for bugs of any status reported by this user in Ubuntu...
  28         bugs_reported = ubuntu.searchTasks(bug_reporter=me, 
  29             status=['New', 'Incomplete', 'Invalid', 'Confirmed', 'Triaged', 
  30                     'In Progress', 'Fix Committed', 'Fix Released', 'Opinion',
  31                     "Won't Fix"])
  32         if len(bugs_reported) > 0:
  33             # Success! Accomplishment completed!
  34             sys.exit(0)
  35         else:
  36             # No such bugs were found...
  37             sys.exit(1)
  38 except SystemExit, e:
  39     sys.exit(e.code)
  40 except:
  41     traceback.print_exc()
  42     sys.exit(2)

This example is an actual code for Filed First Bug accomplishment from previous chapter. It uses launchpadlib to connect to Launchpad, and check bugs that given person reported in Ubuntu. There are few lines of special interest, that are worth explaining:

    from accomplishments.daemon import dbusapi
    api = dbusapi.Accomplishments()

The above used to connect to Accomplishments Daemon.

    f = api.get_extra_information("ubuntu-community", "launchpad-email")
    if bool(f[0]["launchpad-email"]) == False:
        sys.exit(4)
    else:
        email = f[0]["launchpad-email"]

get_extra_information is used to ask for launchpad-email in this example. Note that set's name (ubuntu-comunity in this case) has to be passed too. The following if statement is used to determine if getting extra-information was successful, if not, the script should return 4, in other case we store requested e-mail to a variable.

Testing your scripts

Testing scripts is very easy, and can be done without installing accomplishments to your system, and it is recommended to test them before installing, because this way it's easier to hunt bugs. Simply run your script: python script.py. If you want to check exit code of your script, the simplest trick is to run: python script.py; echo $?

Remember: To test scripts which use extra-information, you need to be running the daemon first. You can start it by launching Accomplishments Viewer, or with twistd -y /usr/bin/accomplishments-daemon.

Note: If you test your scripts before installing them, you need to setup required extra-information manually. After installing your accomplishment, the Accomplishment Viewer will ask user for required credentials. To set that data manually, use e.g. echo user@mail.com | cat > ~/.local/share/accomplishments/trophies/.extrainformation/launchpad-email


Now you should be able to write your own accomplishment script, as well as an .accomplishment file. This should be enough if you want to contribute to one of existing accomplishment collections.

The next chapter will teach you how accomplishment collections are organised, how to make your accomplishments available in multiple languages, how to install them to your system, and how to prepare an installation script.

<-- Previous page (Creating .accomplishment files) - - - - - Next page (Accomplishments sets structure) --->

Accomplishments/CreatingGuide/Scripts (last edited 2012-05-01 15:34:32 by 99-41-167-234)