Skip to content
jovanbulck edited this page Dec 28, 2014 · 4 revisions

Dumping some more work-in-progress thoughts; I'll continue working on it in February as I should have no time now :p

work in progress: feel free to open an issue to discuss ideas / irregularities / enhancements

This page gives an overview of kotnetcli's software design. It focuses on extensibility and elegance to help developers understand, extend and maintain the code.

Overview

kotnetcli has been designed as a cohesive set of classes, each one focusing on its own explicit job: the UNIX philosophy - do one thing and do it good. This section gives an overview of all these classes, grouped into the following set of files:

kotnetcli.py

This file contains the main method and bootstraps the KotNet login procedure. As indicated by its name, this class encapsulates the command line interface. That is to say, it is responsible for parsing the command line arguments and interpreting them to create the correct Worker and Communicator instances below.

Note that This class actually defines the front-end user input interface for the kotnetcli application. User output communication on the other hand, is handled by the communicator class, as explained below.

worker.py

As should be clear by now, kotnetcli's software design is all about dividing cohesive responsibilities over different stand-alone classes. In a way, the worker class hierarchy is the glue that holds it all together. Indeed, the worker class encapsulates kotnetcli's internal behavior. It acts as the director, who's sole job is to call the correct method of the correct class at the correct time. In other words, it encapsulates the sequence of konetcli's actions. It's sole job is to command other slave-classes to do the work and report progress to the Communicator. It's as if it steals credit for all the work, hence the name :p

Worker classes are organized in the hierarchy depicted below:

[ TODO figure of worker class hierarchy ]

Let's give a concrete example of directing the sequence of actions. The LoginWorker class delegates kotnetcli's login procedure to a KotnetLoginBrowser class: connect to netlogin.kuleuven.be, kies kuleuven, input credentials, parse result. Moreover, in between these method calls and in case of failure, it notifies a Communicator instance of the progress.

TODO: overview of all communicator subclasses with short description + show how combining them can create the desired behavior (e.g. force login)

browser.py

The Browser class is the real workhorse of the kotnetcli application. This class encapsulates the fetching, parsing and sending of KotNet web pages. It offers an abstract interface used by the Worker class.

Browser classes are organized in the following hierarchy:

[ TODO figure of browser class hierarchy ]

TODO: overview of all browser subclasses with short description

credentials.py

The Credentials class encapsulates how the username and password are stored and retrieved. To do so, it offers an abstract interface used by kotnetcli.py.

Currently, we store your login settings safely in your operating system's keyring. Moreover, by encapsulating this in the Credentials class, usernames and passwords are handled centrally and shouldn't wander around the code. Extending kotnetcli to use another way of storing passwords is easy too.

communicator.py

a pluggable visualisation system for everyones needs.

[ TODO figure of communicator class hierarchy ]

A crash-course to extending kotnetcli

This section sketches the actions needed to implement a common kotnetcli extension integrated in the design. It is intended to help developers avoid common pitfalls, keeping the code uniform and clean.

Writing a new parser

This is probably the most probable extension to kotnetcli, as KotNet web pages are likely to change. Moreover, by writing a new parser kotnetcli's framework can ultimately be used for parsing totally other things.

Writing a new parser, requires you to extend the KotnetBrowser class, overriding any methods of your interest. In order to use the new parser, you'll probably want to add a new Worker and/or command line option too, see below.

Adding a new Communicator

Simply extend the QuietCommunicator class in the communicator hierarchy described above. Your new communicator then overrides the methods you want to visualize. Focus on visualizing only, the rest will be handled by the other classes. Take a look at the existing communicators in Communicator.py. They should give a good understanding of how this works.

In order to use the new communicator, you'll probably want to add a new command line option too, see below.

Adding a new command line option

Adding new command line options is useful to enable new behavior.

When editing command line arguments, kotnetcli.py is the class you should look into first. Look into the classes below when the internal behavior for the new command line option cannot be accomplished with the existing Worker classes.

Writing an input GUI

This extension is a bit more tricky. An input GUI (or any other user input interface for that matter) will require you to write a new kotnetcli.py file. Such a kotnetgui.py or so then handles user input to ultimately call the correct (Worker, Communicator) combination at some point.

Note that integrating the output in the GUI shouldn't be too hard neither, by writing a new Communicator (see above). Such a communicator then acts a kind of callback to the GUI, reporting progress.