Skip to content

Commit 3426044

Browse files
authored
Merge pull request #1165 from aaronwmorris/dev
Base image URLs from S3 on information from camera
2 parents e95982b + dc996bf commit 3426044

20 files changed

Lines changed: 562 additions & 209 deletions

indi_allsky/allsky.py

Lines changed: 122 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
from .flask.models import IndiAllSkyDbKeogramTable
4141
from .flask.models import IndiAllSkyDbStarTrailsTable
4242
from .flask.models import IndiAllSkyDbStarTrailsVideoTable
43+
from .flask.models import IndiAllSkyDbPanoramaImageTable
44+
from .flask.models import IndiAllSkyDbPanoramaVideoTable
4345
from .flask.models import IndiAllSkyDbTaskQueueTable
4446

4547
from sqlalchemy import or_
@@ -521,7 +523,8 @@ def _stopFileUploadWorkers(self):
521523
active_worker_list.append(upload_worker_dict)
522524

523525
# need to put the stops in the queue before waiting on workers to join
524-
self.upload_q.put({'stop' : True})
526+
#self.upload_q.put({'stop' : True})
527+
upload_worker_dict['worker'].stop()
525528

526529

527530
for upload_worker_dict in active_worker_list:
@@ -670,6 +673,8 @@ def _dbImportImages(self):
670673
'latitude' : 0.0,
671674
'longitude' : 0.0,
672675
'elevation' : 0,
676+
'alt' : 0,
677+
'az' : 0,
673678
}
674679
camera = self._miscDb.addCamera(camera_metadata)
675680
camera_id = camera.id
@@ -709,7 +714,7 @@ def _dbImportImages(self):
709714
d_createDate = datetime.fromtimestamp(f.stat().st_mtime)
710715

