diff --git a/itd/enums.py b/itd/enums.py
index 8eb094e..201373f 100644
--- a/itd/enums.py
+++ b/itd/enums.py
@@ -39,4 +39,13 @@ class AccessType(Enum):
NOBODY = 'nobody' # никто
MUTUAL = 'mutual' # взаимные
FOLLOWERS = 'followers' # подписчики
- EVERYONE = 'everyone' # все
\ No newline at end of file
+ EVERYONE = 'everyone' # все
+
+class SpanType(Enum):
+ MONOSPACE = 'monospace' # моноширный (код)
+ STRIKE = 'strike' # зачеркнутый
+ BOLD = 'bold' # жирный
+ ITALIC = 'italic' # курсив
+ SPOILER = 'spoiler' # спойлер
+ UNDERLINE = 'underline' # подчеркнутый
+ HASHTAG = 'hashtag' # хэштэг ? (появляется только при получении постов, при создании нету)
diff --git a/itd/models/post.py b/itd/models/post.py
index 5a8eaa1..affc289 100644
--- a/itd/models/post.py
+++ b/itd/models/post.py
@@ -7,6 +7,7 @@ from itd.models.user import UserPost, UserNewPost
from itd.models._text import TextObject
from itd.models.file import PostAttach
from itd.models.comment import Comment
+from itd.enums import SpanType
class NewPollOption(BaseModel):
diff --git a/itd/request.py b/itd/request.py
index 391025c..a5acaa0 100644
--- a/itd/request.py
+++ b/itd/request.py
@@ -39,7 +39,7 @@ def fetch(token: str, method: str, url: str, params: dict = {}, files: dict[str,
raise RateLimitExceeded(res.json()['error'].get('retryAfter', 0))
if res.json().get('error', {}).get('code') == 'UNAUTHORIZED':
raise Unauthorized()
- if res.json().get('error', {}).get('code') == 'ACCOUNT_BANNED':
+ if res.json().get('error', {}).get('code') in ('ACCOUNT_BANNED', 'USER_BLOCKED'):
raise AccountBanned()
if res.json().get('error', {}).get('code') == 'PROFILE_REQUIRED':
raise ProfileRequired()
diff --git a/itd/utils.py b/itd/utils.py
new file mode 100644
index 0000000..5074ea6
--- /dev/null
+++ b/itd/utils.py
@@ -0,0 +1,114 @@
+# новая версия от чат гпт. у меня самого не получилось сделать
+from itd.models.post import Span
+from itd.enums import SpanType
+
+
+class Tag:
+ def __init__(self, open: str, close: str, type: SpanType):
+ self.open = open
+ self.close = close
+ self.type = type
+
+
+def _parse_spans(text: str, tags: list[Tag]) -> tuple[str, list[Span]]:
+ spans: list[Span] = []
+ stack: list[tuple[int, SpanType, int, int]] = []
+ clean_chars: list[str] = []
+ i = 0
+
+ while i < len(text):
+ closed = False
+ for idx, tag in enumerate(tags):
+ if text.startswith(tag.close, i) and stack and stack[-1][0] == idx:
+ _, span_type, offset, _ = stack.pop()
+ spans.append(Span(length=len(clean_chars) - offset, offset=offset, type=span_type))
+ i += len(tag.close)
+ closed = True
+ break
+ if closed:
+ continue
+
+ opened = False
+ for idx, tag in enumerate(tags):
+ if text.startswith(tag.open, i):
+ stack.append((idx, tag.type, len(clean_chars), i))
+ i += len(tag.open)
+ opened = True
+ break
+ if opened:
+ continue
+
+ clean_chars.append(text[i])
+ i += 1
+
+ if stack:
+ _, last_type, _, raw_pos = stack[-1]
+ raise ValueError(f'No closing tag for {last_type.value} at pos {raw_pos}')
+
+ spans.sort(key=lambda span: span.offset)
+ return ''.join(clean_chars), spans
+
+
+def parse_html(text: str) -> tuple[str, list[Span]]:
+ return _parse_spans(
+ text,
+ [
+ Tag('', '', SpanType.BOLD),
+ Tag('', '', SpanType.ITALIC),
+ Tag('', '', SpanType.STRIKE),
+ Tag('', '', SpanType.UNDERLINE),
+ Tag('', '', SpanType.MONOSPACE),
+ Tag('', '', SpanType.SPOILER),
+ ],
+ )
+
+
+# версия от человека (не работает с вложенными тэгами)
+# from re import finditer, Match
+
+# from itd.models.post import Span
+# from itd.enums import SpanType
+
+
+# class Tag:
+# def __init__(self, open: str, close: str, type: SpanType):
+# self.open = open
+# self.close = close
+# self.type = type
+
+# def raise_error(self, pos: int):
+# raise ValueError(f'No closing tag for {self.type.value} at pos {pos - len(self.open)}')
+
+# def to_span(self, start: int, end: int) -> Span:
+# return Span(length=end - (start - len(self.open)), offset=start - len(self.open), type=self.type)
+
+# def get_pos(self, match: Match[str], text: str, offset: int) -> tuple[int, int, str]:
+# start = match.end() - offset
+# text = text[:match.start() - offset] + text[start:]
+# end = text.find(self.close, start)
+# if end == -1:
+# self.raise_error(start)
+
+# return start - len(self.open), end, text[:end] + text[end + len(self.close):]
+
+
+# def parse_html(text: str) -> tuple[str, list[Span]]:
+# spans = []
+
+# for tag in [
+# Tag('', '', SpanType.BOLD),
+# Tag('', '', SpanType.ITALIC),
+# Tag('', '', SpanType.STRIKE),
+# Tag('', '', SpanType.UNDERLINE),
+# Tag('', '', SpanType.MONOSPACE),
+# Tag('', '', SpanType.SPOILER),
+# ]:
+
+# offset = 0
+# full_text = text
+# for match in finditer(tag.open, full_text):
+# start, end, text = tag.get_pos(match, text, offset)
+# spans.append(tag.to_span(start, end))
+# offset += len(tag.open) + len(tag.close)
+
+# return text, spans