Commits

Wolfgang Scherer committed 18d076d

adhoc.py: file mode and modification time are now restored.
Modification times are only recorded as naive datetime objects.
Therefore, the restored times will only be correct in the same timezone.

  • Participants
  • Parent commits 45ddc05

Comments (0)

Files changed (2)

 adhoc.py --template doc/adhoc-logo.svg            # !doc/adhoc-logo.svg            adhoc_unpack
 adhoc.py --template doc/conf.py                   # !doc/conf.py                   adhoc_unpack
 adhoc.py --template doc/make.bat                  # !doc/make.bat                  adhoc_unpack
+adhoc.py --template doc/z-massage-index.sh        # !doc/z-massage-index.sh        adhoc_unpack
 adhoc.py --template setup.py                      # !setup.py                      adhoc_unpack
 ================================================= ================================ ================
 
 __adhoc_extract__/doc/conf.py
 __adhoc_extract__/doc/index.rst
 __adhoc_extract__/doc/make.bat
+__adhoc_extract__/doc/z-massage-index.sh
 __adhoc_extract__/docutils.conf
 __adhoc_extract__/setup.py
 __adhoc_extract__/use_case_000_.py
 __adhoc_explode__/doc/conf.py
 __adhoc_explode__/doc/index.rst
 __adhoc_explode__/doc/make.bat
+__adhoc_explode__/doc/z-massage-index.sh
 __adhoc_explode__/docutils.conf
 __adhoc_explode__/namespace_dict.py
 __adhoc_explode__/rt_adhoc.py
 __adhoc_explode__/use_case_005_nested_.py
 >>> shutil.rmtree('__adhoc_explode__')
 
+File Permissions
+================
+
+- File mode is restored.
+- File ownership is not restored.
+- File modification times are restored.
+
+  Since only naive datetimes are recorded, this only works correctly
+  within the same timezone.
+
 
 
 .. :ide: COMPILE: render reST as HTML
 adhoc.py --template doc/adhoc-logo.svg            # !doc/adhoc-logo.svg            adhoc_unpack
 adhoc.py --template doc/conf.py                   # !doc/conf.py                   adhoc_unpack
 adhoc.py --template doc/make.bat                  # !doc/make.bat                  adhoc_unpack
+adhoc.py --template doc/z-massage-index.sh        # !doc/z-massage-index.sh        adhoc_unpack
 adhoc.py --template setup.py                      # !setup.py                      adhoc_unpack
 ================================================= ================================ ================
 
 __adhoc_extract__/doc/conf.py
 __adhoc_extract__/doc/index.rst
 __adhoc_extract__/doc/make.bat
+__adhoc_extract__/doc/z-massage-index.sh
 __adhoc_extract__/docutils.conf
 __adhoc_extract__/setup.py
 __adhoc_extract__/use_case_000_.py
 __adhoc_explode__/doc/conf.py
 __adhoc_explode__/doc/index.rst
 __adhoc_explode__/doc/make.bat
+__adhoc_explode__/doc/z-massage-index.sh
 __adhoc_explode__/docutils.conf
 __adhoc_explode__/namespace_dict.py
 __adhoc_explode__/rt_adhoc.py
 __adhoc_explode__/use_case_005_nested_.py
 >>> shutil.rmtree('__adhoc_explode__')
 
+File Permissions
+================
+
+- File mode is restored.
+- File ownership is not restored.
+- File modification times are restored.
+
+  Since only naive datetimes are recorded, this only works correctly
+  within the same timezone.
+
 .. @:adhoc_index_only:@
 
 AdHoc Module
         return source
 
     @classmethod
-    def write_source(cls, file_, source):                    # |:clm:|
+    def write_source(cls, file_, source, mtime=None, mode=None): # |:clm:|
         # @:adhoc_run_time_section:@ off
         '''Write source to file.
 
             sf = open(file_, 'wb')
             sf.write(esource)
             sf.close()
+            if mode is not None:
+                os.chmod(file_, mode)
+            if mtime is not None:
+                import datetime
+                if cls.isstring(mtime):
+                    try:
+                        date, ms = mtime.split('.')
+                    except ValueError:
+                        date = mtime
+                        ms = 0
+                    mtime = cls.strptime(date, '%Y-%m-%dT%H:%M:%S')
+                    mtime += datetime.timedelta(microseconds=int(ms))
+                if isinstance(mtime, datetime.datetime):
+                    # @:adhoc_run_time_section:@ off
+                    # import calendar
+                    # if mtime.utcoffset() is not None:
+                    #     mtime = mtime - mtime.utcoffset()
+                    # millis = int(calendar.timegm(mtime.timetuple()) * 1000 +
+                    #                mtime.microsecond / 1000)
+                    # ts = float(millis) / 1000
+                    # @:adhoc_run_time_section:@ on
+                    ts = int(mtime.strftime("%s"))
+                else:
+                    ts = mtime
+                os.utime(file_, (ts, ts))
 
     @classmethod
-    def check_xfile(cls, file_, xdir=None, mtime=None):      # |:clm:|
+    def check_xfile(cls, file_, xdir=None):                  # |:clm:|
         # @:adhoc_run_time_section:@ off
         '''Prepare extraction of a file.
 
     # @:adhoc_run_time_section:@ on
     @classmethod
     def unpack_(cls, mod_name=None, file_=None, mtime=None, # |:clm:||:api_fi:|
-                 zipped=True, flat=None, source64=None):
+                mode=None, zipped=True, flat=None, source64=None):
         # @:adhoc_run_time_section:@ off
         """Unpack adhoc'ed file, if it does not exist."""
         # @:adhoc_run_time_section:@ on
             list(map(sys.stderr.write,
                      ("# xf: ", cls.__name__, ": unpacking `", file_, "`\n")))
         source = cls.unpack_file(source64, zipped=zipped, decode=False)
