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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The application allows you to automate the process of generating a bibliography

Supported citation styles:
- ГОСТ Р 7.0.5-2008
- APA

## Installation

Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

Поддерживаемые стили цитирования:
- ГОСТ Р 7.0.5-2008
- APA

Установка
=========
Expand Down
47 changes: 47 additions & 0 deletions src/formatters/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,50 @@ class ArticlesCollectionModel(BaseModel):
publishing_house: str
year: int = Field(..., gt=0)
pages: str

class DissertationModel(BaseModel):
"""
Модель диссертации:
.. code-block::
DissertationModel(
author="Иванов И.М.",
title="Наука как искусство",
academic_degree="канд.",
science="экон.",
specialty_code="01.01.01",
publication_city="СПб.",
publication_year=2020,
page_count=199,
)
"""

author: str
title: str
academic_degree: str
science: str
specialty_code: str
publication_city: str
publication_year: int = Field(..., gt=0)
page_count: int = Field(..., gt=0)


class ArticleNewspaperModel(BaseModel):
"""
Модель статьи из газеты:
.. code-block::
NewspaperArticleModel(
authors="Иванов И.М., Петров С.Н.",
article_title="Наука как искусство",
newspaper_name="Южный Урал",
publication_year=1980,
publication_date="01.10",
аrticle_number=5
)
"""

authors: str
article_title: str
newspaper_name: str
publication_year: int = Field(..., gt=0)
publication_date: str
аrticle_number: int = Field(..., gt=0)
103 changes: 103 additions & 0 deletions src/formatters/styles/apa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
"""
Стиль цитирования по American Psychological Association
"""
from string import Template

from pydantic import BaseModel

from formatters.models import BookModel, InternetResourceModel
from formatters.styles.base import BaseCitationStyle
from logger import get_logger


logger = get_logger(__name__)


class Book_APA(BaseCitationStyle):
"""
Форматирование Книг.
"""

data: BookModel

@property
def template(self) -> Template:
return Template("$authors ($year). $title $edition. $publishing_house.")

def substitute(self) -> str:

logger.info('Форматирование Книги "%s" ...', self.data.title)

return self.template.substitute(
authors=self.data.authors,
title=self.data.title,
edition=self.get_edition(),
city=self.data.publication_city,
publishing_house=self.data.publishing_house,
year=self.data.publication_year,
pages=self.data.pages,
)

def get_edition(self) -> str:
"""
Получение информации об издательстве.
:return: Информация об издательстве.
"""

return f"({self.data.edition} изд.)" if self.data.edition else ""


class InternetResource_APA(BaseCitationStyle):
"""
Форматирование Интернет-ресурсов.
"""

data: InternetResourceModel

@property
def template(self) -> Template:
return Template(
"$article. (n.d.). $website. Retrieved $access_date, from $link"
)

def substitute(self) -> str:

logger.info('Форматирование Интернет-ресурса "%s" ...', self.data.article)

return self.template.substitute(
article=self.data.article,
website=self.data.website,
link=self.data.link,
access_date=self.data.access_date,
)


class Formatter_APA:
"""
Класс для форматирования списка источников по стандартам APA.
"""

formatters_map = {
BookModel.__name__: Book_APA,
InternetResourceModel.__name__: InternetResource_APA,
}

def __init__(self, models: list[BaseModel]) -> None:
"""
Конструктор для форматирования.
:param models: Список объектов для форматирования
"""

formatted_items = []
for model in models:
formatted_items.append(self.formatters_map.get(type(model).__name__(model)))

self.formatted_items = formatted_items

def format(self) -> list[BaseCitationStyle]:
"""
Форматирование списка источников.
:return:
"""

return sorted(self.formatted_items, key=lambda item: item.formatted)
72 changes: 67 additions & 5 deletions src/formatters/styles/gost.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from pydantic import BaseModel

from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel
from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleNewspaperModel
from formatters.styles.base import BaseCitationStyle
from logger import get_logger

Expand Down Expand Up @@ -34,9 +34,9 @@ def substitute(self) -> str:
authors=self.data.authors,
title=self.data.title,
edition=self.get_edition(),
city=self.data.city,
city=self.data.publication_city,
publishing_house=self.data.publishing_house,
year=self.data.year,
year=self.data.publication_year,
pages=self.data.pages,
)

Expand Down Expand Up @@ -96,12 +96,71 @@ def substitute(self) -> str:
authors=self.data.authors,
article_title=self.data.article_title,
collection_title=self.data.collection_title,
city=self.data.city,
city=self.data.publication_city,
publishing_house=self.data.publishing_house,
year=self.data.year,
year=self.data.publication_year,
pages=self.data.pages,
)

