diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a043ce0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +db.sqlite3 +__pycache__/ \ No newline at end of file diff --git a/LibraryApi/admin.py b/LibraryApi/admin.py index 8c38f3f..638d4fb 100644 --- a/LibraryApi/admin.py +++ b/LibraryApi/admin.py @@ -1,3 +1,13 @@ from django.contrib import admin # Register your models here. +from .models import Book,Borrowing,Genre,Author,Publisher,Fine,Reservation + +admin.site.register(Book) +admin.site.register(Borrowing) +admin.site.register(Publisher) +admin.site.register(Author) +admin.site.register(Fine) +admin.site.register(Reservation) +admin.site.register(Genre) + diff --git a/LibraryApi/migrations/0001_initial.py b/LibraryApi/migrations/0001_initial.py new file mode 100644 index 0000000..023689c --- /dev/null +++ b/LibraryApi/migrations/0001_initial.py @@ -0,0 +1,147 @@ +# Generated by Django 4.2.3 on 2023-07-12 00:33 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="Author", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="Book", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=255)), + ("publication_date", models.DateField()), + ("isbn", models.CharField(max_length=20)), + ("copies", models.PositiveIntegerField()), + ("available_copies", models.PositiveIntegerField()), + ("availabity_stautus", models.BooleanField(default=True)), + ("author", models.ManyToManyField(to="LibraryApi.author")), + ], + ), + migrations.CreateModel( + name="Genre", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="Publisher", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name="Reservations", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("reservation_date", models.DateTimeField()), + ( + "book_id", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="LibraryApi.book", + ), + ), + ( + "user_id", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="Borrowings", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("borrowing_date", models.DateTimeField()), + ("due_date", models.DateTimeField()), + ("return_date", models.DateTimeField()), + ( + "book", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="LibraryApi.book", + ), + ), + ( + "borrower", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.AddField( + model_name="book", + name="genre", + field=models.ManyToManyField(to="LibraryApi.genre"), + ), + ] diff --git a/LibraryApi/migrations/0002_rename_borrowings_borrowing_and_more.py b/LibraryApi/migrations/0002_rename_borrowings_borrowing_and_more.py new file mode 100644 index 0000000..0f4d1c4 --- /dev/null +++ b/LibraryApi/migrations/0002_rename_borrowings_borrowing_and_more.py @@ -0,0 +1,54 @@ +# Generated by Django 4.2.3 on 2023-07-12 00:59 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("LibraryApi", "0001_initial"), + ] + + operations = [ + migrations.RenameModel( + old_name="Borrowings", + new_name="Borrowing", + ), + migrations.RenameModel( + old_name="Reservations", + new_name="Reservation", + ), + migrations.CreateModel( + name="Fine", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("fine_amount", models.DecimalField(decimal_places=2, max_digits=6)), + ("fine_date", models.DateTimeField()), + ("fine_paid_status", models.BooleanField(default=False)), + ( + "borrowing_id", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="LibraryApi.book", + ), + ), + ( + "user_id", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ] diff --git a/LibraryApi/migrations/0003_alter_fine_borrowing_id.py b/LibraryApi/migrations/0003_alter_fine_borrowing_id.py new file mode 100644 index 0000000..52a47d6 --- /dev/null +++ b/LibraryApi/migrations/0003_alter_fine_borrowing_id.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.2 on 2023-07-12 07:39 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("LibraryApi", "0002_rename_borrowings_borrowing_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="fine", + name="borrowing_id", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="LibraryApi.borrowing" + ), + ), + ] diff --git a/LibraryApi/migrations/0004_book_edition.py b/LibraryApi/migrations/0004_book_edition.py new file mode 100644 index 0000000..71b79f4 --- /dev/null +++ b/LibraryApi/migrations/0004_book_edition.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.2 on 2023-07-12 20:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("LibraryApi", "0003_alter_fine_borrowing_id"), + ] + + operations = [ + migrations.AddField( + model_name="book", + name="edition", + field=models.SmallIntegerField(default=1), + preserve_default=False, + ), + ] diff --git a/LibraryApi/migrations/0005_borrowing_libarian_alter_borrowing_borrower.py b/LibraryApi/migrations/0005_borrowing_libarian_alter_borrowing_borrower.py new file mode 100644 index 0000000..060e5e5 --- /dev/null +++ b/LibraryApi/migrations/0005_borrowing_libarian_alter_borrowing_borrower.py @@ -0,0 +1,35 @@ +# Generated by Django 4.2.2 on 2023-07-13 19:52 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("LibraryApi", "0004_book_edition"), + ] + + operations = [ + migrations.AddField( + model_name="borrowing", + name="libarian", + field=models.ForeignKey( + default=1, + on_delete=django.db.models.deletion.PROTECT, + related_name="libarian", + to=settings.AUTH_USER_MODEL, + ), + preserve_default=False, + ), + migrations.AlterField( + model_name="borrowing", + name="borrower", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="member", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/LibraryApi/migrations/0006_rename_availabity_stautus_book_available_and_more.py b/LibraryApi/migrations/0006_rename_availabity_stautus_book_available_and_more.py new file mode 100644 index 0000000..7892445 --- /dev/null +++ b/LibraryApi/migrations/0006_rename_availabity_stautus_book_available_and_more.py @@ -0,0 +1,25 @@ +# Generated by Django 4.2.2 on 2023-07-13 23:51 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("LibraryApi", "0005_borrowing_libarian_alter_borrowing_borrower"), + ] + + operations = [ + migrations.RenameField( + model_name="book", + old_name="availabity_stautus", + new_name="available", + ), + migrations.RemoveField( + model_name="book", + name="available_copies", + ), + migrations.RemoveField( + model_name="book", + name="copies", + ), + ] diff --git a/LibraryApi/migrations/0007_alter_borrowing_borrower.py b/LibraryApi/migrations/0007_alter_borrowing_borrower.py new file mode 100644 index 0000000..95fbf62 --- /dev/null +++ b/LibraryApi/migrations/0007_alter_borrowing_borrower.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.2 on 2023-07-14 23:26 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("LibraryApi", "0006_rename_availabity_stautus_book_available_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="borrowing", + name="borrower", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="borrower", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/LibraryApi/models.py b/LibraryApi/models.py index 71a8362..3ceb752 100644 --- a/LibraryApi/models.py +++ b/LibraryApi/models.py @@ -1,3 +1,69 @@ from django.db import models +from django.contrib.auth import get_user_model +import datetime + + # Create your models here. +class Author(models.Model): + name = models.CharField(max_length=255) + + def __str__(self): + return self.name + + +class Publisher(models.Model): + name = models.CharField(max_length=255) + + def __str__(self): + return self.name + + +class Genre(models.Model): + name = models.CharField(max_length=255) + + def __str__(self): + return self.name + + +class Book(models.Model): + author = models.ManyToManyField(Author) + title = models.CharField(max_length=255) + publication_date = models.DateField() + isbn = models.CharField(max_length=20) + edition = models.SmallIntegerField() + genre = models.ManyToManyField(Genre) + available = models.BooleanField(default=True) + + def __str__(self): + return self.title + +class Borrowing(models.Model): + borrower = models.ForeignKey(get_user_model(),on_delete=models.PROTECT,related_name="borrower") + libarian = models.ForeignKey(get_user_model(),on_delete=models.PROTECT,related_name="libarian") + book = models.ForeignKey(Book,on_delete=models.PROTECT) + borrowing_date = models.DateTimeField(auto_now=True) + due_date = models.DateTimeField(default=datetime.datetime.now()+ datetime.timedelta(days=3)) + returned = models.BooleanField(default=False) + return_date = models.DateTimeField() + + def __str__(self): + return f"{self.borrower} borrowed {self.book}" + +class Reservation(models.Model): + user_id = models.ForeignKey(get_user_model(),on_delete=models.CASCADE) + book_id = models.ForeignKey(Book,on_delete=models.PROTECT) + reservation_date = models.DateTimeField(auto_now=True) + + def __str__(self): + return f"{self.user_id} reserved {self.book}" + +class Fine(models.Model): + user_id = models.ForeignKey(get_user_model(),on_delete=models.CASCADE) + borrowing_id = models.ForeignKey(Borrowing,on_delete=models.PROTECT) + fine_amount = models.DecimalField(max_digits=6,decimal_places=2) + fine_date = models.DateTimeField(auto_now=True) + fine_paid_status = models.BooleanField(default=False) + + def __str__(self): + return f"{self.user_id} fined {self.fine_amount} for {self.borrowing_id}" diff --git a/LibraryApi/permissions.py b/LibraryApi/permissions.py new file mode 100644 index 0000000..a607097 --- /dev/null +++ b/LibraryApi/permissions.py @@ -0,0 +1,29 @@ +from rest_framework import permissions + +class IsLibarianOrReadOnly(permissions.BasePermission): + def has_object_permission(self, request, view, obj): + # Read permissions are allowed to any request, + # so we'll always allow GET, HEAD or OPTIONS requests. + if request.method in permissions.SAFE_METHODS: + return True + + if request.user.groups.filter(name="Libarian").exists(): + return True + return False + +class IsLibarian(permissions.BasePermission): + def has_permission(self,request,view): + if request.user.groups.filter(name="Libarian").exists(): + return True + return False + + def has_object_permission(self, request, view, obj): + # Read permissions are allowed to any request, + # so we'll always allow GET, HEAD or OPTIONS requests. + if request.method in permissions.SAFE_METHODS: + return True + + if request.user.groups.filter(name="Libarian").exists(): + return True + return False + diff --git a/LibraryApi/serializers.py b/LibraryApi/serializers.py new file mode 100644 index 0000000..be9a5b9 --- /dev/null +++ b/LibraryApi/serializers.py @@ -0,0 +1,105 @@ +from rest_framework import serializers +from django.contrib.auth.models import User +from .models import Book,Borrowing,Genre,Author,Publisher,Fine,Reservation + + +class UserSerializer(serializers.ModelSerializer): + username = serializers.CharField(max_length=255) + class Meta: + model = User + fields = ["username","email"] + + +class GenreSerializer(serializers.ModelSerializer): + class Meta: + model = Genre + fields = "__all__" + +class AuthorSerializer(serializers.ModelSerializer): + class Meta: + model = Author + fields = "__all__" + +class PublisherSerializer(serializers.ModelSerializer): + class Meta: + model = Publisher + fields = "__all__" + +class BookSerializer(serializers.ModelSerializer): + genre = GenreSerializer(many=True) + author = AuthorSerializer(many=True) + class Meta: + model = Book + fields = "__all__" + + def create(self, validated_data): + author_data = validated_data.pop('author') + genre_data = validated_data.pop('genre') + book = Book.objects.create(**validated_data) + + # for author in author_data: + author_obj = Author.objects.create(**author_data) + book.author.add(author_obj) + + # for genre in genre_data: + genre_obj = Genre.objects.create(**genre_data) + print(genre_obj) + book.genre.add(genre_obj) + + return book + + + +class BorrowedBookSerializer(serializers.ModelSerializer): + class Meta: + model = Book + fields = ["title","isbn","edition"] + + + +class BorrowingSerializer(serializers.ModelSerializer): + due_date = serializers.DateTimeField(read_only=True) + borrower= UserSerializer() + libarian = UserSerializer(read_only=True) + book = BorrowedBookSerializer() + + class Meta: + model = Borrowing + fields = "__all__" + + + + def create(self, validated_data): + borrower_data = validated_data.pop('borrower') + print(borrower_data) + book = validated_data.pop('book') + + # borrower = User.objects.get(**borrower_data) + book = Book.objects.get(**book) + if book.available: + user = User.objects.get(username=borrower_data['username']) + + lent_book = Borrowing.objects.create(**validated_data,book=book,borrower=user) + book.available = False + book.save() + + return lent_book + + + # def update() + + + +class ReservationSerializer(serializers.ModelSerializer): + user_id = UserSerializer() + book_id = BookSerializer() + class Meta: + model = Reservation + fields = "__all__" + +class FineSerializer(serializers.ModelSerializer): + user_id = UserSerializer() + borrowing_id = BorrowingSerializer() + class Meta: + model = Fine + fields = "__all__" \ No newline at end of file diff --git a/LibraryApi/tasks.py b/LibraryApi/tasks.py new file mode 100644 index 0000000..52d7254 --- /dev/null +++ b/LibraryApi/tasks.py @@ -0,0 +1,14 @@ +from celery import shared_task +from .models import Borrowing,Fine +from datetime import datetime + +fine = 0.2 + +@shared_task(name="fine-defaulters") +def fine_defaulters(): + defaulted = Borrowing.objects.filter(returned=False,due_date__lt=datetime.now()) + for i in defaulted: + fine = Fine.objects.get + # if defaulters. + + diff --git a/LibraryApi/urls.py b/LibraryApi/urls.py new file mode 100644 index 0000000..75660e6 --- /dev/null +++ b/LibraryApi/urls.py @@ -0,0 +1,43 @@ +from django.urls import path +from .views import ( + BookDetailView, + BookListView, + AuthorDetailView, + AuthorListView, + PublisherListView, + PublisherDetailView, + FineListView, + FineDetailView, + BorrowingDetailView, + BorrowingListView, + GenreDetailView, + GenreListView, + ReservationDetailView, + ReservationListView, + SearchBookView, + LendBook, + books_lended_by_libarian, + return_book +) + +urlpatterns = [ + path("authors/", AuthorListView.as_view(), name="authors"), + path("authors/", AuthorDetailView.as_view(), name="author-detail"), + path("publishers/", PublisherListView.as_view(), name="publishers"), + path("publishers/", PublisherDetailView.as_view(), name="publisher-detail"), + path("books/", BookListView.as_view(), name="books"), + path("books/", BookDetailView.as_view(), name="book-detail"), + path("fines/", FineListView.as_view(), name="fines"), + path("fines/", FineDetailView.as_view(), name="fine-detail"), + path("genres/", GenreListView.as_view(), name="genres"), + path("genres/", GenreDetailView.as_view(), name="genre-detail"), + path("reservations/", ReservationListView.as_view(), name="reservations"), + path("reservations/", ReservationDetailView.as_view(), name="reservation-detail"), + path("borrowings/", BorrowingListView.as_view(), name="borrowings"), + path("borrowings/", BorrowingDetailView.as_view(), name="borrowing-detail"), + path("lend-book/", LendBook.as_view(), name="lend-book"), + path("books-search",SearchBookView.as_view(),name="search-books"), + path("libarian/lended-books",books_lended_by_libarian,name="books_lended_by_libarian"), + path("borrowed-books/return-book/= '3.6'", + "version": "==5.1.1" + }, + "asgiref": { + "hashes": [ + "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", + "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed" + ], + "markers": "python_version >= '3.7'", + "version": "==3.7.2" + }, + "async-timeout": { + "hashes": [ + "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15", + "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c" + ], + "markers": "python_full_version <= '3.11.2'", + "version": "==4.0.2" + }, + "billiard": { + "hashes": [ + "sha256:0f50d6be051c6b2b75bfbc8bfd85af195c5739c281d3f5b86a5640c65563614a", + "sha256:1ad2eeae8e28053d729ba3373d34d9d6e210f6e4d8bf0a9c64f92bd053f1edf5" + ], + "markers": "python_version >= '3.7'", + "version": "==4.1.0" + }, + "celery": { + "extras": [ + "redis" + ], + "hashes": [ + "sha256:27f8f3f3b58de6e0ab4f174791383bbd7445aff0471a43e99cfd77727940753f", + "sha256:f84d1c21a1520c116c2b7d26593926581191435a03aa74b77c941b93ca1c6210" + ], + "index": "pypi", + "version": "==5.3.1" + }, + "certifi": { + "hashes": [ + "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", + "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" + ], + "markers": "python_version >= '3.6'", + "version": "==2023.5.7" + }, + "cffi": { + "hashes": [ + "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", + "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", + "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", + "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", + "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", + "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", + "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", + "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", + "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", + "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", + "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", + "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", + "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", + "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", + "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", + "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", + "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", + "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", + "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", + "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", + "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", + "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", + "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", + "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", + "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", + "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", + "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", + "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", + "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", + "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", + "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", + "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", + "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", + "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", + "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", + "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", + "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", + "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", + "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", + "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", + "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", + "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", + "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", + "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", + "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", + "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", + "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", + "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", + "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", + "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", + "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", + "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", + "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", + "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", + "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", + "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", + "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", + "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", + "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", + "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", + "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", + "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", + "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", + "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" + ], + "version": "==1.15.1" + }, + "charset-normalizer": { + "hashes": [ + "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96", + "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c", + "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710", + "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706", + "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020", + "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252", + "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad", + "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329", + "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a", + "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f", + "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6", + "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4", + "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a", + "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46", + "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2", + "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23", + "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace", + "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd", + "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982", + "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10", + "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2", + "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea", + "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09", + "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5", + "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149", + "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489", + "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9", + "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80", + "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592", + "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3", + "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6", + "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed", + "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c", + "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200", + "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a", + "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e", + "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d", + "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6", + "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623", + "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669", + "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3", + "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa", + "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9", + "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2", + "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f", + "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1", + "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4", + "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a", + "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8", + "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3", + "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029", + "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f", + "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959", + "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22", + "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7", + "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952", + "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346", + "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e", + "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d", + "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299", + "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd", + "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a", + "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3", + "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037", + "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94", + "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c", + "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858", + "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a", + "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449", + "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c", + "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918", + "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1", + "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c", + "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac", + "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.2.0" + }, + "click": { + "hashes": [ + "sha256:4be4b1af8d665c6d942909916d31a213a106800c47d0eeba73d34da3cbc11367", + "sha256:e576aa487d679441d7d30abb87e1b43d24fc53bffb8758443b1a9e1cee504548" + ], + "markers": "python_version >= '3.7'", + "version": "==8.1.5" + }, + "click-didyoumean": { + "hashes": [ + "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667", + "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035" + ], + "markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'", + "version": "==0.3.0" + }, + "click-plugins": { + "hashes": [ + "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b", + "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8" + ], + "version": "==1.1.1" + }, + "click-repl": { + "hashes": [ + "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9", + "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812" + ], + "markers": "python_version >= '3.6'", + "version": "==0.3.0" + }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "markers": "platform_system == 'Windows'", + "version": "==0.4.6" + }, + "cryptography": { + "hashes": [ + "sha256:01f1d9e537f9a15b037d5d9ee442b8c22e3ae11ce65ea1f3316a41c78756b711", + "sha256:079347de771f9282fbfe0e0236c716686950c19dee1b76240ab09ce1624d76d7", + "sha256:182be4171f9332b6741ee818ec27daff9fb00349f706629f5cbf417bd50e66fd", + "sha256:192255f539d7a89f2102d07d7375b1e0a81f7478925b3bc2e0549ebf739dae0e", + "sha256:2a034bf7d9ca894720f2ec1d8b7b5832d7e363571828037f9e0c4f18c1b58a58", + "sha256:342f3767e25876751e14f8459ad85e77e660537ca0a066e10e75df9c9e9099f0", + "sha256:439c3cc4c0d42fa999b83ded80a9a1fb54d53c58d6e59234cfe97f241e6c781d", + "sha256:49c3222bb8f8e800aead2e376cbef687bc9e3cb9b58b29a261210456a7783d83", + "sha256:674b669d5daa64206c38e507808aae49904c988fa0a71c935e7006a3e1e83831", + "sha256:7a9a3bced53b7f09da251685224d6a260c3cb291768f54954e28f03ef14e3766", + "sha256:7af244b012711a26196450d34f483357e42aeddb04128885d95a69bd8b14b69b", + "sha256:7d230bf856164de164ecb615ccc14c7fc6de6906ddd5b491f3af90d3514c925c", + "sha256:84609ade00a6ec59a89729e87a503c6e36af98ddcd566d5f3be52e29ba993182", + "sha256:9a6673c1828db6270b76b22cc696f40cde9043eb90373da5c2f8f2158957f42f", + "sha256:9b6d717393dbae53d4e52684ef4f022444fc1cce3c48c38cb74fca29e1f08eaa", + "sha256:9c3fe6534d59d071ee82081ca3d71eed3210f76ebd0361798c74abc2bcf347d4", + "sha256:a719399b99377b218dac6cf547b6ec54e6ef20207b6165126a280b0ce97e0d2a", + "sha256:b332cba64d99a70c1e0836902720887fb4529ea49ea7f5462cf6640e095e11d2", + "sha256:d124682c7a23c9764e54ca9ab5b308b14b18eba02722b8659fb238546de83a76", + "sha256:d73f419a56d74fef257955f51b18d046f3506270a5fd2ac5febbfa259d6c0fa5", + "sha256:f0dc40e6f7aa37af01aba07277d3d64d5a03dc66d682097541ec4da03cc140ee", + "sha256:f14ad275364c8b4e525d018f6716537ae7b6d369c094805cae45300847e0894f", + "sha256:f772610fe364372de33d76edcd313636a25684edb94cee53fd790195f5989d14" + ], + "markers": "python_version >= '3.7'", + "version": "==41.0.2" + }, + "defusedxml": { + "hashes": [ + "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", + "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.7.1" + }, + "django": { + "hashes": [ + "sha256:45a747e1c5b3d6df1b141b1481e193b033fd1fdbda3ff52677dc81afdaacbaed", + "sha256:f7c7852a5ac5a3da5a8d5b35cc6168f31b605971441798dac845f17ca8028039" + ], + "markers": "python_version >= '3.8'", + "version": "==4.2.3" + }, + "django-templated-mail": { + "hashes": [ + "sha256:8db807effebb42a532622e2d142dfd453dafcd0d7794c4c3332acb90656315f9", + "sha256:f7127e1e31d7cad4e6c4b4801d25814d4b8782627ead76f4a75b3b7650687556" + ], + "version": "==1.1.1" + }, + "djangorestframework": { + "hashes": [ + "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8", + "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08" + ], + "index": "pypi", + "version": "==3.14.0" + }, + "djangorestframework-simplejwt": { + "hashes": [ + "sha256:4c0d2e2513e12587d93501ac091781684a216c3ee614eb3b5a10586aef5ca845", + "sha256:d27d4bcac2c6394f678dea8b4d0d511c6e18a7f2eb8aaeeb8a7de601aeb77c42" + ], + "markers": "python_version >= '3.7'", + "version": "==5.2.2" + }, + "djoser": { + "hashes": [ + "sha256:4aa48502df870c8b5f07109ad4a749cc881c37bb5efa85cf5462ea695a0dca8c", + "sha256:7b24718cdc51b4294b0abcf6bf0ead11aa3ca83652e351dfb04b7b8b15afa3b0" + ], + "index": "pypi", + "version": "==2.2.0" + }, + "idna": { + "hashes": [ + "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", + "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" + ], + "markers": "python_version >= '3.5'", + "version": "==3.4" + }, + "kombu": { + "hashes": [ + "sha256:48ee589e8833126fd01ceaa08f8a2041334e9f5894e5763c8486a550454551e9", + "sha256:fbd7572d92c0bf71c112a6b45163153dea5a7b6a701ec16b568c27d0fd2370f2" + ], + "markers": "python_version >= '3.8'", + "version": "==5.3.1" + }, + "oauthlib": { + "hashes": [ + "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", + "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918" + ], + "markers": "python_version >= '3.6'", + "version": "==3.2.2" + }, + "prompt-toolkit": { + "hashes": [ + "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac", + "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==3.0.39" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "version": "==2.21" + }, + "pyjwt": { + "hashes": [ + "sha256:ba2b425b15ad5ef12f200dc67dd56af4e26de2331f965c5439994dad075876e1", + "sha256:bd6ca4a3c4285c1a2d4349e5a035fdf8fb94e04ccd0fcbe6ba289dae9cc3e074" + ], + "markers": "python_version >= '3.7'", + "version": "==2.7.0" + }, + "python-dateutil": { + "hashes": [ + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==2.8.2" + }, + "python3-openid": { + "hashes": [ + "sha256:33fbf6928f401e0b790151ed2b5290b02545e8775f982485205a066f874aaeaf", + "sha256:6626f771e0417486701e0b4daff762e7212e820ca5b29fcc0d05f6f8736dfa6b" + ], + "version": "==3.2.0" + }, + "pytz": { + "hashes": [ + "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588", + "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb" + ], + "version": "==2023.3" + }, + "redis": { + "hashes": [ + "sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d", + "sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c" + ], + "version": "==4.6.0" + }, + "requests": { + "hashes": [ + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.31.0" + }, + "requests-oauthlib": { + "hashes": [ + "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5", + "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.3.1" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "social-auth-app-django": { + "hashes": [ + "sha256:0347ca4cd23ea9d15a665da9d22950552fb66b95600e6c2ebae38ca883b3a4ed", + "sha256:4a5dae406f3874b4003708ff120c02cb1a4c8eeead56cd163646347309fcd0f8" + ], + "markers": "python_version >= '3.7'", + "version": "==5.2.0" + }, + "social-auth-core": { + "hashes": [ + "sha256:9791d7c7aee2ac8517fe7a2ea2f942a8a5492b3a4ccb44a9b0dacc87d182f2aa", + "sha256:ea7a19c46b791b767e95f467881b53c5fd0d1efb40048d9ed3dbc46daa05c954" + ], + "markers": "python_version >= '3.6'", + "version": "==4.4.2" + }, + "sqlparse": { + "hashes": [ + "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3", + "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c" + ], + "markers": "python_version >= '3.5'", + "version": "==0.4.4" + }, + "tzdata": { + "hashes": [ + "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a", + "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda" + ], + "markers": "python_version >= '2'", + "version": "==2023.3" + }, + "urllib3": { + "hashes": [ + "sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1", + "sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.3" + }, + "vine": { + "hashes": [ + "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30", + "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e" + ], + "markers": "python_version >= '3.6'", + "version": "==5.0.0" + }, + "wcwidth": { + "hashes": [ + "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e", + "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0" + ], + "version": "==0.2.6" + } + }, + "develop": {} +} diff --git a/README.md b/README.md index 1eadcf7..47386d0 100644 --- a/README.md +++ b/README.md @@ -1 +1,14 @@ -# Library-Management-System \ No newline at end of file +# Library-Management-System +A library management system is designed to efficiently manage the operations and resources of a library. Here are some common features found in library management systems: + +1. Catalog Management: Maintain a centralized catalog of books, periodicals, media, and other library materials. This includes features for adding, editing, and deleting items from the catalog, as well as searching and browsing capabilities for users. + +2. User Management: Manage user accounts and profiles, including registration, authentication, and user roles (e.g., students, faculty, staff). Users may be able to view their borrowing history, manage their personal information, and place holds or requests for materials. + +3. Circulation and Borrowing: Facilitate the borrowing and lending process, including check-in and check-out of library materials. This feature may include due date management, loan renewals, holds, and notifications for overdue items. + +4. Reservation and Request Management: Enable users to reserve or request items that are currently unavailable or in high demand. Users can be notified when the requested items become available. + +5. Fine and Fee Management: Track and manage fines, fees, and penalties for overdue materials, lost items, or other library-related charges. Provide an interface for users to view and pay fines online. + +6. Catalog Search and Discovery: Provide a user-friendly search interface for users to find and discover library materials based on title, author, subject, ISBN, or other criteria. Implement advanced search options, filters, and sorting capabilities.