def write_new_date(filename: Path, new_date: datetime):
    logging.info('update file ' + str(filename) + ' with ' + str(new_date))
    with open(filename, 'rb') as image_file:
        image = Image(image_file)

    new_date_str = new_date.strftime(DATETIME_STR_FORMAT)

    image.datetime_original = new_date_str
    image.datetime = new_date_str

    with open(filename, 'wb') as new_image_file:
        new_image_file.write(image.get_file())
Example #2
0
def main():
    # Open JSON file
    # Parser JSON

    headers = {"Content-type": "application/x-www-form-urlencoded"}
    fd = open("memories_history.json")
    memories = json.load(fd)
    for x in memories["Saved Media"]:
        if x["Media Type"] == "PHOTO":
            url = x["Download Link"]
            split_url = url.split("?")
            r = requests.post(
                split_url[0],
                headers=headers,
                data=split_url[1],
            )
            if r.status_code == 200:
                # 200 means that we got HTTP success
                aws_resp = requests.get(r.text)
                aws_url = r.text.split("?")
                print(aws_url[0])
                last_occur = aws_url[0].rfind("/", 0) + 1
                print(last_occur)
                filename = aws_url[0][last_occur:]
                i = Image.open(BytesIO(aws_resp.content))
                i = i.save(filename, quality="keep")
                time.sleep(1)
                # Prepare the datetime info
                date_datetime = datetime.strptime(x["Date"],
                                                  "%Y-%m-%d %H:%M:%S %Z")
                with open(filename, "rb") as image_file_thing:

                    image_file = EImage(image_file_thing)
                    image_file.datetime_original = date_datetime.strftime(
                        DATETIME_STR_FORMAT)
                    image_file.datetime_scanned = date_datetime.strftime(
                        DATETIME_STR_FORMAT)
                    image_file.datetime_digitized = date_datetime.strftime(
                        DATETIME_STR_FORMAT)

                    with open("{}_akk.jpg".format(filename),
                              "wb") as new_image_file:
                        new_image_file.write(image_file.get_file())

            else:
                print(r.status_code)
                exit()

    fd.close()
Example #3
0
def change_datetimes(image_path, time_delta):
    """Take in image file and time change as a time delta object.
    Change exif datetime, datetime_digitized, and datetime_original
    Save file with updated exif datetimes."""
    # Open image.
    with open(image_path, 'rb') as image_file:
        image = Image(image_file)
    # Generate new datetime.
    old_datetime = datetime.datetime.strptime(image.datetime,
                                              '%Y:%m:%d %H:%M:%S')
    new_datetime = (old_datetime + time_delta).strftime("%Y:%m:%d %H:%M:%S")
    # Replace all exif datetimes with new datetime.
    image.datetime = new_datetime
    image.datetime_digitized = new_datetime
    image.datetime_original = new_datetime
    # Rewrite image file.
    with open(image_path, 'wb') as new_image_file:
        new_image_file.write(image.get_file())
    print(f"{image_path[7::]} datetime fixed!")
Example #4
0
def test_add_to_scanner_image():
    """Test adding metadata to a scanner-produced JPEG without any pre-existing APP1 or EXIF."""
    image = Image(
        os.path.join(os.path.dirname(__file__), "scanner_without_app1.jpg"))
    assert not image.has_exif
    image.gps_latitude = (41.0, 29.0, 57.48)
    image.gps_latitude_ref = "N"
    image.gps_longitude = (81.0, 41.0, 39.84)
    image.gps_longitude_ref = "W"
    image.gps_altitude = 199.034
    image.gps_altitude_ref = GpsAltitudeRef.ABOVE_SEA_LEVEL
    image.make = "Acme Scanner Company"
    image.model = "Scan-o-Matic 5000"
    image.datetime_original = "1999:12:31 23:49:12"
    image.datetime_digitized = "2020:07:11 10:11:37"
    image.brightness_value = 10.9876  # provides coverage for SRATIONAL
    image.user_comment = "This image was scanned in from an old photo album."  # provides coverage for user comment

    assert image.has_exif
    assert image.gps_latitude == (41.0, 29.0, 57.48)
    assert image.gps_latitude_ref == "N"
    assert image.gps_longitude == (81.0, 41.0, 39.84)
    assert image.gps_longitude_ref == "W"
    assert image.gps_altitude == 199.034
    assert image.gps_altitude_ref == GpsAltitudeRef.ABOVE_SEA_LEVEL
    assert image.make == "Acme Scanner Company"
    assert image.model == "Scan-o-Matic 5000"
    assert image.datetime_original == "1999:12:31 23:49:12"
    assert image.datetime_digitized == "2020:07:11 10:11:37"
    assert image.brightness_value == 10.9876  # provides coverage for SRATIONAL
    assert (image.user_comment ==
            "This image was scanned in from an old photo album."
            )  # provides coverage for user comment

    segment_hex = (binascii.hexlify(
        image._segments["APP1"].get_segment_bytes()).decode("utf-8").upper())
    assert "\n".join(textwrap.wrap(segment_hex,
                                   90)) == ADD_TO_SCANNED_IMAGE_BASELINE
