Sort by date after migration to Icloud

Hi, i’m trying to migrate to Obsidian from Simplenote.
My archive have 5000+ notes, i normally sort them by last modified date.
The problem is i want them synced with iOS, and the only way i saw that not involves paying for Obsidian Sync is using ICloud.
Unfortunately, when uploading notes to it, icloud arrogantly updates all files creation and modified date to current time.

Following this
https://www.reddit.com/r/ObsidianMD/comments/10o22q5/comment/jj70s77/?utm_source=share&utm_medium=web2x&context=3
i figured a way to store “Last creations date” and “last modifed date” in YAML Frontmatter fields, only when you create new note.
Even if i manage a way to update all the notes with those values (eventually in AAAA-MM-DD format) included the original “last modified date”, then upload all the archive to icloud that disrupts the files metadata (pure tyranny) i still can’t find a way to order obsidian notes by one of those YAML fields!
Is there some sort of plugin for that?
Another solution wuould be, after icloud upload, reupdate metadata dates in some way, but is it possible? Doesn’t update of “Last modified date” makes the icloud say it is updated than reupdate said date?

Thanks

This isn’t just icloud being arrogant. Many cross-platform file operations can break that metadata.

Yes, editing the creation and modified metadata is possible. On MacOS and Linux, you have the “touch” command. But you would likely need to write a script to automate that. Or read through these discussions to see if someone wrote something that can help you:

(Also check the threads that are linked to those threads. There are several. There may also be plugins that sort by YAML fields.)

Ok, thank you for your reply.
Idk about the legitimacy about the icloud stuff, btw i happily found out with a Windows 10 software that if i change the last modify and creation date of a file in iCloud it syncs it with this new date. So now all i need is:

  1. a script that updates all notes with YAMLs Creation and last modify date from metadata.
  2. a script that updates all files metadata from those YAMLs fields .

Unfortunately i don’t know much about script programming and can’t find much on the forum. Any help would be appreciated.

Up!!!

Here we are, I’m back with the solution, found out by myself not knowing a single thing of Phyton coding. Turns out Chatgpt will make someone unemployed in the end.
How i made it:

  • Had a folder of .txt notes with thier own Windows filesystem timestamp metadata.
  • installed Python from official site.
  • runned script1.py (for this Python IDLE was good enough) after putting the folder path in “cartella1” variable.
    it adds obsidian files properties
    . “Data modifica” =file system metadata date modified
    . “Data creazione” =file system metadata creation date
    formatted like YYYY-MM-DD HH:mm:ss (moment format)
    like:
---
Data modifica: 2023-08-14 14:26:26
Data creazione: 2021-01-07 00:12:09
---
<rest of text file>

and changes files extensions to .md to all .txt files in “cartella1” folder and its subfolders.

  • Moved the folder to ICloud
    icloud updates all windows metadata to today date.
  • runned program script2pt2.py after putting this new folder path in “cartella1” variable.
    this updates back all windows creation date and modified date metadata to the ones in obsidian files properties.
  • using Obsidian plugins to keep dates properties autoupdated in the same format.
  • start using Obsidian like a charm.

Bonus:
after moving the folder to icloud i had tags from Simplenote in notes formatted like this:

<note text>

Tags:
  Lavoro

runned script2pt1.py before script2pt2.py to move files with some predetermined tags inside subfolders. Look at and change:

cartellaP   = cartella1 + r'\Personale'
...
cartellaL   = cartella1 + r'\Lavoro'
...
if s.find(b'  Pers') != -1:
...
 if s.find(b'  Lavoro') != -1:

Hope to have been of some help folks!

script1.py :

# This program, adds obsidian files properties
# -"Data modifica" =file system metadata date modified
# -"Data creazione" =file system metadata creation date
# formatted like YYYY-MM-DD HH:mm:ss (moment format)
# to the .txt files in the folder with path "cartella1" and all it's subfolder
# except for '\.obsidian'
# and renames them to .md format
# examples of file between ```:
#before:
#```
#<note text>
#```
#after:
#```
#---
#Data modifica: 2023-08-14 14:26:26
#Data creazione: 2021-01-07 00:12:09
#---
#<note text>
#```
# feel free to:
#   -   change cartella1 values with the path of the main vault folder or a subfolder.
#   -   change the timestamp format from  "%Y-%m-%d %H:%M:%S" to another.
#   -   name of date properties.

import os
import time
import glob
from pathlib import Path
print('Hello, world!')
x = 0
# Cartella contenente i file
#cartella = r'C:\Users\abertini\Documents\test\inizio\**\*.*'
cartella1   = r'C:\Users\abertini\Documents\test\inizio'
cartellaOBS = cartella1 + r'\.obsidian'
cartella    = cartella1+r'\**\*.txt'

