Code-styling following PEP8.
This commit is contained in:
		
							
								
								
									
										107
									
								
								functions.py
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								functions.py
									
									
									
									
									
								
							| @@ -16,7 +16,8 @@ class Radiation: | ||||
|     Arguments: | ||||
|     timestamp: Date/time string from CSV as string | ||||
|     radiation: Radiation from CSV in CP/M as float | ||||
|     local_timezone: timezone for timezone-unaware CSV / Photo, if GPX is timezone aware | ||||
|     local_timezone: timezone for timezone-unaware CSV / Photo, if GPX is | ||||
|         timezone aware | ||||
|     si_factor: CP/M to (µS/h) conversion factor - specific to GMC-tube | ||||
|      | ||||
|     Returns: | ||||
| @@ -24,7 +25,13 @@ class Radiation: | ||||
|     radiation: radiation in µS/h as str (for Exif comment, UTF-8) | ||||
|     ''' | ||||
|  | ||||
|     def __init__(self, timestamp, radiation, local_timezone, si_factor): | ||||
|     def __init__( | ||||
|         self, | ||||
|         timestamp, | ||||
|         radiation, | ||||
|         local_timezone, | ||||
|         si_factor | ||||
|         ): | ||||
|         self.timestamp = self._time_conversion(timestamp, local_timezone) | ||||
|         self.radiation = self._radiation_conversion(radiation, si_factor) | ||||
|  | ||||
| @@ -48,7 +55,8 @@ class Photo: | ||||
|  | ||||
|     Arguments: | ||||
|     photo: source photo () | ||||
|     local_timezone: timezone for timezone-unaware CSV / Photo, if GPX is timezone aware | ||||
|     local_timezone: timezone for timezone-unaware CSV / Photo, if GPX is  | ||||
|         timezone aware | ||||
|     dest_dir: destination directory where the photo is going to be copied to. | ||||
|     dry_run: whether to actually write (True / False) | ||||
|  | ||||
| @@ -64,7 +72,10 @@ class Photo: | ||||
|         self.get_photo_basename = self._copy_photo(photo, dest_dir, dry_run)[0] | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return 'Photo: %s Creation Date: %s' % (str(self.get_photo_basename), str(self.get_date)) | ||||
|         return 'Photo: %s Creation Date: %s' % ( | ||||
|             str(self.get_photo_basename), | ||||
|             str(self.get_date) | ||||
|             ) | ||||
|  | ||||
|     def _copy_photo(self, photo, dest_dir, dry_run): | ||||
|         # Determine where to work on photo and copy it there if needed. | ||||
| @@ -96,8 +107,8 @@ class Photo: | ||||
|  | ||||
| class Match: | ||||
|     ''' | ||||
|     Receives lists of time / radiation and GPS data and compares it to timestamp. | ||||
|     Then returns relevant values matching to time - or None | ||||
|     Receives lists of time / radiation and GPS data and compares it to  | ||||
|     timestamp.Then returns relevant values matching to time - or None | ||||
|  | ||||
|     Arguments: | ||||
|     photo_time: timestamp of photo | ||||
| @@ -110,12 +121,30 @@ class Match: | ||||
|     ''' | ||||
|  | ||||
|     def __init__(self, photo_time, radiation_list, position_list): | ||||
|         self.radiation_value = self._find_radiation_match(photo_time, radiation_list)[1] | ||||
|         self.radiation_delta = self._find_radiation_match(photo_time, radiation_list)[0] | ||||
|         self.position_delta = self._find_position_match(photo_time, position_list)[0] | ||||
|         self.position_latitude = self._find_position_match(photo_time, position_list)[1][1] | ||||
|         self.position_longitude = self._find_position_match(photo_time, position_list)[1][2] | ||||
|         self.position_altitude = self._find_position_match(photo_time, position_list)[1][3] | ||||
|         self.radiation_value = self._find_radiation_match( | ||||
|             photo_time, | ||||
|             radiation_list | ||||
|             )[1] | ||||
|         self.radiation_delta = self._find_radiation_match( | ||||
|             photo_time, | ||||
|             radiation_list | ||||
|             )[0] | ||||
|         self.position_delta = self._find_position_match( | ||||
|             photo_time, | ||||
|             position_list | ||||
|             )[0] | ||||
|         self.position_latitude = self._find_position_match( | ||||
|             photo_time, | ||||
|             position_list | ||||
|             )[1][1] | ||||
|         self.position_longitude = self._find_position_match( | ||||
|             photo_time, | ||||
|             position_list | ||||
|             )[1][2] | ||||
|         self.position_altitude = self._find_position_match( | ||||
|             photo_time, | ||||
|             position_list | ||||
|             )[1][3] | ||||
|  | ||||
|     def __repr__(self): | ||||
|         if self.radiation_value: | ||||
| @@ -186,9 +215,21 @@ class Exif: | ||||
|     Exif-Comment: that has been written (incl. radiation) | ||||
|     ''' | ||||
|  | ||||
|     def __init__(self, photo, dry_run, radiation, latitude, longitude, elevation): | ||||
|         self.write_exif = self._write_exif(photo, dry_run, radiation, latitude, | ||||
|                                            longitude, elevation) | ||||
|     def __init__( | ||||
|         self, photo, | ||||
|         dry_run, | ||||
|         radiation, | ||||
|         latitude, | ||||
|         longitude, | ||||
|         elevation | ||||
|         ): | ||||
|         self.write_exif = self._write_exif( | ||||
|             photo, | ||||
|             dry_run, | ||||
|             radiation, | ||||
|             latitude, | ||||
|             longitude, elevation | ||||
|             ) | ||||
|   | ||||
|     def __repr__(self): | ||||
|         return 'Position: %s, %s: %s ' % self.write_exif | ||||
| @@ -207,7 +248,15 @@ class Exif: | ||||
|         second = round((t1 - minute) * 60, 5) | ||||
|         return (deg, minute, second, loc_value)  | ||||
|  | ||||
|     def _write_exif(self, photo, dry_run, radiation, latitude, longitude, elevation): | ||||
|     def _write_exif( | ||||
|         self, | ||||
|         photo, | ||||
|         dry_run, | ||||
|         radiation, | ||||
|         latitude, | ||||
|         longitude, | ||||
|         elevation | ||||
|         ): | ||||
|  | ||||
|         metadata = pyexiv2.ImageMetadata(photo) | ||||
|         metadata.read() | ||||
| @@ -217,12 +266,16 @@ class Exif: | ||||
|             longitude_degree = self._to_degree(longitude, ["W", "E"]) | ||||
|  | ||||
|             # convert decimal coordinates into fractions required for pyexiv2 | ||||
|             exiv2_latitude = (Fraction(latitude_degree[0] * 60 + latitude_degree[1], 60), | ||||
|                               Fraction(int(round(latitude_degree[2] * 100, 0)), 6000), | ||||
|                               Fraction(0, 1)) | ||||
|             exiv2_longitude = (Fraction(longitude_degree[0] * 60 + longitude_degree[1], 60), | ||||
|                                Fraction(int(round(longitude_degree[2] * 100, 0)), 6000), | ||||
|                                Fraction(0, 1)) | ||||
|             exiv2_latitude = ( | ||||
|                 Fraction(latitude_degree[0] * 60 + latitude_degree[1], 60), | ||||
|                 Fraction(int(round(latitude_degree[2] * 100, 0)), 6000), | ||||
|                 Fraction(0, 1) | ||||
|                 ) | ||||
|             exiv2_longitude = ( | ||||
|                 Fraction(longitude_degree[0] * 60 + longitude_degree[1], 60), | ||||
|                 Fraction(int(round(longitude_degree[2] * 100, 0)), 6000), | ||||
|                 Fraction(0, 1) | ||||
|                 ) | ||||
|  | ||||
|             # Exif tags to write | ||||
|             metadata['Exif.GPSInfo.GPSLatitude'] = exiv2_latitude | ||||
| @@ -259,7 +312,8 @@ class Exif: | ||||
|  | ||||
| class Output: | ||||
|     ''' | ||||
|     Receives values to be printed, formats them and returns a string for printing. | ||||
|     Receives values to be printed, formats them and returns a string for | ||||
|         printing. | ||||
|  | ||||
|     Arguments: | ||||
|     radiation: radiation as float | ||||
| @@ -272,7 +326,12 @@ class Output: | ||||
|     ''' | ||||
|  | ||||
|     def __init__(self, radiation, latitude, longitude, altitude): | ||||
|         self.get_string = self._get_string(radiation, latitude, longitude, altitude) | ||||
|         self.get_string = self._get_string( | ||||
|             radiation, | ||||
|             latitude, | ||||
|             longitude, | ||||
|             altitude | ||||
|             ) | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return self.get_string | ||||
|   | ||||
							
								
								
									
										128
									
								
								rad_tag.py
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								rad_tag.py
									
									
									
									
									
								
							| @@ -1,9 +1,11 @@ | ||||
