Advertisement
Guest User

task #3 - disk

a guest
Feb 28th, 2015
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.34 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. import random
  3. import string
  4. import datetime
  5. import pymongo
  6.  
  7.  
  8. ''' UTILS '''
  9. def GetNewId():
  10.     return "".join(random.choice(string.ascii_lowercase + string.digits) for i in range(30))
  11.  
  12.  
  13. ''' CONTENT DUMMIES '''
  14. class Content:
  15.     def __init__(self, id=None):
  16.         self.id = id
  17.         self.size = 239
  18.  
  19.     def getSize(self):
  20.         return self.size
  21.  
  22.  
  23. def GetContentById(id):
  24.     return Content(id=id)
  25.  
  26.  
  27. def AddNewContent():
  28.     return Content(id=GetNewId())
  29.  
  30.  
  31. def GetNormPath(path):
  32.     if type(path) is str:
  33.         path = list(filter(lambda s: s, path.split("/")))
  34.     return path
  35.  
  36.  
  37. ''' DB '''
  38. class DBFindErr(Exception):
  39.     def __init__(self):
  40.         super().__init__(self, "Database find error")
  41.  
  42. class DB:
  43.     ''' Singleton '''
  44.     db = None
  45.    
  46.     def __new__(cls):
  47.         if not cls.db:
  48.             cls.db = super().__new__(cls)
  49.             cls.db.db = None
  50.         return cls.db
  51.  
  52.     def __init__(self):
  53.         if not self.db:
  54.             client = pymongo.MongoClient("mongodb://37.200.65.235:27017/")
  55.             self.db = client.disk
  56.  
  57.     def getDB(self):
  58.         return self.db
  59.  
  60.     def findOnce(self, tableName, filt):
  61.         f = self.getDB()[tableName].find(filt)
  62.         if f.count() != 1:
  63.             raise DBFindErr
  64.         #return list(f)[0]
  65.         return f[0]
  66.  
  67.  
  68. ''' META '''
  69. class MetaIsInvalidErr(Exception):
  70.     def __init__(self):
  71.         super().__init__("Meta is invalid")
  72.  
  73.  
  74. class MetaBase:
  75.     def __init__(self, fileType=None, name=None, parentId=None, crTime=None, id=None):
  76.         if id is None:
  77.             self.id = GetNewId()
  78.             self.name = name
  79.             self.fileType = fileType
  80.             self.parentId = parentId
  81.             self.crTime = crTime
  82.             self.data = {}
  83.         else:
  84.             self.id = id
  85.  
  86.     def getId(self):
  87.         return self.id
  88.  
  89.     def load(self):
  90.         try:
  91.             self.data = DB().findOnce("meta", {"id": self.id})
  92.         except DBFindErr:
  93.             raise MetaIsInvalidErr
  94.         self.name = self.data.get("name", None)
  95.         self.fileType = self.data.get("fileType", None)
  96.         self.parentId = self.data.get("parentId", None)
  97.         self.crTime = self.data.get("crTime", datetime.datetime.now())
  98.         return self
  99.  
  100.     def save(self):
  101.         self.data["id"] = self.id
  102.         self.data["name"] = self.name
  103.         self.data["fileType"] = self.fileType
  104.         self.data["parentId"] = self.parentId
  105.         self.data["crTime"] = self.crTime
  106.         DB().getDB().meta.update({"id": self.id}, self.data, upsert=True)
  107.         return self
  108.  
  109.     def getInfo(self):
  110.         return {
  111.             "name": self.name,
  112.             "created time": self.crTime,
  113.         }
  114.  
  115.  
  116. class RegularFile(MetaBase):
  117.     def __init__(self, contentId=None, *args, **kwargs):
  118.         super().__init__("regular", *args, **kwargs)
  119.         if contentId is None:
  120.             contentId = AddNewContent().id
  121.         self.contentId = contentId
  122.  
  123.     def load(self):
  124.         super().load()
  125.         self.contentId = self.data["contentId"]
  126.         return self
  127.  
  128.     def save(self):
  129.         self.data["contentId"] = self.contentId
  130.         super().save()
  131.         return self
  132.  
  133.     def getInfo(self):
  134.         info = super().getInfo()
  135.         info["type"] = "Regular file"
  136.         info["size"] = "{}B".format(GetContentById(self.contentId).getSize())
  137.         return info
  138.  
  139.  
  140. class Directory(MetaBase):
  141.     def __init__(self, *args, **kwargs):
  142.         super().__init__("directory", *args, **kwargs)
  143.  
  144.     def getFiles(self):
  145.         types = {
  146.             "directory": Directory,
  147.             "regular": RegularFile,
  148.         }
  149.         files = {data["name"]: types[data["fileType"]](id=data["id"]).load() for data in \
  150.                     DB().getDB().meta.find({"parentId": self.id})}
  151.         return files
  152.  
  153.     def getInfo(self):
  154.         info = super().getInfo()
  155.         info["type"] = "Directory"
  156.         return info
  157.  
  158.  
  159. ''' DISK '''
  160. class FileDoesNotExistErr(Exception):
  161.     def __init__(self):
  162.         super().__init__("File doesn't exist")
  163.  
  164.  
  165. class FileIsAlreadyExistErr(Exception):
  166.     def __init__(self):
  167.         super().__init__("File is already exist")
  168.  
  169.  
  170. class WrongPathErr(Exception):
  171.     def __init__(self):
  172.         super().__init__("Wrong path")
  173.  
  174.  
  175. class ItIsNotDirectoryPathErr(Exception):
  176.     def __init__(self):
  177.         super().__init__("It's not directory path")
  178.  
  179.  
  180. class Disk:
  181.     def __init__(self, name, root):
  182.         self.root = root
  183.         self.name = name
  184.  
  185.     def getFileByPath(self, path):
  186.         path = GetNormPath(path)
  187.         cur = self.root
  188.         for d in path:
  189.             if type(cur) is not Directory:
  190.                 raise WrongPathErr
  191.             files = cur.getFiles()
  192.             if d not in files:
  193.                 raise FileDoesNotExistErr
  194.             cur = files[d]
  195.         return cur
  196.  
  197.     def fileExists(self, path):
  198.         try:
  199.             self.getFileByPath(path)
  200.         except FileDoesNotExistErr:
  201.             return False
  202.         return True
  203.    
  204.     def addFile(self, path):
  205.         path = GetNormPath(path)
  206.         if self.fileExists(path):
  207.             raise FileIsAlreadyExistErr
  208.         try:
  209.             d = self.getFileByPath(path[:-1])
  210.         except (FileDoesNotExistErr, WrongPathErr):
  211.             raise WrongPathErr
  212.         RegularFile(parentId=d.getId(), name=path[-1],
  213.                     crTime=datetime.datetime.now()).save()
  214.        
  215.     def addDirectory(self, path):
  216.         path = GetNormPath(path)
  217.         if self.fileExists(path):
  218.             raise FileIsAlreadyExistErr
  219.         try:
  220.             d = self.getFileByPath(path[:-1])
  221.         except (FileDoesNotExistErr, WrongPathErr):
  222.             raise WrongPathErr
  223.         Directory(parentId=d.getId(), name=path[-1],
  224.                 crTime=datetime.datetime.now()).save()
  225.  
  226.     def getDirectoryFiles(self, path):
  227.         d = self.getFileByPath(path)
  228.         if type(d) is not Directory:
  229.             raise ItIsNotDirectoryPathErr
  230.         return sorted(d.getFiles().values(), key=lambda f: f.name)
  231.  
  232.     def getFileInfo(self, path):
  233.         return self.getFileByPath(path).getInfo()
  234.  
  235.  
  236. class DiskNameIsBusyErr(Exception):
  237.     def __init__(self):
  238.         super().__init__("Disk name is busy")
  239.  
  240.  
  241. class DiskDoesNotExist(Exception):
  242.     def __init__(self):
  243.         super().__init__("Disk doesn't exist")
  244.  
  245.  
  246. def CreateDisk(name):
  247.     db = DB().getDB()
  248.     if db.disks.find({"name": name}).count():
  249.         raise DiskNameIsBusyErr
  250.     root = Directory()
  251.     root.save()
  252.     disk = Disk(name, root)
  253.     db.disks.insert({
  254.         "name": name,
  255.         "root": root.getId(),
  256.     })
  257.     return disk
  258.  
  259.  
  260. def GetDisk(name):
  261.     try:
  262.         diskData = DB().findOnce("disks", {"name": name})
  263.     except DBFindErr:
  264.         raise DiskDoesNotExistErr
  265.     root = Directory(id=diskData["root"])
  266.     root.load()
  267.     return Disk(name, root)
  268.  
  269.  
  270. ''' SHELL '''
  271. def ShellMode():
  272.     diskName = "testDisk"
  273.     disk = GetDisk(diskName)
  274.     print(
  275.         "Shell mode\n"
  276.         "root is \"/\"\n"
  277.         "using disk \"{}\"\n".format(disk.name) + \
  278.         "Use commands:\n"
  279.         "\t add_file <path>\n"
  280.         "\t add_dir <path>\n"
  281.         "\t ls <path>\n"
  282.         "\t info <path>\n"
  283.         "\t exit [or quit]"
  284.     )
  285.     while True:
  286.         command = input("> ").split()
  287.         try:
  288.             if not command:
  289.                 continue
  290.             if command[0] in ["exit", "quit"]:
  291.                 break
  292.             elif command[0] == "ls":
  293.                 path = command[1]
  294.                 files = disk.getDirectoryFiles(path)
  295.                 for f in files:
  296.                     print("{}{}".format(f.name, "/" if f.fileType == "directory" else ""))
  297.             elif command[0] == "info":
  298.                 path = command[1]
  299.                 info = disk.getFileInfo(path)
  300.                 print("file {} info:".format(path))
  301.                 for attr, val in info.items():
  302.                     print("\t{}: {}".format(attr, val))
  303.             elif command[0] == "add_file":
  304.                 path = command[1]
  305.                 disk.addFile(path)
  306.             elif command[0] == "add_dir":
  307.                 path = command[1]
  308.                 disk.addDirectory(path)
  309.         except Exception as e:
  310.             print("Error: {}".format(e))
  311.  
  312.  
  313. if __name__ == "__main__":
  314.     ShellMode()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement