# Hacking

This codebase could really use a testing framework.

If you are interested in helping out, writing tests is a great place
to start-- you don't need to know much about the code or python to
write useful tests.

In addition to a testing framework, the code is in need of some
general cleanup.  I've been inconsistent in capitalization conventions
as well as in my use of underscores.

The plugin interface could use some attention as well.  Right now,
it's a a bit of a free-for-all until I see how the plugins actually
code up.  Channeling all that into a few plugin interface grooves
would be a help.

If you're feeling more ambitious than that, the best way to improve
Plinth is to add modules.  More functionality, especially in the
router section, could convert the Freedom Box from a good idea to a
must-have appliance.

Beyond that, we need to train some expert eyes on the interaction
between Freedom Boxes.  Transparent, zero-config box-to-box backup is
possible.  We just need to build an auth and dns layer.  There are
lots of theories on how to do this well.  The first theory reduced to
practice wins!

There is a list of TODO items below.  Some of them are discrete pieces
that can be tackled without diving too deep into the code.

## Repository

Plinth is available from github at
`git://github.com/jvasile/plinth.git`.  The [project page on
github](https://github.com/jvasile/plinth) is at
`https://github.com/jvasile/plinth`.

## Bugs

There are lots of bugs.  We don't have a spec or tests, so a bug is
really just any unexpected behavior.  I am not easily surprised, but
there are still lots of bugs.

There's an [issue tracker](https://github.com/jvasile/Plinth/issues).
Please add things and consult it for things to tackle.

<a name="hacking_code_practices" />

## Coding Practices

I try to stick to [PEP 8](http://www.python.org/dev/peps/pep-0008/)
recommendations.  That's not to say I don't deviate, just that
deviations are usually bugs that should be fixed.

### Internationalization

Every module should `from gettext import gettext as _` and wrap
displayed strings with _().  We don't have the language stuff in place
yet (we have no translation files), but we need to put the
infrastructure in place for it from the start.  Use it like this:

    cfg.log.error(_("Couldn't import %s: %s") % (path, e))

### Variables and Data Stores

Plinth needs to keep information for short and long term
future use, and it can't just store all of that on the stack.

Global config information can be put in the `cfg` module namespace.
Keep it thread and session safe, though, or you'll get undefined
behavior as soon as multiple simultaneous users enter the picture.

Cherrpy has support for session variables.  Use those for short term
user-specific data.

For long term storage, the Plinth needs a back end
storage solution.  Databases are a bit opaque and can be hard for
third party software or shell users to manipulate.  For now, I've
decided that persistent data should be placed in dicts and stored in
json format.  We'll need a file locking solution too.

The `user_store.py` module implements the `UserStoreModule` interface
specified in `plugin_mount.py`.  Any new system that respects that
interface can be used.  The existing `user_store.py` holds entire user
files in memory and caches user files as it goes.  This has two
downsides: first, if you have lots of users and store big things in
the user dict, you'll run out of memory.  Second, it's not thread
safe.  Maybe a database is a good idea after all.

We do not yet have a means of storing module data for long terms.  My
current thinking is that modules can store data in their own
directories.  That makes removal easy.

## Todo

Plinth has a number of open todo items.  And there are items in the
[issue tracker](https://github.com/jvasile/Plinth/issues) that need
tackling.  Please help!

* Implement the functions in the submenus of router.py
* Unify our logging and cherrypy's.
