maubot: update plugins

+250 -194
+108 -80
pkgs/tools/networking/maubot/plugins/generated.json
··· 66 66 } 67 67 }, 68 68 "github": { 69 - "hash": "sha256-O3FhZ6US4iACEzEKdHLjBZfOJlHNGEeLSrHdqWULFvk=", 69 + "hash": "sha256-RUwZ6SOsWiygyb10GnDmvskAurSiW9rFwDylYgr6wII=", 70 70 "owner": "rom4nik", 71 71 "repo": "maubot-alternatingcaps", 72 - "rev": "v0.1.2" 72 + "rev": "v0.1.3" 73 73 }, 74 74 "manifest": { 75 75 "id": "pl.rom4nik.maubot.alternatingcaps", 76 76 "license": "MIT", 77 77 "main_class": "AlternatingCaps", 78 + "maubot": "0.4.0", 78 79 "modules": [ 79 80 "alternatingcaps" 80 81 ], 81 - "version": "0.1.2" 82 + "version": "0.1.3" 82 83 } 83 84 }, 84 85 "animemanga": { ··· 202 203 "version": "1.0.0" 203 204 } 204 205 }, 205 - "characterai": { 206 - "attrs": { 207 - "meta": { 208 - "changelog": "https://github.com/Matthieu-LAURENT39/maubot-characterai/releases", 209 - "description": "Chat with characters from [character.ai](https://character.ai/) in your Matrix rooms! Very customizable.", 210 - "downloadPage": "https://github.com/Matthieu-LAURENT39/maubot-characterai/releases", 211 - "homepage": "https://github.com/Matthieu-LAURENT39/maubot-characterai" 212 - } 213 - }, 214 - "github": { 215 - "hash": "sha256-nyVz0PDyNGAIFCxakWzEe8AG/PU+HlZJQQ85SL1bEvs=", 216 - "owner": "Matthieu-LAURENT39", 217 - "repo": "maubot-characterai", 218 - "rev": "v0.2.1" 219 - }, 220 - "manifest": { 221 - "config": true, 222 - "database": true, 223 - "database_type": "asyncpg", 224 - "dependencies": [ 225 - "characterai" 226 - ], 227 - "extra_files": [ 228 - "base-config.yaml" 229 - ], 230 - "id": "com.github.Matthieu-LAURENT39.maubot-characterai", 231 - "license": "MIT", 232 - "main_class": "CAIBot", 233 - "maubot": "0.1.0", 234 - "modules": [ 235 - "cai" 236 - ], 237 - "version": "0.2.1" 238 - } 239 - }, 240 206 "chatgpt": { 241 207 "attrs": { 242 208 "meta": { ··· 337 303 } 338 304 }, 339 305 "github": { 340 - "hash": "sha256-wO63G2mdpz2FWjatVY5R+L7Chki087Ev7oMfpgyOnxM=", 306 + "hash": "sha256-DNKdlbxeLdxb/OSujANzlZkgX1Bg6Q+4Ubxwq/0QV5M=", 341 307 "owner": "williamkray", 342 308 "repo": "maubot-communitybot", 343 - "rev": "v0.1.7" 309 + "rev": "v0.1.17" 344 310 }, 345 311 "manifest": { 346 312 "database": true, ··· 355 321 "modules": [ 356 322 "community" 357 323 ], 358 - "version": "0.1.7" 324 + "version": "0.1.17" 359 325 } 360 326 }, 361 327 "dice": { ··· 542 508 } 543 509 }, 544 510 "github": { 545 - "hash": "sha256-VtZp4c3bbKCgbqQoJRnkle7Qn1zSGhgSPFAIlijQDOs=", 511 + "hash": "sha256-071iR5GlO+1WfMm6IK7by5nDfPhfOJCPr6WwB6qew/U=", 546 512 "owner": "williamkray", 547 513 "repo": "maubot-gifme", 548 - "rev": "a896a07fba53c90455431e79904f79d949c91f92" 514 + "rev": "v0.1.1" 549 515 }, 550 516 "manifest": { 551 517 "database": true, ··· 560 526 "modules": [ 561 527 "gifme" 562 528 ], 563 - "version": "0.1.0" 529 + "version": "0.1.1" 564 530 } 565 531 }, 566 532 "giphy": { ··· 603 569 } 604 570 }, 605 571 "github": { 606 - "hash": "sha256-Qc0KH8iGqMDa+1BXaB5fHtRIcsZRpTF2IufGMEXqV6Q=", 572 + "hash": "sha256-XTX600ugWnaXyk1SFRwXWGCwRLcjXDBo1Vy0BG4kj5g=", 607 573 "owner": "maubot", 608 574 "repo": "github", 609 - "rev": "v0.1.2" 575 + "rev": "v0.2.0" 610 576 }, 611 577 "isOfficial": true, 612 578 "manifest": { ··· 618 584 "id": "xyz.maubot.github", 619 585 "license": "AGPL-3.0-or-later", 620 586 "main_class": "GitHubBot", 621 - "maubot": "0.3.0", 587 + "maubot": "0.4.1", 622 588 "modules": [ 623 589 "github" 624 590 ], 625 - "version": "0.1.2", 591 + "version": "0.2.0", 626 592 "webapp": true 627 593 } 628 594 }, ··· 796 762 "webapp": false 797 763 } 798 764 }, 765 + "idonthavespotify": { 766 + "attrs": { 767 + "meta": { 768 + "changelog": "https://github.com/HarHarLinks/maubot-idonthavespotify/releases", 769 + "description": "Reply to Spotify links with alternative streaming services.", 770 + "downloadPage": "https://github.com/HarHarLinks/maubot-idonthavespotify/releases", 771 + "homepage": "https://github.com/HarHarLinks/maubot-idonthavespotify" 772 + } 773 + }, 774 + "github": { 775 + "hash": "sha256-BFB/eyl1+I5P65RCSNYwEeitGCWBB8u7qpd70qLFJuY=", 776 + "owner": "HarHarLinks", 777 + "repo": "maubot-idonthavespotify", 778 + "rev": "v1.1.0" 779 + }, 780 + "manifest": { 781 + "config": true, 782 + "extra_files": [ 783 + "base-config.yaml" 784 + ], 785 + "id": "de.sosnowkadub.idonthavespotify", 786 + "license": "MIT", 787 + "main_class": "idonthavespotify/IDontHaveSpotifyPlugin", 788 + "maubot": "0.1.0", 789 + "modules": [ 790 + "idonthavespotify" 791 + ], 792 + "version": "1.1.0" 793 + } 794 + }, 799 795 "invite": { 800 796 "attrs": { 801 797 "meta": { ··· 867 863 } 868 864 }, 869 865 "github": { 870 - "hash": "sha256-6bggnk3196M0eCkfYTJWLhiIwIVTtluffQzc58yIYzw=", 866 + "hash": "sha256-ML4NEqn5fa/rBqzrocq0bUiktr81eyh4Uob5lJak+lk=", 871 867 "owner": "williamkray", 872 868 "repo": "maubot-join", 873 - "rev": "v0.3.1" 869 + "rev": "v0.3.2" 874 870 }, 875 871 "manifest": { 876 872 "database": false, ··· 884 880 "modules": [ 885 881 "join" 886 882 ], 887 - "version": "0.3.1" 883 + "version": "0.3.2" 888 884 } 889 885 }, 890 886 "karma": { ··· 1126 1122 "description": "A plugin create Discourse forum post from messages in Matrix or Bridged rooms and perform advanced forum searches directly from Matrix or Bridged rooms. Perfect for community building and engagement.", 1127 1123 "downloadPage": "https://github.com/gitayam/matrix-to-discourse/releases", 1128 1124 "homepage": "https://github.com/gitayam/matrix-to-discourse" 1129 - } 1125 + }, 1126 + "postPatch": "cd plugin" 1130 1127 }, 1131 1128 "github": { 1132 - "hash": "sha256-QIFgCQL9O/SVemXfxlXzPcPQ/qx68IU7ntArCk946iA=", 1129 + "hash": "sha256-GMLpfpNsDKX/3PPeWrHwMVq8ppygJTPY/QhKe1JDphE=", 1133 1130 "owner": "gitayam", 1134 1131 "repo": "matrix-to-discourse", 1135 - "rev": "v0.1.0.1" 1132 + "rev": "v1.2.1" 1136 1133 }, 1137 1134 "manifest": { 1135 + "config": true, 1136 + "database": false, 1138 1137 "dependencies": [ 1139 - "aiohttp", 1140 - "maubot", 1141 - "mautrix", 1142 1138 "openai", 1143 - "pyyaml", 1144 - "requests" 1139 + "pyyaml" 1145 1140 ], 1146 - "id": "com.irregularchat.matrix_to_discourse", 1141 + "extra_files": [ 1142 + "base-config.yaml" 1143 + ], 1144 + "id": "url.irregularchat.matrix_to_discourse", 1147 1145 "license": "GPL-3.0", 1148 1146 "main_class": "MatrixToDiscourseBot", 1149 1147 "maubot": "0.1.0", 1150 1148 "modules": [ 1151 - "bot" 1149 + "MatrixToDiscourseBot" 1152 1150 ], 1153 - "version": "0.1.0.0" 1151 + "version": "1.2.1" 1154 1152 } 1155 1153 }, 1156 1154 "media": { ··· 1214 1212 } 1215 1213 }, 1216 1214 "gitlab": { 1217 - "hash": "sha256-6522dVqhGoPc/qjz65D3kXHks5LLb3yVe0K5abqdXrw=", 1215 + "hash": "sha256-8Xsw/yO5Ma4weKAhk8DPQeCrn2ksk9c7J3oRzlAy2rw=", 1218 1216 "owner": "999eagle", 1219 1217 "repo": "maubot-ntfy", 1220 - "rev": "256aa8f315cbb184eba0256c2ec818abbdd2d408" 1218 + "rev": "4e930c0e7100e06570707564fc471fc3c931708e" 1221 1219 }, 1222 1220 "manifest": { 1223 1221 "config": true, ··· 1249 1247 } 1250 1248 }, 1251 1249 "github": { 1252 - "hash": "sha256-vw2MT4pwmUUWolgzkq0nZ/YaAlKUANrN0NPXXFf7B1k=", 1250 + "hash": "sha256-PoHZhMy5sCgl1pf6xfbFpF0J9cSNk/NaVm6XeIgeAzU=", 1253 1251 "owner": "tcpipuk", 1254 1252 "repo": "maubot-openai-translate", 1255 - "rev": "v0.3.1" 1253 + "rev": "v0.4.0" 1256 1254 }, 1257 1255 "manifest": { 1258 1256 "config": true, ··· 1266 1264 "modules": [ 1267 1265 "openaitranslate" 1268 1266 ], 1269 - "version": "0.3.1" 1267 + "version": "0.4.0" 1270 1268 } 1271 1269 }, 1272 1270 "ovgumensabot": { ··· 1279 1277 } 1280 1278 }, 1281 1279 "github": { 1282 - "hash": "sha256-nuOLUPwE0F15FgOtbq3+qmNNd2eHRrRNJPMM+v1Ksy0=", 1280 + "hash": "sha256-Gzw6YWvku0PbN/sNKABGjPPOpskubOHUVuiwMjD3m+c=", 1283 1281 "owner": "v411e", 1284 1282 "repo": "ovgumensabot", 1285 - "rev": "v0.0.8" 1283 + "rev": "v0.0.9" 1286 1284 }, 1287 1285 "manifest": { 1288 1286 "database": true, ··· 1300 1298 "modules": [ 1301 1299 "ovgumensabot" 1302 1300 ], 1303 - "version": "0.0.8" 1301 + "version": "0.0.9" 1304 1302 } 1305 1303 }, 1306 1304 "pingcheck": { ··· 1395 1393 "pretix-inviter": { 1396 1394 "attrs": { 1397 1395 "meta": { 1398 - "changelog": "https://github.com/fedora-infra/maubot-pretix-invite/blob/v0.3.2/CHANGELOG.md", 1396 + "changelog": "https://github.com/fedora-infra/maubot-pretix-invite/blob/v0.4.1.1/CHANGELOG.md", 1399 1397 "description": "A maubot plugin for inviting event participants from the pretix ticketing platform into a matrix room", 1400 1398 "downloadPage": "https://github.com/fedora-infra/maubot-pretix-invite/releases", 1401 1399 "homepage": "https://github.com/fedora-infra/maubot-pretix-invite" 1402 1400 } 1403 1401 }, 1404 1402 "github": { 1405 - "hash": "sha256-KgWGvZ7QHcH0/u6+kodW8MAXtco4MM5MpbKscW903nQ=", 1403 + "hash": "sha256-3LfIh4THe9lGl2RJHuXA1SKJ9pvi8851F8n+HPSID+o=", 1406 1404 "owner": "fedora-infra", 1407 1405 "repo": "maubot-pretix-invite", 1408 - "rev": "v0.3.2" 1406 + "rev": "v0.4.1.1" 1409 1407 }, 1410 1408 "manifest": { 1411 1409 "config": true, ··· 1418 1416 "modules": [ 1419 1417 "event_helper" 1420 1418 ], 1421 - "version": "0.3.2", 1419 + "version": "0.4.1", 1422 1420 "webapp": true 1423 1421 } 1424 1422 }, ··· 1654 1652 } 1655 1653 }, 1656 1654 "github": { 1657 - "hash": "sha256-p/xJpJbzsOeQGcowvOhJSclPtmZyNyBaZBz+mexVqIY=", 1655 + "hash": "sha256-1Wac/j8qOTA31BCI4emOSYAEYEbtOjdB5ACz1qnY6h8=", 1658 1656 "owner": "maubot", 1659 1657 "repo": "rss", 1660 - "rev": "v0.3.2" 1658 + "rev": "v0.4.1" 1661 1659 }, 1662 1660 "isOfficial": true, 1663 1661 "manifest": { ··· 1676 1674 "modules": [ 1677 1675 "rss" 1678 1676 ], 1679 - "version": "0.3.2" 1677 + "version": "0.4.1" 1678 + } 1679 + }, 1680 + "rsvc": { 1681 + "attrs": { 1682 + "meta": { 1683 + "changelog": "https://github.com/maubot/rsvc/releases", 1684 + "description": "A bot to check the version of servers in room.", 1685 + "downloadPage": "https://github.com/maubot/rsvc/releases", 1686 + "homepage": "https://github.com/maubot/rsvc" 1687 + } 1688 + }, 1689 + "github": { 1690 + "hash": "sha256-4VvC2a0WZ9mlwV4l1Nz9eWatCy0nbhEXFhoAhUhrT1A=", 1691 + "owner": "maubot", 1692 + "repo": "rsvc", 1693 + "rev": "d67750085437fd50a6054bc1b6623b1a1341c0b8" 1694 + }, 1695 + "isOfficial": true, 1696 + "manifest": { 1697 + "extra_files": [ 1698 + "base-config.yaml" 1699 + ], 1700 + "id": "xyz.maubot.rsvc", 1701 + "license": "AGPL-3.0-or-later", 1702 + "main_class": "ServerCheckerBot", 1703 + "maubot": "0.1.0", 1704 + "modules": [ 1705 + "rsvc" 1706 + ], 1707 + "version": "1.0.0" 1680 1708 } 1681 1709 }, 1682 1710 "satwcomic": { ··· 1783 1811 } 1784 1812 }, 1785 1813 "github": { 1786 - "hash": "sha256-naHY6f034uGnPIHidI7WXjcf2h/t0IYaPkO5QfKkXMs=", 1814 + "hash": "sha256-pea3NlDExMkgfWfP003xO5Nt+RnidpVq9PzDOxzz7Ow=", 1787 1815 "owner": "ggogel", 1788 1816 "repo": "SocialMediaDownloadMaubot", 1789 - "rev": "1.4.2" 1817 + "rev": "1.4.4" 1790 1818 }, 1791 1819 "manifest": { 1792 1820 "config": true, ··· 1802 1830 "instaloader", 1803 1831 "socialmediadownload" 1804 1832 ], 1805 - "version": "1.4.2" 1833 + "version": "1.4.4" 1806 1834 } 1807 1835 }, 1808 1836 "songwhip": {
+142 -114
pkgs/tools/networking/maubot/plugins/update.py
··· 10 10 import toml 11 11 import zipfile 12 12 13 - from typing import Dict, List 14 - 15 13 HOSTNAMES = { 16 - 'git.skeg1.se': 'gitlab', 17 - 'edugit.org': 'gitlab', 18 - 'codeberg.org': 'gitea', 14 + "git.skeg1.se": "gitlab", 15 + "edugit.org": "gitlab", 16 + "codeberg.org": "gitea", 19 17 } 20 - PLUGINS: Dict[str, dict] = {} 18 + PLUGINS: dict[str, dict] = {} 19 + # https://github.com/maubot/plugins.maubot.xyz/pull/45 20 + SKIP = {"characterai"} 21 + DIRS = {"matrix-to-discourse": "plugin"} 21 22 22 - yaml = ruamel.yaml.YAML(typ='safe') 23 + yaml = ruamel.yaml.YAML(typ="safe") 23 24 24 - TMP = os.environ.get('TEMPDIR', '/tmp') 25 + TMP = os.environ.get("TEMPDIR", "/tmp") 26 + 25 27 26 28 def process_repo(path: str, official: bool): 27 29 global PLUGINS 28 - with open(path, 'rt') as f: 30 + with open(path, "rt") as f: 29 31 data = yaml.load(f) 30 - name, repourl, license, desc = data['name'], data['repo'], data['license'], data['description'] 32 + name, repourl, license, desc = ( 33 + data["name"], 34 + data["repo"], 35 + data["license"], 36 + data["description"], 37 + ) 38 + if name in SKIP: 39 + return 31 40 origurl = repourl 32 - if '/' in name or ' ' in name: 33 - name = os.path.split(path)[-1].removesuffix('.yaml') 34 - name = name.replace('_', '-').lower() 41 + if "/" in name or " " in name: 42 + name = os.path.split(path)[-1].removesuffix(".yaml") 43 + name = name.replace("_", "-").lower() 35 44 if name in PLUGINS.keys(): 36 - raise ValueError(f'Duplicate plugin {name}, refusing to continue') 37 - repodir = os.path.join(TMP, 'maubot-plugins', name) 45 + raise ValueError(f"Duplicate plugin {name}, refusing to continue") 46 + repodir = os.path.join(TMP, "maubot-plugins", name) 38 47 plugindir = repodir 39 - if '/tree/' in repourl: 40 - repourl, rev_path = repourl.split('/tree/') 41 - rev, subdir = rev_path.strip('/').split('/') 48 + if "/tree/" in repourl: 49 + repourl, rev_path = repourl.split("/tree/") 50 + rev, subdir = rev_path.strip("/").split("/") 51 + plugindir = os.path.join(plugindir, subdir) 52 + elif name in DIRS.keys(): 53 + subdir = DIRS[name] 42 54 plugindir = os.path.join(plugindir, subdir) 43 55 else: 44 56 rev = None 45 57 subdir = None 46 58 47 - if repourl.startswith('http:'): 48 - repourl = 'https' + repourl[4:] 49 - repourl = repourl.rstrip('/') 59 + if repourl.startswith("http:"): 60 + repourl = "https" + repourl[4:] 61 + repourl = repourl.rstrip("/") 50 62 if not os.path.exists(repodir): 51 - print('Fetching', name) 52 - repo = git.Repo.clone_from(repourl + '.git', repodir) 63 + print("Fetching", name) 64 + repo = git.Repo.clone_from(repourl + ".git", repodir) 53 65 else: 54 66 repo = git.Repo(repodir) 55 67 tags = sorted(repo.tags, key=lambda t: t.commit.committed_datetime) 56 - tags = list(filter(lambda x: 'rc' not in str(x), tags)) 68 + tags = list(filter(lambda x: "rc" not in str(x), tags)) 57 69 if tags: 58 70 repo.git.checkout(tags[-1]) 59 71 rev = str(tags[-1]) 60 72 else: 61 - rev = str(repo.commit('HEAD')) 62 - ret: dict = {'attrs':{}} 73 + rev = str(repo.commit("HEAD")) 74 + ret: dict = {"attrs": {}} 63 75 if subdir: 64 - ret['attrs']['postPatch'] = f'cd {subdir}' 65 - domain, query = repourl.removeprefix('https://').split('/', 1) 66 - hash = subprocess.run([ 67 - 'nurl', 68 - '--hash', 69 - f'file://{repodir}', 70 - rev 71 - ], capture_output=True, check=True).stdout.decode('utf-8') 72 - ret['attrs']['meta'] = { 73 - 'description': desc, 74 - 'homepage': origurl, 76 + ret["attrs"]["postPatch"] = f"cd {subdir}" 77 + domain, query = repourl.removeprefix("https://").split("/", 1) 78 + hash = subprocess.run( 79 + ["nurl", "--hash", f"file://{repodir}", rev], capture_output=True, check=True 80 + ).stdout.decode("utf-8") 81 + ret["attrs"]["meta"] = { 82 + "description": desc, 83 + "homepage": origurl, 75 84 } 76 - if domain == 'github.com': 77 - owner, repo = query.split('/') 78 - ret['github'] = { 79 - 'owner': owner, 80 - 'repo': repo, 81 - 'rev': rev, 82 - 'hash': hash, 85 + if domain == "github.com": 86 + owner, repo = query.split("/") 87 + ret["github"] = { 88 + "owner": owner, 89 + "repo": repo, 90 + "rev": rev, 91 + "hash": hash, 83 92 } 84 - ret['attrs']['meta']['downloadPage'] = f'{repourl}/releases' 85 - ret['attrs']['meta']['changelog'] = f'{repourl}/releases' 86 - repobase = f'{repourl}/blob/{rev}' 87 - elif HOSTNAMES.get(domain, 'gitea' if 'gitea.' in domain or 'forgejo.' in domain else None) == 'gitea': 88 - owner, repo = query.split('/') 89 - ret['gitea'] = { 90 - 'domain': domain, 91 - 'owner': owner, 92 - 'repo': repo, 93 - 'rev': rev, 94 - 'hash': hash, 93 + ret["attrs"]["meta"]["downloadPage"] = f"{repourl}/releases" 94 + ret["attrs"]["meta"]["changelog"] = f"{repourl}/releases" 95 + repobase = f"{repourl}/blob/{rev}" 96 + elif ( 97 + HOSTNAMES.get( 98 + domain, "gitea" if "gitea." in domain or "forgejo." in domain else None 99 + ) 100 + == "gitea" 101 + ): 102 + owner, repo = query.split("/") 103 + ret["gitea"] = { 104 + "domain": domain, 105 + "owner": owner, 106 + "repo": repo, 107 + "rev": rev, 108 + "hash": hash, 95 109 } 96 - repobase = f'{repourl}/src/commit/{rev}' 97 - ret['attrs']['meta']['downloadPage'] = f'{repourl}/releases' 98 - ret['attrs']['meta']['changelog'] = f'{repourl}/releases' 99 - elif HOSTNAMES.get(domain, 'gitlab' if 'gitlab.' in domain else None) == 'gitlab': 100 - owner, repo = query.split('/') 101 - ret['gitlab'] = { 102 - 'owner': owner, 103 - 'repo': repo, 104 - 'rev': rev, 105 - 'hash': hash, 110 + repobase = f"{repourl}/src/commit/{rev}" 111 + ret["attrs"]["meta"]["downloadPage"] = f"{repourl}/releases" 112 + ret["attrs"]["meta"]["changelog"] = f"{repourl}/releases" 113 + elif HOSTNAMES.get(domain, "gitlab" if "gitlab." in domain else None) == "gitlab": 114 + owner, repo = query.split("/") 115 + ret["gitlab"] = { 116 + "owner": owner, 117 + "repo": repo, 118 + "rev": rev, 119 + "hash": hash, 106 120 } 107 - if domain != 'gitlab.com': 108 - ret['gitlab']['domain'] = domain 109 - repobase = f'{repourl}/-/blob/{rev}' 121 + if domain != "gitlab.com": 122 + ret["gitlab"]["domain"] = domain 123 + repobase = f"{repourl}/-/blob/{rev}" 110 124 else: 111 - raise ValueError(f'Is {domain} Gitea or Gitlab, or something else? Please specify in the Python script!') 112 - if os.path.exists(os.path.join(plugindir, 'CHANGELOG.md')): 113 - ret['attrs']['meta']['changelog'] = f'{repobase}/CHANGELOG.md' 114 - if os.path.exists(os.path.join(plugindir, 'maubot.yaml')): 115 - with open(os.path.join(plugindir, 'maubot.yaml'), 'rt') as f: 116 - ret['manifest'] = yaml.load(f) 117 - elif os.path.exists(os.path.join(plugindir, 'pyproject.toml')): 118 - ret['isPoetry'] = True 119 - with open(os.path.join(plugindir, 'pyproject.toml'), 'rt') as f: 125 + raise ValueError( 126 + f"Is {domain} Gitea or Gitlab, or something else? Please specify in the Python script!" 127 + ) 128 + if os.path.exists(os.path.join(plugindir, "CHANGELOG.md")): 129 + ret["attrs"]["meta"]["changelog"] = f"{repobase}/CHANGELOG.md" 130 + if os.path.exists(os.path.join(plugindir, "maubot.yaml")): 131 + with open(os.path.join(plugindir, "maubot.yaml"), "rt") as f: 132 + ret["manifest"] = yaml.load(f) 133 + elif os.path.exists(os.path.join(plugindir, "pyproject.toml")): 134 + ret["isPoetry"] = True 135 + with open(os.path.join(plugindir, "pyproject.toml"), "rt") as f: 120 136 data = toml.load(f) 121 137 deps = [] 122 - for key, val in data['tool']['poetry'].get('dependencies', {}).items(): 123 - if key in ['maubot', 'mautrix', 'python']: 138 + for key, val in data["tool"]["poetry"].get("dependencies", {}).items(): 139 + if key in ["maubot", "mautrix", "python"]: 124 140 continue 125 141 reqs = [] 126 - for req in val.split(','): 142 + for req in val.split(","): 127 143 reqs.extend(poetry_to_pep(req)) 128 - deps.append(key + ', '.join(reqs)) 129 - ret['manifest'] = data['tool']['maubot'] 130 - ret['manifest']['id'] = data['tool']['poetry']['name'] 131 - ret['manifest']['version'] = data['tool']['poetry']['version'] 132 - ret['manifest']['license'] = data['tool']['poetry']['license'] 144 + deps.append(key + ", ".join(reqs)) 145 + ret["manifest"] = data["tool"]["maubot"] 146 + ret["manifest"]["id"] = data["tool"]["poetry"]["name"] 147 + ret["manifest"]["version"] = data["tool"]["poetry"]["version"] 148 + ret["manifest"]["license"] = data["tool"]["poetry"]["license"] 133 149 if deps: 134 - ret['manifest']['dependencies'] = deps 150 + ret["manifest"]["dependencies"] = deps 135 151 else: 136 - raise ValueError(f'No maubot.yaml or pyproject.toml found in {repodir}') 152 + raise ValueError(f"No maubot.yaml or pyproject.toml found in {repodir}") 137 153 # normalize non-spdx-conformant licenses this way 138 154 # (and fill out missing license info) 139 - if 'license' not in ret['manifest'] or ret['manifest']['license'] in ['GPLv3', 'AGPL 3.0']: 140 - ret['attrs']['meta']['license'] = license 141 - elif ret['manifest']['license'] != license: 142 - print(f"Warning: licenses for {repourl} don't match! {ret['manifest']['license']} != {license}") 155 + if "license" not in ret["manifest"] or ret["manifest"]["license"] in [ 156 + "GPLv3", 157 + "AGPL 3.0", 158 + ]: 159 + ret["attrs"]["meta"]["license"] = license 160 + elif ret["manifest"]["license"] != license: 161 + print( 162 + f"Warning: licenses for {repourl} don't match! {ret['manifest']['license']} != {license}" 163 + ) 143 164 if official: 144 - ret['isOfficial'] = official 165 + ret["isOfficial"] = official 145 166 PLUGINS[name] = ret 167 + 146 168 147 169 def next_incomp(ver_s: str) -> str: 148 - ver = ver_s.split('.') 170 + ver = ver_s.split(".") 149 171 zero = False 150 172 for i in range(len(ver)): 151 173 try: ··· 156 178 break 157 179 continue 158 180 if zero: 159 - ver[i] = '0' 181 + ver[i] = "0" 160 182 elif seg: 161 183 ver[i] = str(seg + 1) 162 184 zero = True 163 - return '.'.join(ver) 185 + return ".".join(ver) 164 186 165 - def poetry_to_pep(ver_req: str) -> List[str]: 166 - if '*' in ver_req: 167 - raise NotImplementedError('Wildcard poetry versions not implemented!') 168 - if ver_req.startswith('^'): 169 - return ['>=' + ver_req[1:], '<' + next_incomp(ver_req[1:])] 170 - if ver_req.startswith('~'): 171 - return ['~=' + ver_req[1:]] 187 + 188 + def poetry_to_pep(ver_req: str) -> list[str]: 189 + if "*" in ver_req: 190 + raise NotImplementedError("Wildcard poetry versions not implemented!") 191 + if ver_req.startswith("^"): 192 + return [">=" + ver_req[1:], "<" + next_incomp(ver_req[1:])] 193 + if ver_req.startswith("~"): 194 + return ["~=" + ver_req[1:]] 172 195 return [ver_req] 196 + 173 197 174 198 def main(): 175 - cache_path = os.path.join(TMP, 'maubot-plugins') 199 + cache_path = os.path.join(TMP, "maubot-plugins") 176 200 if not os.path.exists(cache_path): 177 201 os.makedirs(cache_path) 178 - git.Repo.clone_from('https://github.com/maubot/plugins.maubot.xyz', os.path.join(cache_path, '_repo')) 202 + git.Repo.clone_from( 203 + "https://github.com/maubot/plugins.maubot.xyz", 204 + os.path.join(cache_path, "_repo"), 205 + ) 179 206 else: 180 207 pass 181 208 182 - repodir = os.path.join(cache_path, '_repo') 209 + repodir = os.path.join(cache_path, "_repo") 183 210 184 - for suffix, official in (('official', True), ('thirdparty', False)): 185 - directory = os.path.join(repodir, 'data', 'plugins', suffix) 211 + for suffix, official in (("official", True), ("thirdparty", False)): 212 + directory = os.path.join(repodir, "data", "plugins", suffix) 186 213 for plugin_name in os.listdir(directory): 187 214 process_repo(os.path.join(directory, plugin_name), official) 188 215 189 - if os.path.isdir('pkgs/tools/networking/maubot/plugins'): 190 - generated = 'pkgs/tools/networking/maubot/plugins/generated.json' 216 + if os.path.isdir("pkgs/tools/networking/maubot/plugins"): 217 + generated = "pkgs/tools/networking/maubot/plugins/generated.json" 191 218 else: 192 219 script_dir = os.path.dirname(os.path.realpath(__file__)) 193 - generated = os.path.join(script_dir, 'generated.json') 220 + generated = os.path.join(script_dir, "generated.json") 194 221 195 - with open(generated, 'wt') as file: 196 - json.dump(PLUGINS, file, indent=' ', separators=(',', ': '), sort_keys=True) 197 - file.write('\n') 222 + with open(generated, "wt") as file: 223 + json.dump(PLUGINS, file, indent=" ", separators=(",", ": "), sort_keys=True) 224 + file.write("\n") 198 225 199 - if __name__ == '__main__': 226 + 227 + if __name__ == "__main__": 200 228 main()