bioLOLPython 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,64 @@
1
+ DIALECT = {
2
+ "name": "lolcat",
3
+ "era": "~2005-2012",
4
+ "description": "I CAN HAS BIOINFORMATICS? Classic lolspeak from the cheezburger era.",
5
+ "commands": {
6
+ "init": {
7
+ "pattern": "HAI GENZOME",
8
+ "greeting": "🐾 LOADING bioLOLCODE V1... LETZ GOOOO 💥",
9
+ },
10
+ "end": {
11
+ "pattern": "KTHXBYE",
12
+ },
13
+ "declare": {
14
+ "pattern": "DNA GO {name} ITZ {seq}",
15
+ },
16
+ "reverse": {
17
+ "pattern": "REVERSE THAT {name}",
18
+ },
19
+ "gc_content": {
20
+ "pattern": "GC BOMB {name}",
21
+ "response": "💥 GC content: {value:.2f}% 🧬",
22
+ },
23
+ "print": {
24
+ "pattern": "VISIBLE",
25
+ },
26
+ "transcribe": {
27
+ "pattern": "TRANSCRIBE {name}",
28
+ },
29
+ "translate": {
30
+ "pattern": "TRANSLATE {name}",
31
+ },
32
+ "align": {
33
+ "pattern": "ALIGN {a} WIT {b}",
34
+ "response": "🌈 ALINE SCOREZ: {score:.2f} 🔥 itz {rating}!!",
35
+ },
36
+ "mutate": {
37
+ "pattern": "I CRAVE VIOLENCE {name}",
38
+ "response": "💣 mutated {name} at pos {pos}: {old} ➜ {new}",
39
+ },
40
+ "length": {
41
+ "pattern": "HOW LONG {name}",
42
+ "response": "📏 {name} iz {value} bases long",
43
+ },
44
+ "complement": {
45
+ "pattern": "COMPLEMENT {name}",
46
+ },
47
+ "find_orf": {
48
+ "pattern": "FIND ORF {name}",
49
+ "orf_found": "🔍 ORF found: {orf} ({length} bp)",
50
+ "orf_missing": "🔍 No ORF found in {name} (no ATG start codon)",
51
+ },
52
+ "motif": {
53
+ "pattern": "MOTIF HUNT {name} FOR {pattern}",
54
+ "found": "🎯 Found {count} match(es) for '{pattern}' in {name}:",
55
+ "position": " pos {start}-{end}",
56
+ "not_found": "🎯 No matches for '{pattern}' in {name}",
57
+ },
58
+ },
59
+ "examples": {
60
+ "GC Content": 'HAI GENZOME 1.0\nDNA GO X ITZ "ATGCATGC"\nGC BOMB X\nKTHXBYE',
61
+ "Protein Translation": 'HAI GENZOME 1.0\nDNA GO Y ITZ "ATGGAGGAGCC"\nTRANSLATE Y\nVISIBLE "Protein: " + Y\nKTHXBYE',
62
+ "Alignment": 'HAI GENZOME 1.0\nDNA GO A ITZ "ATGCGTAGG"\nDNA GO B ITZ "ATGCGTACG"\nALIGN A WIT B\nKTHXBYE',
63
+ },
64
+ }
@@ -0,0 +1,91 @@
1
+ """
2
+ Remote dialect fetching and caching.
3
+
4
+ Fetches dialect YAML files from a remote registry (GitHub raw URL by default),
5
+ caches them locally in ~/.bioLOL/dialects/, and reloads the dialect registry.
6
+ """
7
+ import os
8
+ import time
9
+ from pathlib import Path
10
+ from urllib.request import urlopen, Request
11
+ from urllib.error import URLError
12
+
13
+ from bioLOLPython.dialects.base import USER_DIR
14
+
15
+ # Default registry: raw GitHub URL pointing to the definitions/ directory
16
+ DEFAULT_REGISTRY_URL = (
17
+ "https://raw.githubusercontent.com/ChenHsieh/bioLOLPython/master/"
18
+ "bioLOLPython/dialects/definitions"
19
+ )
20
+
21
+ # Default index file listing available dialect filenames
22
+ INDEX_FILENAME = "index.txt"
23
+
24
+ # Cache TTL: 24 hours
25
+ CACHE_TTL_SECONDS = 86400
26
+
27
+
28
+ def _ensure_user_dir():
29
+ USER_DIR.mkdir(parents=True, exist_ok=True)
30
+
31
+
32
+ def _is_cache_fresh(path, ttl=CACHE_TTL_SECONDS):
33
+ """Check if a cached file is fresh enough."""
34
+ if not path.exists():
35
+ return False
36
+ age = time.time() - path.stat().st_mtime
37
+ return age < ttl
38
+
39
+
40
+ def _fetch_url(url, timeout=10):
41
+ """Fetch content from a URL."""
42
+ req = Request(url, headers={"User-Agent": "bioLOLPython"})
43
+ with urlopen(req, timeout=timeout) as resp:
44
+ return resp.read().decode("utf-8")
45
+
46
+
47
+ def fetch_dialect(name, registry_url=DEFAULT_REGISTRY_URL):
48
+ """Fetch a single dialect YAML from the remote registry and cache it."""
49
+ _ensure_user_dir()
50
+ url = f"{registry_url}/{name}.yaml"
51
+ content = _fetch_url(url)
52
+ cache_path = USER_DIR / f"{name}.yaml"
53
+ cache_path.write_text(content)
54
+ return cache_path
55
+
56
+
57
+ def fetch_index(registry_url=DEFAULT_REGISTRY_URL):
58
+ """Fetch the index of available remote dialects."""
59
+ url = f"{registry_url}/{INDEX_FILENAME}"
60
+ content = _fetch_url(url)
61
+ return [line.strip() for line in content.splitlines() if line.strip()]
62
+
63
+
64
+ def update_dialects(registry_url=DEFAULT_REGISTRY_URL, force=False):
65
+ """Fetch all remote dialects and update local cache.
66
+
67
+ Returns a list of (name, status) tuples where status is
68
+ 'updated', 'cached', or 'error: ...'.
69
+ """
70
+ _ensure_user_dir()
71
+ results = []
72
+
73
+ # Try to fetch index; if unavailable, fetch known dialect names
74
+ try:
75
+ dialect_names = fetch_index(registry_url)
76
+ except URLError:
77
+ # Fallback: try common names
78
+ dialect_names = ["lolcat", "gen_z", "brainrot"]
79
+
80
+ for name in dialect_names:
81
+ cache_path = USER_DIR / f"{name}.yaml"
82
+ if not force and _is_cache_fresh(cache_path):
83
+ results.append((name, "cached"))
84
+ continue
85
+ try:
86
+ fetch_dialect(name, registry_url)
87
+ results.append((name, "updated"))
88
+ except Exception as e:
89
+ results.append((name, f"error: {e}"))
90
+
91
+ return results