| #!/usr/bin/env python | ||||
| # -*- coding: utf-8 -*- | ||||
|  | ||||
| ''' Iterates over a bunch of .jpg or .cr2 files and matches  | ||||
| ''' | ||||
| Iterates over a bunch of .jpg or .cr2 files and matches  | ||||
| DateTimeOriginal from Exif tags to DateTime in a csv log  | ||||
| of a GeigerMuellerCounter and writes its value to Exif/ITPC/XMP tags in µS/h ''' | ||||
| of a GeigerMuellerCounter and writes its value to Exif/ITPC/XMP tags in µS/h | ||||
| ''' | ||||
|  | ||||
| import csv | ||||
| import argparse | ||||
| @@ -21,26 +23,57 @@ from functions import Radiation, Photo, Match, Exif, Output | ||||
| # 600+ series: 0.002637 µSv/h / CPM | ||||
|  | ||||
| # Configure argument parser for cli options | ||||
| parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter,  | ||||
|                                  description='''A unix-tyle tool that  | ||||
|     extracts GPS and/or radiation data from GPX/CSV files and writes | ||||
|     them into the Exif/ITPC/XMP tags of given photos.''') | ||||
| parser.add_argument('-si', '--sifactor', type=float, default=0.0065,  | ||||
|                     help='Factor to multiply recorded CPM with.') | ||||
| parser.add_argument('-tz', '--timezone', type=str, metavar='Timezone', default='utc', | ||||
|                     help='''Manually set timezone of CSV / and Photo timestamp, | ||||
|                     defaults to UTC if omitted. This is useful, if the GPS-Logger | ||||
|                     saves the time incl. timezone''') | ||||
| parser.add_argument('-d', '--dry', action='store_true',  | ||||
|                     help='Dry-run, do not actually write anything.') | ||||
| parser.add_argument('csv', metavar='CSV', type=str,  | ||||
|                     help='Geiger counter history file in CSV format.') | ||||
| parser.add_argument('-g', '--gpx', metavar='GPX', type=str, | ||||
|                     help='GPS track in GPX format') | ||||
| parser.add_argument('photos', metavar='Photo', type=str, nargs='+',  | ||||
|                     help='One or multiple photo image files to process.') | ||||
| parser.add_argument('-o', '--outdir', type=str, default='.',  | ||||
|                     help='Directory to output processed photos.') | ||||
| parser = argparse.ArgumentParser( | ||||
|     formatter_class=argparse.ArgumentDefaultsHelpFormatter, | ||||
|     description='''A unix-tyle tool that extracts GPS and/or radiation data | ||||
|     from GPX/CSV files and writes them into the Exif/ITPC/XMP tags of given | ||||
|     photos.''' | ||||
|     ) | ||||
| parser.add_argument( | ||||
|     '-si', '--sifactor', | ||||
|     type=float, | ||||
|     default=0.0065, | ||||
|     help='Factor to multiply recorded CPM with.' | ||||
|     ) | ||||
| parser.add_argument( | ||||
|     '-tz', '--timezone', | ||||
|     type=str, | ||||
|     metavar='Timezone', | ||||
|     default='utc', | ||||
|     help='''Manually set timezone of CSV / and Photo timestamp, defaults to | ||||
|     UTC if omitted. This is useful, if the GPS-Logger saves the time incl.  | ||||
|     timezone''' | ||||
|     ) | ||||
| parser.add_argument( | ||||
|     '-d', '--dry',  | ||||
|     action='store_true', | ||||
|     help='Dry-run, do not actually write anything.' | ||||
|     ) | ||||
| parser.add_argument( | ||||
|     'csv', | ||||
|     metavar='CSV', | ||||
|     type=str, | ||||
|     help='Geiger counter history file in CSV format.' | ||||
|     ) | ||||
| parser.add_argument( | ||||
|     '-g', '--gpx', | ||||
|     metavar='GPX', | ||||
|     type=str, | ||||
|     help='GPS track in GPX format' | ||||
|     ) | ||||
| parser.add_argument( | ||||
|     'photos', | ||||
|     metavar='Photo', | ||||
|     type=str, | ||||
|     nargs='+', | ||||
|     help='One or multiple photo image files to process.' | ||||
|     ) | ||||
| parser.add_argument( | ||||
|     '-o', '--outdir', | ||||
|     type=str, | ||||
|     default='.',  | ||||
|     help='Directory to output processed photos.' | ||||
|     ) | ||||
|  | ||||
| args = parser.parse_args() | ||||
|  | ||||
| @@ -53,12 +86,21 @@ position_list = [] | ||||
|  | ||||
| # Import GeigerCounter log | ||||
| with open(args.csv, "r") as f: | ||||
|     csv = csv.reader(filter(lambda row: row[0] != '#', f),  | ||||
|                      delimiter=',', skipinitialspace=True) | ||||
|     # Read csv file, filter out lines beginning with # | ||||
|     csv = csv.reader( | ||||
|         filter(lambda row: row[0] != '#', f),  | ||||
|         delimiter=',', | ||||
|         skipinitialspace=True | ||||
|         ) | ||||
|  | ||||
|     # Import only relevant values, that's timestamp and CP/M | ||||
|     for _, csv_raw_time, csv_raw_cpm, _ in csv: | ||||
|         radiation = Radiation(csv_raw_time, csv_raw_cpm, local_timezone, args.sifactor) | ||||
|         radiation = Radiation( | ||||
|             csv_raw_time, | ||||
|             csv_raw_cpm, | ||||
|             local_timezone, | ||||
|             args.sifactor | ||||
|             ) | ||||
|         radiation_list.append(radiation) | ||||
|     # close CSV file | ||||
|     f.close() | ||||
| @@ -71,8 +113,12 @@ if args.gpx: | ||||
|         for segment in track.segments: | ||||
|             for point in segment.points: | ||||
|                 point_aware_time = point.time.astimezone(local_timezone) | ||||
|                 position = (point_aware_time, point.latitude, point.longitude, | ||||
|                             point.elevation) | ||||
|                 position = ( | ||||
|                     point_aware_time, | ||||
|                     point.latitude, | ||||
|                     point.longitude, | ||||
|                     point.elevation | ||||
|                     ) | ||||
|                 position_list.append(position) | ||||
|  | ||||
| # Inform the user about what is going to happen | ||||
| @@ -87,18 +133,34 @@ else: | ||||
| # Print table header | ||||
| print('{:<15} {:<25} {:<22}'.format('filename', 'date / time', 'Matched Data')) | ||||
|  | ||||
| # Iterate over list of photos | ||||
| for src_photo in args.photos: | ||||
|     # Instantiate photo, copy it to destdir if needed and receive filename to work on | ||||
|     # Instantiate photo, copy it to destdir if needed and receive filename | ||||
|     # to work on | ||||
|     photo = Photo(src_photo, local_timezone, args.outdir, args.dry) | ||||
|  | ||||
|     # Here the matching magic takes place | ||||
|     match = Match(photo.get_date, radiation_list, position_list) | ||||
|  | ||||
|     # Formatted output: | ||||
|     data = Output(match.radiation_value, match.position_latitude,  | ||||
|                   match.position_longitude, match.position_altitude) | ||||
|     print('{:<15} {:<25} {:<22}'.format(photo.get_photo_basename, str(photo.get_date), str(data))) | ||||
|     data = Output( | ||||
|         match.radiation_value, | ||||
|         match.position_latitude, | ||||
|         match.position_longitude, | ||||
|         match.position_altitude | ||||
|         ) | ||||
|     print( | ||||
|         '{:<15} {:<25} {:<22}'.format(photo.get_photo_basename, | ||||
|         str(photo.get_date), | ||||
|         str(data)) | ||||
|         ) | ||||
|  | ||||
|     # Write exif data | ||||
|     Exif(photo.get_photo_filename, args.dry, match.radiation_value,  | ||||
|          match.position_latitude, match.position_longitude, match.position_altitude) | ||||
|     Exif( | ||||
|         photo.get_photo_filename, | ||||
|         args.dry, | ||||
|         match.radiation_value, | ||||
|         match.position_latitude, | ||||
|         match.position_longitude, | ||||
|         match.position_altitude | ||||
|         ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user