## Modifying the source code

Spothole is Public Domain licenced, so you can grab the source code and start modifying it for your own needs.
Contributions of code back to the main repository are encouraged, but completely optional.

### Code structure

To navigate your way around the source code, this list may help.

*Python back-end code*

* `/core` - Core classes and utilities
* `/data` - Data storage classes
* `/providers/spot` - Classes providing spots by accessing the APIs of other services
* `/providers/alert` - Classes providing alerts by accessing the APIs of other services
* `/providers/solarconditions` - Classes providing solar and propagation by accessing the APIs of other services
* `/providers/staticdata` - Classes providing static lookup data by accessing bundled data files or the APIs of other
  services
* `/providers/sigrefdata` - Classes providing SIG reference lookup data by accessing bundled data files or the APIs of
  other services
* `/server` - Classes for running Spothole's own web server
* `spothole.py` - Main application script

*Templates*

* `/templates` - Templates used for constructing Spothole's user-targeted HTML pages

*HTML/JS/CSS front-end code*

* `/static` - Root for static files served by the web server. These are all served from a path starting `/static/`.
* `/static/apidocs` - Contains the OpenAPI spec (`openapi.yml`)
* `/static/audio` - Audio files used by the web front-end
* `/static/css` - CSS files used by the web front-end
* `/static/img` - image files used by the web front-end
* `/static/js` - JavaScript used by the web front-end
* `/static/vendor` - Third-party libraries (CSS, JS, fonts and images)

*Miscellaneous*

* `/` - pip `requirements.txt`, config, README, etc.
* `/docs` - Documentation
* `/images` - Image sources
* `/datafiles` - Local data files, used by some providers when the data will never change and/or is not easily available
  online in a format Spothole can handle
* `/cache` - Directory where Spothole stores all the data it uses that should be persisted to disk. Created on first
  run.

### Extending the server

Spothole is designed to be easily extensible. If you want to write your own spot provider, for example, simply add a
module to the `providers.spot` package containing your class. (Currently, in order to be loaded correctly, the module (
file) name should be the same as the class name, but lower case.)

Your class should extend "SpotProvider"; if it operates by polling an HTTP Server on a timer, it can instead extend "
HTTPSpotProvider" where some of the work is done for you.

The class will need to implement a constructor that takes in the `provider_config` and provides it to the superclass
constructor, while also taking any other config parameters it needs.

If you're extending the base `SpotProvider` class, you will need to implement `start()` and `stop()` methods that start
and stop a separate thread which handles the provider's processing needs. The thread should call `submit()` or
`submit_batch()` when it has one or more spots to report.

If you're extending the `HTTPSpotProvider` class, you will need to provide a URI to query and an interval to the
superclass constructor. You'll then need to implement the `http_response_to_spots()` method which is called when new
data is retrieved. Your implementation should then call `submit()` or `submit_batch()` when it has one or more spots to
report.

When constructing spots, use the comments in the Spot class and the existing implementations as an example. All
parameters are optional, but you will at least want to provide a `time` (which must be timezone-aware) and a `dx_call`.

Finally, simply add the appropriate config to the `spot_providers` section of `config.yml`, and your provider should be
instantiated on startup.

The same approach as above is also used for alerts, and other types of providers. Give me a shout if you need any
advice.