for _ in range(2):
##!!!!!!!!!!!!!!!!!!!!!! x includere file che iniziano con "." poi con :
##cartella = r'C:\Users\abertini\Documents\obsidian\Note\**\.*'
    # Lista dei file nella cartella
    ##files = os.listdir(cartella)x = 0
    ##for file in files:
    for percorso_file0 in glob.glob(cartella, recursive=True):
        #print(percorso_file0)
        ##percorso_file0 = os.path.join(cartella, file)
        file_path = Path(percorso_file0)
        
        if os.path.isfile(percorso_file0) and percorso_file0.endswith('.txt') and not(percorso_file0.startswith(cartellaOBS)):
            print('Hello, world!')
            # Make a new path with the file's extension changed
            percorso_file = file_path.with_suffix(".md")
            # Rename the file's extension to that new path. Catch errors when the file
            # is already there or is missing. Report the result if successful.
            try:
                renamed_path = file_path.rename(percorso_file)
            except FileNotFoundError:
                print(f"Error: could not find the '{file_path}' file.")
            except FileExistsError:
               print(f"Error: the '{percorso_file}' target file already exists.")
            #else:
                #print(f"Changed extension of '{file_path.name}' to '{renamed_path.name}'.")
            
            data_creazione = os.path.getctime(percorso_file)
            data_modifica = os.path.getmtime(percorso_file)

            data_creazione_formattata = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(data_creazione))
            data_modifica_formattata = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(data_modifica))
            
            with open(percorso_file, 'r+', encoding="utf8") as f:
                contenuto = f.read()
                f.seek(0, 0)
                #scrive il template per obsidian
                #f.write(f'```dynbedded\n')
                #f.write(f'[[Heading Template]]\n')
                #f.write(f'```\n')
                #scrive date 
                f.write(f'---\n')
                f.write(f'Data modifica: {data_modifica_formattata}\n')
                ###f.write(f'Data creazione: {data_creazione_formattata}\n')
                f.write(f'Data creazione: {data_modifica_formattata}\n')
                f.write(f'---\n')
                f.write(contenuto)
                x += 1
    cartella    = cartella1+r'\**\.*'

print (x)

script2pt1.py FACULTATIVE

# This program moves files based on tag strings listed down.
import os
# import datetime
import calendar
import glob
import mmap
import shutil
from datetime import datetime
from ctypes import windll, wintypes, byref
# Cartella contenente i file
# cartella = r'C:\Users\abertini\iCloudDrive\testnote'
#cartella1   = r'C:\Users\abertini\Documents\test'
cartella1   = r'C:\Users\abertini\iCloudDrive\iCloud~md~obsidian\Note'
#cartella1   = r'C:\Users\abertini\Documents\test\fine'
cartellaOBS = cartella1 + r'\.obsidian'
cartellaP   = cartella1 + r'\Personale'
cartellaL   = cartella1 + r'\Lavoro'
cartellaD   = cartella1 + r'\Dati'
cartellaS   = cartella1 + r'\Studio'
cartellaC   = cartella1 + r'\Chan'
cartella    = cartella1+r'\**\*.md'
##!!!!!!!!!!!!!!!!!!!!!! x includere file che iniziano con "." poi con :
##cartella    = cartella1+r'\**\.*'
x = 0
for _ in range(2):
    # Lista dei file nella cartella
    ##files = os.listdir(cartella)

    print('Hello, world! inizio ciclo')

    #Primo ciclo che sposta i file:
    for percorso_file in glob.glob(cartella, recursive=True):
        #print(percorso_file)
        ##percorso_file = os.path.join(cartella, file)
        ##file_path = Path(percorso_file)
        if os.path.isfile(percorso_file) and percorso_file.endswith('.md') and not(percorso_file.startswith(r'C:\Users\abertini\Documents\test\.obsidian')):
            with open(percorso_file, 'r', encoding="utf8") as f:
                #filename
                file_name = os.path.basename(percorso_file)
                #creates a bytearray object that checks the underlying file instead of reading the whole file in memory.
                s = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)

                if s.find(b'  Pers') != -1:
                    s.close()
                    f.close()
                    ##print('tag Pers exist in a file')
                    carte_finale=os.path.join(cartellaP, file_name)
                    shutil.move(percorso_file, carte_finale)
                else:
                    if s.find(b'  Lavoro') != -1:
                        s.close()
                        f.close()
                        ##print('tag Lavoro exist in a file')
                        carte_finale=os.path.join(cartellaL, file_name)
                        shutil.move(percorso_file, carte_finale)
                    else:
                        if s.find(b'  Dati') != -1:
                            s.close()
                            f.close()
                            ##print('tag Dati exist in a file')
                            carte_finale=os.path.join(cartellaD, file_name)
                            shutil.move(percorso_file, carte_finale)
                        else:
                            if s.find(b'  Studio') != -1:
                                s.close()
                                f.close()
                                ##print('tag Studio exist in a file')
                                arte_finale=os.path.join(cartellaS, file_name)
                                shutil.move(percorso_file, carte_finale)
                            else:
                                if s.find(b'  chan') != -1:
                                    s.close()
                                    f.close()
                                    ##print('tag chan exist in a file')
                                    carte_finale=os.path.join(cartellaC, file_name)
                                    shutil.move(percorso_file, carte_finale)
                                else:
                                    s.close()
                                    f.close()

