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)]