123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- # -*- coding: utf-8 -*-
-
- # Server agnostic file operation similar to local files
- # Currently supported - local, ftp, http
-
- import os, sys, re
- import urllib2, ftplib
-
- def parse_url(url):
- #logger.info("Url: %s" % url)
- url = url.strip()
- import re
- m = re.search(r"^(?P<protocol>\w+)://(?:(?P<domain>[^;]+);)?(?:(?P<user>[^:@]+)[:|@])?(?:(?P<password>[^@]+)@)?(?P<host>[^/^:]+)?(?::(?P<port>[^/]+))?(?P<path>[/]?.*?)$", url, re.DOTALL | re.MULTILINE)
- if m:
- res = m.groupdict()
- else:
- res = {"domain": None, "host": None, "password": None, "path": url, "port": None, "protocol": "file", "user": None}
- return res
-
-
- class FileObject(object):
-
- def __init__(self, url, mode="r", encoding=""):
- self.url = url
- self.mode = mode
- self.encoding = encoding
- self.file = None
- p = parse_url(url)
- self.p = p
- if p["protocol"] == "file":
- self.file = __builtins__["open"](p["path"], mode)
- elif p["protocol"] == "ftp":
- import ftplib, urllib2
- if "w" in mode or "a" in mode:
- self.file = ftplib.FTP(p["host"], p["user"], p["password"])
- elif "r" in mode:
- self.file = urllib2.urlopen(url)
- elif p["protocol"] in ["http", "https"]:
- self.file = urllib2.urlopen(url)
- else:
- raise Exception("Not valid protocol")
- self.first = True
-
- def read(self, bytes=None):
- if self.p["protocol"] == "file":
- return self.file.read(bytes)
- elif self.p["protocol"] == "ftp":
- return self.file.read(bytes)
- elif self.p["protocol"] in ("http", "https"):
- return self.file.read(bytes)
-
- def write(self, data, bytes=None):
- if self.p["protocol"] == "file":
- return self.file.write(data)
- elif self.p["protocol"] == "ftp":
- from StringIO import StringIO
- if "w" in self.mode and self.first:
- cmd = "STOR "
- elif "a" in self.mode or "w" in self.mode:
- cmd = "APPE "
- else:
- raise Exception("Can not write in r mode")
- if "b" in self.mode:
- self.file.storbinary(cmd + self.p["path"], StringIO(data))
- else:
- self.file.storlines(cmd + self.p["path"], StringIO(data))
- self.first = False
- elif self.p["protocol"] in ("http", "https"):
- raise Exception("Write not allowed for http")
- else:
- raise Exception("Not valid protocol")
-
- def close(self):
- if self.p["protocol"] == "file":
- self.file.close()
- elif self.p["protocol"] == "ftp":
- if "w" in self.mode or "a" in self.mode:
- self.file.close()
- elif self.p["protocol"] in ("http", "https"):
- pass
- else:
- raise Exception("Not valid protocol")
-
- def open(url, mode="r", encoding=""):
- return FileObject(url, mode, encoding)
-
- def exists(url):
- p = parse_url(url)
- if p["protocol"] == "file":
- if isinstance(url, str):
- url = url.decode("utf8")
- return os.path.exists(url)
- elif p["protocol"] in ("ftp", "http", "https"):
- try:
- f = urllib2.urlopen(url)
- del f
- return True
- except:
- return False
- else:
- raise Exception("Not valid protocol")
-
- def isdir(url):
- p = parse_url(url)
- if p["protocol"] == "file":
- if isinstance(url, str):
- url = url.decode("utf8")
- return os.path.isdir(url)
- elif p["protocol"] in ("ftp"):
- file = ftplib.FTP(p["host"], p["user"], p["password"])
- cmd = "MLSD "+p["path"]
- lines = []
- file.retrbinary(cmd, lines.append)
- file.close()
- return False if lines and "No such file or directory" in lines[0] else True
- else:
- raise Exception("Not valid protocol")
-
- def mkdir(url):
- p = parse_url(url)
- if p["protocol"] == "file":
- os.mkdir(url)
- elif p["protocol"] in ("ftp"):
- file = ftplib.FTP(p["host"], p["user"], p["password"])
- file.mkd(p["path"])
- file.close()
- else:
- raise Exception("Not valid protocol")
-
- def rmdir(url):
- p = parse_url(url)
- if p["protocol"] == "file":
- os.rmdir(url)
- elif p["protocol"] in ("ftp"):
- file = ftplib.FTP(p["host"], p["user"], p["password"])
- file.rmd(p["path"])
- file.close()
- else:
- raise Exception("Not valid protocol")
-
- def remove(url):
- p = parse_url(url)
- if p["protocol"] == "file":
- os.remove(url)
- elif p["protocol"] in ("ftp"):
- file = ftplib.FTP(p["host"], p["user"], p["password"])
- file.delete(p["path"])
- file.close()
- else:
- raise Exception("Not valid protocol")
-
- def rename(url, url2):
- p = parse_url(url)
- p2 = parse_url(url2)
- if p["protocol"] == "file":
- os.rename(url, url2)
- elif p["protocol"] in ("ftp"):
- file = ftplib.FTP(p["host"], p["user"], p["password"])
- file.rename(p["path"], p2["path"])
- file.close()
- else:
- raise Exception("Not valid protocol")
-
- def listdir(url):
- p = parse_url(url)
- if p["protocol"] == "file":
- return os.listdir(url)
- elif p["protocol"] in ("ftp"):
- cmd = "MLSD "+p["path"]
- file = ftplib.FTP(p["host"], p["user"], p["password"])
- lines = []
- file.retrlines(cmd, lines.append)
- file.close()
- return lines
- else:
- raise Exception("Not valid protocol")
-
- def join(*arg):
- n = len(arg)
- if n == 0:
- return ""
- elif n == 1:
- return arg[0]
- p = parse_url(arg[0])
- sep = os.path.sep if p["protocol"] == "file" else "/"
- if "/" in arg[0]:
- sep = "/"
- elif "\\" in arg[0]:
- sep = "\\"
- path = arg[0]
- for i in xrange(1, n):
- if arg[i-1][-1] == sep:
- path = path + arg[i]
- else:
- path = path + sep + arg[i]
- return path
-
- def encoding(url):
- p = parse_url(url)
- if p["protocol"] == "file":
- enc = sys.getfilesystemencoding()
- #enc = "utf8" # TODO
- else:
- enc = "utf8"
- return enc
-
- def make_fname(name):
- #"\[.+?\]" "[/\n\r\t,:]"
- name = re.sub(r"[/\n\r\t,:/\\]", " ", name)
- name = re.sub("['""\?\*<>]","", name)
- name = re.sub(r"(\[[^\[]*\])", "", name)
- name = name.replace(""","")
- name = name.strip()
- return name
-
-
- def encode(url):
- p = parse_url(url)
- if p["protocol"] == "file": # unicode
- if not isinstance(url, unicode):
- url = url.decode("utf8")
- else:
- if isinstance(url, unicode):
- url = url.encode("utf8")
- return url
-
- if __name__ == "__main__":
- res = join("aaa", "bbb")
- #url = "smb://user:xxxx@192.168.77.197/hdd/test"
- url = "ftp://user:xxxx@home.blue.lv:21/hdd/test"
- url = "ftp://user:xxxx@192.168.77.197:21/hdd/test"
-
- mkdir("ftp://user:xxxx@192.168.77.197:21/hdd/movie/AAA")
- res = listdir("ftp://user:xxxx@home.blue.lv/hdd/movie/")
- print res
- rmdir("ftp://user:xxxx@192.168.77.197:21/hdd/movie/AAA")
- rename("ftp://user:xxxx@192.168.77.197:21/hdd/test", "ftp://user:xxxx@192.168.77.197:21/hdd/test2")
- remove("ftp://user:xxxx@192.168.77.197:21/hdd/test2")
- e = isdir("ftp://user:xxxx@192.168.77.197:21/hdd/movies/TV2")
- print e
-
- f = open(url, "wb")
- f.write("6.rinda\n")
- f.write("7.rinda\n")
- f.close()
- f = open(url, "rb")
- res = f.read()
- print res
- f.close()
- e = exists(url)
- print e
- e = exists(url+"2")
- print e
-
-
|