mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-10-27 16:59:25 +00:00
Load providers by class & module name. Closes #6
This commit is contained in:
16
README.md
16
README.md
@@ -15,3 +15,19 @@ Currently supports:
|
|||||||
* Parks n Peaks
|
* Parks n Peaks
|
||||||
* RBN
|
* RBN
|
||||||
* APRS
|
* APRS
|
||||||
|
|
||||||
|
### Writing your own Providers
|
||||||
|
|
||||||
|
(S)pothole is designed to be easily extensible. If you want to write your own provider, simply add a module to the `providers` 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 "Provider"; if it operates by polling an HTTP Server on a timer, it can instead extend "HTTPProvider" 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 `Provider` 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 `HTTPProvider` 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 `providers` section of `config.yml`, and your provider should be instantiated on startup.
|
||||||
|
|||||||
@@ -8,56 +8,56 @@ server-owner-callsign: "N0CALL"
|
|||||||
|
|
||||||
# Data providers to use. This is an example set, tailor it to your liking by commenting and uncommenting.
|
# Data providers to use. This is an example set, tailor it to your liking by commenting and uncommenting.
|
||||||
# RBN and APRS-IS are supported but have such a high data rate, you probably don't want them enabled.
|
# RBN and APRS-IS are supported but have such a high data rate, you probably don't want them enabled.
|
||||||
# Each provider needs a type, a name, and an enabled/disabled state. Some require more config such as hostnames/IP
|
# Each provider needs a class, a name, and an enabled/disabled state. Some require more config such as hostnames/IP
|
||||||
# addresses and ports. You can duplicate them if you like, e.g. to support several DX clusters. RBN uses two ports, 7000
|
# addresses and ports. You can duplicate them if you like, e.g. to support several DX clusters. RBN uses two ports, 7000
|
||||||
# for CW/RTTY and 7001 for FT8, so if you want both, you need two entries, as shown below.
|
# for CW/RTTY and 7001 for FT8, so if you want both, you need two entries, as shown below.
|
||||||
# Feel free to write your own provider classes!
|
# Feel free to write your own provider classes! There are details in the README.
|
||||||
providers:
|
providers:
|
||||||
-
|
-
|
||||||
type: "POTA"
|
class: "POTA"
|
||||||
name: "POTA"
|
name: "POTA"
|
||||||
enabled: true
|
enabled: true
|
||||||
-
|
-
|
||||||
type: "SOTA"
|
class: "SOTA"
|
||||||
name: "SOTA"
|
name: "SOTA"
|
||||||
enabled: true
|
enabled: true
|
||||||
-
|
-
|
||||||
type: "WWFF"
|
class: "WWFF"
|
||||||
name: "WWFF"
|
name: "WWFF"
|
||||||
enabled: true
|
enabled: true
|
||||||
-
|
-
|
||||||
type: "WWBOTA"
|
class: "WWBOTA"
|
||||||
name: "WWBOTA"
|
name: "WWBOTA"
|
||||||
enabled: true
|
enabled: true
|
||||||
-
|
-
|
||||||
type: "GMA"
|
class: "GMA"
|
||||||
name: "GMA"
|
name: "GMA"
|
||||||
enabled: true
|
enabled: true
|
||||||
-
|
-
|
||||||
type: "HEMA"
|
class: "HEMA"
|
||||||
name: "HEMA"
|
name: "HEMA"
|
||||||
enabled: true
|
enabled: true
|
||||||
-
|
-
|
||||||
type: "ParksNPeaks"
|
class: "ParksNPeaks"
|
||||||
name: "ParksNPeaks"
|
name: "ParksNPeaks"
|
||||||
enabled: true
|
enabled: true
|
||||||
-
|
-
|
||||||
type: "APRS-IS"
|
class: "APRSIS"
|
||||||
name: "APRS-IS"
|
name: "APRS-IS"
|
||||||
enabled: false
|
enabled: false
|
||||||
-
|
-
|
||||||
type: "DXCluster"
|
class: "DXCluster"
|
||||||
name: "HRD Dx Cluster"
|
name: "HRD Dx Cluster"
|
||||||
enabled: true
|
enabled: true
|
||||||
host: "hrd.wa9pie.net"
|
host: "hrd.wa9pie.net"
|
||||||
port: 8000
|
port: 8000
|
||||||
-
|
-
|
||||||
type: "RBN"
|
class: "RBN"
|
||||||
name: "RBN CW/RTTY"
|
name: "RBN CW/RTTY"
|
||||||
enabled: false
|
enabled: false
|
||||||
port: 7000
|
port: 7000
|
||||||
-
|
-
|
||||||
type: "RBN"
|
class: "RBN"
|
||||||
name: "RBN FT8"
|
name: "RBN FT8"
|
||||||
enabled: false
|
enabled: false
|
||||||
port: 7001
|
port: 7001
|
||||||
|
|||||||
28
main.py
28
main.py
@@ -6,6 +6,7 @@ import sys
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
import importlib
|
||||||
import psutil
|
import psutil
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
@@ -41,30 +42,11 @@ def shutdown(sig, frame):
|
|||||||
p.stop()
|
p.stop()
|
||||||
cleanup_timer.stop()
|
cleanup_timer.stop()
|
||||||
|
|
||||||
# Utility method to get a data provider based on its config entry.
|
# Utility method to get a data provider based on the class specified in its config entry.
|
||||||
def get_provider_from_config(config_providers_entry):
|
def get_provider_from_config(config_providers_entry):
|
||||||
match config_providers_entry["type"]:
|
module = importlib.import_module('providers.' + config_providers_entry["class"].lower())
|
||||||
case "POTA":
|
provider_class = getattr(module, config_providers_entry["class"])
|
||||||
return POTA(config_providers_entry)
|
return provider_class(config_providers_entry)
|
||||||
case "SOTA":
|
|
||||||
return SOTA(config_providers_entry)
|
|
||||||
case "WWFF":
|
|
||||||
return WWFF(config_providers_entry)
|
|
||||||
case "GMA":
|
|
||||||
return GMA(config_providers_entry)
|
|
||||||
case "WWBOTA":
|
|
||||||
return WWBOTA(config_providers_entry)
|
|
||||||
case "HEMA":
|
|
||||||
return HEMA(config_providers_entry)
|
|
||||||
case "ParksNPeaks":
|
|
||||||
return ParksNPeaks(config_providers_entry)
|
|
||||||
case "DXCluster":
|
|
||||||
return DXCluster(config_providers_entry)
|
|
||||||
case "RBN":
|
|
||||||
return RBN(config_providers_entry)
|
|
||||||
case "APRS-IS":
|
|
||||||
return APRSIS(config_providers_entry)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
# Main function
|
# Main function
|
||||||
|
|||||||
Reference in New Issue
Block a user