{"id":447,"date":"2008-03-08T09:55:29","date_gmt":"2008-03-08T13:55:29","guid":{"rendered":"http:\/\/www.dr-chuck.com\/wordpress\/?p=447"},"modified":"2011-12-17T12:25:49","modified_gmt":"2011-12-17T16:25:49","slug":"restoring-lost-modification-datetime-on-my-macintosh-using-python","status":"publish","type":"post","link":"https:\/\/www.dr-chuck.com\/csev-blog\/2008\/03\/restoring-lost-modification-datetime-on-my-macintosh-using-python\/","title":{"rendered":"Restoring lost Modification Date\/Time on My Macintosh Using Python"},"content":{"rendered":"<p>\nIf you are an  avid Dr. Chuck Blog reader &#8211; you recall on November 9, 2007 when I upgraded to Leopard for the second time and lost my modification dates on my files.  I was too lazy to re-do the upgrade so I was left with a bunch of files with November 9, 2007 modification dates making ls -l look yucky.<\/p>\n<p>\nhttp:\/\/www.dr-chuck.com\/csev-blog\/000139.html<\/p>\n<p>\nI made a mistake of not reading my own earlier blog entry telling me how to properly backup and restore my home directory over a Mac OS upgrade.<\/p>\n<p>\nhttp:\/\/www.dr-chuck.com\/csev-blog\/000381.html<\/p>\n<p>\nApparently I am not such an avid reader of the Dr. Chuck Blog.<\/p>\n<p>\nWell today I rectified the situation and have my files dating back to 2004 and earlier &#8211; I don&#8217;t have a bunch of files tantalizingly telling me &#8220;November 9, 2007&#8221; &#8211; teasing me and telling me that the actual date was much earlier.  I also figured I should do some Python coding this week to get up on my game as I go to Pycon 08 in Chicago next week &#8211; and hang out with none other than Steven Githens- the official badge maker of Pycon 2008!<\/p>\n<p>\nI had saved that backup from November  2007 and vowed to write some code that would scan my current home directory and look for files with suspect modification dates (right around November 9, 2007) and grab the modification dates form the backup and patch my current home directory.<\/p>\n<p>\nThen and only then would I be willing to &#8220;let that backup file go&#8221;.  It was keeping me from reformatting a nice 320GB USB drive that I had orther uses for&#8230;<\/p>\n<p>\nSo I wrote some Python &#8211; below that uses the nice Python os.walk() capability along with the os.stat() capability, and os.utime() capability.<\/p>\n<p>\nIt turned out to be surprisingly elegant and simple in Python.<\/p>\n<p>\nIt ran pretty quickly in about 5 minutes (even reading off USB) and ended up patching about 110,000 files with the right modification date in my laptop home directory.  I had a couple copies of my home directory (Mac Air, Mac Pro, and my 320GB extended home directory on USB drive) &#8211; and I patched them all.<\/p>\n<p>\nI include the code below &#8211; with the utime() call commented out &#8211; so it does a dry run until you are happy with the results and then uncomment the utime().  It nicely can be run over and over &#8211; it only patches files in the suspect date range &#8211; once the files are moved to their proper earlier time, they are no longer candidates for patching.   You can even run it live decide to freak out &#8211; press CTRL-C and start over &#8211; it will silently glide right past the already patched files.<\/p>\n<p><!--more--><\/p>\n<pre>\nimport os\nimport string\nimport datetime\n# Our bad restore happened on\n# Fri Nov 9 16:14:36 2007\nbaddate = 1194642876L\n# So we suspect things two days before and after\nbadbeg = baddate - (2 * 24 * 60 * 60)\nbadend = baddate + (2 * 24 * 60 * 60)\ndbeg = datetime.datetime.fromtimestamp(badbeg).ctime()\ndend = datetime.datetime.fromtimestamp(badend).ctime()\nprint 'Fixing any file with modification between',dbeg,'and',dend\n# currpath - the directory which needs fixing\n# backup - the directory with the backup\ncurrpath = '\/Users\/csev'\nbackup = '\/Volumes\/UserHome\/Users\/csev'\niter = os.walk(currpath)\ncount = 0\nnextprint = 0\nwhile True:\nentry = iter.next()\npwd = entry[0]\n# print entry\nif  pwd.find('\/.') &gt; 0 :\ncontinue\nfor dir in entry[1] + entry[2]:\n# print dir\nif dir[0] == '.' :\ncontinue\ncname = os.path.join(pwd,dir)\ntry:\nsv = os.stat(cname)\nexcept:\nprint \"Could not stat\",cname\ncontinue\nca = sv[7]\ncm = sv[8]\n# print cname,ca,cm\nif cm &lt; badbeg or cm &gt; badend :\ncontinue\nbname = backup + cname[len(currpath):]\ntry:\nbv = os.stat(bname)\nexcept:\nprint 'No Backup', bname\ncontinue\n# Now we have a backup file - get the times\nba = bv[7]\nbm = bv[8]\n# print '  ',bname,ba,bm\n# no need to change the times if the backup\n# is not older than current\nif bm &gt; cm:\nprint 'Backup not older than current ',bname\ncontinue\n# We already know we want the backup's mod time\ngm = bm\n# If the current access time is in the bad range\n# we take the one from the backup\nga = ca\nif ca &gt;= badbeg and ca &lt;= badend:\nga = ba\nnewmt = datetime.datetime.fromtimestamp(gm).ctime()\n# Go ahead and set the modification and access time\ntimes = (ga, gm)\n# print times\ntry:\n# os.utime(cname,times)\nprint 'Fixed',cname,times,newmt\nexcept:\nprint 'Unable to Fix',cname,times,newmt\n# Here is how we get the value for baddate\n# import os\n# oname = raw_input('Enter a file:')\n# sv = os.stat(oname)\n# oa = sv[7]\n# om = sv[8]\n# print '  ',oname,oa,om\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>If you are an avid Dr. Chuck Blog reader &#8211; you recall on November 9, 2007 when I upgraded to Leopard for the second time and lost my modification dates on my files. I was too lazy to re-do the upgrade so I was left with a bunch of files with November 9, 2007 modification [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-447","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts\/447","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/comments?post=447"}],"version-history":[{"count":1,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts\/447\/revisions"}],"predecessor-version":[{"id":2550,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts\/447\/revisions\/2550"}],"wp:attachment":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/media?parent=447"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/categories?post=447"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/tags?post=447"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}