class GOSTDissertationModel(BaseCitationStyle):
"""
Форматирование для Диссертации.
"""

data: DissertationModel

@property
def template(self) -> Template:
return Template(
"$author $title: дис. ... $academic_degree $science наук: $specialty_code $publication_city $publication_year. $page_count с."
)

def substitute(self) -> str:

logger.info('Форматирование Диссертации "%s" ...', self.data.title)

return self.template.substitute(
author=self.data.author,
title=self.data.title,
academic_degree=self.data.academic_degree,
science=self.data.science,
specialty_code=self.data.specialty_code,
publication_city=self.data.publication_city,
publication_year=self.data.publication_year,
page_count=self.data.page_count,
)


class GOSTArticleNewspaper(BaseCitationStyle):
"""
Форматирование для Статьи из газеты.
"""

data: ArticleNewspaperModel

@property
def template(self) -> Template:
return Template(
"$authors $article_title // $newspaper_name. – $publication_year. - $publication_date. - №$аrticle_number."
)

def substitute(self) -> str:

logger.info('Форматирование Статьи из газеты "%s" ...', self.data.article_title)

return self.template.substitute(
authors=self.data.authors,
article_title=self.data.article_title,
newspaper_name=self.data.newspaper_name,
publication_year=self.data.publication_year,
publication_date=self.data.publication_date,
аrticle_number=self.data.аrticle_number,
)






class GOSTCitationFormatter:
"""
Expand All @@ -112,6 +171,9 @@ class GOSTCitationFormatter:
BookModel.__name__: GOSTBook,
InternetResourceModel.__name__: GOSTInternetResource,
ArticlesCollectionModel.__name__: GOSTCollectionArticle,
DissertationModel.__name__: GOSTDissertationModel,
ArticleNewspaperModel.__name__: GOSTArticleNewspaper,

}

def __init__(self, models: list[BaseModel]) -> None:
Expand Down
14 changes: 11 additions & 3 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from readers.reader import SourcesReader
from renderer import Renderer
from settings import INPUT_FILE_PATH, OUTPUT_FILE_PATH
from formatters.styles.apa import Formatter_APA

logger = get_logger(__name__)

Expand Down Expand Up @@ -77,9 +78,16 @@ def process_input(
)

models = SourcesReader(path_input).read()
formatted_models = tuple(
str(item) for item in GOSTCitationFormatter(models).format()
)
formatters = {
CitationEnum.GOST.name: GOSTCitationFormatter,
CitationEnum.APA.name: Formatter_APA,
}

if citation not in formatters:
logger.error("Данный стиль не поддерживается")

formatter = formatters[citation]
formatted_models = tuple(str(item) for item in formatter(models).format())

logger.info("Генерация выходного файла ...")
Renderer(formatted_models).render(path_output)
Expand Down
56 changes: 55 additions & 1 deletion src/readers/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import openpyxl
from openpyxl.workbook import Workbook

from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel
from formatters.models import BookModel, InternetResourceModel, ArticlesCollectionModel, DissertationModel, ArticleNewspaperModel
from logger import get_logger
from readers.base import BaseReader

Expand Down Expand Up @@ -90,6 +90,57 @@ def attributes(self) -> dict:
}


class DissertationReader(BaseReader):
"""
Чтение модели Диссертации.
"""

@property
def model(self) -> Type[DissertationModel]:
return DissertationModel

@property
def sheet(self) -> str:
return "Диссертация"

@property
def attributes(self) -> dict:
return {
"author": {0: str},
"title": {1: str},
"academic_degree": {2: str},
"science": {3: str},
"specialty_code": {4: str},
"publication_city": {5: str},
"publication_year": {6: int},
"page_count": {7: int},
}

class ArticleNewspaperReader(BaseReader):
"""
Чтение модели Статьи из газеты.
"""

@property
def model(self) -> Type[ArticleNewspaperModel]:
return ArticleNewspaperModel

@property
def sheet(self) -> str:
return "Статья из газеты"

@property
def attributes(self) -> dict:
return {
"authors": {0: str},
"article_title": {1: str},
"newspaper_name": {2: str},
"publication_year": {3: int},
"publication_date": {4: str},
"аrticle_number": {5: int},
}


class SourcesReader:
"""
Чтение из источника данных.
Expand All @@ -100,6 +151,9 @@ class SourcesReader:
BookReader,
InternetResourceReader,
ArticlesCollectionReader,
DissertationReader,
ArticleNewspaperReader,

]

def __init__(self, path: str) -> None:
Expand Down
Loading