First code import
This commit is contained in:
parent
c47644d63c
commit
73ca0395d6
23
README.md
23
README.md
@ -1,3 +1,24 @@
|
||||
# presto2gemini
|
||||
|
||||
Download solar storm alerts from the Presto service and converts them into gemtext (text/gemini) to be served via Gemini.
|
||||
Download [solar storm](https://en.wikipedia.org/wiki/Solar_storm) alerts from the [Presto service](http://www.sidc.be/products/presto/) and converts them
|
||||
into gemtext (`text/gemini`) to be served via
|
||||
[Gemini](https://en.wikipedia.org/wiki/Gemini_(protocol)).
|
||||
|
||||
The result can be seen (if you have a Gemini browser( [on my Gemini capsule](gemini://gemini.bortzmeyer.org/presto/).
|
||||
|
||||
## Installation
|
||||
|
||||
Download the program, Be sure you have the [Python requests
|
||||
library](http://python-requests.org/) then run the program periodically, for instance through
|
||||
cron:
|
||||
|
||||
```
|
||||
# Solar alerts
|
||||
33 3,7,11,15,19,23 * * * /path/to/program/presto2gemini.py
|
||||
```
|
||||
|
||||
## Technical details
|
||||
|
||||
We start from plain text files like [this
|
||||
alert](http://www.sidc.be/archive/product/presto/2020/12/13) since
|
||||
Presto alerts are not available in a structured format.
|
||||
|
178
presto2gemini.py
Executable file
178
presto2gemini.py
Executable file
@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""A program to retrieve Presto solar storm alerts
|
||||
<http://www.sidc.be/products/presto/> and transform them to gemtext
|
||||
<https://gemini.circumlunar.space/>.
|
||||
|
||||
Run it from cron from time to time.
|
||||
|
||||
"""
|
||||
|
||||
# Standard library
|
||||
import getopt
|
||||
import time
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import shutil
|
||||
|
||||
# Other libraries
|
||||
# http://python-requests.org/
|
||||
import requests
|
||||
|
||||
PRESTO_URL = "http://www.sidc.be/archive/product/presto"
|
||||
|
||||
# Defaults
|
||||
date = time.strftime("%Y-%m-%d", time.gmtime(time.time()))
|
||||
dest_dir = "/var/gemini/presto"
|
||||
raw_file_dir = "/home/stephane/Gemini/PrestoAlert/raw-files"
|
||||
verbose = False
|
||||
index = True
|
||||
force_index = False
|
||||
input = None
|
||||
|
||||
def usage(msg=None):
|
||||
print("Usage: %s [--date YYYY-MM-DD] [--destination STRING] [--verbose]" % sys.argv[0], file=sys.stderr)
|
||||
if msg is not None:
|
||||
print(msg, file=sys.stderr)
|
||||
|
||||
def create_index(gem_dir, raw_dir):
|
||||
f = open("%s%s" % (gem_dir, "index.gmi"), "w")
|
||||
print("""# List of Presto solar storms alerts
|
||||
|
||||
From the alerts sent by SIDC (Solar Influences Data analysis Center).
|
||||
|
||||
=> http://www.sidc.be/products/presto/ SIDC Presto reference site
|
||||
=> https://en.wikipedia.org/wiki/Solar_storm Wikipedia on solar storms
|
||||
|
||||
""", file=f)
|
||||
files = []
|
||||
for file in os.listdir(raw_dir):
|
||||
files.append(file)
|
||||
sorted_files = sorted(files, reverse=True)
|
||||
fs = open("%s%s.txt" % (gem_dir, sorted_files[0]), "r")
|
||||
print("""
|
||||
Last alert:
|
||||
|
||||
%s
|
||||
""" % fs.read(), file=f)
|
||||
fs.close()
|
||||
for file in sorted(files, reverse=True):
|
||||
print("=> %s.gmi Alert of %s" % (file, file), file=f)
|
||||
|
||||
print("""
|
||||
## Legal and contact
|
||||
|
||||
### This Gemini mirror
|
||||
|
||||
Maintained by Stéphane Bortzmeyer stephane+gemini@bortzmeyer.org from the SIDC data.
|
||||
|
||||
### SIDC - Solar Influences Data analysis Center - RWC Belgium
|
||||
|
||||
Royal Observatory of Belgium
|
||||
|
||||
=> http://www.sidc.be/ Website
|
||||
|
||||
E-mail sidc-support@oma.be
|
||||
|
||||
=> http://www.astro.oma.be/common/internet/en/data-policy-en.pdf Intellectual Property Rights
|
||||
=> http://www.astro.oma.be/common/internet/en/disclaimer-en.pdf Liability Disclaimer
|
||||
=> http://www.astro.oma.be/common/internet/en/privacy-policy-en.pdf Use and processing of your personal information
|
||||
""", file=f)
|
||||
f.close()
|
||||
|
||||
try:
|
||||
optlist, args = getopt.getopt (sys.argv[1:], "d:vi",
|
||||
["date=", "help", "verbose",
|
||||
"force-index", "no-index",
|
||||
"destination=", "source=", "input="])
|
||||
for option, value in optlist:
|
||||
if option == "--help" or option == "-h":
|
||||
usage()
|
||||
sys.exit(0)
|
||||
elif option == "--date" or option == "-d":
|
||||
date = value # TODO check the syntax?
|
||||
elif option == "--destination":
|
||||
dest_dir = value
|
||||
elif option == "--source":
|
||||
raw_file_dir = value
|
||||
elif option == "--verbose" or option == "-v":
|
||||
verbose = True
|
||||
elif option == "--force-index" or option == "-i":
|
||||
force_index = True
|
||||
elif option == "--no-index":
|
||||
index = False
|
||||
elif option == "--input":
|
||||
input = value
|
||||
else:
|
||||
# Should never occur, it is trapped by getopt
|
||||
usage("Unknown option %s" % option)
|
||||
except getopt.error as reason:
|
||||
usage(reason)
|
||||
sys.exit(1)
|
||||
if len(args) != 0:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
urlpath = date.replace("-", "/")
|
||||
url = "%s/%s" % (PRESTO_URL, urlpath)
|
||||
if not raw_file_dir.endswith("/"):
|
||||
raw_file_dir += "/"
|
||||
if not dest_dir.endswith("/"):
|
||||
dest_dir += "/"
|
||||
input_ok = False
|
||||
if input is None:
|
||||
r = requests.get(url, allow_redirects = False)
|
||||
if r.status_code == 200 and r.text != "" and r.text != "\r\n" and r.text != "\n": # Yes,
|
||||
# when there is no alert, they reply with 200 and an empty file :-(
|
||||
raw = open("%s%s" % (raw_file_dir, date), "w")
|
||||
print(r.text, file=raw)
|
||||
raw.close()
|
||||
input_ok = True
|
||||
else:
|
||||
shutil.copyfile(input, "%s%s" % (raw_file_dir, date))
|
||||
input_ok = True
|
||||
if input_ok:
|
||||
gemfile = open ("%s%s.gmi" % (dest_dir, date), "w")
|
||||
txtfile = open ("%s%s.txt" % (dest_dir, date), "w")
|
||||
raw = open("%s%s" % (raw_file_dir, date), "r")
|
||||
print("""
|
||||
# Solar alert
|
||||
|
||||
""", file=gemfile)
|
||||
for line in raw.readlines():
|
||||
line=line[:-1] # Chop end-of-line
|
||||
if re.search("^\s*#", line):
|
||||
continue # Ignore comments
|
||||
else:
|
||||
match = re.search("^\s*:([a-zA-Z]+):\s*(.*)", line)
|
||||
if match:
|
||||
if match.group(1) == "Issued":
|
||||
issued = match.group(2)
|
||||
print("""
|
||||
Issued on %s
|
||||
|
||||
""" % issued, file=gemfile)
|
||||
print("""
|
||||
Issued on %s
|
||||
|
||||
""" % issued, file=txtfile)
|
||||
continue # Ignore other metadata
|
||||
else:
|
||||
print(line, file=gemfile, end=" ")
|
||||
print(line, file=txtfile, end=" ")
|
||||
if line == "":
|
||||
print("", file=gemfile)
|
||||
print("", file=txtfile)
|
||||
print("""
|
||||
|
||||
=> %s Reference for this alert
|
||||
=> /presto All Presto solar alerts
|
||||
""" % url, file=gemfile)
|
||||
raw.close()
|
||||
gemfile.close()
|
||||
txtfile.close()
|
||||
if index:
|
||||
create_index(dest_dir, raw_file_dir)
|
||||
elif force_index and index:
|
||||
create_index(dest_dir, raw_file_dir)
|
Loading…
x
Reference in New Issue
Block a user