rmm commited on
Commit
3b302a7
·
1 Parent(s): 821ac40

fix: timezone from file metadata, or from locale if absent

Browse files
src/input/input_handling.py CHANGED
@@ -11,7 +11,7 @@ import cv2
11
  import numpy as np
12
 
13
  from input.input_observation import InputObservation
14
- from input.input_validator import get_image_datetime, is_valid_email, is_valid_number, get_image_latlon
15
 
16
  m_logger = logging.getLogger(__name__)
17
  m_logger.setLevel(logging.INFO)
@@ -186,6 +186,7 @@ def metadata_inputs_one_file(file:UploadedFile, image_hash:str, dbg_ix:int=0) ->
186
  author_email = st.session_state["input_author_email"]
187
  filename = file.name
188
  image_datetime_raw = get_image_datetime(file)
 
189
  latitude0, longitude0 = get_image_latlon(file)
190
  msg = f"[D] {filename}: lat, lon from image metadata: {latitude0}, {longitude0}"
191
  m_logger.debug(msg)
@@ -226,11 +227,29 @@ def metadata_inputs_one_file(file:UploadedFile, image_hash:str, dbg_ix:int=0) ->
226
  # 5. Date/time
227
  ## first from image metadata
228
  if image_datetime_raw is not None:
229
- time_value = datetime.datetime.strptime(image_datetime_raw, '%Y:%m:%d %H:%M:%S').time()
230
- date_value = datetime.datetime.strptime(image_datetime_raw, '%Y:%m:%d %H:%M:%S').date()
 
 
 
 
 
 
 
 
 
 
 
231
  else:
232
- time_value = datetime.datetime.now().time() # Default to current time
233
- date_value = datetime.datetime.now().date()
 
 
 
 
 
 
 
234
 
235
  ## either way, give user the option to enter manually (or correct, e.g. if camera has no rtc clock)
236
  date = viewcontainer.date_input("Date for "+filename, value=date_value, key=f"input_date_{image_hash}")
 
11
  import numpy as np
12
 
13
  from input.input_observation import InputObservation
14
+ from input.input_validator import get_image_datetime, is_valid_email, is_valid_number, get_image_latlon, get_image_timezone
15
 
16
  m_logger = logging.getLogger(__name__)
17
  m_logger.setLevel(logging.INFO)
 
186
  author_email = st.session_state["input_author_email"]
187
  filename = file.name
188
  image_datetime_raw = get_image_datetime(file)
189
+ image_timezone_raw = get_image_timezone(file)
190
  latitude0, longitude0 = get_image_latlon(file)
191
  msg = f"[D] {filename}: lat, lon from image metadata: {latitude0}, {longitude0}"
192
  m_logger.debug(msg)
 
227
  # 5. Date/time
228
  ## first from image metadata
229
  if image_datetime_raw is not None:
230
+ # if we have a timezone let's use it (but only if we also have datetime)
231
+ time_fmt = '%Y:%m:%d %H:%M:%S'
232
+ if image_timezone_raw is not None:
233
+ image_datetime_raw += f" {image_timezone_raw}"
234
+ time_fmt += ' %z'
235
+ #
236
+ dt = datetime.datetime.strptime(image_datetime_raw, time_fmt)
237
+ date_value = dt.date()
238
+ time_value = dt.time()
239
+ tz_value = dt.tzinfo # could be None...
240
+
241
+ #time_value = datetime.datetime.strptime(image_datetime_raw, '%Y:%m:%d %H:%M:%S').time()
242
+ #date_value = datetime.datetime.strptime(image_datetime_raw, '%Y:%m:%d %H:%M:%S').date()
243
  else:
244
+ # get current time, with user timezone (or is it server timezone?! TODO: test with different zones)
245
+ dt = datetime.datetime.now().astimezone().replace(microsecond=0)
246
+ time_value = dt.time()
247
+ date_value = dt.date()
248
+ tz_value = dt.tzinfo
249
+
250
+ #time_value = datetime.datetime.now().time() # Default to current time
251
+ #date_value = datetime.datetime.now().date()
252
+
253
 
254
  ## either way, give user the option to enter manually (or correct, e.g. if camera has no rtc clock)
255
  date = viewcontainer.date_input("Date for "+filename, value=date_value, key=f"input_date_{image_hash}")
src/input/input_validator.py CHANGED
@@ -84,6 +84,28 @@ def get_image_datetime(image_file:UploadedFile) -> Union[str, None]:
84
  # TODO: add to logger
85
  return None
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  def decimal_coords(coords:tuple, ref:str) -> Fraction:
89
  """
 
84
  # TODO: add to logger
85
  return None
86
 
87
+ # function to extract the timezone from image metadata
88
+ def get_image_timezone(image_file:UploadedFile) -> Union[str, None]:
89
+ """
90
+ Extracts the timezone from the EXIF metadata of an uploaded image file.
91
+
92
+ Args:
93
+ image_file (UploadedFile): The uploaded image file from which to extract the timezone.
94
+
95
+ Returns:
96
+ str: The timezone as a string if available, otherwise None.
97
+
98
+ Raises:
99
+ Warning: If the timezone could not be extracted from the image metadata.
100
+ """
101
+ try:
102
+ image = Image.open(image_file)
103
+ exif_data = image._getexif()
104
+ if exif_data is not None:
105
+ if ExifTags.Base.OffsetTimeOriginal in exif_data:
106
+ return exif_data.get(ExifTags.Base.OffsetTimeOriginal)
107
+ except Exception as e: # FIXME: what types of exception?
108
+ st.warning(f"Could not extract timezone from image metadata. (file: {image_file.name})")
109
 
110
  def decimal_coords(coords:tuple, ref:str) -> Fraction:
111
  """