def strip_exifdates(myfile, date_now, dryrun):
    """Function to remove known EXIF date data that affects sorting"""
    if dryrun == False:
        local_exceptions = {}
        with open(myfile, "rb") as image_file:
            try:
                my_image = Image(image_file)
            except AssertionError as err:
                exc_type, value, traceback = sys.exc_info()
                local_exceptions[myfile] = exc_type
                logger.exception(
                    f"exif library exception caught with {myfile}",
                    exc_info=True)
                return
            try:
                logger.debug(
                    f"Attempting to modify EXIF datetime for {myfile}")
                logger.debug(f"Before my_image.datetime: {my_image.datetime}")
                my_image.datetime = f"{date_now.year}:{date_now.month}:{date_now.day} {date_now.hour}:{date_now.minute}:{date_now.second}"
                logger.debug(f"After my_image.datetime: {my_image.datetime}")
            except (AttributeError, KeyError) as err:
                exc_type, value, traceback = sys.exc_info()
                local_exceptions[myfile] = exc_type
                logger.exception(
                    f"Exception caught modifying datetime with {myfile}",
                    exc_info=True)
                pass
            try:
                logger.debug(
                    f"Attempting to modify EXIF datetime_original for {myfile}"
                )
                logger.debug(
                    f"Before my_image.datetime_original: {my_image.datetime_original}"
                )
                my_image.datetime_original = f"{date_now.year}:{date_now.month}:{date_now.day} {date_now.hour}:{date_now.minute}:{date_now.second}"
                logger.debug(
                    f"After my_image.datetime_original: {my_image.datetime_original}"
                )
            except (AttributeError, KeyError) as err:
                exc_type, value, traceback = sys.exc_info()
                local_exceptions[myfile] = exc_type
                logger.exception(
                    f"Exception caught modifying datetime_original with {myfile}",
                    exc_info=True)
                pass
            try:
                logger.debug(
                    f"Attempting to modify EXIF datetime_digitized for {myfile}"
                )
                logger.debug(
                    f"Before my_image.datetime_digitized: {my_image.datetime_digitized}"
                )
                my_image.datetime_digitized = f"{date_now.year}:{date_now.month}:{date_now.day} {date_now.hour}:{date_now.minute}:{date_now.second}"
                logger.debug(
                    f"After my_image.datetime_digitized: {my_image.datetime_digitized}"
                )
            except (AttributeError, KeyError) as err:
                exc_type, value, traceback = sys.exc_info()
                local_exceptions[myfile] = exc_type
                logger.exception(
                    f"Exception caught modifying datetime_digitized with {myfile}",
                    exc_info=True)
                pass
            try:
                logger.debug(
                    f"Attempting to modify EXIF gps_datestamp for {myfile}")
                logger.debug(
                    f"Before my_image.gps_datestamp: {my_image.gps_datestamp}")
                my_image.gps_datestamp = f"{date_now.year}:{date_now.month}:{date_now.day}"
                logger.debug(
                    f"After my_image.gps_datestamp: {my_image.gps_datestamp}")
            except (AttributeError, KeyError) as err:
                exc_type, value, traceback = sys.exc_info()
                local_exceptions[myfile] = exc_type
                logger.exception(
                    f"Exception caught modifying gps_datestamp with {myfile}",
                    exc_info=True)
                pass
            with open(myfile, "wb") as new_image_file:
                new_image_file.write(my_image.get_file())
    if dryrun == True:
        print(f"DRYRUN: Would have removed EXIF date data on {myfile}")
    logger.debug(f"Iteration exceptions: {local_exceptions}")
    return local_exceptions
