summaryrefslogtreecommitdiff
path: root/howlers/src/howler.jac
blob: 677154929fe0416647e8d3cfbc6626b0e89f90db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import sys;
import socket;
import signal;
import mmap;
import struct;
import from types { FrameType }
import from typing { List, Dict, Optional }
import from os { path }

glob MAX_EVENTS:    int = 256;
glob DIR_SCRIPTS:   str = "";

enum EVENT {
    CHLD_PROC_START,
	CHLD_PROC_DONE,
	CHLD_PROC_FAILED,
	CHLD_PROC_HURT,
	CHLD_PROC_HEALING,
	CHLD_PROC_HEALED
}

glob EventName: Dict[EVENT, str] = {
    EVENT.CHLD_PROC_START:    "child_start",
    EVENT.CHLD_PROC_DONE:     "child_done",
    EVENT.CHLD_PROC_FAILED:   "child_failed",
    EVENT.CHLD_PROC_HURT:     "child_hurt",
    EVENT.CHLD_PROC_HEALING:  "child_healing",
    EVENT.CHLD_PROC_HEALED:   "child_healed"
};

obj SysLurchEvent_t {
    has eventTime:  int;
    has eventKind:  EVENT;
    has eventID:    int;
    has data1:      int;
    has data2:      int;
}

obj WatchMen {
    static has eventHead:   int;
    static has eventTail:   int;
    static has EventQue:    List[bytes(SysLurchEvent_t)];

    static def isBufferFull() -> bool {
        report ((eventHead + 1) % MAX_EVENTS) == eventTail;
    }
}

node Website {
    has url:            str;
    has timemout:       int;
    has retry:          int;
    has script:         str;

    has:priv _globals:  Dict;
    has:priv _locals:   Dict;

    can run with Crawler entry {
        exec(script, _globals, _locals);
        # do stuff with the data
    }
}

walker Crawler {
    has data: Dict[str, ...];

    can crawl with Website entry {
        self.data[visit.url] = visit.data;
    }
}

def fix_scrape_script(script: str) -> str by llm();

def signal_handler(sig: int, frame: Optional[FrameType]) -> None {
    print("\n\n[!] Interupt CTRL+C. Exiting...");
    sys.exit(0);
}

with entry:__main__ {
    SOCKET_PATH: str = "/tmp/lurchers.sock";

    signal.signal(signal.SIGINT, signal_handler);

    while True {
        try {
        user_input: str = input("\nsend_bytes> ");

        if user_input.strip().lower() in ["exit()", "quit()"] {
            print("exiting...");
            break;
        }

        if not user_input {
            continue;
        }

        # Ex: '{"method": "query","function": "get User","params": {"id": 1, "user": "wcole"}}'
        payload: bytes = (user_input + "\n").encode('utf-8');

        with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client {
            client.connect(SOCKET_PATH);
            client.sendall(payload);

            resp = client.recv(4096);
            if resp {
                print("\n--- Server Response ---");
                print(resp.decode('utf-8').strip());
            } else {
                print("\nData sent to server success (no data returned)");
            }
        }

        } except FileNotFoundError {
            print(f"Error: the socket file '{SOCKET_PATH}' does not exist");
        } except PermissionError {
            print(f"Error: missing permissions to write to '{SOCKET_PATH}");
        } except ConnectionRefusedError {
            print(f"Error: conn refused");
        } except Exception as e {
            print(f"Error: unexpected error occurred: {e}");
        }
    }
}