Skip to content

Commit

Permalink
add change permission
Browse files Browse the repository at this point in the history
  • Loading branch information
Thiago Brito committed Mar 20, 2020
1 parent 8e82cda commit ff7f33d
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 34 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,20 @@ print(file.permission.onwer.is_writable)
print(file.permission.onwer.is_readable)
-> True
file.permission.change_permission('owner', 'execute')
-> grants or revokes execution permission to the owner of the file
file.permission.change_permission('group', 'read')
-> grants or revokes read permission to the file group
file.permission.change_permission('others', 'write')
-> grants or revokes write permission to others
```

### content:

### cogrant or revoke permission for read to the file's groupntent:
```
for line in file.content.read_only():
print(line)
Expand Down
135 changes: 104 additions & 31 deletions pyfiles/file.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,38 @@
import os
import stat
import subprocess
from pathlib import Path
from dataclasses import dataclass
from enum import Enum

class File:
from .mixins import FileInfoMixin


class File(FileInfoMixin):
def __init__(self, filepath: str):
self.path = Path(filepath)
if not self.path.exists():
raise FileNotFoundError(f"{filepath} doesn't exists")
if not self.path.is_file():
raise TypeError(f"{filepath} doesn't a file")
self.info = os.stat(filepath)
self._size = self.info.st_size
self._mode = stat.filemode(self.info.st_mode)
self._inode = self.info.st_ino
self.permission = FilePermission(self)
self.content = FileContent(self.path)

@property
def size(self):
return self._size

@property
def mode(self):
return self._mode
def octal_format(self):
return (
self.permission.owner.octal_notation(),
self.permission.group.octal_notation(),
self.permission.others.octal_notation(),
)

@property
def inode(self):
return self._inode
def octal_format_to_string(self):
return (
str(self.permission.owner.octal_notation()),
str(self.permission.group.octal_notation()),
str(self.permission.others.octal_notation())
)

def change_at(self):
return self.info.st_ctime

def modify_at(self):
return self.info.st_mtime

def access_at(self):
return self.info.st_atime


class FileContent:
def __init__(self, path: str):
Expand All @@ -52,30 +47,108 @@ def read_only(self):
for line in file.readlines():
yield line


class FilePermission:
def __init__(self, file: File):
self.file = file
self.owner = _Permission(*file.mode[1:4])
self.group = _Permission(*file.mode[4:7])
self.others = _Permission(*file.mode[7:])

def mode(self):
return f'-{self.owner}{self.group}{self.others}'

def change_permission(self, where_change: str, which_permission: str):
'''
where_change: owner, group, others
which_permission: read, write, execute
'''
perm = getattr(self, where_change)
rwx = getattr(perm, which_permission)
if rwx == '-':
if which_permission == 'read':
setattr(perm, which_permission, 'r' )
elif which_permission == 'write':
setattr(perm, which_permission, 'w' )
elif which_permission == 'execute':
setattr(perm, which_permission, 'x' )
else:
setattr(perm, which_permission, '-' )

output = subprocess.run(['chmod', ''.join(self.file.octal_format_to_string()), self.file.path], capture_output=True)
if output.stderr:
print({'error': str(output.stderr)})
raise RuntimeError(f'Not possible to change file permissions')



class _Permission:
def __init__(self, read: str, write: str, execute: str):
self.read = read
self.write = write
self.execute = execute
self._read = read
self._write = write
self._execute = execute

def __repr__(self):
return f'{self.read}{self.write}{self.execute}'

@property
def read(self) -> str:
return self._read

@read.setter
def read(self, new_permission) -> None:
self._read = new_permission

@property
def write(self) -> str:
return self._write

@write.setter
def write(self, new_permission) -> None:
self._write = new_permission

@property
def execute(self) -> str:
return self._execute

@execute.setter
def execute(self, new_permission) -> None:
self._execute = new_permission

def is_executable(self) -> bool:
return True if self.execute == "x" else False
return True if self.execute == 'x' else False

def is_writable(self) -> bool:
return True if self.write == "w" else False
return True if self.write == 'w' else False

def is_readable(self) -> bool:
return True if self.read == "r" else False

return True if self.read == 'r' else False

def octal_notation(self):
octal_sum = 0
if self.is_readable():
octal_sum += 4
if self.is_writable():
octal_sum += 2
if self.is_executable():
octal_sum += 1
return octal_sum


class OctalEnum(Enum):
READ = 4
WRITE = 2
EXECUTE = 1


class PermissionEnum(Enum):
EXECUTE_ONLY = '--x'
WRITE_ONLY = '-w-'
READ_ONLY = 'r--'
READ_WRITE = 'rw-'
READ_EXECUTE = 'r-x'
WRITE_EXECUTE = '-wx'
FULL_PERMISSION = 'rwx'
NO_PERMISSION = '---'


@dataclass
Expand Down
44 changes: 44 additions & 0 deletions pyfiles/mixins.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import os
import stat

class FileInfoMixin:

@property
def size(self):
return os.stat(self.path).st_size

@property
def inode(self):
return os.stat(self.path).st_ino

@property
def mode(self):
return stat.filemode(os.stat(self.path).st_mode)

@property
def change_at(self):
return os.stat(self.path).st_ctime

@property
def modify_at(self):
return os.stat(self.path).st_mtime

@property
def access_at(self):
return os.stat(self.path).st_atime

@property
def uid(self):
return os.stat(self.path).st_uid

@property
def gid(self):
return os.stat(self.path).st_gid

@property
def dev(self):
return os.stat(self.path).st_dev

@property
def links(self):
return os.stat(self.path).st_nlink
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
setup(
name='pyfiles',
packages = ['pyfiles'],
version='0.1.0',
version='0.2.0',
license='MIT',
description='manage for files with python',
description='management for files with python',
author='TBA',
keywords=['files', 'management'],
url='https://github.com/tba91/pyfiles',
Expand Down

0 comments on commit ff7f33d

Please sign in to comment.