Snapshot: full project state
This commit is contained in:
8
deploy/check_net.py
Normal file
8
deploy/check_net.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import urllib.request, socket
|
||||
socket.setdefaulttimeout(8)
|
||||
for url, name in [("https://remoteok.com/api", "remoteok"), ("https://www.google.com", "google")]:
|
||||
try:
|
||||
urllib.request.urlopen(url)
|
||||
print(name, "OK")
|
||||
except Exception as e:
|
||||
print(name, "FAIL ->", type(e).__name__)
|
||||
21
deploy/cleanup.py
Normal file
21
deploy/cleanup.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import os, glob
|
||||
import db
|
||||
db.init_db()
|
||||
db.set_setting('llm_timeout', '45')
|
||||
# remove test artifacts
|
||||
for p in glob.glob('/opt/procyon/test_*.py') + glob.glob('/opt/procyon/data/resumes/test_*.pdf'):
|
||||
try:
|
||||
os.remove(p)
|
||||
except Exception:
|
||||
pass
|
||||
# clean the synthetic test job/application from earlier verification
|
||||
conn = db.get_conn()
|
||||
try:
|
||||
conn.execute("DELETE FROM applications WHERE job_id IN (SELECT id FROM jobs WHERE url LIKE 'https://example.com%')")
|
||||
conn.execute("DELETE FROM jobs WHERE url LIKE 'https://example.com%'")
|
||||
conn.commit()
|
||||
finally:
|
||||
conn.close()
|
||||
print('llm_timeout =', db.get_setting('llm_timeout'))
|
||||
print('jobs remaining =', len(db.list_jobs(limit=1000)))
|
||||
print('CLEANUP_DONE')
|
||||
4
deploy/fix_timeout.py
Normal file
4
deploy/fix_timeout.py
Normal file
@@ -0,0 +1,4 @@
|
||||
import db
|
||||
db.init_db()
|
||||
db.set_setting('llm_timeout', '45')
|
||||
print('llm_timeout now =', db.get_setting('llm_timeout'))
|
||||
12
deploy/nginx-procyon.conf
Normal file
12
deploy/nginx-procyon.conf
Normal file
@@ -0,0 +1,12 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 300s;
|
||||
}
|
||||
}
|
||||
10
deploy/procyon-autopilot.service
Normal file
10
deploy/procyon-autopilot.service
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Procyon autopilot (discover + enrich + score + prepare)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
WorkingDirectory=/opt/procyon
|
||||
ExecStart=/usr/bin/python3 /opt/procyon/autopilot.py
|
||||
StandardOutput=append:/var/log/procyon-autopilot.log
|
||||
StandardError=append:/var/log/procyon-autopilot.log
|
||||
10
deploy/procyon-autopilot.timer
Normal file
10
deploy/procyon-autopilot.timer
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Run Procyon autopilot every 6 hours
|
||||
|
||||
[Timer]
|
||||
OnBootSec=10min
|
||||
OnUnitActiveSec=6h
|
||||
RandomizedDelaySec=15min
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
15
deploy/procyon.service
Normal file
15
deploy/procyon.service
Normal file
@@ -0,0 +1,15 @@
|
||||
[Unit]
|
||||
Description=Procyon Job Hunt Workflow Engine
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/procyon
|
||||
Environment=PROCYON_SECRET=procyon-local-dev-key
|
||||
ExecStart=/usr/local/bin/gunicorn -w 2 -b 127.0.0.1:5000 app:app --timeout 300
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
21
deploy/setup.sh
Normal file
21
deploy/setup.sh
Normal file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
mkdir -p /opt/procyon
|
||||
cd /opt/procyon
|
||||
tar xzf /tmp/procyon.tar.gz
|
||||
mkdir -p data
|
||||
python3 -c "import db; db.init_db()" && echo "DB_INIT_OK"
|
||||
cp deploy/procyon.service /etc/systemd/system/procyon.service
|
||||
cp deploy/procyon-autopilot.service /etc/systemd/system/procyon-autopilot.service
|
||||
cp deploy/procyon-autopilot.timer /etc/systemd/system/procyon-autopilot.timer
|
||||
systemctl daemon-reload
|
||||
systemctl enable procyon >/dev/null 2>&1
|
||||
systemctl restart procyon
|
||||
systemctl enable procyon-autopilot.timer >/dev/null 2>&1
|
||||
systemctl restart procyon-autopilot.timer
|
||||
cp deploy/nginx-procyon.conf /etc/nginx/sites-available/procyon
|
||||
ln -sf /etc/nginx/sites-available/procyon /etc/nginx/sites-enabled/procyon
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
nginx -t
|
||||
systemctl restart nginx
|
||||
echo "SETUP_DONE"
|
||||
43
deploy/test_core.py
Normal file
43
deploy/test_core.py
Normal file
@@ -0,0 +1,43 @@
|
||||
import db, tailor, audit, improve
|
||||
|
||||
db.init_db()
|
||||
# force fast fallback so this test doesn't wait on the cold-loading/saturated LLM
|
||||
db.set_setting('llm_timeout', '5')
|
||||
import llm
|
||||
llm.COOLDOWN = 5
|
||||
print("DB init: OK (llm_timeout forced to 5s to exercise fallback)")
|
||||
|
||||
# classification
|
||||
print("classify tech:", tailor.classify_track({"title": "DevOps Engineer", "description": "Linux Docker Python automation networking"}))
|
||||
print("classify hydro:", tailor.classify_track({"title": "Head Grower", "description": "hydroponic cultivation IPM greenhouse nutrition"}))
|
||||
print("classify driving:", tailor.classify_track({"title": "Delivery Driver", "description": "route fleet logistics warehouse forklift"}))
|
||||
|
||||
# build_master + combining
|
||||
tracks, master = tailor.build_master({"title": "Head Grower", "description": "hydroponic IPM greenhouse"})
|
||||
print("hydro tracks:", tracks, "| tech differentiator present:", "Technical Differentiator" in master)
|
||||
|
||||
tracks2, master2 = tailor.build_master({"title": "Backend Engineer", "description": "Python Flask Docker Linux"})
|
||||
print("tech tracks:", tracks2, "| master chars:", len(master2))
|
||||
|
||||
# keyword score (deterministic)
|
||||
s, op = tailor.score_job({"title": "x", "description": "proxmox docker python linux networking automation security"})
|
||||
print("keyword score:", s, "|", op[:50])
|
||||
|
||||
# audit round-trip
|
||||
job = db.upsert_job("DevOps Engineer", "Acme", "Seattle", "https://example.com/j1", "test",
|
||||
"Linux Docker Python Proxmox networking")
|
||||
aid = db.create_application(job, subject="Application: DevOps Engineer — Acme",
|
||||
body="Hello,\n\nI'm applying to Acme.\n\nThanks,\nIndiana Holmes\n(425) 280-0023\nindianaholmes1@icloud.com")
|
||||
checks = audit.run_audit(aid, db.get_job(job),
|
||||
"Application: DevOps Engineer — Acme",
|
||||
"Hello,\n\nI'm applying to Acme.\n\nThanks,\nIndiana Holmes\n(425) 280-0023\nindianaholmes1@icloud.com",
|
||||
"Targeting: DevOps Engineer at Acme\n\n" + master2)
|
||||
print("audit results:")
|
||||
for c in checks:
|
||||
print(" ", c["item"], "->", c["result"])
|
||||
print("all_pass:", audit.all_pass(checks))
|
||||
|
||||
# library
|
||||
print("library:", [(r["track"], r["exists"]) for r in tailor.list_library()])
|
||||
print("insights:", improve.insights())
|
||||
print("ALL_CORE_TESTS_PASSED")
|
||||
24
deploy/test_pdf.py
Normal file
24
deploy/test_pdf.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import re
|
||||
import db, tailor, resume_pdf
|
||||
|
||||
db.init_db()
|
||||
db.set_setting('llm_timeout', '5') # force fallback so test is fast
|
||||
import llm; llm.COOLDOWN = 5
|
||||
|
||||
for title, desc, track_expect in [
|
||||
("DevOps Engineer", "Linux Docker Python Proxmox automation networking infrastructure", 'tech'),
|
||||
("Head Grower", "hydroponic cultivation IPM greenhouse plant nutrition", 'hydro'),
|
||||
("Delivery Driver", "route fleet logistics warehouse forklift", 'driving'),
|
||||
]:
|
||||
job = {"title": title, "company": "TestCo", "description": desc}
|
||||
track = tailor.classify_track(job)
|
||||
structured = tailor.structured_resume(job)
|
||||
text = tailor.structured_to_text(structured)
|
||||
pdf_path = resume_pdf.render(structured, out_path=f"/opt/procyon/data/resumes/test_{track}.pdf")
|
||||
raw = open(pdf_path, 'rb').read()
|
||||
m = re.search(rb'/Count (\d+)', raw)
|
||||
pages = int(m.group(1)) if m else -1
|
||||
print(f"[{track}] title={title!r} -> pages={pages}, skills={len(structured['skills'])}, "
|
||||
f"exp={len(structured.get('experience',[]))}, projects={'projects' in structured}, "
|
||||
f"pdf={len(raw)} bytes")
|
||||
print("PDF_TEST_DONE")
|
||||
38
deploy/test_pipeline.py
Normal file
38
deploy/test_pipeline.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import db, tailor, scraper, audit
|
||||
|
||||
db.init_db()
|
||||
|
||||
# 1. internet check via urllib
|
||||
try:
|
||||
import urllib.request
|
||||
urllib.request.urlopen("https://remoteok.com/api", timeout=10)
|
||||
print("INTERNET: reachable")
|
||||
except Exception as e:
|
||||
print("INTERNET: blocked ->", type(e).__name__)
|
||||
|
||||
# 2. synthetic job -> full pipeline
|
||||
job = {
|
||||
"title": "Senior DevOps Engineer",
|
||||
"company": "Acme",
|
||||
"description": "Seeking a Linux systems engineer with Proxmox, Docker, Python automation, and networking experience.",
|
||||
}
|
||||
print("TRACK:", tailor.classify_track(job))
|
||||
tracks, master = tailor.build_master(job)
|
||||
print("TRACKS USED:", tracks, "| master chars:", len(master))
|
||||
score, opinion = tailor.score_job(job)
|
||||
print("SCORE:", score, "| OPINION:", opinion[:80])
|
||||
t = tailor.tailor_resume(job)
|
||||
print("TAILORED chars:", len(t), "| header:", t.split("\n")[0][:60])
|
||||
subj = tailor.make_subject(job)
|
||||
body = tailor.draft_email(job, t)
|
||||
jid = db.upsert_job(job["title"], job["company"], "", "https://example.com/j1", "test", job["description"])
|
||||
aid = db.create_application(jid, subject=subj, body=body)
|
||||
checks = audit.run_audit(aid, db.get_job(jid), subj, body, t)
|
||||
print("AUDIT:", [(c["item"], c["result"]) for c in checks])
|
||||
print("ALL_PASS:", audit.all_pass(checks))
|
||||
|
||||
# 3. hydro classification test
|
||||
hydro_job = {"title": "Head Grower", "description": "Hydroponic cultivation, IPM, greenhouse environment control, plant nutrition."}
|
||||
print("HYDRO TRACK:", tailor.classify_track(hydro_job))
|
||||
h_tracks, h_master = tailor.build_master(hydro_job)
|
||||
print("HYDRO TRACKS USED:", h_tracks, "| has tech diff:", "Technical Differentiator" in h_master)
|
||||
Reference in New Issue
Block a user