Source code for pynion.filesystem._filetypes.basefile

import os
import json
import pathlib

from ...          import Manager
from ...metaclass import Multiton
from ...errors.fe import FileOpenError                 as FOE
from ...errors.fe import FileWrongRequestedActionError as FWR

m = Manager()


[docs]class BaseFile(object): """ The **BaseFile** :py:class:`pynion.Multiton` is a file management object created directly through the py:class:`pynion.File` factory. It specifically manages regular files. Allows the with statement in read files. """ __metaclass__ = Multiton _IDENTIFIER = 'file_name' def __init__(self, file_name, action): self.fname = pathlib.Path(file_name) self.action = action self._fd = None self._pattern = None ############## # ATTRIBUTES # ############## @property def full(self): """ :return: Full path of the file :rtype: str """ try: return str(self.fname.resolve()) except: return os.path.abspath(str(self.fname)) @property def dir(self): """ :return: Full path containing directory :rtype: str """ return str(self.fname.resolve().parent) @property def last_dir(self): """ :return: Name of the containing directory :rtype: str """ return str(self.fname.resolve().parent.name) @property def name(self): """ :return: Name of the file :rtype: str """ return str(self.fname.name) @property def prefix(self): """ :return: Name of the file without extension :rtype: str """ return str(self.fname.stem) @property def first_prefix(self): """ :return: Name of the first section of the file :rtype: str """ return self.name.split('.')[0] @property def extension(self): """ :return: Name of the file's extension :rtype: str """ return str(self.fname.suffix) @property def extensions(self): """ :return: List of all the sections of the file name except the first one. :rtype: list """ return self.fname.suffixes @property def descriptor(self): """ :return: Descriptor of the stored file :rtype: str """ return self._fd @property def size(self): """ :return: File size :rtype: str """ return self.fname.stat().st_size @property def pattern(self): """ :return: Dictionary with the pattern assigned sections of the file name. :rtype: dict """ if self._pattern is None: return None pattern = {} for p in self._pattern: pattern[p] = self.__dict__[p] return pattern ############ # BOOLEANS # ############ @property def is_open(self): """ :return: Check if the file descriptor is open :rtype: bool """ return self._fd is not None @property def is_to_write(self): """ :return: Check if the file is set to write :rtype: bool """ return self.action in set(['w', 'a']) @property def is_to_read(self): """ :return: Check if the file is set to read :rtype: bool """ return self.action in set(['r']) ########### # METHODS # ###########
[docs] def relative_to(self, path = pathlib.Path.cwd()): """ :param str path: Path to which the relative path is required. :return: Actual path relative to the query path :rtype: str """ return self.fname.relative_to(path)
#################### # METHODS: ON FILE # ####################
[docs] def open(self): """ Open the file in the previously defined action type. :rtype: self """ if self.is_open: return self self._fd = open(self.full, self.action) return self
[docs] def read(self): """ :raise: :py:class:`pynion.errors.fe.FileWrongRequestedActionError` if opened in write mode. :rtype: File Descriptor """ self._check_action('r') return self._fd
[docs] def readline(self): """ :raise: :py:class:`pynion.errors.fe.FileWrongRequestedActionError` if opened in write mode. :return: One line of the file. :rtype: str """ self._check_action('r') return self._fd.readline()
[docs] def readJSON(self, encoding = 'utf-8'): """ Retrieve all data in file as a JSON dictionary. :param str encoding: Encoding read format (default: utf-8) :raise: :py:class:`pynion.errors.fe.FileWrongRequestedActionError` if opened in write mode. :rtype: dict """ d = [] self.open() for l in self.read(): d.append(l.strip()) return json.loads(''.join(d), encoding=encoding)
[docs] def write(self, line, encoding = None): """ Write to the file :param str line: Content to write :param str encoding: Encoding format (use utf-8, for example, if needs to print greek characters) :raise: :py:class:`pynion.errors.fe.FileWrongRequestedActionError` if opened in read mode. """ self._check_action('w') if encoding is None: self._fd.write(line) else: self._fd.write(line.encode(encoding))
[docs] def flush(self): """ :raise: :py:class:`pynion.errors.fe.FileWrongRequestedActionError` if opened in read mode. """ self._check_action('w') self._fd.flush()
[docs] def close(self): """ Close the file. """ self._fd.close() self._fd = None
################### # PRIVATE METHODS # ################### def _check_action(self, call_method): if not self.is_open: raise FOE(self.full, self.action) if call_method == 'r' and self.is_to_write: raise FWR(self.full, self.action) elif call_method == 'w' and self.is_to_read: raise FWR(self.full, self.action) def __enter__(self): self.open() return self.read() def __exit__(self, type, value, traceback): self.close() ################# # MAGIC METHODS # ################# def __str__(self): return self.full def __repr__(self): return '<{0}: {1.full}>'.format(self.__class__.__name__, self)