social media crossposting tool. 3rd time's the charm
mastodon
misskey
crossposting
bluesky
1import grapheme
2from cross.fragments import Fragment, LinkFragment
3from dataclasses import replace
4
5
6def canonical_label(label: str | None, href: str):
7 if not label or label == href:
8 return True
9
10 split = href.split("://", 1)
11 if len(split) > 1:
12 if split[1] == label:
13 return True
14
15 return False
16
17
18class FragmentSplitter:
19 def __init__(self, climit: int, urllen: int):
20 self.climit: int = climit
21 self.urllen: int = urllen
22
23 def normalize_link(self, label: str, url: str) -> str:
24 #if canonical_label(label, url):
25 # if self.urltrunc == "dotted":
26 # nlabel = url.split("://", 1)[1]
27 # if len(nlabel) <= self.urllen:
28 # return nlabel
29 # return nlabel[: self.urllen - 1] + "…"
30 return label
31
32 def url_normalize(
33 self, text: str, fragments: list[Fragment]
34 ) -> tuple[str, list[Fragment]]:
35 if self.urllen == -1:
36 return text, fragments
37
38 ntext: list[str] = []
39 nfragments: list[Fragment] = []
40
41 offset: int = 0
42 last_index: int = 0
43
44 fragments = [fg for fg in fragments]
45 fragments.sort(key=lambda x: x.start)
46
47 for fg in fragments:
48 ntext.append(text[last_index:fg.start])
49 label = text[fg.start:fg.end]
50 nlabel = label
51 if isinstance(fg, LinkFragment):
52 nlabel = self.normalize_link(nlabel, fg.url)
53 ntext.append(nlabel)
54
55 nfg = replace(fg, start=fg.start + offset)
56 change = len(nlabel) - len(label)
57 offset += change
58 nfg = replace(nfg, end=fg.end + offset)
59
60 nfragments.append(nfg)
61 last_index = fg.end
62
63 ntext.append(text[last_index:])
64
65 return ''.join(ntext), nfragments
66
67 def split(
68 self, text: str, fragments: list[Fragment]
69 ) -> list[tuple[str, list[Fragment]]]:
70 text, fragments = self.url_normalize(text, fragments)
71 if grapheme.length(text) <= self.climit:
72 return [(text, fragments)]