script2pt2.py

# This program updates modifed and creation date in windows system of .md files in folder "cartella1".
# and its subfolders based on Obsidian properties "Data modifica" (modify) and "Data creazione" (creation)
# formatted like YYYY-MM-DD HH:mm:ss (moment format).
# Those two properties must be the first two of the file or they wont' be read. Thier order is ininfluent.
# No problem if one or both are missing.
# It excluedes to elaborate subfolder \.obsidian.
# Examples of file between ```:
#ex1)
#```
#---
#Data creazione: 2019-12-14 14:26:26
#Data modifica: 2021-10-07 00:12:09
#---
#<note text>
#```
#
#ex2)
#```
#---
#Data modifica: 2021-10-07 00:12:09
#Data creazione: 2019-12-14 14:26:26
#---
#<note text>
#```
#
#ex3)
#```
#<note text>
#```
#
#ex4)
#```
#---
#Data modifica: 2021-10-07 00:12:09
#---
#<note text>
#```
#
# feel free to:
#   -   change cartella1 values with the path of the main vault folder or a subfolder.
#   -   change the timestamp format from  "%Y-%m-%d %H:%M:%S" to another.
#   -   name of date properties.
import os
# import datetime
import calendar
import glob
#import mmap
#import shutil
from datetime import datetime
from ctypes import windll, wintypes, byref
# Cartella contenente i file
#cartella1   = r'E:\User\Documents\obsidiantest\old'
cartella1   = r'C:\Users\andre\iCloudDrive\iCloud~md~obsidian\Note'
cartellaOBS = cartella1 + r'\.obsidian'
cartella    = cartella1+r'\**\*.md'
#counter
x = 0
#cycles counter
ccount=0
print(f"Start cycle 1")
# !!!! two cycles to includere files that start with "." , at the second cycle
for _ in range(2):
    # Lista dei file nella cartella
    ##files = os.listdir(cartella)



#ciclo che aggiorna le date:

    ##for file in files:
    for percorso_file in glob.glob(cartella, recursive=True):
        #print(percorso_file)
        if os.path.isfile(percorso_file) and percorso_file.endswith('.md') and not(percorso_file.startswith(cartellaOBS)):
            with open(percorso_file, 'r', encoding="utf8") as f:
                errmodi=0
                errcrea=0
                #filename
                file_name = os.path.basename(percorso_file)
                lines = f.readlines()
                try:
                    data_modifica = lines[1].strip().split('Data modifica: ')[1]
                except IndexError as e:
                    try:
                        data_modifica = lines[2].strip().split('Data modifica: ')[1]
                    except IndexError as e:
                        print(f"can't find modified date of "+file_name)
                        errmodi=1
                try:
                    data_creazione = lines[2].strip().split('Data creazione: ')[1]
                except IndexError as e:
                    try:
                        data_creazione = lines[1].strip().split('Data creazione: ')[1]
                    except IndexError as e:
                        print(f"can't find modified creation date of "+file_name)
                        errcrea=1

                if errmodi==0:
                    #print(data_creazione)
                    data_m= datetime.strptime(data_modifica, "%Y-%m-%d %H:%M:%S")
                    # Ottieni la rappresentazione in secondi dalla "epoch"
                    timestampM = data_m.timestamp()
                    # scrive data modifica
                    os.utime(percorso_file, (timestampM - 1.0 , timestampM))
                if errcrea==0:
                    #print(data_creazione)
                    data_c= datetime.strptime(data_creazione, "%Y-%m-%d %H:%M:%S")
                    # Ottieni la rappresentazione in secondi dalla "epoch"
                    timestampC = data_c.timestamp()
                    #EPOCH timestamp:
                    time_C_E = calendar.timegm(data_c.timetuple())
                    # Convert Unix timestamp to Windows FileTime using some magic numbers
                    # See documentation: https://support.microsoft.com/en-us/help/167296
                    timestamp = int((time_C_E * 10000000) + 116444736000000000)
                    ctime = wintypes.FILETIME(timestamp & 0xFFFFFFFF, timestamp >> 32)

                    # Call Win32 API to modify the file creation date
                    handle = windll.kernel32.CreateFileW(percorso_file, 256, 0, None, 3, 128, None)
                    windll.kernel32.SetFileTime(handle, byref(ctime), None, None)
                    windll.kernel32.CloseHandle(handle)
            
            x += 1
    if ccount==0:
        print(f"Start cycle 2")
        ccount=ccount+1
    cartella    = cartella1+r'\**\.*'
print (f"Files elaborated: "+ str(x))

I must add that you can run script2pt2.py everytime you tink metadata file timestamps needs to be reupdated from obsidian properties like i already did. At least backup first.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.