##// END OF EJS Templates
Walter's ipipe patch #8:...
vivainio -
Show More
@@ -157,6 +157,8 b' try:'
157 157 except ImportError:
158 158 curses = None
159 159
160 import path
161
160 162
161 163 __all__ = [
162 164 "ifile", "ils", "iglob", "iwalk", "ipwdentry", "ipwd", "igrpentry", "igrp",
@@ -342,7 +344,10 b' def _getattr(obj, name, default=_default):'
342 344 if name is None:
343 345 return obj
344 346 elif isinstance(name, basestring):
345 return getattr(obj, name, default)
347 if name.endswith("()"):
348 return getattr(obj, name[:-2], default)()
349 else:
350 return getattr(obj, name, default)
346 351 elif callable(name):
347 352 try:
348 353 return name(obj)
@@ -429,10 +434,12 b' style_default = Style(COLOR_WHITE, COLOR_BLACK)'
429 434 style_type_none = Style(COLOR_MAGENTA, COLOR_BLACK)
430 435 style_type_bool = Style(COLOR_MAGENTA, COLOR_BLACK)
431 436 style_type_number = Style(COLOR_YELLOW, COLOR_BLACK)
432 style_type_datetime = Style(COLOR_CYAN, COLOR_BLACK)
437 style_type_datetime = Style(COLOR_MAGENTA, COLOR_BLACK)
433 438
434 # Style for URLs and filenames
439 # Style for URLs and file/directory names
435 440 style_url = Style(COLOR_GREEN, COLOR_BLACK)
441 style_dir = Style(COLOR_CYAN, COLOR_BLACK)
442 style_file = Style(COLOR_GREEN, COLOR_BLACK)
436 443
437 444 # Style for ellipsis (when an output has been shortened
438 445 style_ellisis = Style(COLOR_RED, COLOR_BLACK)
@@ -659,69 +666,119 b' class ichain(Pipe):'
659 666 (self.__class__.__module__, self.__class__.__name__, args)
660 667
661 668
662 class ifile(object):
669 class ifile(path.path):
663 670 """
664 671 file (or directory) object.
665 672 """
666 __slots__ = ("name", "_abspath", "_realpath", "_stat", "_lstat")
667
668 def __init__(self, name):
669 if isinstance(name, ifile): # copying files
670 self.name = name.name
671 self._abspath = name._abspath
672 self._realpath = name._realpath
673 self._stat = name._stat
674 self._lstat = name._lstat
675 else:
676 self.name = os.path.normpath(name)
677 self._abspath = None
678 self._realpath = None
679 self._stat = None
680 self._lstat = None
681 673
682 def __repr__(self):
683 return "%s.%s(%r)" % \
684 (self.__class__.__module__, self.__class__.__name__, self.name)
674 def __add_(self, other):
675 return ifile(path._base(self) + other)
685 676
686 def open(self, mode="rb", buffer=None):
687 if buffer is None:
688 return open(self.abspath, mode)
689 else:
690 return open(self.abspath, mode, buffer)
691
692 def remove(self):
693 os.remove(self.abspath)
694
695 def getabspath(self):
696 if self._abspath is None:
697 self._abspath = os.path.abspath(self.name)
698 return self._abspath
699 abspath = property(getabspath, None, None, "Path to file")
700
701 def getrealpath(self):
702 if self._realpath is None:
703 self._realpath = os.path.realpath(self.name)
704 return self._realpath
705 realpath = property(getrealpath, None, None, "Path with links resolved")
706
707 def getbasename(self):
708 return os.path.basename(self.abspath)
709 basename = property(getbasename, None, None, "File name without directory")
710
711 def getstat(self):
712 if self._stat is None:
713 self._stat = os.stat(self.abspath)
714 return self._stat
715 stat = property(getstat, None, None, "os.stat() result")
716
717 def getlstat(self):
718 if self._lstat is None:
719 self._lstat = os.lstat(self.abspath)
720 return self._lstat
721 lstat = property(getlstat, None, None, "os.lstat() result")
677 def __radd_(self, other):
678 return ifile(other + path._base(self))
679
680 def __div_(self, other):
681 return ifile(path.__div__(self, other))
682
683 def getcwd():
684 """ Return the current working directory as a path object. """
685 return ifile(path.path.getcwd())
686 getcwd = staticmethod(getcwd)
687
688 def abspath(self):
689 return ifile(path.path.abspath(self))
690
691 def normcase(self):
692 return ifile(path.path.normcase(self))
693
694 def normpath(self):
695 return ifile(path.path.normpath(self))
696
697 def realpath(self):
698 return ifile(path.path.realpath(self))
699
700 def expanduser(self):
701 return ifile(path.path.expanduser(self))
702
703 def expandvars(self):
704 return ifile(path.path.expandvars(self))
705
706 def dirname(self):
707 return ifile(path.path.dirname(self))
708
709 parent = property(dirname, None, None, path.path.parent.__doc__)
710
711 def splitpath(self):
712 (parent, child) = path.path.splitpath(self)
713 return (ifile(parent), child)
714
715 def splitdrive(self):
716 (drive, rel) = path.path.splitdrive(self)
717 return (ifile(drive), rel)
718
719 def splitext(self):
720 (filename, ext) = path.path.splitext(self)
721 return (ifile(filename), ext)
722
723 if hasattr(path.path, "splitunc"):
724 def splitunc(self):
725 (unc, rest) = path.path.splitunc(self)
726 return (ifile(unc), rest)
727
728 def _get_uncshare(self):
729 unc, r = os.path.splitunc(self)
730 return ifile(unc)
731
732 uncshare = property(
733 _get_uncshare, None, None,
734 """ The UNC mount point for this path.
735 This is empty for paths on local drives. """)
736
737 def joinpath(self, *args):
738 return ifile(path.path.joinpath(self, *args))
739
740 def splitall(self):
741 return map(ifile, path.path.splitall(self))
742
743 def relpath(self):
744 return ifile(path.path.relpath(self))
745
746 def relpathto(self, dest):
747 return ifile(path.path.relpathto(self, dest))
748
749 def listdir(self, pattern=None):
750 return [ifile(child) for child in path.path.listdir(self, pattern)]
751
752 def dirs(self, pattern=None):
753 return [ifile(child) for child in path.path.dirs(self, pattern)]
754
755 def files(self, pattern=None):
756 return [ifile(child) for child in path.path.files(self, pattern)]
757
758 def walk(self, pattern=None):
759 for child in path.path.walk(self, pattern):
760 yield ifile(child)
761
762 def walkdirs(self, pattern=None):
763 for child in path.path.walkdirs(self, pattern):
764 yield ifile(child)
765
766 def walkfiles(self, pattern=None):
767 for child in path.path.walkfiles(self, pattern):
768 yield ifile(child)
769
770 def glob(self, pattern):
771 return map(ifile, path.path.glob(self, pattern))
772
773 if hasattr(os, 'readlink'):
774 def readlink(self):
775 return ifile(path.path.readlink(self))
776
777 def readlinkabs(self):
778 return ifile(path.path.readlinkabs(self))
722 779
723 780 def getmode(self):
724 return self.stat.st_mode
781 return self.stat().st_mode
725 782 mode = property(getmode, None, None, "Access mode")
726 783
727 784 def gettype(self):
@@ -734,7 +791,7 b' class ifile(object):'
734 791 (stat.S_ISLNK, "symlink"),
735 792 (stat.S_ISSOCK,"socket"),
736 793 ]
737 lstat = self.lstat
794 lstat = self.lstat()
738 795 if lstat is not None:
739 796 types = set([text for (func, text) in data if func(lstat.st_mode)])
740 797 else:
@@ -742,9 +799,9 b' class ifile(object):'
742 799 m = self.mode
743 800 types.update([text for (func, text) in data if func(m)])
744 801 return ", ".join(types)
745 type = property(gettype, None, None, "file type")
802 type = property(gettype, None, None, "file type (file, directory, link, etc.)")
746 803
747 def getaccess(self):
804 def getmodestr(self):
748 805 m = self.mode
749 806 data = [
750 807 (stat.S_IRUSR, "-r"),
@@ -759,164 +816,130 b' class ifile(object):'
759 816 ]
760 817 return "".join([text[bool(m&bit)] for (bit, text) in data])
761 818
762 access = property(getaccess, None, None, "Access mode as string")
763
764 def getsize(self):
765 return int(self.stat.st_size)
766 size = property(getsize, None, None, "File size in bytes")
819 modestr = property(getmodestr, None, None, "Access mode as string")
767 820
768 821 def getblocks(self):
769 return self.stat.st_blocks
822 return self.stat().st_blocks
770 823 blocks = property(getblocks, None, None, "File size in blocks")
771 824
772 825 def getblksize(self):
773 return self.stat.st_blksize
826 return self.stat().st_blksize
774 827 blksize = property(getblksize, None, None, "Filesystem block size")
775 828
776 829 def getdev(self):
777 return self.stat.st_dev
830 return self.stat().st_dev
778 831 dev = property(getdev)
779 832
780 833 def getnlink(self):
781 return self.stat.st_nlink
834 return self.stat().st_nlink
782 835 nlink = property(getnlink, None, None, "Number of links")
783 836
784 837 def getuid(self):
785 return self.stat.st_uid
838 return self.stat().st_uid
786 839 uid = property(getuid, None, None, "User id of file owner")
787 840
788 841 def getgid(self):
789 return self.stat.st_gid
842 return self.stat().st_gid
790 843 gid = property(getgid, None, None, "Group id of file owner")
791 844
792 845 def getowner(self):
846 stat = self.stat()
793 847 try:
794 return pwd.getpwuid(self.stat.st_uid).pw_name
848 return pwd.getpwuid(stat.st_uid).pw_name
795 849 except KeyError:
796 return self.stat.st_uid
850 return stat.st_uid
797 851 owner = property(getowner, None, None, "Owner name (or id)")
798 852
799 853 def getgroup(self):
854 stat = self.stat()
800 855 try:
801 return grp.getgrgid(self.stat.st_gid).gr_name
856 return grp.getgrgid(stat.st_gid).gr_name
802 857 except KeyError:
803 return self.stat.st_gid
858 return stat.st_gid
804 859 group = property(getgroup, None, None, "Group name (or id)")
805 860
806 def getatime(self):
807 return self.stat.st_atime
808 atime = property(getatime, None, None, "Access date")
809
810 861 def getadate(self):
811 862 return datetime.datetime.utcfromtimestamp(self.atime)
812 863 adate = property(getadate, None, None, "Access date")
813 864
814 def getctime(self):
815 return self.stat.st_ctime
816 ctime = property(getctime, None, None, "Creation date")
817
818 865 def getcdate(self):
819 866 return datetime.datetime.utcfromtimestamp(self.ctime)
820 867 cdate = property(getcdate, None, None, "Creation date")
821 868
822 def getmtime(self):
823 return self.stat.st_mtime
824 mtime = property(getmtime, None, None, "Modification date")
825
826 869 def getmdate(self):
827 870 return datetime.datetime.utcfromtimestamp(self.mtime)
828 871 mdate = property(getmdate, None, None, "Modification date")
829 872
830 873 def getmimetype(self):
831 return mimetypes.guess_type(self.basename)[0]
874 return mimetypes.guess_type(self.basename())[0]
832 875 mimetype = property(getmimetype, None, None, "MIME type")
833 876
834 877 def getencoding(self):
835 return mimetypes.guess_type(self.basename)[1]
878 return mimetypes.guess_type(self.basename())[1]
836 879 encoding = property(getencoding, None, None, "Compression")
837 880
838 def getisdir(self):
839 return os.path.isdir(self.abspath)
840 isdir = property(getisdir, None, None, "Is this a directory?")
841
842 def getislink(self):
843 return os.path.islink(self.abspath)
844 islink = property(getislink, None, None, "Is this a link?")
845
846 def __eq__(self, other):
847 return self.abspath == other.abspath
881 def __repr__(self):
882 return "ifile(%s)" % path._base.__repr__(self)
848 883
849 def __neq__(self, other):
850 return self.abspath != other.abspath
884 defaultattrs = (None, "type", "size", "modestr", "owner", "group", "mdate")
851 885
852 886 def __xattrs__(self, mode):
853 887 if mode == "detail":
854 888 return (
855 "name", "basename", "abspath", "realpath",
856 "mode", "type", "access", "stat", "lstat",
889 "name", "basename()", "abspath()", "realpath()",
890 "type", "mode", "modestr", "stat()", "lstat()",
857 891 "uid", "gid", "owner", "group", "dev", "nlink",
858 892 "ctime", "mtime", "atime", "cdate", "mdate", "adate",
859 "size", "blocks", "blksize", "isdir", "islink",
893 "size", "blocks", "blksize", "isdir()", "islink()",
860 894 "mimetype", "encoding"
861 895 )
862 return ("name", "type", "size", "access", "owner", "group", "mdate")
896 return self.defaultattrs
863 897
864 898 def __xrepr__(self, mode):
865 899 yield (-1, True)
866 if mode in "header" or mode == "footer" or mode == "cell":
900 try:
901 if self.isdir():
902 name = "idir"
903 style = style_dir
904 else:
905 name = "ifile"
906 style = style_file
907 except IOError:
867 908 name = "ifile"
868 try:
869 if self.isdir:
870 name = "idir"
871 except IOError:
872 pass
873 yield (style_url, "%s(%r)" % (name, self.abspath))
874 elif mode == "cell":
875 yield (style_url, repr(self.abspath)[1:-1])
909 style = style_default
910 if mode == "cell" or mode in "header" or mode == "footer":
911 abspath = repr(path._base(self.abspath()))
912 if abspath.startswith("u"):
913 abspath = abspath[2:-1]
914 else:
915 abspath = abspath[1:-1]
916 if mode == "cell":
917 yield (style, abspath)
918 else:
919 yield (style, "%s(%s)" % (name, abspath))
876 920 else:
877 yield (style_url, repr(self))
921 yield (style, repr(self))
878 922
879 923 def __xiter__(self, mode):
880 if self.isdir:
881 abspath = self.abspath
882 if abspath != os.path.abspath(os.path.join(abspath, os.pardir)):
883 yield iparentdir(abspath)
884 for name in sorted(os.listdir(abspath), key=lambda n: n.lower()):
885 if self.name != os.curdir:
886 name = os.path.join(abspath, name)
887 yield ifile(name)
924 if self.isdir():
925 yield iparentdir(self / os.pardir)
926 for child in sorted(self.listdir()):
927 yield child
888 928 else:
889 929 f = self.open("rb")
890 930 for line in f:
891 931 yield line
892 932 f.close()
893 933
894 def __repr__(self):
895 return "%s.%s(%r)" % \
896 (self.__class__.__module__, self.__class__.__name__, self.abspath)
897
898 934
899 935 class iparentdir(ifile):
900 def __init__(self, base):
901 self._base = base
902 self.name = os.pardir
903 self._abspath = None
904 self._realpath = None
905 self._stat = None
906 self._lstat = None
907
908 def getabspath(self):
909 if self._abspath is None:
910 self._abspath = os.path.abspath(os.path.join(self._base, self.name))
911 return self._abspath
912 abspath = property(getabspath, None, None, "Path to file")
913
914 def getrealpath(self):
915 if self._realpath is None:
916 self._realpath = os.path.realpath(
917 os.path.join(self._base, self.name))
918 return self._realpath
919 realpath = property(getrealpath, None, None, "Path with links resolved")
936 def __xrepr__(self, mode):
937 yield (-1, True)
938 if mode == "cell":
939 yield (style_dir, os.pardir)
940 else:
941 for part in ifile.__xrepr__(self, mode):
942 yield part
920 943
921 944
922 945 class ils(Table):
@@ -930,13 +953,7 b' class ils(Table):'
930 953 return xiter(ifile(self.base), mode)
931 954
932 955 def __xrepr__(self, mode):
933 yield (-1, True)
934 if mode == "header" or mode == "footer" or mode == "cell":
935 yield (style_url, "idir(%r)" % (os.path.abspath(self.base)))
936 elif mode == "cell":
937 yield (style_url, repr(os.path.abspath(self.base))[1:-1])
938 else:
939 yield (style_url, repr(self))
956 return ifile(self.base).__xrepr__(mode)
940 957
941 958 def __repr__(self):
942 959 return "%s.%s(%r)" % \
@@ -1752,18 +1769,19 b' class XAttr(object):'
1752 1769
1753 1770 doc = None
1754 1771 if isinstance(name, basestring):
1755 try:
1756 meta = getattr(type(object), name)
1757 except AttributeError:
1758 pass
1772 if name.endswith("()"):
1773 doc = getattr(getattr(object, name[:-2]), "__doc__", None)
1759 1774 else:
1760 if isinstance(meta, property):
1761 self.doc = getattr(meta, "__doc__", None)
1775 try:
1776 meta = getattr(type(object), name)
1777 except AttributeError:
1778 pass
1779 else:
1780 if isinstance(meta, property):
1781 doc = getattr(meta, "__doc__", None)
1762 1782 elif callable(name):
1763 try:
1764 self.doc = name.__doc__
1765 except AttributeError:
1766 pass
1783 doc = getattr(name, "__doc__", None)
1784 self.doc = doc
1767 1785
1768 1786 def __xattrs__(self, mode):
1769 1787 return ("name", "type", "doc", "value")
General Comments 0
You need to be logged in to leave comments. Login now