import gradio as gr
import requests
import json
import os
from PIL import Image
import moviepy.video.io.ImageSequenceClip as ic
from pathlib import Path
import bs4
import datetime
import urllib.request
import uuid
main_directory = "https://services.swpc.noaa.gov/"
sdo_source = "https://sdo.gsfc.nasa.gov/assets/img/browse/"
sdo_source_format = "https://sdo.gsfc.nasa.gov/assets/img/browse/YEAR/MONTH/DAY/DATE_IDENT_SIZE_TOOL.jpg"
comp_list=[
"https://services.swpc.noaa.gov/images/geospace/geospace_1_day.png",
"https://services.swpc.noaa.gov/images/ace-epam-24-hour.gif",
"https://services.swpc.noaa.gov/images/ace-epam-e-24-hour.gif",
"https://services.swpc.noaa.gov/images/ace-epam-p-24-hour.gif",
"https://services.swpc.noaa.gov/images/ace-mag-24-hour.gif",
"https://services.swpc.noaa.gov/images/ace-mag-swepam-24-hour.gif",
"https://services.swpc.noaa.gov/images/ace-sis-24-hour.gif",
"https://services.swpc.noaa.gov/images/boulder-magnetometer.png",
"https://services.swpc.noaa.gov/images/seaesrt-time-series-270.png",
"https://services.swpc.noaa.gov/images/station-k-index.png",
#"https://services.swpc.noaa.gov/images/swx-overview-large.gif",
"https://services.swpc.noaa.gov/images/notifications-timeline.png",
]
sdo_aia_latest=[
{"name":"Fe18 94A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_94.gif"},
{"name":"Fe20 131A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_131.gif"},
{"name":"Fe9/10 171A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_171.gif"},
{"name":"Fe12 193A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_193.gif"},
{"name":"Fe14 211A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_211.gif"},
{"name":"He2 304A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_304.gif"},
{"name":"Fe16 335A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_335.gif"},
{"name":"cont+C4 1600A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_1600.gif"},
{"name":"continuum 1700A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_1700.gif"},
{"name":"continuum 4500A", "source":"https://umbra.nascom.nasa.gov/images/latest_aia_4500.gif"},
]
nasa_images=[
{"name":"EIT 171A", "source":"https://soho.nascom.nasa.gov/data/realtime/eit_171/512/latest.jpg"},
{"name":"EIT 195A", "source":"https://soho.nascom.nasa.gov/data/realtime/eit_195/512/latest.jpg"},
{"name":"EIT 284A", "source":"https://soho.nascom.nasa.gov/data/realtime/eit_284/512/latest.jpg"},
{"name":"EIT 304A", "source":"https://soho.nascom.nasa.gov/data/realtime/eit_304/512/latest.jpg"},
]
nasa_soho_gifs=[
{"name":"EIT 304A", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_eit_304small.gif"},
{"name":"EIT 195A", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_eit_195small.gif"},
{"name":"EIT 171A", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_eit_171small.gif"},
{"name":"EIT 284A", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_eit_284small.gif"},
]
nasa_soho_mp4=[
{"name":"EIT 171A", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_eit_171small.mp4"},
{"name":"EIT 195A", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_eit_195small.mp4"},
{"name":"EIT 284A", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_eit_284small.mp4"},
{"name":"EIT 304A", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_eit_304small.mp4"},
{"name":"LASCO C2", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_c2small.mp4"},
{"name":"LASCO C3", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_c3small.mp4"},
{"name":"SDO/HMI Continuum", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_hmi_igr-512.mp4"},
{"name":"SDO/HMI Magnetogram", "source":"https://soho.nascom.nasa.gov/data/LATEST/current_hmi_mag-512.mp4"},
]
sdo_obj = ["HMIB","HMIBC","HMIIC","HMIIF","HMID","HMII","HMI171",
"0094","0131","0171","0193","0211",
"0304","0335","1600","1700","4500",
"211193171","211193171n","211193171rg",
"094335193","304211171"]
sdo_size= [256,512,1024,2048,4096]
html = """
PAGE_LINK
"""
css="""
.img_box{
display: flex;
flex-direction: column;
flex-flow: unset;
flex-wrap: wrap;
justify-content: space-around;
}
.img_class{
background: #ffffff;
max-width: 48%;
font-family: monospace;
border-top: #9300ff;
border-style: inset;
margin-top: 5px;
}
.img_class_raw{
background: #ffffff;
width: 100%;
font-family: monospace;
border-top: #9300ff;
border-style: inset;
margin-top: 5px;
display:flex;
flex-direction:column;
}
.img_box_soho{
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.img_class_soho{
background: #ffffff;
font-family: monospace;
border-top: #9300ff;
border-style: inset;
margin-top: 5px;
max-width: 48%;
}
.img_class_sdo{
background: #ffffff;
font-family: monospace;
border-top: #9300ff;
border-style: inset;
margin-top: 5px;
max-width: 25%;
font-size: small;
}
"""
def load_json(url1="",url2="",url3="",url4="",url5="",url6="",url7="",url8=""):
get_url=f'{main_directory}{url1}{url2}{url3}{url4}{url5}{url6}{url7}{url8}'
print(f'{get_url}')
get_url=get_url.split("None")[0]
print(f'{get_url}')
get_url=get_url.split("[]")[0]
print(f'{get_url}')
if get_url.endswith('.json'):
feed1 = requests.get(get_url)
return None, feed1.text
elif get_url.endswith(".png") or get_url.endswith(".gif") or get_url.endswith(".jpg"):
html_out=f"'
return html_out, None
return None,None
def make_tree(url1="",url2="",url3="",url4="",url5="",url6="",url7="",url8=""):
link_box=[]
html_out=""
get_url=f'{main_directory}{url1}{url2}{url3}{url4}{url5}{url6}{url7}{url8}'
print(f'######### :: {get_url}')
if not get_url.endswith('.json'):
feed1 = requests.get(get_url)
spl = feed1.text.split("href=")
for line in spl:
spl2 = line.split(">")[0]
print(spl2)
if spl2.endswith('/"') or spl2.endswith('.json"') or spl2.endswith('.png"') or spl2.endswith('.gif"') or spl2.endswith('.jpg"'):
fin=line.split(">")[0].strip('""')
link_box.append(fin)
#html_out=html_out+html.replace("PAGE_LINK",fin)
return gr.update(choices=[l for l in link_box],interactive=True)
else:
return None
def get_images():
html_out=f""
get_url=f'{main_directory}images/geospace/'
feed1 = requests.get(get_url)
spl = feed1.text.split("href=")
for line in spl:
spl2 = line.split(">")[0].strip('""')
if spl2.endswith(".png") or spl2.endswith(".gif") or spl2.endswith(".jpg"):
print(spl2)
html_out+=f'
'
else:
print(spl2)
get_url2=f'{main_directory}images/'
feed2 = requests.get(get_url2)
spl = feed2.text.split("href=")
for line2 in spl:
spl2 = line2.split(">")[0].strip('""')
if spl2.endswith(".png") or spl2.endswith(".gif") or spl2.endswith(".jpg"):
print(spl2)
html_out+=f'
'
else:
print(spl2)
html_out+="
"
return html_out
def make_animation():
get_url=f'{main_directory}images/animations/'
feed1 = requests.get(get_url)
spl = feed1.text.split("href=")
files_out=[]
for line in spl:
gif_box=[]
spl2 = line.split(">")[0].strip('""')
if spl2.endswith("/"):
feed2 = requests.get(f'{get_url}{spl2}')
spl3 = feed2.text.split("href=")
for line2 in spl3:
spl3 = line2.split(">")[0].strip('""')
print("$$$$$$$$$$$$$$")
print(spl3)
if spl3.endswith(".png") or spl3.endswith(".gif") or spl3.endswith(".jpg"):
gif_box.append(f'{get_url}{spl2}{spl3}')
if gif_box:
try:
#frames = [Image.open(image) for image in glob.glob(f"{frame_folder}/*.JPG")]
frames = []
for i,ea in enumerate(gif_box):
print("############")
print(ea)
urllib.request.urlretrieve(ea,f'tmp{i}.png')
frames.append(f'tmp{i}.png')
fps=60
uid=uuid.uuid4()
clip = ic.ImageSequenceClip(frames, fps = fps)
clip.to_gif(f"{uid}.gif",fps=fps)
files_out.append(f'{uid}.gif')
except Exception as e:
print(e)
return files_out
def make_html(inp_files):
html_out=f""
for ea in inp_files:
print(ea)
html_out+=f'
'
html_out+='
'
return html_out
def make_nasa_soho_videos():
html_out=f""
for ea in nasa_soho_mp4:
file_name=ea['source']
html_out+=f'''
Your browser does not support the video tag.
'''
#html_out+=f'
'
html_out+='
'
return html_out
def make_nasa_soho_images(inp_src: list):
html_out=""
#html_out=f""
for ea in inp_src:
file_name=ea['source']
html_out+=f'
'
#html_out+='
'
#html_out+=html_in
return html_out
def make_nasa_soho_image_trigger():
html_in=f""
html_in+= make_nasa_soho_images(nasa_images)
html_in+= make_nasa_soho_images(sdo_aia_latest)
#html_in+= make_nasa_soho_videos()
html_in+="
"
return html_in
def nasa_sdo_images(obj,size,date1,date2):
html_in=f""
if int(date2[6:8])-int(date1[6:8]) >0:
return ("
Reduce Timespan to 24 hours
")
in_year=f"{date2[0:4]}"
in_month=f"{date2[4:6]}"
in_day=f"{date2[6:8]}"
file_name="DATE_TIME_SIZE_TOOL.jpg"
sdo_source_format = f"https://sdo.gsfc.nasa.gov/assets/img/browse/{in_year}/{in_month}/{in_day}/"
get_url=sdo_source_format
print(get_url)
feed1 = requests.get(get_url)
if "All" in size:
size = sdo_size
if "All" in obj:
obj = sdo_obj
link_box=[]
# Parse the HTML content using BeautifulSoup
soup = bs4.BeautifulSoup(feed1.content, 'html.parser')
#print(soup)
anchor_elements = soup.find_all('a')
for element in anchor_elements:
href=element.get('href')
if href.endswith('.jpg'):
for o in obj:
for s in size:
ls=href.split("_")
print(ls[1][0:4])
print(date1[8:13])
if ls[1][0:4]>=date1[8:13]:
src_obj=ls[3].split('.jpg')[0]
if src_obj == o:
if int(ls[2]) == int(s):
html_in+=f'
'
html_in+="
"
return html_in
def get_concat_h_cut(in1, in2):
uid=uuid.uuid4()
im1=Image.open(in1)
im2=Image.open(in2)
dst = Image.new('RGB', (im1.width + im2.width,
min(im1.height, im2.height)))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
dst.save(f"h_{uid}.jpg")
return f"h_{uid}.jpg"
def get_concat_v_cut(in1, in2, theme='dark'):
uid=uuid.uuid4()
im1=Image.open(in1)
im2=Image.open(in2)
if theme=='dark':
color=(31,41,55)
if theme=='light':
color=(255,255,255)
dst = Image.new('RGB', (min(im1.width, im2.width), im1.height + im2.height),color=color)
dst.paste(im1, (0, 0))
dst.paste(im2, (0, im1.height))
dst.save(f"v_{uid}.jpg")
return f"v_{uid}.jpg"
def nasa_sdo_composite(obj,size,date1,date2,ret_num):
html_in=f""
if int(date2[6:8])-int(date1[6:8]) >0:
return ("
Reduce Timespan to 24 hours
")
in_year=f"{date2[0:4]}"
in_month=f"{date2[4:6]}"
in_day=f"{date2[6:8]}"
file_name="DATE_TIME_SIZE_TOOL.jpg"
sdo_source_format = f"https://sdo.gsfc.nasa.gov/assets/img/browse/{in_year}/{in_month}/{in_day}/"
get_url=sdo_source_format
print(get_url)
feed1 = requests.get(get_url)
if "All" in size:
size = sdo_size
if "All" in obj:
obj = sdo_obj
link_box=[]
soup = bs4.BeautifulSoup(feed1.content, 'html.parser')
anchor_elements = soup.find_all('a')
#anchor_elements.sort()
cnt=1
max_cnt=ret_num
for element in anchor_elements:
href=element.get('href')
if href.endswith('.jpg'):
for o in obj:
for s in size:
ls=href.split("_")
#print(ls[1][0:4])
#print(date1[8:13])
if ls[1][0:4]>=date1[8:13]:
src_obj=ls[3].split('.jpg')[0]
if src_obj == o:
if int(ls[2]) == int(s):
link_box.append(href)
#print(link_box)
#print("$$$$$$$$$$$$$$$$$")
link_box.sort(reverse=True)
#print(link_box)
out_box=[]
for ea in link_box:
if cnt<=max_cnt:
out_link=f'{sdo_source_format}{ea}'
out_box.append(out_link)
cnt+=1
html_in+=f'
'
html_in+="
"
return html_in, out_box
def run():
out=make_tree()
im_html=get_images()
return im_html
def get_date(year1,month1,day1,hour1,minute1,year2,month2,day2,hour2,minute2):
if len(str(month1))<2: m1=0
else: m1=""
if len(str(day1))<2: d1=0
else: d1=""
if len(str(hour1))<2: h1=0
else: h1=""
if len(str(minute1))<2: mi1=0
else: mi1=""
date1=f'{year1}{m1}{month1}{d1}{day1}{h1}{hour1}{mi1}{minute1}'
if len(str(month2))<2: m2=0
else: m2=""
if len(str(day2))<2: d2=0
else: d2=""
if len(str(hour2))<2: h2=0
else: h2=""
if len(str(minute2))<2: mi2=0
else: mi2=""
date2=f'{year2}{m2}{month2}{d2}{day2}{h2}{hour2}{mi2}{minute2}'
print(date1)
print(date2)
return date1,date2
def comp_combine(inp_ims: list,comp_col,comp_row,resize=False):
#print(inp_ims)
im_box=[]
v_box=[]
rows=comp_row
cols=comp_col
if not type(inp_ims)==type([]):
inp_ims=eval(inp_ims)
for i,im in enumerate(inp_ims):
urllib.request.urlretrieve(im, f"tmp-{i}.jpg")
if resize:
pil_im = Image.open(f'tmp-{i}.jpg')
pil_im = pil_im.resize((int(resize[0]),int(resize[1])),resample=Image.Resampling.LANCZOS).convert('RGB')
pil_im.save(f'tmp-{i}.jpg')
im_box.append(f"tmp-{i}.jpg")
im_cnt=len(im_box)
cnt=1
for rr in range(rows):
print(rr)
col_start=[im_box[cnt-1]]
for cc in range(cols-1):
try:
print(cc)
col_out=get_concat_h_cut(col_start[0],im_box[cnt])
col_start[0]=col_out
cnt+=1
#if cnt>=im_cnt:
# rr=range(rows)
# cc=range(cols)
except Exception as e:
print(e)
pass
cnt+=1
v_box.append(col_out)
print(v_box)
v_cnt=1
v_box_cnt=len(v_box)
v_start=[v_box[0]]
for vv in range(v_box_cnt-1):
print(vv)
v_out=get_concat_v_cut(v_start[0],v_box[v_cnt])
v_start[0]=v_out
v_cnt+=1
return v_out
def comp_1(comp_list=comp_list,col=3,row=4,resize=[640,450]):
#1280x900
outp=comp_combine(comp_list,col,row,resize)
return (outp)
datestamp=["1","1","1"]
timestamp=["1","1","1"]
datetimestamp="1:1:1"
def get_time():
datetimestamp=str(datetime.datetime.now()).split(".")[0]
datestamp=datetimestamp.replace(" ","-").split("-")
timestamp=datestamp[3].split(":")
html_out=f"""Current: {datetimestamp} UTC
"""
year1=int(datestamp[0])
month1=int(datestamp[1])
day1=int(datestamp[2])
hour1=int(timestamp[0])
minute1=int(timestamp[1])
year2=int(datestamp[0])
month2=int(datestamp[1])
day2=int(datestamp[2])
hour2=int(timestamp[0])
minute2=int(timestamp[1])
return (gr.update(value=html_out),gr.update(value=year1),gr.update(value=month1),
gr.update(value=day1),gr.update(value=hour1),gr.update(value=minute1),
gr.update(value=year2),gr.update(value=month2),gr.update(value=day2),gr.update(value=hour2),gr.update(value=minute2))
with gr.Blocks() as app:
#datetimestamp=gr.Textbox()
#datestamp=gr.Textbox()
#timestamp=gr.State()
datetimestamp=str(datetime.datetime.now()).split(".")[0]
datestamp=datetimestamp.replace(" ","-").split("-")
timestamp=datestamp[3].split(":")
time_html=gr.HTML(f"""Current: {datetimestamp} UTC
""")
with gr.Tab("NOAA"):
with gr.Tab("Compilation"):
first_comp_btn=gr.Button("Load")
first_comp_img=gr.Image()
with gr.Tab("Images"):
first_btn=gr.Button("Load")
html_im=gr.HTML()
with gr.Tab("Animations"):
anim_btn=gr.Button()
anim_out=gr.HTML()
file_out=gr.Files()
with gr.Tab("Raw"):
with gr.Row():
drop1=gr.Dropdown()
drop2=gr.Dropdown()
drop3=gr.Dropdown()
drop4=gr.Dropdown()
with gr.Row():
drop5=gr.Dropdown()
drop6=gr.Dropdown()
drop7=gr.Dropdown()
drop8=gr.Dropdown()
load_btn=gr.Button("Load")
html_raw=gr.HTML()
links=gr.JSON()
with gr.Tab("NASA"):
with gr.Tab("SDO Images"):
with gr.Row():
gr.Markdown("From:")
year1=gr.Number(label="Year",minimum=2000,maximum=2024,precision=0,value=int(datestamp[0]),min_width=10)
month1=gr.Number(label="Month",minimum=1,maximum=12,precision=0,value=int(datestamp[1]),min_width=10)
day1=gr.Number(label="Day",minimum=1,maximum=31,precision=0,value=int(datestamp[2]),min_width=10)
hour1=gr.Number(label="Hour",minimum=0,maximum=23,precision=0,value=int(timestamp[0]),min_width=10)
minute1=gr.Number(label="Minute",minimum=0,maximum=59,precision=0,value=int(timestamp[1]),min_width=10)
gr.Markdown("To:")
year2=gr.Number(label="Year",minimum=2000,maximum=2024,precision=0,value=int(datestamp[0]),min_width=10)
month2=gr.Number(label="Month",minimum=1,maximum=12,precision=0,value=int(datestamp[1]),min_width=10)
day2=gr.Number(label="Day",minimum=1,maximum=31,precision=0,value=int(datestamp[2]),min_width=10)
hour2=gr.Number(label="Hour",minimum=0,maximum=23,precision=0,value=int(timestamp[0]),min_width=10)
minute2=gr.Number(label="Minute",minimum=0,maximum=59,precision=0,value=int(timestamp[1]),min_width=10)
with gr.Row():
sdo_drop1=gr.Dropdown(label="Instrument", multiselect=True, choices=["All"]+sdo_obj, value="0094")
sdo_drop2=gr.Dropdown(label="Size", multiselect=True, choices=["All"]+sdo_size,value=512)
with gr.Tab("Composite"):
with gr.Row():
comp_num=gr.Number(label="Return",precision=0,value=4,interactive=True)
comp_col=gr.Number(label="Columns",precision=0,value=2,interactive=True)
comp_row=gr.Number(label="Rows",precision=0,value=2,interactive=True)
with gr.Row():
comp_combine_btn=gr.Button("Combine")
sdo_comp_btn=gr.Button("Load")
img_out=gr.Image()
comp_combine_html=gr.HTML()
sdo_comp_html=gr.HTML()
image_comp_list=gr.Textbox(visible=True)
with gr.Tab("Images"):
sdo_btn=gr.Button("Load")
sdo_html=gr.HTML()
date1=gr.Textbox(visible=False)
date2=gr.Textbox(visible=False)
#sdo_json=gr.JSON()
with gr.Tab("SOHO Images"):
soho_btn=gr.Button("Load")
html_nasa=gr.HTML()
with gr.Tab("SOHO Video"):
soho_vid_btn=gr.Button("Load")
html_vid_nasa=gr.HTML()
app.load(get_time,None,[time_html,year1,month1,day1,hour1,minute1,year2,month2,day2,hour2,minute2]).then(make_tree,None,drop1)
first_comp_btn.click(comp_1,None,first_comp_img)
###### Composite Images ##########
comp_combine_btn.click(comp_combine,[image_comp_list,comp_col,comp_row],img_out)
sdo_comp_btn.click(get_date,[year1,month1,day1,hour1,minute1,year2,month2,day2,hour2,minute2],[date1,date2]).then(nasa_sdo_composite,[sdo_drop1,sdo_drop2,date1,date2,comp_num],[sdo_comp_html,image_comp_list])
###### NASA Images ##########
sdo_btn.click(get_date,[year1,month1,day1,hour1,minute1,year2,month2,day2,hour2,minute2],[date1,date2]).then(nasa_sdo_images,[sdo_drop1,sdo_drop2,date1,date2],sdo_html)
soho_btn.click(make_nasa_soho_image_trigger,None,html_nasa)
soho_vid_btn.click(make_nasa_soho_videos,None,html_vid_nasa)
###### NOAA Images ##########
load_btn.click(load_json,[drop1,drop2,drop3,drop4,drop5,drop6,drop7,drop8],[html_raw,links])
anim_btn.click(make_animation,None,[file_out]).then(make_html,file_out,anim_out)
####### Raw ############
drop1.change(make_tree,drop1,[drop2])
drop2.change(make_tree,[drop1,drop2],[drop3])
drop3.change(make_tree,[drop1,drop2,drop3],[drop4])
drop4.change(make_tree,[drop1,drop2,drop3,drop4],[drop5])
drop5.change(make_tree,[drop1,drop2,drop3,drop4,drop5],[drop6])
drop6.change(make_tree,[drop1,drop2,drop3,drop4,drop5,drop6],[drop7])
drop7.change(make_tree,[drop1,drop2,drop3,drop4,drop5,drop6,drop7],[drop8])
######################
first_btn.click(run,None,[html_im])
#app.load(make_tree,None,drop1)
app.queue(default_concurrency_limit=10).launch()