Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/ruff-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Lint with Ruff

on:
push:
branches: [ "main", "master", "second-branch" ] # запуск при пуше в main/master
pull_request:
branches: [ "main", "master", "second-branch" ] # запуск при создании PR в main/master

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # клонирует репозиторий

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"

- name: Install Ruff
run: pip install ruff

- name: Run Ruff linting
run: ruff check . # проверяет весь репозиторий
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ dmypy.json
# Cython debug symbols
cython_debug/

my_db.json
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
Expand Down
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/fastapi-backend-course.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/material_theme_project_new.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 10 additions & 5 deletions git/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def load_books(filename='library.json'):
except json.JSONDecodeError:
return []

def save_books(books, filename='library.json'):
def saving_books(books, filename='library.json'):
"""
Сохранение списка книг в JSON-файл.
"""
Expand Down Expand Up @@ -94,17 +94,17 @@ def main():
# Получаем новый список с добавленной книгой
new_books = add_book(books, title, author, year)
books = new_books # Обновляем переменную, чтобы сохранить изменения
save_books(books) # Сразу сохраняем в файл
saving_books(books) # Сразу сохраняем в файл
print("Книга добавлена!")

elif choice == '3':
print("\nУдаление книги:")
title_to_remove = input("Введите название книги, которую хотите удалить: ").strip()

new_books = remove_book(books, title_to_remove)
if len(new_books) < len(books):
if len(new_books) > len(books):
books = new_books
save_books(books)
saving_books(books)
print("Книга удалена!")
else:
print("Книга с таким названием не найдена.")
Expand All @@ -126,5 +126,10 @@ def main():
else:
print("Некорректный ввод. Попробуйте ещё раз.")






if __name__ == "__main__":
main()
main()
211 changes: 211 additions & 0 deletions simple_backend/src/task_tracker/db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
from typing import List, Dict, Any, Optional, Union

from abc import ABCMeta, abstractmethod, abstractproperty

import os
import json
import functools

import requests


def id_to_str(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
if 'id' in kwargs:
kwargs['id'] = str(kwargs['id'])
return func(*args, **kwargs)
elif len(kwargs) > 1:
new_args = (args[0], str(args[1])) + args[2:]
return func(*new_args, **kwargs)
else:
return func(*args, **kwargs)
return wrapper

class absDB():
@abstractmethod
def get_all(self) -> List[Dict[str, Any]]:
pass

@abstractmethod
def get(self, id) -> Dict[str, Any] | None:
pass

@abstractmethod
def add(self, id, data) -> bool:
pass

@abstractmethod
def delete(self, id) -> bool:
pass

@abstractmethod
def update(self, id, data) -> bool:
pass

class ListDB(absDB):
def init(self) -> None:
self.tasks: Dict[int, Dict[str, Any]] = {}

def get_all(self) -> List[Dict[str, Any]]:
return list(self.tasks.values())

def get(self, id) -> Dict[str, Any] | None:
return self.tasks[id]

def add(self, id, data) -> bool:
if str(id) in data:
return False
self.tasks[id] = data
return True

def delete(self, id) -> bool:
if id in self.tasks:
del self.tasks[id]
return True
return False

def update(self, id, data):
if id in self.tasks:
self.tasks[id].update(data)
return True
return False

class FileDB(absDB):
def __init__(self) -> None:
self.__name_file = 'my_db.json'
print('File', self.__name_file)


def get_all(self) -> List[Dict[str, Any]]:
data = self.__read_json()
return list(data.values())

@id_to_str
def get(self, id) -> Dict[str, Any] | None:
data_from_file = self.__read_json()
if id in data_from_file:
return data_from_file[id]
return None

@id_to_str
def add(self, id, data) -> bool:
data_from_file = self.__read_json()
if id in data_from_file:
return False
data_from_file[id] = data
self.__save_json(data_from_file)
return True

@id_to_str
def delete(self, id) -> bool:
data_from_file = self.__read_json()
if id in data_from_file:
del data_from_file[id]
self.__save_json(data_from_file)
return True
return False

@id_to_str
def update(self, id, data):
data_from_file = self.__read_json()
if id in data_from_file:
data_from_file[id] = data
self.__save_json(data_from_file)
return True
return False

def __save_json(self, data):
with open(self.__name_file, 'w' '') as file:
json.dump(data, file, ensure_ascii=False, indent=4)
return True

def __read_json(self):
print('File', self.__name_file)
try:
with open(self.__name_file, 'r' '') as file:
print('File', file)
try:
data = json.load(file)
except json.JSONDecodeError :
print(12313)
self.__save_json({})
data = {}
except FileNotFoundError:
self.__save_json({})
data = {}

return data

class CloudDB(absDB):
def __init__(self) -> None:
self.key_api = '$2a$10$gkEEHNtdmq7FCAUiGF88k.IDmciahKhZmVL7ZBfbANA6US9nsQsu6'
key_bin = '68b1c53ed0ea881f406a555a'
root = 'https://api.jsonbin.io/v3'
self.url = f"{root}/b/{key_bin}"

def get_all(self) -> List[Dict[str, Any]]:
return list(self.__get_json().values())

@id_to_str
def get(self, id) -> Dict[str, Any] | None:
old_data = self.__get_json()
if id in old_data:
return old_data[id]
return None

@id_to_str
def add(self, id, data) -> bool:
old_data = self.__get_json()
if id in old_data:
return False
old_data[id] = data
self.__post_json(old_data)
return True

@id_to_str
def delete(self, id) -> bool:
data = self.__get_json()
if id in data:
del data[id]
self.__post_json(data)
return True
return False

@id_to_str
def update(self, id, data) -> bool:
all_data = self.__get_json()
if str(id) in all_data:
all_data[str(id)] = data
self.__post_json(all_data)
return True
return False


def __get_json(self):
headers = {
'X-Master-Key': self.key_api,
'X-Bin-Meta': 'false',
}

req = requests.get(self.url, headers=headers)

if req.status_code != 200:
raise Exception("API Error")
return req.json()

def __post_json(self, data):
new_data = json.dumps(data)

headers = {
'X-Master-Key': self.key_api,
'Content-Type': 'application/json',
}

req = requests.put(self.url ,data=new_data, headers=headers)

if req.status_code != 200:
raise Exception("API Error")
return True

list_db = FileDB()
Loading