-        cls.write_source(xfile, source)
+        cls.write_source(xfile, source, mtime, mode)
 
     @classmethod
     def strptime(cls, date_string, format_):                 # |:clm:|
 
     @classmethod
     def import_(cls, mod_name=None, file_=None, mtime=None, # |:clm:||:api_fi:|
-                zipped=True, flat=None, source64=None, mode=int("666" ,8)):
+                mode=None, zipped=True, flat=None, source64=None):
         # @:adhoc_run_time_section:@ off
         """Import adhoc'ed module."""
         # @:adhoc_run_time_section:@ on
 
     @classmethod
     def module_setup(cls, module=None, file_=None, mtime=None, # |:clm:||:api_fi:|
-                     source=None, mode=int("666", 8)):
+                     source=None, mode=None):
         # @:adhoc_run_time_section:@ off
         '''Setup module for `AdHoc`.
         \\|:todo:| various modes are possible:
     # @:adhoc_run_time_section:@ on
     @classmethod
     def export__(cls, mod_name=None, file_=None, mtime=None, # |:clm:||:api_fi:|
-                zipped=True, flat=None, source64=None):
+                 mode=None, zipped=True, flat=None, source64=None):
         source = cls.unpack_file(source64, zipped=zipped, decode=False)
         # @:adhoc_run_time_section:@ off
         if cls.debug:
             cls.export_have_init[module_dir] = True
         module_file = os.path.join(module_dir, file_base)
 
-        cls.export_(source, module_file, flat)
+        cls.export_(source, module_file, mtime, mode, flat)
 
     @classmethod
-    def export_(cls, source, file_, flat=None):              # |:clm:|
+    def export_(cls, source, file_, mtime, mode, flat=None): # |:clm:|
         cflat = cls.flat
         if flat is None:
             flat = cflat
 
             xfile = cls.check_xfile(file_, cls.export_dir)
             if xfile is not None:
-                cls.write_source(xfile, source)
+                cls.write_source(xfile, source, mtime, mode)
                 if cls.verbose:
                     list(map(sys.stderr.write,
                              ("# xp: ", cls.__name__, ".export_ for `", file_,
         else:
             xfile = cls.check_xfile(file_, cls.export_dir)
             if xfile is not None:
-                cls.write_source(xfile, source)
+                cls.write_source(xfile, source, mtime, mode)
                 if cls.verbose:
                     list(map(sys.stderr.write,
                              ("# xp: ", cls.__name__, ".export_ for `", file_,
             list(map(sys.stderr.write,
                      ("# xp: ", cls.__name__, ".export for `", file_, "`\n")))
         # @:adhoc_run_time_section:@ on
-        cls.export_(source, file_, False)
+        cls.export_(source, file_, None, None, False)
         sv_extract_dir = cls.extract_dir
         cls.extract_dir = cls.export_dir
         engine_tag = cls.section_tag('adhoc_run_time_engine')
     # @:adhoc_run_time_section:@ on
     @classmethod
     def dump__(cls, mod_name=None, file_=None, mtime=None, # |:clm:||:api_fi:|
-               zipped=True, flat=None, source64=None):
+               mode=None, zipped=True, flat=None, source64=None):
         if cls.verbose:
             list(map(sys.stderr.write,
                      ("# xf: ", cls.__name__, ": dumping `", file_, "`\n")))
         "{mod},"
         " file_={fnm},\n{ina}"
         " mtime={mtm},"
+        " mode={fmd},\n{ina}"
         " zipped={zip},"
         " flat={flt},"
         " source64=\n"
         @:adhoc_include... Makefile
         # @:adhoc_unpack...
         RtAdHoc.unpack_(None, file_='Makefile',
-            mtime='...', zipped=True, flat=None, source64=
+            mtime='...', mode=...,
+            zipped=True, flat=None, source64=
         ...
         # @:adhoc_unpack...
         text
                                 ('mtm', (((mtime is not None)
                                           and repr(mtime.isoformat()))
                                          or repr(mtime))),
-                                ('fmd', mode),
+                                ('fmd', (mode is not None and sformat('int("{0:o}", 8)', mode)) or mode),
                                 ('zip', zipped),
                                 ('flt', flat),
                                 ('src', output.rstrip()),
             ('mtm', (((mtime is not None)
                       and repr(mtime.isoformat()))
                      or repr(mtime))),
-            ('fmd', mode),
+            ('fmd', (mode is not None and sformat('int("{0:o}", 8)', mode)) or mode),
             ('zip', zipped),
             ('src', output.rstrip()),
             ('flt', flat),
 
     # @:adhoc_include:@ Makefile, MANIFEST.in, README.css, setup.py
 
-    # @:adhoc_include:@ doc/conf.py, doc/make.bat, doc/Makefile, doc/adhoc-logo.svg, doc/_static/adhoc-logo-32.ico
+    # @:adhoc_include:@ doc/conf.py, doc/make.bat, doc/Makefile, doc/z-massage-index.sh, doc/adhoc-logo.svg, doc/_static/adhoc-logo-32.ico
 
     # |:here:|