711716
video_dict = {
712-
'filename' : str(f),
717+
'filename' : str(f.relative_to(self.image_dir)),
713718
'createDate' : d_createDate,
714719
'dayDate' : d_dayDate,
715720
'night' : night,
@@ -765,7 +770,7 @@ def _dbImportImages(self):
765770
d_createDate = datetime.fromtimestamp(f.stat().st_mtime)
766771

767772
keogram_dict = {
768-
'filename' : str(f),
773+
'filename' : str(f.relative_to(self.image_dir)),
769774
'createDate' : d_createDate,
770775
'dayDate' : d_dayDate,
771776
'night' : night,
@@ -815,7 +820,7 @@ def _dbImportImages(self):
815820
d_createDate = datetime.fromtimestamp(f.stat().st_mtime)
816821

817822
startrail_dict = {
818-
'filename' : str(f),
823+
'filename' : str(f.relative_to(self.image_dir)),
819824
'createDate' : d_createDate,
820825
'dayDate' : d_dayDate,
821826
'night' : night,
@@ -866,7 +871,7 @@ def _dbImportImages(self):
866871
d_createDate = datetime.fromtimestamp(f.stat().st_mtime)
867872

868873
startrail_video_dict = {
869-
'filename' : str(f),
874+
'filename' : str(f.relative_to(self.image_dir)),
870875
'createDate' : d_createDate,
871876
'dayDate' : d_dayDate,
872877
'night' : night,
@@ -887,17 +892,70 @@ def _dbImportImages(self):
887892
db.session.rollback()
888893

889894

895+
### Panorama Videos
896+
file_list_panorama_video_tl = filter(lambda p: 'timelapse' in p.name, file_list_videos)
897+
file_list_panorama_video = filter(lambda p: 'panorama' in p.name, file_list_panorama_video_tl)
898+
899+
#/var/www/html/allsky/images/20210915/allsky-panorama_timelapse_ccd1_20210915_night.mp4
900+
re_panorama_video = re.compile(r'(?P<dayDate_str>\d{8})\/.+panorama_timelapse_ccd(?P<ccd_id_str>\d+)_\d{8}_(?P<timeofday_str>[a-z]+)\.[a-z0-9]+$')
901+
902+
panorama_video_entries = list()
903+
for f in file_list_panorama_video:
904+
#logger.info('Panorama timelapse: %s', f)
905+
906+
m = re.search(re_panorama_video, str(f))
907+
if not m:
908+
logger.error('Regex did not match file: %s', f)
909+
continue
910+
911+
#logger.info('dayDate string: %s', m.group('dayDate_str'))
912+
#logger.info('Time of day string: %s', m.group('timeofday_str'))
913+
914+
d_dayDate = datetime.strptime(m.group('dayDate_str'), '%Y%m%d').date()
915+
#logger.info('dayDate: %s', str(d_dayDate))
916+
917+
if m.group('timeofday_str') == 'night':
918+
night = True
919+
else:
920+
night = False
921+
922+
d_createDate = datetime.fromtimestamp(f.stat().st_mtime)
923+
924+
panorama_video_dict = {
925+
'filename' : str(f.relative_to(self.image_dir)),
926+
'createDate' : d_createDate,
927+
'dayDate' : d_dayDate,
928+
'night' : night,
929+
'uploaded' : False,
930+
'camera_id' : camera_id,
931+
}
932+
933+
panorama_video_entries.append(panorama_video_dict)
934+
935+
936+
try:
937+
db.session.bulk_insert_mappings(IndiAllSkyDbPanoramaVideoTable, panorama_video_entries)
938+
db.session.commit()
939+
940+
logger.warning('*** Panorama timelapses inserted: %d ***', len(panorama_video_entries))
941+
except IntegrityError as e:
942+
logger.warning('Integrity error: %s', str(e))
943+
db.session.rollback()
944+
945+
890946
### Images
891947
# Exclude keograms and star trails
892948
file_list_images_nok = filter(lambda p: 'keogram' not in p.name, file_list_images)
893949
file_list_images_nok_nost = filter(lambda p: 'startrail' not in p.name, file_list_images_nok)
894950
file_list_images_nok_nost_noraw = filter(lambda p: 'raw' not in p.name, file_list_images_nok_nost)
951+
file_list_images_nok_nost_noraw_nopan = filter(lambda p: 'panorama' not in p.name, file_list_images_nok_nost_noraw)
952+
file_list_images_nok_nost_noraw_nopan_nothumb = filter(lambda p: 'thumbnail' not in p.name, file_list_images_nok_nost_noraw_nopan)
895953

896954
#/var/www/html/allsky/images/20210825/night/26_02/ccd1_20210826_020202.jpg
897955
re_image = re.compile(r'(?P<dayDate_str>\d{8})\/(?P<timeofday_str>[a-z]+)\/\d{2}_\d{2}\/ccd(?P<ccd_id_str>\d+)_(?P<createDate_str>[0-9_]+)\.[a-z]+$')
898956

899957
image_entries = list()
900-
for f in file_list_images_nok_nost_noraw:
958+
for f in file_list_images_nok_nost_noraw_nopan_nothumb:
901959
#logger.info('Image: %s', f)
902960

903961
m = re.search(re_image, str(f))
@@ -923,7 +981,7 @@ def _dbImportImages(self):
923981

924982

925983
image_dict = {
926-
'filename' : str(f),
984+
'filename' : str(f.relative_to(self.image_dir)),
927985
'camera_id' : camera_id,
928986
'createDate' : d_createDate,
929987
'dayDate' : d_dayDate,
@@ -951,6 +1009,63 @@ def _dbImportImages(self):
9511009
db.session.rollback()
9521010

9531011

1012+
### Panorama images
1013+
file_list_panorama_images = filter(lambda p: 'panoram' in p.name, file_list_images)
1014+
1015+
#/var/www/html/allsky/images/20210825/night/26_02/panorama_ccd1_20210826_020202.jpg
1016+
re_image = re.compile(r'(?P<dayDate_str>\d{8})\/(?P<timeofday_str>[a-z]+)\/\d{2}_\d{2}\/panorama_ccd(?P<ccd_id_str>\d+)_(?P<createDate_str>[0-9_]+)\.[a-z]+$')
1017+
1018+
panorama_image_entries = list()
1019+
for f in file_list_panorama_images:
1020+
#logger.info('Image: %s', f)
1021+
1022+
m = re.search(re_image, str(f))
1023+
if not m:
1024+
logger.error('Regex did not match file: %s', f)
1025+
continue
1026+
1027+
#logger.info('dayDate string: %s', m.group('dayDate_str'))
1028+
#logger.info('Time of day string: %s', m.group('timeofday_str'))
1029+
#logger.info('createDate string: %s', m.group('createDate_str'))
1030+
1031+
d_dayDate = datetime.strptime(m.group('dayDate_str'), '%Y%m%d').date()
1032+
#logger.info('dayDate: %s', str(d_dayDate))
1033+
1034+
if m.group('timeofday_str') == 'night':
1035+
night = True
1036+
else:
1037+
night = False
1038+
1039+
#d_createDate = datetime.strptime(m.group('createDate_str'), '%Y%m%d_%H%M%S')
1040+
d_createDate = datetime.fromtimestamp(f.stat().st_mtime)
1041+
#logger.info('createDate: %s', str(d_createDate))
1042+
1043+
1044+
panorama_image_dict = {
1045+
'filename' : str(f.relative_to(self.image_dir)),
1046+
'camera_id' : camera_id,
1047+
'createDate' : d_createDate,
1048+
'dayDate' : d_dayDate,
1049+
'exposure' : 0.0,
1050+
'gain' : -1,
1051+
'binmode' : 1,
1052+
'night' : night,
1053+
'uploaded' : False,
1054+
}
1055+
1056+
1057+
panorama_image_entries.append(panorama_image_dict)
1058+
1059+
try:
1060+
db.session.bulk_insert_mappings(IndiAllSkyDbPanoramaImageTable, panorama_image_entries)
1061+
db.session.commit()
1062+
1063+
logger.warning('*** Panorama images inserted: %d ***', len(panorama_image_entries))
1064+
except IntegrityError as e:
1065+
logger.warning('Integrity error: %s', str(e))
1066+
db.session.rollback()
1067+
1068+
9541069
def _getFolderFilesByExt(self, folder, file_list, extension_list=None):
9551070
if not extension_list:
9561071
extension_list = [self.config['IMAGE_FILE_TYPE']]

indi_allsky/capture.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,27 @@ def _initialize(self):
618618
cfa_pattern = ccd_info['CCD_CFA']['CFA_TYPE'].get('text')
619619

620620

621+
# populate S3 data
622+
s3_data = {
623+
'host' : self.config['S3UPLOAD'].get('HOST', ''),
624+
'bucket' : self.config['S3UPLOAD'].get('BUCKET', ''),
625+
'region' : self.config['S3UPLOAD'].get('REGION', ''),
626+
'namespace' : self.config['S3UPLOAD'].get('NAMESPACE', ''),
627+
}
628+
629+
630+
try:
631+
s3_prefix = self.config['S3UPLOAD']['URL_TEMPLATE'].format(**s3_data)
632+
except KeyError as e:
633+
app.logger.error('Failure to generate S3 prefix: %s', str(e))
634+
s3_prefix = ''
635+
except ValueError as e:
636+
app.logger.error('Failure to generate S3 prefix: %s', str(e))
637+
s3_prefix = ''
638+
639+
640+
now = datetime.now()
641+
621642
# need to get camera info before adding to DB
622643
camera_metadata = {
623644
'type' : constants.CAMERA,
@@ -641,6 +662,9 @@ def _initialize(self):
641662
'longitude' : self.longitude_v.value,
642663
'elevation' : self.elevation_v.value,
643664

665+
'tz' : str(now.astimezone().tzinfo),
666+
'utc_offset' : now.astimezone().utcoffset().total_seconds(),
667+
644668
'owner' : self.config['OWNER'],
645669
'lensName' : self.config['LENS_NAME'],
646670
'lensFocalLength' : self.config['LENS_FOCAL_LENGTH'],
@@ -649,8 +673,13 @@ def _initialize(self):
649673
'alt' : self.config['LENS_ALTITUDE'],
650674
'az' : self.config['LENS_AZIMUTH'],
651675
'nightSunAlt' : self.config['NIGHT_SUN_ALT_DEG'],
676+
677+
's3_prefix' : s3_prefix,
678+
'web_nonlocal_images' : self.config.get('WEB_NONLOCAL_IMAGES', False),
679+
'web_local_images_admin': self.config.get('WEB_LOCAL_IMAGES_ADMIN', False),
652680
}
653681

682+
654683
camera = self._miscDb.addCamera(camera_metadata)
655684
self.camera_id = camera.id
656685

indi_allsky/darks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ def _run(self, stacking_class):
829829
def _take_exposures(self, exposure, dark_filename_t, bpm_filename_t, ccd_bits, stacking_class):
830830
exposure_f = float(exposure)
831831

832-
tmp_fit_dir = tempfile.TemporaryDirectory()
832+
tmp_fit_dir = tempfile.TemporaryDirectory() # context manager automatically deletes files when finished
833833
tmp_fit_dir_p = Path(tmp_fit_dir.name)
834834

835835
logger.info('Temp folder: %s', tmp_fit_dir_p)

indi_allsky/flask/base_views.py

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -55,30 +55,29 @@ def __init__(self, **kwargs):
5555

5656
self._miscDb = miscDb(self.indi_allsky_config)
5757

58-
self.s3_prefix = self.getS3Prefix()
58+
self.camera = None # set in setupSession()
5959

60+
self.setupSession()
6061

61-
def getS3Prefix(self):
62-
s3_data = {
63-
'host' : self.indi_allsky_config['S3UPLOAD']['HOST'],
64-
'bucket' : self.indi_allsky_config['S3UPLOAD']['BUCKET'],
65-
'region' : self.indi_allsky_config['S3UPLOAD']['REGION'],
66-
'namespace' : self.indi_allsky_config['S3UPLOAD'].get('NAMESPACE', ''),
67-
}
62+
self.s3_prefix = self.camera.s3_prefix
63+
self.web_nonlocal_images = self.camera.web_nonlocal_images
64+
self.web_local_images_admin = self.camera.web_local_images_admin
65+
66+
camera_time_offset = self.camera.utc_offset - datetime.now().astimezone().utcoffset().total_seconds()
67+
self.camera_now = datetime.now() + timedelta(seconds=camera_time_offset)
6868

69-
try:
70-
prefix = self.indi_allsky_config['S3UPLOAD']['URL_TEMPLATE'].format(**s3_data)
71-
except KeyError as e:
72-
app.logger.error('Failure to generate S3 prefix: %s', str(e))
73-
return ''
74-
except ValueError as e:
75-
app.logger.error('Failure to generate S3 prefix: %s', str(e))
76-
return ''
7769

70+
def setupSession(self):
71+
if session.get('camera_id'):
72+
self.camera = self.getCameraById(session['camera_id'])
73+
return
7874

79-
#app.logger.info('S3 Prefix: %s', prefix)
75+
try:
76+
self.camera = self.getLatestCamera()
77+
except NoResultFound:
78+
self.camera = FakeCamera()
8079

81-
return prefix
80+
session['camera_id'] = self.camera.id
8281

8382

8483
def getLatestCamera(self):
@@ -179,10 +178,6 @@ def __init__(self, template_name, **kwargs):
179178
super(TemplateView, self).__init__(**kwargs)
180179
self.template_name = template_name
181180

182-
self.camera = None # set in setupSession()
183-
184-
self.setupSession()
185-
186181
self.local_indi_allsky = self.camera.local
187182

188183
self.check_config(self._indi_allsky_config_obj.config_id)
@@ -193,19 +188,6 @@ def __init__(self, template_name, **kwargs):
193188
self.night = True
194189

195190

196-
def setupSession(self):
197-
if session.get('camera_id'):
198-
self.camera = self.getCameraById(session['camera_id'])
199-
return
200-
201-
try:
202-
self.camera = self.getLatestCamera()
203-
except NoResultFound:
204-
self.camera = FakeCamera()
205-
206-
session['camera_id'] = self.camera.id
207-
208-
209191
def render_template(self, context):
210192
return render_template(self.template_name, **context)
211193

@@ -358,10 +340,20 @@ def get_camera_info(self):
358340
'location' : str(self.camera.location),
359341
'owner' : str(self.camera.owner),
360342
'lens_name' : str(self.camera.lensName),
361-
'alt' : float(self.camera.alt),
362-
'az' : float(self.camera.az),
363343
}
364344

345+
346+
if isinstance(self.camera.alt, type(None)):
347+
data['alt'] = 0
348+
else:
349+
data['alt'] = float(self.camera.alt)
350+
351+
if isinstance(self.camera.az, type(None)):
352+
data['az'] = 0
353+
else:
354+
data['az'] = float(self.camera.az)
355+
356+
365357
return data
366358

367359

@@ -707,5 +699,8 @@ class FakeCamera(object):
707699
lensName = ''
708700
name = ''
709701
friendlyName = ''
702+
s3_prefix = ''
703+
web_nonlocal_images = False
704+
web_local_images_admin = False
710705
data = {}
711706

0 commit comments

Comments
 (0)