forked from iarv/meshing-around
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fb351ef4d | ||
|
|
2f6abade80 | ||
|
|
5247f8d9d3 | ||
|
|
b36059183c | ||
|
|
f737e401a5 | ||
|
|
98b5f4fb7f | ||
|
|
17fa03ff9d | ||
|
|
40aaa7202c | ||
|
|
5088397856 | ||
|
|
db1c31579c | ||
|
|
dcf1b8f3cc | ||
|
|
2a7000a2e6 |
2
.github/workflows/docker-image.yml
vendored
2
.github/workflows/docker-image.yml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
|
||||
- name: Build and push Docker image
|
||||
id: push
|
||||
uses: docker/build-push-action@8c1e8f8e5bf845ba3773a14f3967965548a2341e
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
||||
@@ -959,18 +959,6 @@
|
||||
"To relay messages between satellites"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "E2A13",
|
||||
"correct": 1,
|
||||
"refs": "",
|
||||
"question": "Which of the following techniques is used by digital satellites to relay messages?",
|
||||
"answers": [
|
||||
"Digipeating",
|
||||
"Store-and-forward",
|
||||
"Multisatellite relaying",
|
||||
"Node hopping"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "E2B01",
|
||||
"correct": 0,
|
||||
@@ -2495,18 +2483,6 @@
|
||||
"Utilizing a Class D final amplifier"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "E4D05",
|
||||
"correct": 0,
|
||||
"refs": "",
|
||||
"question": "What transmitter frequencies would create an intermodulation-product signal in a receiver tuned to 146.70 MHz when a nearby station transmits on 146.52 MHz?",
|
||||
"answers": [
|
||||
"146.34 MHz and 146.61 MHz",
|
||||
"146.88 MHz and 146.34 MHz",
|
||||
"146.10 MHz and 147.30 MHz",
|
||||
"146.30 MHz and 146.90 MHz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "E4D06",
|
||||
"correct": 2,
|
||||
@@ -3851,18 +3827,6 @@
|
||||
"Permeability"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "E6D07",
|
||||
"correct": 3,
|
||||
"refs": "",
|
||||
"question": "What is the current that flows in the primary winding of a transformer when there is no load on the secondary winding?",
|
||||
"answers": [
|
||||
"Stabilizing current",
|
||||
"Direct current",
|
||||
"Excitation current",
|
||||
"Magnetizing current"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "E6D08",
|
||||
"correct": 1,
|
||||
|
||||
@@ -35,18 +35,6 @@
|
||||
"12 meters"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "G1A04",
|
||||
"correct": 3,
|
||||
"refs": "[97.303(h)]",
|
||||
"question": "Which of the following amateur bands is restricted to communication only on specific channels, rather than frequency ranges?",
|
||||
"answers": [
|
||||
"11 meters",
|
||||
"12 meters",
|
||||
"30 meters",
|
||||
"60 meters"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "G1A05",
|
||||
"correct": 0,
|
||||
@@ -347,18 +335,6 @@
|
||||
"Submit a rule-making proposal to the FCC describing the codes and methods of the technique"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "G1C09",
|
||||
"correct": 2,
|
||||
"refs": "[97.313(i)]",
|
||||
"question": "What is the maximum power limit on the 60-meter band?",
|
||||
"answers": [
|
||||
"1500 watts PEP",
|
||||
"10 watts RMS",
|
||||
"ERP of 100 watts PEP with respect to a dipole",
|
||||
"ERP of 100 watts PEP with respect to an isotropic antenna"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "G1C11",
|
||||
"correct": 3,
|
||||
@@ -611,18 +587,6 @@
|
||||
"1500 watts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "G1E09",
|
||||
"correct": 0,
|
||||
"refs": "[97.115]",
|
||||
"question": "Under what circumstances are messages that are sent via digital modes exempt from Part 97 third-party rules that apply to other modes of communication?",
|
||||
"answers": [
|
||||
"Under no circumstances",
|
||||
"When messages are encrypted",
|
||||
"When messages are not encrypted",
|
||||
"When under automatic control"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "G1E10",
|
||||
"correct": 0,
|
||||
@@ -4079,18 +4043,6 @@
|
||||
"All these choices are correct"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "G8C01",
|
||||
"correct": 2,
|
||||
"refs": "",
|
||||
"question": "On what band do amateurs share channels with the unlicensed Wi-Fi service?",
|
||||
"answers": [
|
||||
"432 MHz",
|
||||
"902 MHz",
|
||||
"2.4 GHz",
|
||||
"10.7 GHz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "G8C02",
|
||||
"correct": 0,
|
||||
|
||||
12
install.sh
12
install.sh
@@ -107,6 +107,18 @@ if [[ ! -w ${program_path} ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if we have git and curl installed
|
||||
if ! command -v git &> /dev/null
|
||||
then
|
||||
printf "git not found, trying 'apt-get install git'\n"
|
||||
sudo apt-get install git
|
||||
fi
|
||||
if ! command -v curl &> /dev/null
|
||||
then
|
||||
printf "curl not found, trying 'apt-get install curl'\n"
|
||||
sudo apt-get install curl
|
||||
fi
|
||||
|
||||
# check if we are in /opt/meshing-around
|
||||
if [[ "$program_path" != "/opt/meshing-around" ]]; then
|
||||
echo "----------------------------------------------"
|
||||
|
||||
@@ -136,8 +136,16 @@ class HamTest:
|
||||
|
||||
# remove the game[id] from the list
|
||||
del self.game[id]
|
||||
# hamtestTracker stores dicts like {"nodeID": nodeID, ...}
|
||||
for i in range(len(hamtestTracker)):
|
||||
try:
|
||||
if hamtestTracker[i].get('nodeID') == id:
|
||||
hamtestTracker.pop(i)
|
||||
break
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
return msg
|
||||
|
||||
hamtestTracker = []
|
||||
hamtest = HamTest()
|
||||
|
||||
@@ -83,8 +83,10 @@ def getRepeaterBook(lat=0, lon=0):
|
||||
elsewhereapi = "https://www.repeaterbook.com/row_repeaters/prox2_result.php?"
|
||||
if grid[:2] in ['CN', 'DN', 'EN', 'FN', 'CM', 'DM', 'EM', 'FM', 'DL', 'EL', 'FL']:
|
||||
repeater_url = usapi
|
||||
logger.debug("Location: Fetching repeater data from RepeaterBook US API for grid " + grid)
|
||||
else:
|
||||
repeater_url = elsewhereapi
|
||||
logger.debug("Location: Fetching repeater data from RepeaterBook International API for grid " + grid)
|
||||
|
||||
repeater_url += f"city={grid}&lat=&long=&distance=50&Dunit=m&band%5B%5D=4&band%5B%5D=16&freq=&call=&mode%5B%5D=1&mode%5B%5D=2&mode%5B%5D=4&mode%5B%5D=64&status_id=1&use=%25&use=OPEN&order=distance_calc%2C+state_id+ASC"
|
||||
|
||||
@@ -92,8 +94,28 @@ def getRepeaterBook(lat=0, lon=0):
|
||||
msg = ''
|
||||
user_agent = {'User-agent': 'Mozilla/5.0'}
|
||||
response = requests.get(repeater_url, headers=user_agent, timeout=my_settings.urlTimeoutSeconds)
|
||||
if response.status_code!=200:
|
||||
# Fail early on bad HTTP status
|
||||
if response.status_code != 200:
|
||||
logger.error(f"Location:Error fetching repeater data from {repeater_url} with status code {response.status_code}")
|
||||
return my_settings.ERROR_FETCHING_DATA
|
||||
|
||||
# Detect Cloudflare / bot-check pages or other anti-bot responses by looking
|
||||
# for known phrases that indicate a challenge page instead of the expected HTML table.
|
||||
try:
|
||||
lowered = response.text.lower()
|
||||
except Exception:
|
||||
lowered = ''
|
||||
cloudflare_signs = (
|
||||
"checking your browser",
|
||||
"please enable javascript",
|
||||
"just a moment",
|
||||
"cf-chl-bypass",
|
||||
"attention required",
|
||||
)
|
||||
if any(sig in lowered for sig in cloudflare_signs):
|
||||
logger.warning("Location: Cloudflare/bot-check detected when fetching repeater data")
|
||||
return my_settings.ERROR_FETCHING_DATA
|
||||
|
||||
soup = bs.BeautifulSoup(response.text, 'html.parser')
|
||||
table = soup.find('table', attrs={'class': 'table table-striped table-hover align-middle sortable'})
|
||||
if table is not None:
|
||||
@@ -115,6 +137,8 @@ def getRepeaterBook(lat=0, lon=0):
|
||||
}
|
||||
data.append(repeater)
|
||||
else:
|
||||
# No table found — could be legitimately no data or markup change.
|
||||
logger.debug("Location: No repeater table found on RepeaterBook page, scraping failed or no data for region.")
|
||||
msg = "No Data for your Region"
|
||||
except Exception as e:
|
||||
msg = "No repeaters found 😔"
|
||||
|
||||
@@ -5,6 +5,7 @@ import schedule
|
||||
from datetime import datetime
|
||||
from modules.log import logger
|
||||
from modules.system import send_message
|
||||
from modules.settings import MOTD, schedulerMotd, schedulerMessage, schedulerChannel, schedulerInterface, schedulerValue, schedulerTime, schedulerInterval
|
||||
|
||||
async def run_scheduler_loop(interval=1):
|
||||
logger.debug(f"System: Scheduler loop started Tasks: {len(schedule.jobs)}, Details:{extract_schedule_fields(schedule.get_jobs())}")
|
||||
@@ -24,11 +25,12 @@ async def run_scheduler_loop(interval=1):
|
||||
except asyncio.CancelledError:
|
||||
logger.debug("System: Scheduler loop cancelled, shutting down.")
|
||||
|
||||
def safe_int(val, default=0, type=""):
|
||||
def safe_int(val, default=0, type=''):
|
||||
try:
|
||||
return int(val)
|
||||
except (ValueError, TypeError):
|
||||
logger.debug(f"System: Scheduler config {type} error '{val}' to int, using default {default}")
|
||||
if val != '':
|
||||
logger.debug(f"System: Scheduler config {type} error '{val}' to int, using default {default}")
|
||||
return default
|
||||
|
||||
def extract_schedule_fields(jobs):
|
||||
|
||||
Reference in New Issue
Block a user