Compare commits
93 Commits
4c569e6be3
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 571d36439c | |||
| adecd40bdf | |||
| dda5bf848c | |||
| 16d0303780 | |||
| f6dedfad2d | |||
| 292feef557 | |||
| 47dcfe0514 | |||
| d14b0b1f09 | |||
| 8fb7320998 | |||
| 0df62464c6 | |||
| 87fce8bab5 | |||
| 33ce2061dd | |||
| 46f2576e50 | |||
| 2f262324d0 | |||
| c4169937fe | |||
| 75b9a35d5a | |||
| de2fb4472f | |||
| a9336a95a0 | |||
| 39d9839d1d | |||
| a36238ddd6 | |||
| 4efaffaa1c | |||
| eae6fc2d21 | |||
| 81e8098350 | |||
| 540b45f23d | |||
| b670123442 | |||
| 0afdea949c | |||
| 9260cd2645 | |||
| 89d5f4a30d | |||
| 9ae3a5e2a2 | |||
| ee0b955168 | |||
| 271a724cc8 | |||
| b496bfdc1d | |||
| a19a255803 | |||
| 6bb479ca63 | |||
| fc1a3db03c | |||
| 41f003ed92 | |||
| 61323ee24b | |||
| 5b0c81a9e4 | |||
| c8bde849c8 | |||
| 9d7db43261 | |||
| 25310c4ffc | |||
| 66ab28c118 | |||
| 02db41e938 | |||
| 0a991253b0 | |||
| d5fac9d904 | |||
| faf2f674d0 | |||
| 3e2d74afcd | |||
| 95f1476958 | |||
| 40d60edc24 | |||
| 091e80e53a | |||
| 5e34ec00ef | |||
| b1c15a30f8 | |||
| 163d67efca | |||
| 56fe41c806 | |||
| 02b206c216 | |||
| 083e52ac94 | |||
| 054cdf6d31 | |||
| cc968b637d | |||
| 92d228ed63 | |||
| 60dee8d6d4 | |||
| 3f220f1811 | |||
| df64161e57 | |||
| 52a000a172 | |||
| 1113030566 | |||
| 61c2567206 | |||
| 546249fd92 | |||
| d97a6e0e32 | |||
| 2d549e3c54 | |||
| fb87983212 | |||
| 6546e9b26d | |||
| 9a3ae8ed67 | |||
| ff70df1b4b | |||
| bf60c268a2 | |||
| 832f33bd7d | |||
| 099ef4f252 | |||
| 8cc0e5b8bc | |||
| 3ba6c6b35a | |||
| aada5c1253 | |||
| cf80f44edc | |||
| 3c2509dac3 | |||
| ea164fd94f | |||
| ff5a4c7051 | |||
| ff3ae6488c | |||
| 2a098f418f | |||
| 15f9dd41cb | |||
| e772505866 | |||
| 7a1f203ea9 | |||
| 75e81fa11e | |||
| 784012e781 | |||
| 3f8a13dc77 | |||
| eae9c91e2a | |||
| cf38ec1759 | |||
| 02a47be16a |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
.ipynb_checkpoints
|
||||
__pycache__
|
||||
cpu-bench/*.png
|
||||
|
||||
123
README.md
123
README.md
@@ -1,32 +1,109 @@
|
||||
## ThreadPoolExecutor
|
||||
```py
|
||||
__import__('concurrent').futures.ThreadPoolExecutor().submit(
|
||||
lambda x: (print(x * 2) or x ** 2 / 0), 3).result()
|
||||
## Debian
|
||||
```sh
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
sudo apt install -y curl python3-venv
|
||||
|
||||
curl -fsSL https://code-server.dev/install.sh | sh
|
||||
mkdir -p ~/.config/code-server
|
||||
tee ~/.config/code-server/config.yaml <<EOF
|
||||
bind-addr: 0.0.0.0:8888
|
||||
auth: none
|
||||
cert: false
|
||||
EOF
|
||||
sudo systemctl enable --now code-server@$USER
|
||||
|
||||
about:config
|
||||
dom.events.testing.asyncClipboard
|
||||
true
|
||||
|
||||
python3 -m venv .venv
|
||||
tee -a ~/.bash_aliases <<EOF
|
||||
export PATH=~/.venv/bin:\$PATH
|
||||
EOF
|
||||
source .bashrc
|
||||
|
||||
pip install ipykernel jupyterlab mitmproxy
|
||||
```
|
||||
|
||||
## sqlite3
|
||||
## sqlite3 [25-03-17]
|
||||
```py
|
||||
def SQL():
|
||||
def File(blob):
|
||||
try: import zmq; File.sock.send_pyobj(blob); return File.sock.recv_pyobj()
|
||||
except (AttributeError, zmq.Again):
|
||||
(sock := zmq.Context().socket(zmq.REQ)).connect('tcp://localhost:6106')
|
||||
sock.RCVTIMEO = 1000; File.sock = sock; return File(blob)
|
||||
import sqlite3, os; init = not os.path.exists('.db')
|
||||
(con := sqlite3.connect('.db', isolation_level=None)).row_factory = sqlite3.Row
|
||||
if init: con.executescript("""
|
||||
PRAGMA journal_mode=WAL;
|
||||
CREATE TABLE kv(k, v, t DEFAULT CURRENT_TIMESTAMP);
|
||||
CREATE INDEX index_kv_v ON kv(v);
|
||||
CREATE INDEX index_kv_k_t ON kv(k, t DESC);""")
|
||||
return type('', (), dict(__call__=lambda _, q, *p: list(map(dict, con.execute(q, p))),
|
||||
__setitem__=lambda sql, k, v: sql('INSERT INTO kv(k,v) VALUES(?,?)', k, File(v)),
|
||||
__getitem__=lambda sql, k: File(v[0]['v']) if (v := sql(
|
||||
'SELECT v FROM kv WHERE k=? ORDER BY t DESC LIMIT 1', k)) else None,
|
||||
__contains__=lambda sql, k: bool(sql('SELECT 1 FROM kv WHERE k=?', k))))()
|
||||
import sqlite3, os, json
|
||||
class SQL:
|
||||
def __init__(sql, db='.db'):
|
||||
if not os.path.exists(db): os.makedirs(db); SQL(db).con.executescript(
|
||||
"PRAGMA journal_mode=WAL; CREATE TABLE kv(k,v,t DEFAULT CURRENT_TIMESTAMP);"
|
||||
"CREATE INDEX idx_kv_v ON kv(v); CREATE INDEX idx_kv_k_t ON kv(k,t DESC);")
|
||||
(con := sqlite3.connect(f'{db}/sql', check_same_thread=False,
|
||||
isolation_level=None)).execute(f"PRAGMA busy_timeout={1e9}")
|
||||
sql.con, sql.db = con, db
|
||||
def __call__(sql, q, *p): return [*sql.con.execute(q, p)]
|
||||
def __setitem__(sql, k, v): return sql("INSERT INTO kv(k,v) VALUES(?,?)",
|
||||
k, v if type(v) is bytes else json.dumps(v, ensure_ascii=False))
|
||||
def __getitem__(sql, k):
|
||||
if (v := sql("SELECT v FROM kv WHERE k=? ORDER BY t DESC LIMIT 1", k)):
|
||||
return json.loads(v) if type(v := v[0][0]) is str else v
|
||||
def __delitem__(sql, rows):
|
||||
for row in rows: sql("DELETE FROM kv WHERE k=? AND v=? AND t=?", *row)
|
||||
def __contains__(sql, k): return bool(sql("SELECT 1 FROM kv WHERE k=?", k))
|
||||
def __eq__(sql, query): return sql("SELECT * FROM kv WHERE k LIKE ?", query)
|
||||
def __ne__(sql, query): return sql("SELECT * FROM kv WHERE k NOT LIKE ?", query)
|
||||
def __repr__(sql): return f"SQL(db={sql.db})"
|
||||
sql = SQL()
|
||||
```
|
||||
|
||||
## tauri + svelte + shadcn
|
||||
```sh
|
||||
git clone https://github.com/alysonhower/tauri2-svelte5-shadcn.git
|
||||
cd tauri2-svelte5-shadcn
|
||||
bun i
|
||||
bun run dev -- --host
|
||||
```
|
||||
|
||||
## syncify
|
||||
```py
|
||||
def sync(coro):
|
||||
import asyncio, functools, nest_asyncio; nest_asyncio.apply()
|
||||
return functools.wraps(coro)(lambda *args, **kwargs:
|
||||
asyncio.run(coro(*args, **kwargs)))
|
||||
|
||||
@sync
|
||||
async def main(): print('hello'); return 'world'
|
||||
|
||||
main()
|
||||
```
|
||||
|
||||
## playwright [25-03-01]
|
||||
```python
|
||||
def Page():
|
||||
def sync(obj):
|
||||
import asyncio, functools
|
||||
if asyncio.iscoroutine(coro := obj):
|
||||
loop, future = asyncio.get_event_loop(), asyncio.ensure_future(coro)
|
||||
while not future.done():
|
||||
loop._process_events(loop._selector.select(0))
|
||||
if (ready := loop._ready) and not (handle := ready.popleft())._cancelled:
|
||||
task = (tasks := asyncio.tasks._current_tasks).pop(loop, None)
|
||||
handle._run()
|
||||
tasks[loop] = task
|
||||
return future.result()
|
||||
if asyncio.iscoroutinefunction(func := obj): return functools.wraps(func)(
|
||||
lambda *args, **kwargs: sync(func(*args, **kwargs)))
|
||||
for attr in dir(obj):
|
||||
if asyncio.iscoroutinefunction(method := getattr(obj, attr)):
|
||||
setattr(obj, attr, sync(method))
|
||||
return obj
|
||||
|
||||
from playwright.async_api import async_playwright
|
||||
browser = sync(sync(async_playwright().start()).firefox.launch())
|
||||
page = sync(sync(browser.new_page()))
|
||||
page._repr_png_ = page.screenshot
|
||||
return page
|
||||
|
||||
page = Page()
|
||||
page.goto('https://naver.com')
|
||||
page
|
||||
```
|
||||
|
||||
# wireguard
|
||||
```powershell
|
||||
wg genkey|%{$_;$_|wg pubkey}
|
||||
|
||||
8
User-Agent Client Hints/REAMDE.md
Normal file
8
User-Agent Client Hints/REAMDE.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# User-Agent보다 정밀하게 Browser를 Fingerprinting 하는 기능
|
||||
- https://github.com/ungoogled-software/ungoogled-chromium/issues/1422
|
||||
- firefox에서는 Off / Chrome/Chromium에서는 끌수 없음 `--disable-features=UserAgentClientHint`
|
||||
|
||||
# Test
|
||||
https://browserleaks.com/client-hints
|
||||
|
||||
|
||||
46
adb/README.md
Normal file
46
adb/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Android Studio
|
||||
- https://developer.android.com/studio
|
||||
- Disable AVD during installation
|
||||
- Blank project
|
||||
- Permit USB from Phone
|
||||
|
||||
# User env
|
||||
`%LOCALAPPDATA%\Android\sdk\platform-tools`
|
||||
|
||||
```shell
|
||||
adb devices
|
||||
List of devices attached
|
||||
R3CW70RGJMW device
|
||||
|
||||
adb forward tcp:8080 tcp:8080
|
||||
|
||||
pkg update && pkg upgrade -y
|
||||
|
||||
# netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 connectaddress=127.0.0.1 connectport=8080
|
||||
```
|
||||
|
||||
# proot
|
||||
```shell
|
||||
proot-distro list
|
||||
proot-distro install debian
|
||||
proot-distro login debian
|
||||
|
||||
apt updtate
|
||||
apt install -y mitmdump
|
||||
|
||||
mitmdump -q
|
||||
|
||||
curl -x localhost:8080 ip.yauk.tv
|
||||
```
|
||||
|
||||
https://m.blog.naver.com/wonjinho81/222597996987
|
||||
|
||||
# KeepAlive
|
||||
|
||||
```shell
|
||||
adb -a nodaemon server start # blocking
|
||||
adb forward tcp:8080 tcp:8080 # reentrant
|
||||
|
||||
adb shell svc data disable
|
||||
adb shell svc data enable
|
||||
```
|
||||
68
asyncio-threading/README.md
Normal file
68
asyncio-threading/README.md
Normal file
@@ -0,0 +1,68 @@
|
||||
```python
|
||||
"""
|
||||
This gist shows how to run asyncio loop in a separate thread.
|
||||
It could be useful if you want to mix sync and async code together.
|
||||
Python 3.7+
|
||||
"""
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from threading import Thread
|
||||
from typing import Tuple, List, Iterable
|
||||
|
||||
import httpx
|
||||
|
||||
URLS = [
|
||||
"https://pypi.org",
|
||||
"https://python.org",
|
||||
"https://google.com",
|
||||
"https://amazon.com",
|
||||
"https://reddit.com",
|
||||
"https://stackoverflow.com",
|
||||
"https://ubuntu.com",
|
||||
"https://github.com",
|
||||
"https://microsoft.com",
|
||||
]
|
||||
|
||||
|
||||
def start_background_loop(loop: asyncio.AbstractEventLoop) -> None:
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_forever()
|
||||
|
||||
|
||||
async def fetch(url: str) -> Tuple[str, int]:
|
||||
"""Does HTTP get on url and returns url and status code"""
|
||||
async with httpx.AsyncClient() as session:
|
||||
response = await session.get(url)
|
||||
return url, response.status_code
|
||||
|
||||
|
||||
async def fetch_all_urls(urls: Iterable[str]) -> List[Tuple[str, int]]:
|
||||
"""Fetch all urls from the list of urls
|
||||
|
||||
It is done concurrently and combined into a single coroutine"""
|
||||
tasks = [asyncio.create_task(fetch(url)) for url in urls]
|
||||
results = await asyncio.gather(*tasks)
|
||||
return results
|
||||
|
||||
|
||||
def main() -> None:
|
||||
loop = asyncio.new_event_loop()
|
||||
t = Thread(target=start_background_loop, args=(loop,), daemon=True)
|
||||
t.start()
|
||||
|
||||
start_time = datetime.now()
|
||||
|
||||
task = asyncio.run_coroutine_threadsafe(fetch_all_urls(URLS), loop)
|
||||
for url, status_code in task.result():
|
||||
print(f"{url} -> {status_code}")
|
||||
|
||||
exec_time = (datetime.now() - start_time).total_seconds()
|
||||
print(f"It took {exec_time:,.2f} seconds to run")
|
||||
loop.stop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
```
|
||||
CREDIT: https://gist.githubusercontent.com/dmfigol/3e7d5b84a16d076df02baa9f53271058/raw/dd7f9acf7afcc3c68b2b363d2e17ff6393dbde43/asyncio_loop_in_thread.py
|
||||
18
beej/telnot.go
Normal file
18
beej/telnot.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import ("fmt";"io";"log";"net";"os")
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 3 {
|
||||
log.Fatal("usage: telnot hostname port")
|
||||
}
|
||||
hostname, port := os.Args[1], os.Args[2]
|
||||
if conn, err := net.Dial("tcp", net.JoinHostPort(hostname, port)); err != nil {
|
||||
log.Fatal("failed to connect:", err)
|
||||
} else {
|
||||
defer conn.Close()
|
||||
fmt.Printf("Connected to %s port %s\nHit ^C to exit\n", hostname, port)
|
||||
go io.Copy(conn, os.Stdin)
|
||||
io.Copy(os.Stdout, conn)
|
||||
}
|
||||
}
|
||||
58
browser/README.md
Normal file
58
browser/README.md
Normal file
@@ -0,0 +1,58 @@
|
||||
```python
|
||||
def Browser(cdp='localhost:9222', browser=type('', (), {})):
|
||||
import os, json, requests, websocket
|
||||
try: requests.get(f'http://{cdp}/json/version', timeout=0.1)
|
||||
except requests.exceptions.RequestException:
|
||||
os.popen('wsl chromium --proxy-server=172.17.112.1:8080 --ignore-certificate-errors --remote-debugging-port=9222 --remote-allow-origins=* --user-agent="Mozilla/5.0 (Linux; Android 15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.122 Mobile Safari/537.36"')
|
||||
browser.url = requests.get(
|
||||
f'http://{cdp}/json/version').json()['webSocketDebuggerUrl']
|
||||
def send(url, request):
|
||||
ws = websocket.create_connection(url)
|
||||
try: ws.send(json.dumps(request)); return json.loads(ws.recv())
|
||||
finally: ws.close()
|
||||
|
||||
def Page(page=type('', (), {})):
|
||||
page.url = f'ws://{cdp}/devtools/page/' + send(browser.url, {
|
||||
"id": 1,
|
||||
"method": "Target.createTarget",
|
||||
"params": {
|
||||
"url": "about:blank",
|
||||
"newWindow": True,
|
||||
"background": False
|
||||
}
|
||||
})['result']['targetId']
|
||||
|
||||
def goto(url):
|
||||
if '://' not in url: url = f'https://{url}'
|
||||
send(page.url, {
|
||||
"id": 1,
|
||||
"method": "Page.navigate",
|
||||
"params": {
|
||||
"url": url
|
||||
}
|
||||
})
|
||||
|
||||
def evaluate(javascript):
|
||||
result = send(page.url, {
|
||||
"id": 1,
|
||||
"method": "Runtime.evaluate",
|
||||
"params": {
|
||||
"expression": javascript,
|
||||
"returnByValue": True
|
||||
}
|
||||
})
|
||||
if 'result' in result and 'result' in result['result']:
|
||||
return result['result']['result'].get('value')
|
||||
elif 'exceptionDetails' in result['result']:
|
||||
raise Exception(f"JavaScript execution failed: {result['result']['exceptionDetails']}")
|
||||
|
||||
page.goto = goto
|
||||
page.evaluate = evaluate
|
||||
return page
|
||||
browser.new_page = Page
|
||||
return browser
|
||||
browser = Browser()
|
||||
page = browser.new_page()
|
||||
page.goto('example.org')
|
||||
page.evaluate('console.log("hello, world")')
|
||||
```
|
||||
54
chrome/README.md
Normal file
54
chrome/README.md
Normal file
@@ -0,0 +1,54 @@
|
||||
```python
|
||||
def Chrome(agent=None, proxy=None, cookies=[], headless=True):
|
||||
import requests, subprocess, base64
|
||||
try: requests.get(f'http://localhost:9222', timeout=.1)
|
||||
except: subprocess.Popen(['chrome', f'--remote-debugging-port={9222}',
|
||||
*([f'--user-agent={agent}'] if agent else []), *(['--headless=new'] if headless else []),
|
||||
*([f'--proxy-server={proxy}'] if proxy else []), '--disable-web-security',
|
||||
'--disable-translate', '--ignore-certificate-errors', '--remote-allow-origins=*',
|
||||
'--disable-backgrounding-occluded-windows',])
|
||||
browser = requests.get(f'http://localhost:9222/json/version').json()['webSocketDebuggerUrl']
|
||||
def Page():
|
||||
def send(url, request):
|
||||
try: import json, websocket; (ws := websocket.create_connection(url)
|
||||
).send(json.dumps(request)); return json.loads(ws.recv())
|
||||
finally: ws.close()
|
||||
page = 'ws://localhost:9222/devtools/page/' + (targetId := send(browser,
|
||||
dict(id=1, method='Target.createTarget',
|
||||
params=dict(url='about:blank', newWindow=True)))['result']['targetId'])
|
||||
def evaluate(self, javascript):
|
||||
try: return (res := self('Runtime.evaluate',
|
||||
expression=javascript, returnByValue=True)['result'])['value']
|
||||
except: raise Exception(res)
|
||||
def wait_element(self, selector, timeout=30, check_interval=0.5):
|
||||
import time; start_time = time.time()
|
||||
while time.time() - start_time < timeout:
|
||||
if self.evaluate(f"!!(document.querySelector('{selector}'))"): return
|
||||
self.sleep(check_interval)
|
||||
raise TimeoutError(f"Element '{selector}' not found within {timeout} seconds")
|
||||
def cookies(self, cookies=None):
|
||||
if cookies is None: return self('Network.getAllCookies')['cookies']
|
||||
self('Network.clearBrowserCookies')
|
||||
for cookie in cookies: self('Network.setCookie', **cookie)
|
||||
def screenshot(self):
|
||||
from IPython.display import HTML; display(HTML(
|
||||
f'<img src="data:image/png;base64,{self('Page.captureScreenshot')['data']}">'))
|
||||
def goto(self, url):
|
||||
self('Page.navigate', url=url if '://' in url else f'https://{url}')
|
||||
while self.evaluate('document.readyState') != 'complete': self.sleep(0.1)
|
||||
Soup = lambda html: __import__('bs4').BeautifulSoup(html, 'lxml')
|
||||
return Soup(self.source())
|
||||
return type('', (), dict(__call__=lambda _, method, **params:
|
||||
send(page, {"id": 1, "method": method, "params": params})['result'],
|
||||
close=lambda self: self('Target.closeTarget', targetId=targetId)['success'],
|
||||
sleep=lambda _, seconds: __import__('time').sleep(seconds), goto=goto,
|
||||
evaluate=evaluate, wait_element=wait_element, cookies=cookies, screenshot=screenshot,
|
||||
source=lambda self: self.evaluate('document.documentElement.outerHTML')))()
|
||||
(page := Page()).cookies(cookies); return page
|
||||
|
||||
page = Chrome()
|
||||
print(page.goto('naver.com').title) # <title>NAVER</title>
|
||||
page.wait_element('img')
|
||||
page.screenshot()
|
||||
page.evaluate('2 + 2'), page.evaluate('window.location.href') # (5, 'https://www.naver.com/')
|
||||
```
|
||||
@@ -1,5 +1,17 @@
|
||||
```python
|
||||
for i,x in enumerate('RGYBMC'):globals()[x]=lambda s,i=i:f'\x1b[{91+i}m{s}\x1b[0m'
|
||||
|
||||
for i,x in enumerate('rgybmcRGYBMC'):globals()[x]=lambda s,i=i:f'\x1b[{31+i//6*60+i%6}m{s}\x1b[0m'
|
||||
|
||||
print(r('hello'), R('hello'))
|
||||
|
||||
|
||||
def color(text, code=None):
|
||||
if code: code = int(__import__('hashlib').sha1(code.encode()).hexdigest(), 16)
|
||||
else: code = int(__import__('random').random() * 214)
|
||||
return f'\x1b[38;5;{code % 214 + 17}m{text}\x1b[0m'
|
||||
|
||||
print(color('hello'))
|
||||
print(color('world'))
|
||||
print(color('fixed', 'fixed'))
|
||||
```
|
||||
@@ -1,3 +1,10 @@
|
||||
FROM python:slim
|
||||
|
||||
RUN apt update && apt install -y sysbench fastfetch
|
||||
|
||||
RUN pip install tqdm pandas tabulate
|
||||
|
||||
RUN tee bench.py <<EOF
|
||||
#!/usr/bin/env python
|
||||
|
||||
def ensure(*packages):
|
||||
@@ -12,7 +19,7 @@ from tabulate import tabulate
|
||||
warnings.filterwarnings("ignore")
|
||||
R, G, B, W = (f'\x1b[{x}m' for x in (31, 32, 34, 0))
|
||||
subprocess.run('clear')
|
||||
subprocess.run('neofetch')
|
||||
subprocess.run('fastfetch')
|
||||
|
||||
command = lambda core: f'sysbench cpu --cpu-max-prime=20000 --time=1 --threads={core} run | grep second'
|
||||
|
||||
@@ -26,13 +33,15 @@ def speed(core):
|
||||
return float(output)
|
||||
|
||||
df = []
|
||||
prev = 0
|
||||
for core in range(1, mp.cpu_count()+1):
|
||||
s = speed(core)
|
||||
row = {
|
||||
'#Threads': core,
|
||||
'Throughput(/s)': s,
|
||||
'(per-core)': s/core
|
||||
'(per-core)': s - prev
|
||||
}
|
||||
prev = s
|
||||
df.append(row)
|
||||
df = pd.DataFrame(df)
|
||||
df.to_csv('result.csv', index=False)
|
||||
@@ -41,3 +50,6 @@ df.iloc[:, 0] = df.iloc[:, 0].apply(lambda s: f'{R}{s}{W}')
|
||||
df.iloc[:, 1] = df.iloc[:, 1].apply(lambda s: f'{G}{int(s)}{W}')
|
||||
df.iloc[:, 2] = df.iloc[:, 2].apply(lambda s: f'{B}{int(s)}{W}')
|
||||
print(tabulate(df, headers='keys', tablefmt='rounded_outline', showindex=False))
|
||||
EOF
|
||||
|
||||
ENTRYPOINT ["python", "bench.py"]
|
||||
4
cpu-bench/Makefile
Normal file
4
cpu-bench/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
all: build
|
||||
docker run yauk.tv/bench
|
||||
build:
|
||||
sudo docker build . -t yauk.tv/bench
|
||||
19
cron/README.md
Normal file
19
cron/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
compose.yml
|
||||
```yml
|
||||
services:
|
||||
cron:
|
||||
build:
|
||||
dockerfile_inline: |
|
||||
FROM alpine
|
||||
RUN apk add --no-cache openssh
|
||||
volumes: [$HOME/.ssh:/root/.ssh]
|
||||
network_mode: host
|
||||
entrypoint: ssh $USER@localhost
|
||||
stop_grace_period: 0s
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- |
|
||||
cd /Users/w/dock/public/radiology.yauk.tv
|
||||
/Users/w/.venv/bin/python main.py
|
||||
tail -f /dev/null
|
||||
```
|
||||
75
fedora/README.md
Normal file
75
fedora/README.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# 한글
|
||||
- Fedora 42에서 별도 프로그램 설치 없이 한영키=RAlt로 쉽게 설정 가능 Korean(한글)
|
||||
- RAlt가 한박자 느리게 작동하는 문제 (KeyDown이 아니라 KeyUp에서 반응하는 느낌)
|
||||
|
||||
# 설치
|
||||
```sh
|
||||
curl -fsSL https://code-server.dev/install.sh | sh
|
||||
sudo systemctl enable --now code-server@$USER
|
||||
vi .config/code-server/config.yaml
|
||||
|
||||
sudo dnf install -y golang nodejs npm
|
||||
go version
|
||||
node -v
|
||||
|
||||
go install github.com/wailsapp/wails/v2/cmd/wails@latest
|
||||
|
||||
pip install mitmproxy
|
||||
|
||||
tee -a .bashrc <<'EOF'
|
||||
export GOPATH=$HOME/go
|
||||
export PATH=$PATH:$GOPATH/bin
|
||||
|
||||
sudo dnf install cmake
|
||||
|
||||
sudo dnf config-manager addrepo --from-repofile https://developer.download.nvidia.com/compute/cuda/repos/fedora42/x86_64/cuda-fedora42.repo
|
||||
sudo dnf clean all
|
||||
sudo dnf -y install cuda-toolkit-13-0
|
||||
EOF
|
||||
```
|
||||
|
||||
# Firefox developer edition
|
||||
```sh
|
||||
#!/bin/bash
|
||||
|
||||
# Download Firefox Developer Edition
|
||||
cd ~/Downloads
|
||||
wget -O firefox-developer-edition.tar.bz2 "https://download.mozilla.org/?product=firefox-devedition-latest-ssl&os=linux64&lang=en-GB"
|
||||
|
||||
# Extract to ~/.local/opt
|
||||
mkdir -p ~/.local/opt
|
||||
tar -xf firefox-developer-edition.tar.bz2 -C ~/.local/opt/
|
||||
mv ~/.local/opt/firefox ~/.local/opt/firefox-developer-edition
|
||||
|
||||
# Create symlink in ~/.local/bin
|
||||
mkdir -p ~/.local/bin
|
||||
ln -sf ~/.local/opt/firefox-developer-edition/firefox ~/.local/bin/firefox-dev
|
||||
|
||||
# Create desktop entry
|
||||
mkdir -p ~/.local/share/applications
|
||||
cat > ~/.local/share/applications/firefox-developer-edition.desktop << EOF
|
||||
[Desktop Entry]
|
||||
Name=Firefox Developer Edition
|
||||
GenericName=Web Browser
|
||||
Comment=Browse the World Wide Web
|
||||
Keywords=Internet;WWW;Browser;Web;Explorer
|
||||
Exec=$HOME/.local/bin/firefox-dev %u
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=$HOME/.local/opt/firefox-developer-edition/browser/chrome/icons/default/default128.png
|
||||
Categories=Network;WebBrowser;
|
||||
MimeType=text/html;text/xml;application/xhtml+xml;x-scheme-handler/http;x-scheme-handler/https;
|
||||
StartupNotify=true
|
||||
EOF
|
||||
|
||||
# Update desktop database
|
||||
update-desktop-database ~/.local/share/applications/
|
||||
|
||||
# Update KDE cache
|
||||
kbuildsycoca5 2>/dev/null || true
|
||||
|
||||
# Clean up
|
||||
rm ~/Downloads/firefox-developer-edition.tar.bz2
|
||||
|
||||
echo "Firefox Developer Edition installed successfully!"
|
||||
```
|
||||
23
frontend/.gitignore
vendored
Normal file
23
frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
node_modules
|
||||
|
||||
# Output
|
||||
.output
|
||||
.vercel
|
||||
.netlify
|
||||
.wrangler
|
||||
/.svelte-kit
|
||||
/build
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.test
|
||||
|
||||
# Vite
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
1
frontend/.npmrc
Normal file
1
frontend/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
engine-strict=true
|
||||
38
frontend/README.md
Normal file
38
frontend/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# sv
|
||||
|
||||
Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli).
|
||||
|
||||
## Creating a project
|
||||
|
||||
If you're seeing this, you've probably already done this step. Congrats!
|
||||
|
||||
```sh
|
||||
# create a new project in the current directory
|
||||
npx sv create
|
||||
|
||||
# create a new project in my-app
|
||||
npx sv create my-app
|
||||
```
|
||||
|
||||
## Developing
|
||||
|
||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
|
||||
# or start the server and open the app in a new browser tab
|
||||
npm run dev -- --open
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
To create a production version of your app:
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
You can preview the production build with `npm run preview`.
|
||||
|
||||
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
|
||||
13
frontend/jsconfig.json
Normal file
13
frontend/jsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": false,
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
||||
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
||||
2161
frontend/package-lock.json
generated
Normal file
2161
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
24
frontend/package.json
Normal file
24
frontend/package.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"prepare": "svelte-kit sync || echo ''"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^6.1.0",
|
||||
"@sveltejs/kit": "^2.43.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^6.2.0",
|
||||
"@tailwindcss/vite": "^4.1.13",
|
||||
"svelte": "^5.39.5",
|
||||
"tailwindcss": "^4.1.13",
|
||||
"vite": "^7.1.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"pretendard": "^1.3.9"
|
||||
}
|
||||
}
|
||||
6
frontend/src/app.css
Normal file
6
frontend/src/app.css
Normal file
@@ -0,0 +1,6 @@
|
||||
@import 'tailwindcss';
|
||||
@import 'pretendard/dist/web/variable/pretendardvariable.css';
|
||||
|
||||
body {
|
||||
font-family: 'Pretendard Variable', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
|
||||
}
|
||||
11
frontend/src/app.html
Normal file
11
frontend/src/app.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
1
frontend/src/lib/assets/favicon.svg
Normal file
1
frontend/src/lib/assets/favicon.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.157 22.819c-10.4-14.885-30.94-19.297-45.792-9.835L22.282 29.608A29.92 29.92 0 0 0 8.764 49.65a31.5 31.5 0 0 0 3.108 20.231 30 30 0 0 0-4.477 11.183 31.9 31.9 0 0 0 5.448 24.116c10.402 14.887 30.942 19.297 45.791 9.835l26.083-16.624A29.92 29.92 0 0 0 98.235 78.35a31.53 31.53 0 0 0-3.105-20.232 30 30 0 0 0 4.474-11.182 31.88 31.88 0 0 0-5.447-24.116" style="fill:#ff3e00"/><path d="M45.817 106.582a20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.503 18 18 0 0 1 .624-2.435l.49-1.498 1.337.981a33.6 33.6 0 0 0 10.203 5.098l.97.294-.09.968a5.85 5.85 0 0 0 1.052 3.878 6.24 6.24 0 0 0 6.695 2.485 5.8 5.8 0 0 0 1.603-.704L69.27 76.28a5.43 5.43 0 0 0 2.45-3.631 5.8 5.8 0 0 0-.987-4.371 6.24 6.24 0 0 0-6.698-2.487 5.7 5.7 0 0 0-1.6.704l-9.953 6.345a19 19 0 0 1-5.296 2.326 20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.502 17.99 17.99 0 0 1 8.13-12.052l26.081-16.623a19 19 0 0 1 5.3-2.329 20.72 20.72 0 0 1 22.237 8.243 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-.624 2.435l-.49 1.498-1.337-.98a33.6 33.6 0 0 0-10.203-5.1l-.97-.294.09-.968a5.86 5.86 0 0 0-1.052-3.878 6.24 6.24 0 0 0-6.696-2.485 5.8 5.8 0 0 0-1.602.704L37.73 51.72a5.42 5.42 0 0 0-2.449 3.63 5.79 5.79 0 0 0 .986 4.372 6.24 6.24 0 0 0 6.698 2.486 5.8 5.8 0 0 0 1.602-.704l9.952-6.342a19 19 0 0 1 5.295-2.328 20.72 20.72 0 0 1 22.237 8.242 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-8.13 12.053l-26.081 16.622a19 19 0 0 1-5.3 2.328" style="fill:#fff"/></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
frontend/src/lib/index.js
Normal file
1
frontend/src/lib/index.js
Normal file
@@ -0,0 +1 @@
|
||||
// place files you want to import through the `$lib` alias in this folder.
|
||||
12
frontend/src/routes/+layout.svelte
Normal file
12
frontend/src/routes/+layout.svelte
Normal file
@@ -0,0 +1,12 @@
|
||||
<script>
|
||||
import '../app.css';
|
||||
import favicon from '$lib/assets/favicon.svg';
|
||||
|
||||
let { children } = $props();
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<link rel="icon" href={favicon} />
|
||||
</svelte:head>
|
||||
|
||||
{@render children?.()}
|
||||
1
frontend/src/routes/+page.svelte
Symbolic link
1
frontend/src/routes/+page.svelte
Symbolic link
@@ -0,0 +1 @@
|
||||
/home/j/venv/todo.yauk.tv/+page.svelte
|
||||
3
frontend/static/robots.txt
Normal file
3
frontend/static/robots.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
# allow crawling everything by default
|
||||
User-agent: *
|
||||
Disallow:
|
||||
13
frontend/svelte.config.js
Normal file
13
frontend/svelte.config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import adapter from '@sveltejs/adapter-auto';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
|
||||
adapter: adapter()
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
||||
8
frontend/vite.config.js
Normal file
8
frontend/vite.config.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [tailwindcss(), sveltekit()],
|
||||
server: {allowedHosts: true}
|
||||
});
|
||||
5
golang/README.md
Normal file
5
golang/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Hot reload
|
||||
```bash
|
||||
go install github.com/air-verse/air@latest
|
||||
air
|
||||
```
|
||||
60
golang/tcpproxy.go
Normal file
60
golang/tcpproxy.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Example usage:
|
||||
// Terminal 1: python -m http.server 8000
|
||||
// Terminal 2: go run tcpproxy.go 9000 localhost:8000
|
||||
// Terminal 3: curl localhost:9000
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Println("Usage: go run tcpproxy.go <listen_port> <target_host:port>")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
listenPort := os.Args[1] // port to listen on
|
||||
targetAddr := os.Args[2] // target server address
|
||||
|
||||
// create TCP listener on specified port
|
||||
listener, err := net.Listen("tcp", ":"+listenPort)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to listen on port %s: %v\n", listenPort, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer listener.Close()
|
||||
|
||||
fmt.Printf("TCP proxy listening on port %s, forwarding to %s\n", listenPort, targetAddr)
|
||||
|
||||
// accept incoming connections
|
||||
for {
|
||||
clientConn, err := listener.Accept()
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to accept connection: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// handle each client connection concurrently
|
||||
go handleConnection(clientConn, targetAddr)
|
||||
}
|
||||
}
|
||||
|
||||
func handleConnection(clientConn net.Conn, targetAddr string) {
|
||||
defer clientConn.Close() // ensure client connection is closed
|
||||
|
||||
// connect to target server
|
||||
serverConn, err := net.Dial("tcp", targetAddr)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to connect to target %s: %v\n", targetAddr, err)
|
||||
return
|
||||
}
|
||||
defer serverConn.Close() // ensure server connection is closed
|
||||
|
||||
// start bidirectional data copying
|
||||
go io.Copy(serverConn, clientConn) // client -> server
|
||||
io.Copy(clientConn, serverConn) // server -> client (blocks until done)
|
||||
}
|
||||
@@ -1,226 +1,94 @@
|
||||
export CLOUDFLARE_API_TOKEN=Pah8Q6hBUsQsKnKhaMJB2QvL-LHAWCcU8xti66Q3
|
||||
dive(){ docker exec -it "$@" bash }
|
||||
alias reboot='sudo reboot'
|
||||
alias restart='docker restart'
|
||||
export HOMEBREW_NO_ENV_HINTS=true
|
||||
alias wg="sudo wg"
|
||||
# alias wg="docker exec wg wg "
|
||||
# alias caddy="docker exec -w /etc/caddy caddy caddy fmt --overwrite; docker exec -w /etc/caddy caddy caddy reload"
|
||||
# alias caddy-passwd="docker exec -w /etc/caddy caddy caddy hash-password -p"
|
||||
alias up="docker compose down; docker compose up -d --remove-orphans; docker compose logs -f"
|
||||
alias vite="npm run dev -- --host 0.0.0.0"
|
||||
alias cls="clear"
|
||||
alias nginx="docker exec -it nginx bash"
|
||||
export GGML_CUDA=1
|
||||
export LLAMA_CURL=1
|
||||
export LLAMA_ARG_N_GPU_LAYERS=99
|
||||
export LLAMA_ARG_FLASH_ATTN=1
|
||||
export LLAMA_ARG_HOST="0.0.0.0"
|
||||
export LLAMA_ARG_HF_REPO="bartowski/Phi-3-medium-128k-instruct-GGUF"
|
||||
export LLAMA_ARG_HF_FILE="Phi-3-medium-128k-instruct-Q4_K_S.gguf"
|
||||
export LLAMA_ARG_CTX_SIZE=65536
|
||||
# >>>> PATH
|
||||
export CEF_PATH="$HOME/.local/share/cef"
|
||||
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$CEF_PATH"
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./build/bin
|
||||
export PATH="/Users/w/.venv/bin:$PATH:$HOME/go/bin"
|
||||
export PATH="$HOME/hub/llama.cpp/build/bin:$PATH"
|
||||
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:/usr/local/lib:$LD_LIBRARY_PATH:$CEF_PATH:./build/bin"
|
||||
export GOPATH=$HOME/go
|
||||
export PATH="/usr/local/cuda/bin:$HOME/hub/depot_tools:$HOME/.venv/bin:$HOME/hub/llama.cpp/build/bin::$PATH:$HOME/go/bin:."
|
||||
export HOMEBREW_NO_AUTO_UPDATE=1
|
||||
|
||||
# export LANG=C.UTF-8
|
||||
# export LC_ALL=C.UTF-8
|
||||
export HOMEBREW_NO_ENV_HINTS=true
|
||||
export LLAMA_ARG_HF_REPO=unsloth/gemma-3n-E4B-it-GGUF:Q4_K_XL
|
||||
export LLAMA_ARG_N_GPU_LAYERS=99
|
||||
export LLAMA_ARG_HOST="0.0.0.0"
|
||||
export LLAMA_ARG_CTX_SIZE=16384
|
||||
# export LANG=ko_KR.UTF-8
|
||||
# export LC_CTYPE=ko_KR.UTF-8
|
||||
|
||||
|
||||
alias rerun="docker compose down && docker compose up -d --build && docker compose logs -f"
|
||||
export PATH="/Users/w/hub/wireguard-go/:/Users/w/.venv/bin:/usr/local/bin:/home/w/.cache/ms-playwright/chromium-1129/chrome-linux:$PATH"
|
||||
# export OLLAMA_HOST=host.docker.internal:11434
|
||||
|
||||
alias rp=runpodctl
|
||||
export PATH="/home/w/hub/llama.cpp/build/bin:/usr/local/bin:/home/w/.cache/ms-playwright/chromium-1129/chrome-linux:$PATH"
|
||||
export COMPOSE_STOP_GRACE_PERIOD=0
|
||||
export PATH=/usr/bin:$PATH
|
||||
alias prune="docker system prune -f"
|
||||
alias rc="vi ~/.bash_aliases && tail ~/.bash_aliases && source ~/.bash_aliases"
|
||||
# alias up="down && docker compose up --remove-orphans"
|
||||
alias down="docker compose down"
|
||||
pkill() { pkill -f "$@" ; ps ux ; }
|
||||
inspect() { docker image inspect "$@" | jq ; }
|
||||
alias d="docker"
|
||||
alias c="docker compose"
|
||||
alias i="sudo apt-get install -y"
|
||||
alias run="docker build . -t temp && docker run --network host --rm temp"
|
||||
alias debian="docker run -it --rm --gpus all pytorch/pytorch:2.4.0-cuda12.4-cudnn9-devel bash"
|
||||
check() { curl -x "localhost:$1" -k https://httpbin.org/ip; }
|
||||
redis-lastsave() { redis-cli "$@" --raw lastsave | xargs -I{} date -d @{} "+%Y-%m-%d %H:%M:%S"; }
|
||||
redis-dump() { sudo rsync -a /var/lib/redis/dump.rdb ~/.backup/dump.rdb-$(date +%Y%m%d); }
|
||||
alias systemctl="sudo systemctl"
|
||||
|
||||
# cd() { clear; echo "$(pwd)/$*"; echo; command cd "$@" && ls -lh --color=auto; echo; }
|
||||
alias ip="ip -4"
|
||||
alias py="python"
|
||||
alias p="python"
|
||||
|
||||
alias my="sudo chown -R $(id -u):$(id -g)"
|
||||
alias l="clear; pwd; echo; command ls -lh --color=auto"
|
||||
alias ls="clear; pwd; echo; command ls -alh --color=auto"
|
||||
export PATH=$PATH:$HOME/minio-binaries/
|
||||
alias make="make -j"
|
||||
alias ns="watch -n 0.1 nvidia-smi"
|
||||
log() {
|
||||
if [ $# -eq 0 ]; then
|
||||
docker compose logs -f
|
||||
else
|
||||
docker logs -f "$@"
|
||||
fi
|
||||
# >>> Super useful
|
||||
vite() {
|
||||
ln -sf "$(pwd)/+page.svelte" "$HOME/wiki/frontend/src/routes/+page.svelte"
|
||||
(cd "$HOME/wiki/frontend" && npm run dev -- --host 0.0.0.0)
|
||||
}
|
||||
|
||||
alias download="huggingface-cli download"
|
||||
alias journal="sudo journalctl -u"
|
||||
|
||||
export LIBGL_ALWAYS_INDIRECT=1
|
||||
|
||||
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:/usr/local/lib:$LD_LIBRARY_PATH"
|
||||
export PATH="/home/w/.venv/bin:/home/w/hub/llama.cpp:/usr/local/cuda/bin:$PATH"
|
||||
alias rsync="rsync -avPh"
|
||||
alias dpkg="sudo dpkg"
|
||||
alias service="sudo service"
|
||||
alias apt="sudo apt-get"
|
||||
|
||||
alias chwon="sudo chown"
|
||||
alias bsah="bash" # common typing error
|
||||
alias pyhton="python" # common typing error
|
||||
alias soruce="source"
|
||||
alias stauts="status"
|
||||
alias stuats="status"
|
||||
|
||||
dash() { sudo docker run -it --rm --gpus all --entrypoint=bash "$1"; }
|
||||
|
||||
alpine() {
|
||||
docker run -it --rm alpine
|
||||
}
|
||||
|
||||
dsh() { sudo docker run -it --rm "$1" sh; }
|
||||
alias nuc="ssh w@192.168.12.5"
|
||||
# alias mac="ssh jaewooklee@192.168.12.45"
|
||||
alias mac="ssh w@192.168.12.2"
|
||||
alias ip="ip -4"
|
||||
alias l='clear; echo -e "\x1b[92m$(pwd)\x1b[0m"; command ls -alh --color=auto'
|
||||
alias nmap="nmap -p1-65535"
|
||||
alias rc="vi ~/.bash_aliases && source ~/.bash_aliases && echo OK"
|
||||
alias c="clear"
|
||||
alias mac="ssh w@10.0.0.2"
|
||||
alias ping="ping -c 2"
|
||||
alias i="sudo dnf install -y"
|
||||
alias ip="ip -4"
|
||||
alias rsync="rsync -avPh"
|
||||
alias ns="watch -n 0.1 nvidia-smi"
|
||||
dive(){ docker exec -it "$@" sh; }
|
||||
alias up="docker compose down; docker compose up -d --remove-orphans && docker compose logs -f"
|
||||
alias down="docker compose down"
|
||||
alias restart='docker restart'
|
||||
|
||||
youtube(){
|
||||
cd ~/Videos/+youtube
|
||||
channel=$(basename "$1")
|
||||
mkdir "$channel"
|
||||
cd "$channel"
|
||||
yt-dlp --cookies-from-browser chrome "$1"
|
||||
}
|
||||
|
||||
# alias less="less -SEX"
|
||||
|
||||
pkill() { sudo command pkill -f "$@" && ps ux; }
|
||||
log() { if [ $# -eq 0 ]; then docker compose logs -f; else docker logs -f "$@"; fi; }
|
||||
build(){ git pull && rm -rf build && cmake -B build -DBUILD_SHARED_LIBS=ON -DGGML_CUDA=ON -DLLAMA_CURL=ON && cmake --build build --config Release -j ; }
|
||||
docker() {
|
||||
if [[ "$1" == "ps" ]]; then
|
||||
command docker ps | less -SEX
|
||||
elif [[ "$1" == "images" ]]; then
|
||||
command docker images | less -SEX
|
||||
elif [[ "$1" == "rm" ]]; then
|
||||
command docker "$@" -f
|
||||
else
|
||||
command docker "$@"
|
||||
fi
|
||||
case "$1" in
|
||||
ps) command docker ps --format 'table {{.Names}}\t{{.RunningFor}}\t{{.Networks}}\t{{.Ports}}\t{{.Image}}\t{{.Command}}\t{{.ID}}' | less -SEX;;
|
||||
rm) command docker "$@" -f;;
|
||||
*) command docker "$@";;
|
||||
esac
|
||||
}
|
||||
|
||||
alias ..="cd .." # 상위 디렉토리로 이동
|
||||
alias ...="cd ../.." # 두 단계 위로 이동
|
||||
alias ~="cd ~" # 홈 디렉토리로 이동
|
||||
alias mkdir="mkdir -p"
|
||||
|
||||
alias myip="curl ifconfig.me" # 내 IP 주소 확인
|
||||
alias ports="netstat -tuln" # 열려 있는 포트 확인
|
||||
alias free="free -h --si"
|
||||
alias df="df -h"
|
||||
# alias diff="git diff --staged"
|
||||
alias status="git status ."
|
||||
alias push="git push"
|
||||
alias pull="git pull"
|
||||
alias fetch="git fetch"
|
||||
add() {
|
||||
if [ $# -eq 0 ]; then
|
||||
git add .
|
||||
else
|
||||
git add $@
|
||||
fi
|
||||
git status
|
||||
}
|
||||
parallel() {
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "Usage: parallel <number_of_instances> <command>"
|
||||
return 1
|
||||
fi
|
||||
|
||||
count=$1
|
||||
shift
|
||||
command="$@"
|
||||
|
||||
for i in $(seq 1 $count); do
|
||||
eval "$command" &
|
||||
done
|
||||
|
||||
wait
|
||||
}
|
||||
|
||||
# repeat() {
|
||||
# if [ $# -lt 2 ]; then
|
||||
# echo "Usage: repeat <interval>[s|m|h] <command>"
|
||||
# return 1
|
||||
# fi
|
||||
|
||||
# interval=$(echo $1 | sed 's/[smh]$//')
|
||||
# unit=${1##*[0-9]}
|
||||
# command="${@:2}"
|
||||
|
||||
# case $unit in
|
||||
# s|'') seconds=$interval;;
|
||||
# m) seconds=$((interval * 60));;
|
||||
# h) seconds=$((interval * 3600));;
|
||||
# *) echo "Invalid time unit. Use 's' for seconds, 'm' for minutes, 'h' for hours, or no unit for seconds."; return 1;;
|
||||
# esac
|
||||
|
||||
# while true; do
|
||||
# eval $command
|
||||
# sleep $seconds
|
||||
# done
|
||||
# }
|
||||
|
||||
alias remote="git remote -v"
|
||||
alias stash="git stash"
|
||||
alias branch="git branch"
|
||||
alias checkout="git checkout"
|
||||
alias vimrc="vi ~/.vimrc"
|
||||
commit() {
|
||||
git commit -m "$*" && git push
|
||||
}
|
||||
|
||||
git() {
|
||||
if [[ "$1" == "remote" ]]; then
|
||||
shift
|
||||
command git remote -v "$@"
|
||||
elif [[ "$1" == "status" ]]; then
|
||||
command git status .
|
||||
command git diff --staged --stat
|
||||
else
|
||||
command git "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
alias weather="curl ko.wttr.in"
|
||||
alias sudo="sudo "
|
||||
alias dryblack="clear; black --check --diff --color ."
|
||||
alias compose="docker compose"
|
||||
alias compsoe="compose"
|
||||
|
||||
alias ps="ps ux"
|
||||
clone() { git clone "https://git.yauk.tv/$@"; }
|
||||
alias mkdir="mkdir -p"
|
||||
|
||||
ign() {
|
||||
for item in "$@"; do
|
||||
if [ -d "$item" ]; then
|
||||
echo "$item/" >> .gitignore
|
||||
echo "Added directory: $item/ to .gitignore"
|
||||
elif [ -f "$item" ]; then
|
||||
echo "$item" >> .gitignore
|
||||
echo "Added file: $item to .gitignore"
|
||||
else
|
||||
echo "Warning: $item does not exist"
|
||||
fi
|
||||
done
|
||||
alias push="git push"
|
||||
alias pull="git pull"
|
||||
alias clone="git clone"
|
||||
alias status="git status"
|
||||
alias add="git add"
|
||||
commit() { git commit -m "$*" && git push; }
|
||||
|
||||
git() {
|
||||
case "$1" in
|
||||
remote) shift; command git remote -v "$@";;
|
||||
status) command git status . && git diff --staged --stat;;
|
||||
add) shift; command git add ${@:-.}; command git status;;
|
||||
*) command git "$@";;
|
||||
esac
|
||||
}
|
||||
# >>> sudos
|
||||
alias sudo="sudo "
|
||||
|
||||
alias r="redis-cli"
|
||||
q() { "$@" > /dev/null 2>&1 & }
|
||||
alias wg="sudo wg"
|
||||
alias dnf="sudo dnf"
|
||||
alias dpkg="sudo dpkg"
|
||||
alias apt="sudo apt-get"
|
||||
alias reboot="sudo reboot"
|
||||
alias service="sudo service"
|
||||
alias wg-quick="sudo wg-quick"
|
||||
alias systemctl="sudo systemctl"
|
||||
alpine() { docker run -it --rm alpine; }
|
||||
|
||||
|
||||
# >>> SECRET
|
||||
export HF_TOKEN=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
|
||||
export CLOUDFLARE_API_TOKEN=Pah8Q6hBUsQsKnKhaMJB2QvL-LHAWCcU8xti66Q3
|
||||
export ANTHROPIC_API_KEY=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
|
||||
|
||||
15
llama.cpp/README.md
Normal file
15
llama.cpp/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Gemma3:12b:Q4 on CUDA
|
||||
```sh
|
||||
docker run -p 1032:8080 -v $HOME/.cache/llama.cpp:/root/.cache/llama.cpp --gpus all ghcr.io/ggml-org/llama.cpp:server-cuda -t 2 --prio 3 -ngl 99 -fa --temp 0 -hf ggml-org/gemma-3-12b-it-GGUF:Q4_K_M
|
||||
```
|
||||
|
||||
```python
|
||||
import subprocess
|
||||
subprocess.Popen(['llama-server', '-t', '2', '--prio', '2', '-ngl', '99', '-fa',
|
||||
'-hf', 'ggml-org/gemma-3-4b-it-GGUF'], stderr=subprocess.DEVNULL)
|
||||
|
||||
def en2ko(en):
|
||||
import json, requests; return json.loads(requests.post('http://localhost:8080/v1/chat/completions', json=dict(messages=[dict(role='user', content=f"{ {'en-US': en}}")],response_format={'type': 'json_object', 'schema': {'type': 'object', 'properties': {'ko-KR': {'type': 'string'}}}})).json()['choices'][0]['message']['content'])['ko-KR']
|
||||
en2ko('Hello') # '안녕하세요
|
||||
```
|
||||
```
|
||||
49
mitmproxy/README.md
Normal file
49
mitmproxy/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# `dump.py`
|
||||
```python
|
||||
I = lambda module: __import__('importlib').import_module(module)
|
||||
|
||||
def request(flow):
|
||||
with I('dbm.sqlite3').open('dbm.sql') as db:
|
||||
if (url := flow.request.url) in db:
|
||||
flow.response = I('mitmproxy.http').Response.make(200, db[url])
|
||||
|
||||
def response(flow):
|
||||
if flow.response.status_code == 200:
|
||||
with I('dbm.sqlite3').open('dbm.sql', 'c') as db:
|
||||
db[flow.request.url] = flow.response.content
|
||||
|
||||
if __name__ == '__main__':
|
||||
I('subprocess').run(['mitmdump', '-s', __file__])
|
||||
```
|
||||
|
||||
# Retries if failed
|
||||
```python
|
||||
def response(flow):
|
||||
retries = 0
|
||||
while flow.response.status_code != 206:
|
||||
retries += 1
|
||||
flow.response = flow.replay().response
|
||||
print(f"재시도 {retries}: 상태 코드 {flow.response.status_code}")
|
||||
```
|
||||
```python
|
||||
for idx, line in enumerate(open('m3u8').readlines()):
|
||||
os.system(f"ffmpeg -y -http_proxy http://localhost:8080 -i '{line.strip()}' -c:v copy -c:a copy {idx+1:02}.mp4")
|
||||
```
|
||||
---
|
||||
```shell
|
||||
mitmweb
|
||||
```
|
||||
|
||||
```shell
|
||||
playwright ff --proxy-server http://localhost:8080 --ignore-https-errors
|
||||
```
|
||||
|
||||
```shell
|
||||
chromium --proxy-server=localhost:8080 --ignore-certificate-errors --disable-backgrounding-occluded-windows
|
||||
```
|
||||
```shell
|
||||
chromium --proxy-server=172.17.112.1:8080 --ignore-certificate-errors --remote-debugging-port=9222 --remote-allow-origins=* --user-agent="Mozilla/5.0 (Linux; Android 15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.122 Mobile Safari/537.36"
|
||||
```
|
||||
```shell
|
||||
chrome --proxy-server=localhost:8080 --ignore-certificate-errors --disable-backgrounding-occluded-windows --user-agent="Mozilla/5.0 (Linux; Android 15) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.122 Mobile Safari/537.36"
|
||||
```
|
||||
31
mobile/README.md
Normal file
31
mobile/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# iOS
|
||||
## Wireguard
|
||||
## Server: iSH shell
|
||||
```
|
||||
apk add openssh tinyproxy
|
||||
|
||||
/etc/ssh/sshd_config
|
||||
Port 2222
|
||||
PermitRootLogin yes
|
||||
AllowTcpForwarding yes
|
||||
GatewayPorts yes
|
||||
|
||||
killall sshd
|
||||
/usr/sbin/sshd
|
||||
|
||||
tee tinyproxy.conf <<EOF
|
||||
Port 8888
|
||||
Listen 0.0.0.0
|
||||
Timeout 600
|
||||
Allow 10.0.0.1
|
||||
EOF
|
||||
|
||||
tinyproxy -d -c tinyproxy.conf
|
||||
```
|
||||
|
||||
## Client
|
||||
```
|
||||
curl -x 10.0.0.2:8888 ip.yauk.tv
|
||||
|
||||
mitmweb -q --ssl-insecure -s proxy.py --mode upstream:http://10.0.0.2:8888@8079
|
||||
```
|
||||
@@ -1,3 +1,33 @@
|
||||
```python
|
||||
def sync(obj):
|
||||
import asyncio, functools
|
||||
if asyncio.iscoroutine(coro := obj):
|
||||
loop, future = asyncio.get_event_loop(), asyncio.ensure_future(coro)
|
||||
while not future.done():
|
||||
loop._process_events(loop._selector.select(0))
|
||||
if (ready := loop._ready) and not (handle := ready.popleft())._cancelled:
|
||||
task = (tasks := asyncio.tasks._current_tasks).pop(loop, None)
|
||||
handle._run()
|
||||
tasks[loop] = task
|
||||
return future.result()
|
||||
if asyncio.iscoroutinefunction(func := obj): return functools.wraps(func)(
|
||||
lambda *args, **kwargs: sync(func(*args, **kwargs)))
|
||||
for attr in dir(obj):
|
||||
if asyncio.iscoroutinefunction(method := getattr(obj, attr)):
|
||||
setattr(obj, attr, sync(method))
|
||||
return obj
|
||||
|
||||
async def foo(): return 42
|
||||
print(sync(foo()), sync(foo)())
|
||||
|
||||
from playwright.async_api import async_playwright
|
||||
browser = sync(sync(async_playwright().start()).firefox.launch())
|
||||
page = sync(sync(browser.new_page()))
|
||||
page._repr_png_ = page.screenshot
|
||||
page.goto('https://naver.com')
|
||||
page
|
||||
```
|
||||
|
||||
```python
|
||||
def sync(coro):
|
||||
import asyncio, functools
|
||||
|
||||
6
nssm/README.md
Normal file
6
nssm/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
```
|
||||
nssm install +adb adb -a nodaemon server start
|
||||
nssm install +dlna rclone serve dlna Y:
|
||||
nssm install +blob python -u blob.py
|
||||
nssm install +proxy python proxy.py
|
||||
```
|
||||
13
parallel/README.md
Normal file
13
parallel/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
```python
|
||||
def worker(x):
|
||||
__import__('time').sleep(1)
|
||||
print(x, end=' ')
|
||||
return x ** 3
|
||||
|
||||
with __import__('concurrent').futures.ThreadPoolExecutor(64) as T:
|
||||
y = list(T.map(worker, range(100)))
|
||||
# 64개 worker로 100개의 1초 소요되는 작업: 2초후 종료
|
||||
|
||||
# x는 순서대로 호출 안되지만 y는 순서대로 나옴
|
||||
print(y)
|
||||
```
|
||||
@@ -1,3 +1,17 @@
|
||||
# IPython on Linux
|
||||
```python
|
||||
def run(coro): __import__('nest_asyncio').apply(); return __import__('asyncio').run(coro)
|
||||
def sync(func): return lambda *args, **kwargs: run(func(*args, **kwargs))
|
||||
|
||||
from playwright.async_api import async_playwright
|
||||
browser = run(run(async_playwright().start()).firefox.launch())
|
||||
for attr in dir(page := run(browser.new_page())):
|
||||
if attr[0] != '_' and callable(method := getattr(page, attr)):
|
||||
setattr(page, attr, sync(method))
|
||||
page._repr_png_ = page.screenshot
|
||||
page.goto('https://naver.com')
|
||||
```
|
||||
|
||||
```python
|
||||
"""
|
||||
Linux (WSL Debian)
|
||||
@@ -30,3 +44,26 @@ page = Page()
|
||||
page.goto('google.com')
|
||||
page
|
||||
```
|
||||
|
||||
# IPython on Windows
|
||||
|
||||
```python
|
||||
def thread(func):
|
||||
import asyncio, concurrent
|
||||
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
|
||||
return lambda: concurrent.futures.ThreadPoolExecutor().submit(func).result()
|
||||
|
||||
def handle(route):
|
||||
print(route.request.url)
|
||||
route.continue_()
|
||||
|
||||
@thread
|
||||
def main():
|
||||
from playwright.sync_api import sync_playwright
|
||||
with sync_playwright() as playwright:
|
||||
(page := playwright.firefox.launch().new_page()).set_default_timeout(0)
|
||||
page.route('**/*', handle)
|
||||
page.goto('https://google.com')
|
||||
|
||||
main()
|
||||
```
|
||||
3
powershell/README.md
Normal file
3
powershell/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
```powershell
|
||||
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force; if(!(Test-Path $PROFILE)){New-Item $PROFILE -Force}; Add-Content $PROFILE "'curl','iwr','wget'|ForEach-Object{Remove-Item alias:`$_ -EA 0}"
|
||||
```
|
||||
4
schtasks/README.md
Normal file
4
schtasks/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
```cmd
|
||||
schtasks /create /tn "+ahk" /tr "\"C:\Program Files\AutoHotkey\AutoHotkeyU64.exe\" \"D:/run.ahk\"" /sc onlogon /rl highest /f
|
||||
schtasks /query /tn "+ahk" /xml
|
||||
```
|
||||
24
security/README.md
Normal file
24
security/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# DNS 0x20 인코딩 (DNS Case Randomization)
|
||||
```
|
||||
캐시 포이즈닝 공격 방어
|
||||
|
||||
DNS 쿼리 ID는 16비트(65,536개)로 예측 가능
|
||||
공격자가 가짜 응답을 보내서 DNS 캐시를 오염시킬 수 있음
|
||||
대소문자 랜덤화로 추가 엔트로피 제공 (2^도메인길이)
|
||||
쿼리 고유성 증가
|
||||
|
||||
원본: worker.yauk.tv
|
||||
랜덤화: workER.YAuK.TV, WORker.yauk.TV, etc.
|
||||
|
||||
같은 도메인이라도 매번 다른 대소문자로 쿼리
|
||||
공격자가 정확한 케이스를 맞추기 어려워짐
|
||||
RFC 문서
|
||||
|
||||
RFC 1035: DNS는 case-insensitive
|
||||
RFC 5452: DNS 0x20 보안 확장 표준
|
||||
실제 구현체들
|
||||
Cloudflare, Google DNS: 기본적으로 0x20 사용
|
||||
BIND: use-v4-udp-ports, use-v6-udp-ports 옵션
|
||||
Unbound: use-caps-for-id 옵션
|
||||
그래서 DNS 서버는 항상 case-insensitive하게 처리해야 합니다. 이는 보안 기능이 아니라 DNS 표준 준수입니다.
|
||||
```
|
||||
71
supervisor/README.md
Normal file
71
supervisor/README.md
Normal file
@@ -0,0 +1,71 @@
|
||||
## Run
|
||||
```sh
|
||||
sudo apt install -y supervisor
|
||||
supervisord -c supervisord.conf -n
|
||||
```
|
||||
|
||||
## `supervisord.conf`
|
||||
```toml
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/dev/null
|
||||
loglevel=critical
|
||||
|
||||
[program:process1]
|
||||
command=sh -c "while true; do echo hello; sleep 2; done"
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:process2]
|
||||
command=sh -c "while true; do echo world; sleep 3; done"
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
```
|
||||
|
||||
## compose.yml
|
||||
```yaml
|
||||
services:
|
||||
chrome:
|
||||
image: yauk.tv/python
|
||||
build:
|
||||
dockerfile_inline: |
|
||||
FROM debian
|
||||
|
||||
RUN apt-get update && apt-get install -y chromium supervisor
|
||||
RUN pip install mitmproxy
|
||||
|
||||
COPY <<EOF /supervisord.conf
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/dev/null
|
||||
loglevel=critical
|
||||
|
||||
[program:process1]
|
||||
command=sh -c "while true; do echo hello; sleep 2; done"
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
|
||||
[program:process2]
|
||||
command=sh -c "while true; do echo world; sleep 3; done"
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
EOF
|
||||
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
```
|
||||
13
thread-python/README.md
Normal file
13
thread-python/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
```python
|
||||
def worker(x):
|
||||
__import__('time').sleep(1)
|
||||
print(x, end=' ')
|
||||
return x ** 3
|
||||
|
||||
with __import__('concurrent').futures.ThreadPoolExecutor(64) as T:
|
||||
y = list(T.map(worker, range(100)))
|
||||
# 64개 worker로 100개의 1초 소요되는 작업: 2초후 종료
|
||||
|
||||
# x는 순서대로 호출 안되지만 y는 순서대로 나옴
|
||||
print(y)
|
||||
```
|
||||
8
windows-C++/README.md
Normal file
8
windows-C++/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# MSYS2 UCRT64
|
||||
https://www.msys2.org/docs/environments/
|
||||
```sh
|
||||
pacman -Syu --noconfirm mingw-w64-ucrt-x86_64-toolchain
|
||||
```
|
||||
```
|
||||
pacman -Sy --noconfirm --needed base-devel mingw-w64-x86_64-gcc mingw-w64-x86_64-toolchain mingw-w64-x86_64-windows-default-manifest mingw-w64-x86_64-headers-git
|
||||
```
|
||||
15
windows-gcc/README.md
Normal file
15
windows-gcc/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Install MSYS2 from https://www.msys2.org/
|
||||
```
|
||||
msys2-x86_64-20241208.exe
|
||||
```
|
||||
|
||||
# Install gcc
|
||||
```
|
||||
pacman -S mingw-w64-ucrt-x86_64-gcc
|
||||
```
|
||||
|
||||
# Add PATH using cmd
|
||||
```
|
||||
setx /M PATH "%PATH%;C:\msys64\ucrt64\bin"
|
||||
```
|
||||
1024자가 넘어서 안된다;
|
||||
182
windows-libzmq/README.md
Normal file
182
windows-libzmq/README.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# msys2 ucrt64 gcc 설치
|
||||
|
||||
|
||||
# go 프로젝트 폴더로 복사
|
||||
```
|
||||
C:\Users\j\+win\vcpkg\packages\zeromq_x64-windows\bin\libzmq-mt-4_3_5.dll
|
||||
```
|
||||
|
||||
```cmd
|
||||
set CGO_ENABLED=1
|
||||
go run server.go
|
||||
```
|
||||
|
||||
# server.go
|
||||
```go
|
||||
package main
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -IC:/Users/j/+win/vcpkg/packages/zeromq_x64-windows/include
|
||||
#cgo LDFLAGS: -LC:/Users/j/+win/vcpkg/packages/zeromq_x64-windows/lib -lzmq-mt-4_3_5
|
||||
#include <zmq.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
func main() {
|
||||
context := C.zmq_ctx_new()
|
||||
defer C.zmq_ctx_term(context)
|
||||
|
||||
socket := C.zmq_socket(context, C.ZMQ_REP)
|
||||
defer C.zmq_close(socket)
|
||||
|
||||
C.zmq_bind(socket, C.CString("tcp://*:5555"))
|
||||
|
||||
for {
|
||||
msg := C.zmq_msg_t{}
|
||||
C.zmq_msg_init(&msg)
|
||||
defer C.zmq_msg_close(&msg)
|
||||
|
||||
C.zmq_msg_recv(&msg, socket, 0)
|
||||
size := C.zmq_msg_size(&msg)
|
||||
data := C.zmq_msg_data(&msg)
|
||||
|
||||
goData := C.GoBytes(data, C.int(size))
|
||||
fmt.Printf("Received: %s\n", string(goData))
|
||||
|
||||
C.zmq_send(socket, unsafe.Pointer(&goData[0]), C.size_t(len(goData)), 0)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# client.py
|
||||
```py
|
||||
import zmq
|
||||
import time
|
||||
|
||||
context = zmq.Context()
|
||||
|
||||
print("Connecting to server...")
|
||||
socket = context.socket(zmq.REQ)
|
||||
socket.connect("tcp://localhost:5555")
|
||||
|
||||
for request in range(10):
|
||||
print(f"Sending request {request} ...")
|
||||
socket.send(f"Hello {request}".encode())
|
||||
|
||||
# Get the reply.
|
||||
message = socket.recv()
|
||||
print(f"Received reply {request} [ {message.decode()} ]")
|
||||
|
||||
# Wait for a second before next request
|
||||
time.sleep(1)
|
||||
```
|
||||
|
||||
# wrapper server.go
|
||||
```go
|
||||
package main
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -IC:/Users/j/+win/vcpkg/packages/zeromq_x64-windows/include
|
||||
#cgo LDFLAGS: -LC:/Users/j/+win/vcpkg/packages/zeromq_x64-windows/lib -lzmq-mt-4_3_5
|
||||
#include <zmq.h>
|
||||
#include <stdlib.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// 타입 별칭
|
||||
type (
|
||||
ZmqContext unsafe.Pointer
|
||||
ZmqSocket unsafe.Pointer
|
||||
ZmqMsg C.zmq_msg_t
|
||||
)
|
||||
|
||||
// 상수
|
||||
const (
|
||||
ZMQ_REP = C.ZMQ_REP
|
||||
)
|
||||
|
||||
// 래퍼 함수들
|
||||
func zmq_ctx_new() ZmqContext {
|
||||
return ZmqContext(C.zmq_ctx_new())
|
||||
}
|
||||
|
||||
func zmq_ctx_term(context ZmqContext) {
|
||||
C.zmq_ctx_term(unsafe.Pointer(context))
|
||||
}
|
||||
|
||||
func zmq_socket(context ZmqContext, typ int) ZmqSocket {
|
||||
return ZmqSocket(C.zmq_socket(unsafe.Pointer(context), C.int(typ)))
|
||||
}
|
||||
|
||||
func zmq_close(socket ZmqSocket) {
|
||||
C.zmq_close(unsafe.Pointer(socket))
|
||||
}
|
||||
|
||||
func zmq_bind(socket ZmqSocket, endpoint string) {
|
||||
cEndpoint := C.CString(endpoint)
|
||||
defer C.free(unsafe.Pointer(cEndpoint))
|
||||
C.zmq_bind(unsafe.Pointer(socket), cEndpoint)
|
||||
}
|
||||
|
||||
func zmq_msg_init(msg *ZmqMsg) {
|
||||
C.zmq_msg_init((*C.zmq_msg_t)(msg))
|
||||
}
|
||||
|
||||
func zmq_msg_close(msg *ZmqMsg) {
|
||||
C.zmq_msg_close((*C.zmq_msg_t)(msg))
|
||||
}
|
||||
|
||||
func zmq_msg_recv(msg *ZmqMsg, socket ZmqSocket, flags int) {
|
||||
C.zmq_msg_recv((*C.zmq_msg_t)(msg), unsafe.Pointer(socket), C.int(flags))
|
||||
}
|
||||
|
||||
func zmq_msg_size(msg *ZmqMsg) int {
|
||||
return int(C.zmq_msg_size((*C.zmq_msg_t)(msg)))
|
||||
}
|
||||
|
||||
func zmq_msg_data(msg *ZmqMsg) unsafe.Pointer {
|
||||
return C.zmq_msg_data((*C.zmq_msg_t)(msg))
|
||||
}
|
||||
|
||||
func zmq_send(socket ZmqSocket, data []byte, flags int) {
|
||||
C.zmq_send(unsafe.Pointer(socket), unsafe.Pointer(&data[0]), C.size_t(len(data)), C.int(flags))
|
||||
}
|
||||
|
||||
// 새로운 래퍼 함수: ZmqMsg에서 Go 바이트 슬라이스로 변환
|
||||
func zmq_msg_to_bytes(msg *ZmqMsg) []byte {
|
||||
size := zmq_msg_size(msg)
|
||||
data := zmq_msg_data(msg)
|
||||
return C.GoBytes(data, C.int(size))
|
||||
}
|
||||
|
||||
func main() {
|
||||
context := zmq_ctx_new()
|
||||
defer zmq_ctx_term(context)
|
||||
|
||||
socket := zmq_socket(context, ZMQ_REP)
|
||||
defer zmq_close(socket)
|
||||
|
||||
zmq_bind(socket, "tcp://*:5555")
|
||||
|
||||
for {
|
||||
msg := ZmqMsg{}
|
||||
zmq_msg_init(&msg)
|
||||
defer zmq_msg_close(&msg)
|
||||
|
||||
zmq_msg_recv(&msg, socket, 0)
|
||||
goData := zmq_msg_to_bytes(&msg)
|
||||
fmt.Printf("Received: %s\n", string(goData))
|
||||
|
||||
zmq_send(socket, goData, 0)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
@@ -60,17 +60,15 @@ https://apps.microsoft.com/detail/9n0dx20hk701?hl=en-US&gl=US
|
||||
## 5. WSL background 실행
|
||||
WSL는 기본적으로 실행중인 터미널이 하나도 없으면 WSL 자체가 종료되도록 되어 있어서 서버를 굴릴수가 없다.
|
||||
|
||||
- https://www.autohotkey.com/
|
||||
- AHK v2 설치
|
||||
- Windows에 python은 설치되어 있어야 한다.
|
||||
- Win+R > `shell:startup` : `시작프로그램` 폴더가 열린다.
|
||||
- 메모장으로 아래의 `wsl.ahk` 파일을 생성하여 `시작프로그램` 폴더에 저장
|
||||
```ahk
|
||||
Run "wsl.exe",,"Hide"
|
||||
- 메모장으로 아래의 `wsl.pyw` 파일을 생성하여 `시작프로그램` 폴더에 저장
|
||||
```python
|
||||
while True: (S := __import__('subprocess')).run(['wsl'], creationflags=S.CREATE_NO_WINDOW)
|
||||
```
|
||||
- 이 `wsl.ahk` 파일을 더블클릭해서 실행해보아도 눈에 보이는 것은 없지만, 백그라운드 터미널 하나가 실행되어, wsl이 꺼지지 않게 된다.
|
||||
- 이 `wsl.pyw` 파일을 더블클릭해서 실행해보아도 눈에 보이는 것은 없지만, 백그라운드 터미널 하나가 실행되어, wsl이 꺼지지 않게 된다.
|
||||
- 컴퓨터를 재시작 할 경우에도 항상 하나가 켜져 있을 것이다.
|
||||
- 예외: 본인이 `wsl --shutdown`으로 강제 종료하면 눈에 안보이는 이것도 꺼지므로 그때는 저걸 다시 켜주어야 함)
|
||||
|
||||
- 주의 `wsl --shutdown`으로 강제종료하여도 계속 wsl을 시작할 것이기 때문에 완전한 종료를 원할 경우에는, 저 파일을 지우고 재부팅하는 것이 제일 간단할 것이다.
|
||||
|
||||
# Docker에 NVIDIA 설치
|
||||
|
||||
@@ -80,15 +78,16 @@ WSL는 기본적으로 실행중인 터미널이 하나도 없으면 WSL 자체
|
||||
## (추가) CUDA 12.6 설치
|
||||
|
||||
|
||||
- WSL에서 설치하는 CUDA는 12.4인데 CUDA 12.6을 필요로 하는 경우 아래와 같이 설치한다.
|
||||
- WSL에서 설치하는 CUDA는 12.4인데 CUDA 12.9을 필요로 하는 경우 아래와 같이 설치한다.
|
||||
|
||||
https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&Distribution=Debian&target_version=12&target_type=deb_local
|
||||
|
||||
```sh
|
||||
wget https://developer.download.nvidia.com/compute/cuda/12.6.1/local_installers/cuda-repo-debian12-12-6-local_12.6.1-560.35.03-1_amd64.deb
|
||||
sudo dpkg -i cuda-repo-debian12-12-6-local_12.6.1-560.35.03-1_amd64.deb
|
||||
sudo cp /var/cuda-repo-debian12-12-6-local/cuda-*-keyring.gpg /usr/share/keyrings/
|
||||
sudo add-apt-repository contrib && sudo apt-get update && sudo apt-get -y install cuda-toolkit-12-6
|
||||
wget https://developer.download.nvidia.com/compute/cuda/repos/debian12/x86_64/cuda-keyring_1.1-1_all.deb
|
||||
sudo dpkg -i cuda-keyring_1.1-1_all.deb
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install cuda-toolkit-12-9
|
||||
|
||||
nvidia-smi
|
||||
```
|
||||
|
||||
|
||||
87
x11/ahk.py
Executable file
87
x11/ahk.py
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env python3
|
||||
import os, sys, subprocess
|
||||
os.environ['DISPLAY'] = ':0'
|
||||
|
||||
def cmd(*args): return subprocess.run([str(a) for a in args], capture_output=True, text=True).stdout.strip()
|
||||
|
||||
def tile_window(position):
|
||||
window_id = subprocess.run(['xdotool', 'getactivewindow'],
|
||||
capture_output=True, text=True).stdout.strip()
|
||||
|
||||
cmd('wmctrl', '-i', '-r', window_id, '-b', 'remove,maximized_vert,maximized_horz')
|
||||
|
||||
if position == 'maximize':
|
||||
cmd('wmctrl', '-i', '-r', window_id, '-b', 'add,maximized_vert,maximized_horz')
|
||||
return
|
||||
|
||||
SCREEN_WIDTH, SCREEN_HEIGHT, TASKBAR = 3840, 2160, 48
|
||||
work_height = SCREEN_HEIGHT - TASKBAR
|
||||
quarter = SCREEN_WIDTH // 4
|
||||
positions = {
|
||||
'left': (0, 0, quarter, work_height),
|
||||
'center': (quarter, 0, quarter * 2, work_height),
|
||||
'right': (quarter * 3, 0, quarter, work_height),
|
||||
}
|
||||
x, y, width, height = positions[position]
|
||||
if 'xfce4-terminal' in cmd('xprop', '-id', window_id, 'WM_CLASS').lower():
|
||||
height -= 10
|
||||
cmd('xdotool', 'windowsize', window_id, width, height)
|
||||
cmd('xdotool', 'windowmove', window_id, x, y)
|
||||
|
||||
def XButton1():
|
||||
for line in cmd('xdotool', 'getmouselocation', '--shell').splitlines():
|
||||
if 'WINDOW=' in line:
|
||||
window = line.split('=')[1]
|
||||
cmd('xdotool', 'windowactivate', '--sync', window)
|
||||
classname = cmd('xdotool', 'getwindowclassname', window)
|
||||
name = cmd('xdotool', 'getwindowname', window)
|
||||
if classname == 'Xfce4-terminal': key = 'alt+F4'
|
||||
elif name.startswith('New tab - obsidian'): key = 'alt+F4'
|
||||
else: key = 'ctrl+w'
|
||||
cmd('xdotool', 'key', key)
|
||||
|
||||
def popup(message): cmd("zenity", "--info", f"--text={message}", "--timeout=1")
|
||||
|
||||
def F1():
|
||||
import random,time
|
||||
SCREEN_WIDTH, SCREEN_HEIGHT, TASKBAR = 3840, 2160, 48
|
||||
work_height = SCREEN_HEIGHT - TASKBAR
|
||||
quarter = SCREEN_WIDTH // 4
|
||||
x, y, w, h = 0, 0, quarter, work_height
|
||||
cmd("chromium-browser",
|
||||
"--disable-features=ExtensionManifestV2Unsupported,ExtensionManifestV2Disabled", "--new-window", "https://yauk.net")
|
||||
time.sleep(0.1)
|
||||
window_id = cmd('xdotool', 'getactivewindow')
|
||||
|
||||
cmd('xdotool', 'windowsize', window_id, w, h)
|
||||
cmd('xdotool', 'windowmove', window_id, x, y)
|
||||
|
||||
def F12():
|
||||
if ret := subprocess.run(['wmctrl', '-x', '-a', 'obsidian']).returncode:
|
||||
cmd('dbus-launch', 'flatpak', 'run', 'md.obsidian.Obsidian')
|
||||
|
||||
def F10():
|
||||
cmd('killall', 'xbindkeys')
|
||||
cmd('xbindkeys')
|
||||
popup('Reload')
|
||||
|
||||
def Win():
|
||||
cmd('xfce4-popup-whiskermenu')
|
||||
|
||||
def Win_1():
|
||||
cmd("chromium-browser",
|
||||
"--disable-features=ExtensionManifestV2Unsupported,ExtensionManifestV2Disabled")
|
||||
|
||||
if __name__ == '__main__':
|
||||
match sys.argv[1]:
|
||||
case 'Win+Up': tile_window('maximize')
|
||||
case 'Win+Left': tile_window('left')
|
||||
case 'Win+Down': tile_window('center')
|
||||
case 'Win+Right': tile_window('right')
|
||||
case 'Win': Win()
|
||||
case 'Win+1': Win_1()
|
||||
case 'F1': F1()
|
||||
case "XButton1": XButton1()
|
||||
case "XButton2": cmd("xdotool", "key", "ctrl+Tab")
|
||||
case "F10": F10()
|
||||
case "F12": F12()
|
||||
35
x11/xbindkeysrc
Normal file
35
x11/xbindkeysrc
Normal file
@@ -0,0 +1,35 @@
|
||||
"ahk.py XButton1"
|
||||
b:8
|
||||
|
||||
"ahk.py XButton2"
|
||||
b:9
|
||||
|
||||
"xte 'keydown Control_L' 'keydown Shift_L' 'key Tab' 'keyup Shift_L' 'keyup Control_L'"
|
||||
Shift + b:9
|
||||
|
||||
"ahk.py F12"
|
||||
F12
|
||||
|
||||
"ahk.py F1"
|
||||
F1
|
||||
|
||||
"ahk.py F10"
|
||||
F10
|
||||
|
||||
"ahk.py Win+1"
|
||||
Mod4 + 1
|
||||
|
||||
"ahk.py Win+Up"
|
||||
Mod4 + Up
|
||||
|
||||
"ahk.py Win+Left"
|
||||
Mod4 + Left
|
||||
|
||||
"ahk.py Win+Down"
|
||||
Mod4 + Down
|
||||
|
||||
"ahk.py Win+Right"
|
||||
Mod4 + Right
|
||||
|
||||
"ahk.py Win"
|
||||
Alt + F1
|
||||
33
zmq-sqlite/README.md
Normal file
33
zmq-sqlite/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Server
|
||||
```python
|
||||
def SQL():
|
||||
import sqlite3, hashlib, os; con = sqlite3.connect('.db', isolation_level=None)
|
||||
sql = lambda q, *p: list(con.execute(q, p))
|
||||
if not os.path.exists('.db-blob') and os.mkdir('.db-blob') is None:
|
||||
con.executescript('''PRAGMA journal_mode=WAL;
|
||||
CREATE TABLE kv(k, v, t DEFAULT CURRENT_TIMESTAMP);
|
||||
CREATE INDEX idx_kv_v ON kv(v); CREATE INDEX idx_kv_k_t ON kv(k,t DESC)''')
|
||||
def setitem(_, filename, blob):
|
||||
if not sql('SELECT 1 FROM kv WHERE v=?', sha1 := hashlib.sha1(blob).hexdigest()):
|
||||
with open(f'.db-blob/{sha1}', 'xb') as f: f.write(blob)
|
||||
sql('INSERT INTO kv(k,v) VALUES(?,?)', filename, sha1)
|
||||
def getitem(_, filename):
|
||||
if sha1 := sql('SELECT v FROM kv WHERE k=? ORDER BY t DESC', filename):
|
||||
return open(f'.db-blob/{sha1[0][0]}', 'rb').read()
|
||||
return type('', (), dict(__setitem__=setitem, __getitem__=getitem))()
|
||||
sql = SQL()
|
||||
|
||||
import zmq; (socket := zmq.Context().socket(zmq.REP)).bind('tcp://*:5555')
|
||||
while True:
|
||||
filename, blob = socket.recv_pyobj()
|
||||
sql[filename] = blob
|
||||
socket.send_string('OK')
|
||||
```
|
||||
|
||||
# Client
|
||||
```python
|
||||
def put(filename, blob, addr='tcp://localhost:5555'):
|
||||
import zmq; (socket := zmq.Context().socket(zmq.REQ)).connect(addr)
|
||||
assert socket.send_pyobj((filename, blob)) or socket.recv_string() == 'OK'
|
||||
put('hello', b'world')
|
||||
```
|
||||
Reference in New Issue
Block a user