def processFile(args):
    argob, path = args
    path = Path(path)
    file_info = {
        "creation": None,
        "file_prefix": "",
        "file_suffix": "",
        "file_content_type": "",
        "old_conflict": "",
        "dtpattern_in_path": False,
        "conflict_count": 0,
        "cleaned_file_name": ""
    }
    creation = None
    image_exif = None
    image_exif_date_error = False
    lower_suffix = path.suffix.lower()
    if lower_suffix in img_suffixes:
        file_info["file_content_type"] = "IMG"
        try:
            with path.open(mode='rb') as f:
                image_exif = Image(f)
        except Exception as exc:
            logger.debug("Exception while reading exif: %s" % exc)
        if not image_exif or not image_exif.has_exif:
            logger.debug("image has no exif data/is not compatible: %s", path)
            image_exif = None
        elif hasattr(image_exif, "datetime"):
            try:
                creation = \
                    dt.strptime(image_exif.datetime, "%Y:%m:%d %H:%M:%S")
            except ValueError:
                logger.warning("Invalid format: %s", image_exif.datetime)
                image_exif_date_error = True
        elif hasattr(image_exif, "datetime_original"):
            try:
                creation = \
                    dt.strptime(
                        image_exif.datetime_original, "%Y:%m:%d %H:%M:%S"
                    )
            except ValueError:
                logger.warning("Invalid format: %s",
                               image_exif.datetime_original)
                image_exif_date_error = True
    elif lower_suffix in mov_suffixes:
        file_info["file_content_type"] = "MOV"
    else:
        if not argob.prune:
            logger.info("unrecognized file: %s", path)
        elif argob.dry_run:
            logger.info("Would remove: %s (unrecognized)", path)
        else:
            path.unlink()
        return 1
    if argob.conflict == "ignore":
        file_info["cleaned_file_name"] = path.stem
    else:
        # find conflict counter and hash
        conflictmatch = extract_conflict_pattern.match(path.stem).groupdict()
        file_info["cleaned_file_name"] = conflictmatch["unrelated"]
        if conflictmatch["conflict_hash"]:
            if argob.conflict == "hash":
                # if hash is found, one conflict is indicated
                file_info["conflict_count"] = 1
            else:
                file_info["cleaned_file_name"] = "%s-%s" % (
                    file_info["cleaned_file_name"],
                    conflictmatch["conflict_hash"])
        # if hash and counter: conflict_count = counter + 1
        # if counter: conflict_count  = counter
        # if hash: conflict_count  = 1
        file_info["conflict_count"] += \
            int(conflictmatch["conflict_counter"] or 0)
    # check and potential extract datetime info from filename
    dtnamematch = extraction_pattern.match(file_info["cleaned_file_name"])
    if dtnamematch:
        dtnamematchg = dtnamematch.groupdict()
        file_info["file_prefix"] = dtnamematchg["prefix"] or ""
        file_info["file_suffix"] = dtnamematchg["suffix"] or ""

        file_info["dtpattern_in_path"] = True

        if not creation:
            logger.debug("extract time from path: %s", path)
            creation = dt(year=int(dtnamematchg["year"]),
                          month=int(dtnamematchg["month"]),
                          day=int(dtnamematchg["day"]),
                          hour=int(dtnamematchg["hour"] or 0),
                          minute=int(dtnamematchg["minute"] or 0),
                          second=int(dtnamematchg["second"] or 0))
    # still no creation time
    if not creation:
        logger.debug("extract time from st_ctime: %s", path)
        creation = dt.fromtimestamp(path.stat().st_ctime)
    file_info["creation"] = creation

    if image_exif_date_error:
        file_info["old_file_hash"] = generate_hash(path)
        if argob.dry_run:
            logger.info("Would fix: %s to %s, of %s", image_exif.datetime,
                        creation.strftime("%Y:%m:%d %H:%M:%S"), path)
        else:
            image_exif.datetime = creation.strftime("%Y:%m:%d %H:%M:%S")
            image_exif.datetime_original = image_exif.datetime
            with path.open(mode='wb') as f:
                f.write(image_exif.get_file())

    file_info["file_hash"] = generate_hash(path)
    if rename_file(argob, path, file_info):
        return 1
    return 0
                                          args.crop_left:width -
                                          args.crop_right]
                        cv2.imwrite("tmp.jpg", image)
                        e_image = Image("tmp.jpg")
                        e_image.gps_latitude = lat2
                        e_image.gps_latitude_ref = latref
                        e_image.gps_longitude = lon2
                        e_image.gps_longitude_ref = lonref
                        e_image.gps_img_direction = new_bear
                        e_image.gps_dest_bearing = new_bear
                        e_image.make = make
                        e_image.model = model
                        datetime_taken = datetime.fromtimestamp(new_ts +
                                                                args.timezone *
                                                                3600)
                        e_image.datetime_original = datetime_taken.strftime(
                            DATETIME_STR_FORMAT)

                        with open(
                                folder + os.path.sep + input_ts_file.split(
                                    os.path.sep)[-1].replace(".ts", "_") +
                                "_" + "%06d" % count + ".jpg",
                                'wb') as new_image_file:
                            new_image_file.write(e_image.get_file())
                        #print('Frame: ', framecount)
                        count += 1
                else:
                    if errormessage == 0:
                        print(
                            "No valid GPS for frame %d, this frame and others will be skipped."
                            % framecount)
                        errormessage = 1