diff options
| author | msglm <msglm@techchud.xyz> | 2026-05-09 00:31:51 -0500 |
|---|---|---|
| committer | msglm <msglm@techchud.xyz> | 2026-05-09 00:31:51 -0500 |
| commit | e15d891cd2133561994a92b63cdae35f57604494 (patch) | |
| tree | 7f242bbfe7bb665054688e7f9ea5bdc33a8005d3 | |
| parent | 0d2c8000d6b10bdcaa0ff547c1c0a58ebc4ef5bd (diff) | |
| download | getmeajob-e15d891cd2133561994a92b63cdae35f57604494.tar.gz getmeajob-e15d891cd2133561994a92b63cdae35f57604494.tar.bz2 getmeajob-e15d891cd2133561994a92b63cdae35f57604494.zip | |
Inital Commit0.0.1
| -rw-r--r-- | contrib/example.toml | 11 | ||||
| -rw-r--r-- | contrib/guix/python-ruff/license-not-array.patch | 25 | ||||
| -rw-r--r-- | getmeajob/getmeajob.py | 160 | ||||
| -rw-r--r-- | manifest.scm | 389 | ||||
| -rw-r--r-- | pyproject.toml | 2 | ||||
| -rw-r--r-- | requirements.txt | 2 |
6 files changed, 559 insertions, 30 deletions
diff --git a/contrib/example.toml b/contrib/example.toml index e8ef72b..dde10a1 100644 --- a/contrib/example.toml +++ b/contrib/example.toml @@ -1,13 +1,14 @@ [aviation] - -sites=["indeed", "linkedin", "zip_recruiter", "google", "glassdoor", "bayt", "naukri", "bdjobs"] +sites=["indeed", "zip_recruiter", "google", "glassdoor", "bayt", "naukri"] +#sites=["indeed", "linkedin", "zip_recruiter", "google", "glassdoor", "bayt", "naukri", "bdjobs"] search="Entry level Aviation Technician" -location="Arizona" +location="Phoenix, Arizona" country="USA" results_wanted=200 hours_old=336 +proxy=false automated_questions = [ -"Does this job require a college diploma?" -"Does this job offer PTO?" +"Does this job require a college diploma?", +"Does this job offer PTO?", "Is there a listed salary?" ] diff --git a/contrib/guix/python-ruff/license-not-array.patch b/contrib/guix/python-ruff/license-not-array.patch new file mode 100644 index 0000000..9d9bb79 --- /dev/null +++ b/contrib/guix/python-ruff/license-not-array.patch @@ -0,0 +1,25 @@ +From aba7b61e294710ffe3a5aa274e541df9bc82388d Mon Sep 17 00:00:00 2001 +From: Anonymous <anonymous@example.org> +Date: Sat, 2 May 2026 00:02:57 -0500 +Subject: [PATCH] make license not an array + +--- + pyproject.toml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/pyproject.toml b/pyproject.toml +index 62d8094..873d338 100644 +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -10,7 +10,7 @@ authors = [{ name = "Astral Software Inc.", email = "hey@astral.sh" }] + readme = "README.md" + requires-python = ">=3.7" + license = "MIT" +-license-files = ["LICENSE"] ++license-files = "LICENSE" + keywords = [ + "automation", + "flake8", +-- +2.52.0 + diff --git a/getmeajob/getmeajob.py b/getmeajob/getmeajob.py index 87c383e..b78d4e3 100644 --- a/getmeajob/getmeajob.py +++ b/getmeajob/getmeajob.py @@ -1,29 +1,143 @@ import csv -import tomli +import sys +if sys.version_info >= (3, 11): + import tomllib as toml +else: + import tomli as toml from jobspy import scrape_jobs import argparse +from fp.fp import FreeProxy +from jinja2 import Template +from llama_cpp import Llama + +template = Template(""" +{# jobs is a list of dicts with the fields you specified #} +<!doctype html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Job Export</title> +</head> +<body style="font-family:system-ui,Segoe UI,Roboto,Arial,sans-serif;line-height:1.4;color:#111;padding:18px;"> + +{% for job in jobs %} + <div style="padding:14px 0;"> + <!-- Header row --> + <div style="display:flex;justify-content:space-between;align-items:baseline;gap:12px;"> + <div> + <a href="{{ job.job_url }}" style="font-size:18px;font-weight:600;color:#0b66c2;text-decoration:none;"> + {{ job.title | e }} + </a> + <div style="font-size:13px;color:#444;margin-top:2px;"> + <a href="{{ job.company_url }}" style="color:#444;text-decoration:none;">{{ job.company | e }}</a> + {% if job.location %} + — {{ job.location.city|default('') }}{% if job.location.city and job.location.state %}, {% endif %}{{ job.location.state|default('') }}{% if job.location.city or job.location.state %} • {% endif %}{{ job.location.country|default('') }} + {% endif %} + {% if job.is_remote %} + • Remote + {% endif %} + </div> + </div> + + <div style="text-align:right;font-size:13px;color:#666;"> + <div>{{ job.job_type | capitalize }}</div> + <div style="margin-top:6px;color:#333;font-weight:500;"> + {% if job.job_function %} + {% set jf = job.job_function %} + {% if jf.min_amount or jf.max_amount %} + {{ jf.currency|default('') }} + {% if jf.min_amount %}{{ jf.min_amount }}{% endif %} + {% if jf.min_amount and jf.max_amount %}–{% endif %} + {% if jf.max_amount %}{{ jf.max_amount }}{% endif %} + <span style="font-size:12px;color:#666;">/ {{ jf.interval }}</span> + {% endif %} + <div style="font-size:12px;color:#666;margin-top:4px;"> + Source: {{ jf.salary_source | replace('_',' ') }} + </div> + {% endif %} + </div> + <div style="font-size:12px;color:#888;margin-top:6px;">Posted: {{ job.date_posted }}</div> + </div> + </div> + + <!-- Description --> + <div style="margin-top:10px;color:#222;"> + <div style="white-space:pre-wrap;">{{ job.description | e }}</div> + </div> + + <!-- Emails & Links --> + <div style="margin-top:10px;font-size:13px;color:#333;"> + {% if job.emails %} + <div><strong>Contact:</strong> {{ job.emails | join(', ') }}</div> + {% endif %} + <div style="margin-top:6px;font-size:13px;"><a href="{{ job.job_url }}" style="color:#0b66c2;text-decoration:none;">View posting</a></div> + </div> + + <!-- Program summary box --> + <div style="margin-top:12px;padding:10px;background:#f7f9fb;border:1px solid #e3e7ea;border-radius:6px;font-size:13px;color:#222;"> + <strong style="display:block;margin-bottom:6px;">Program notes</strong> + <div style="white-space:pre-wrap;">{{ job.summary | default('—') | e }}</div> + </div> + + </div> + + <!-- Delimiter between jobs --> + <hr style="border:none;border-top:1px solid #e0e6ea;margin:12px 0;"> +{% endfor %} + +</body> +</html> + """) def main(): - print("gat") - parser = argparse.ArgumentParser(description='Get Me A Job!') - parser.add_argument('arg', type=str, help='The location of your getmeajob config file.') + parser = argparse.ArgumentParser(description='Get Me A Job!\n\nA CLI tool for scraping various sites and getting you a job. Outputs an HTML document.') + parser.add_argument('config_file', type=str, help='The location of your getmeajob config file.') + parser.add_argument('output_file', type=str, help='The file where you want your jobs outputted.') args = parser.parse_args() - config = toml.load(args.arg) - jobs = scrape_jobs( - site_name=config["sites"], - search_term=config["search"], - google_search_term=config["search"] + " near " + config["location"], - location=config["location"], - results_wanted=config["results_wanted"], - hours_old=config["hours_old"], - country_indeed=config["country"], - - linkedin_fetch_description=True # gets more info such as description, direct job url (slower) - # proxies=["208.195.175.46:65095", "208.195.175.45:65095", "localhost"], - ) - print(f"Found {len(jobs)} jobs") - for job in jobs: - print(job) - -if __name__ == "__main__": - main() + config = toml.load(open(args.config_file, 'rb')) + for joblistingnames in config.keys(): + + listingentry = config[joblistingnames] + + jobs = scrape_jobs( + site_name=listingentry["sites"], + search_term=listingentry["search"], + google_search_term=listingentry["search"] + " near " + listingentry["location"], + location=listingentry["location"], + results_wanted=listingentry["results_wanted"], + hours_old=listingentry["hours_old"], + country_indeed=listingentry["country"], + linkedin_fetch_description=True, # gets more info such as description, direct job url (slower) + proxies=[FreeProxy().get()] if listingentry["proxy"] else [] + ) + + jobsdict = jobs.to_dict(orient='records') + + print(f"Found {len(jobs)} jobs") + for job in jobsdict: + print(job) + +# if len(listingentry["automated_questions"]) > 0: +# +# qanda = [] +# +# llm = Llama.from_pretrained(repo_id="Mungert/Qwen3-4B-abliterated-GGUF", +# filename="*Q8_0.gguf", +# verbose=True +# ) +# for question in listingentry["automated_questions"]: +# qanda.append(llm.create_chat_completion( +# messages = [ +# {"role": "system", "content": "You are a summarizer tasked with summarizing job applications. Presented to you are the user's question about a job description and the description. Using only the provided description, answer the question to the best of your ability. If you are incapable of figuring out the answer, inform the user of this."}, +# { +# "role": "user", +# "content": "Job Summary: \n" + jobsdict["description"] + "\n\n Here is my question:\n " + question +# } +# ])) +# +# print(qanda) + + + open(args.output_file, "w", encoding="utf-8").write(template.render(jobs=jobsdict))) + + print("Wrote file!") diff --git a/manifest.scm b/manifest.scm index cbbfcd9..48fb81f 100644 --- a/manifest.scm +++ b/manifest.scm @@ -7,15 +7,22 @@ #:use-module (guix download) #:use-module (guix git-download) #:use-module (guix gexp) + #:use-module (guix packages) #:use-module (guix profiles) #:use-module (gnu packages) #:use-module (gnu packages wget) #:use-module (gnu packages musl) #:use-module (gnu packages markup) + #:use-module (gnu packages iso-codes) + #:use-module (gnu packages xml) #:use-module (gnu packages python-web) #:use-module (gnu packages version-control) #:use-module (gnu packages commencement) #:use-module (gnu packages python-graphics) + #:use-module (gnu packages python-crypto) + #:use-module (gnu packages libffi) + #:use-module (gnu packages serialization) + #:use-module (gnu packages rust-apps) #:use-module (gnu packages python-compression) #:use-module (gnu packages python-check) #:use-module (gnu packages golang) @@ -25,6 +32,7 @@ #:use-module (gnu packages golang-web) #:use-module (gnu packages golang-crypto) #:use-module (gnu packages check) + #:use-module (gnu packages cmake) #:use-module (gnu packages compression) #:use-module (gnu packages python-xyz) #:use-module (gnu packages python-build) @@ -50,6 +58,8 @@ (native-inputs (list python-setuptools)) (propagated-inputs (list python-jinja2 python-jobspy + python-free-proxy + python-llama-cpp )) (home-page "") (synopsis @@ -58,6 +68,41 @@ "Job hunting application.") (license license:agpl3))) +(define-public python-curl-cffi + (package + (name "python-curl-cffi") + (version "0.15.0") + (source + (origin + (method url-fetch) + (uri (pypi-uri "curl_cffi" version)) + (sha256 + (base32 "1v9dn12nbk3i2zpinhp98xhqyj3yyd2ck0hgxqs3v2gn5djnf37a")))) + (build-system pyproject-build-system) + (propagated-inputs (list python-certifi python-cffi python-rich)) + (native-inputs (list python-cffi + python-charset-normalizer + python-cryptography + python-httpx + python-litestar + python-proxy-py + python-pytest + python-pytest-asyncio + python-pytest-trio + python-multipart + python-ruff + python-setuptools + python-trio + python-trustme + python-typing-extensions + python-uvicorn + python-websockets)) + (home-page #f) + (synopsis "libcurl ffi bindings for Python, with impersonation support.") + (description + "libcurl ffi bindings for Python, with impersonation support.") + (license #f))) + (define-public python-jobspy (package (name "python-jobspy") @@ -171,7 +216,6 @@ (arguments (list #:tests? #f - #:tests? #f #:import-path "github.com/bdandy/go-socks4" )) (propagated-inputs (list go-github-com-bdandy-go-errors @@ -392,4 +436,347 @@ repositories from Carcraftz are not maintained anymore.") (license license:bsd-4))) +(define-public python-free-verify-proxy + (package + (name "python-free-verify-proxy") + (version "2.0.4") + (source + (origin + (method url-fetch) + (uri (pypi-uri "free_verify_proxy" version)) + (sha256 + (base32 "185l9fc41wjm9myqgxgb82xmj9aj9s2vk06blsb6230nrfms86cr")))) + (build-system pyproject-build-system) + (propagated-inputs (list python-beautifulsoup4 python-country-converter + python-curl-cffi python-requests)) + (native-inputs (list python-setuptools)) + (home-page "https://github.com/mominurr/free_verify_proxy") + (synopsis + "A simple package to provide http and https working proxy lists.") + (description + "This package provides a simple package to provide http and https working proxy +lists.") + (license license:expat))) + +(define-public python-ruff + (package + (name "python-ruff") + (version "0.15.12") + (source + (origin + (method url-fetch) + (uri (pypi-uri "ruff" version)) + (sha256 + (base32 "19j03bjqqlq50rh2mfhb312879l302ycq6faqb034hkbnanjdspc")) + (patches (list (local-file "./contrib/guix/python-ruff/license-not-array.patch"))) + )) + (build-system pyproject-build-system) + (native-inputs (list maturin)) + (home-page "https://docs.astral.sh/ruff") + (synopsis + "An extremely fast Python linter and code formatter, written in Rust.") + (description + "An extremely fast Python linter and code formatter, written in Rust.") + (license #f))) + +(define-public python-py-spy + (package + (name "python-py-spy") + (version "0.4.2") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/benfred/py-spy") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 "067wg8m8d7a8xb8ngqv8gn8gqzicviwnv2c56lmhz5xcszc92gp5")))) + (build-system pyproject-build-system) + (native-inputs (list maturin python-numpy)) + (home-page "https://github.com/benfred/py-spy") + (synopsis "") + (description #f) + (license license:expat))) + +(define-public python-proxy-py + (package + (name "python-proxy-py") + (version "2.4.10") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/abhinavsingh/proxy.py") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 "1pqz1q0sh0zc1nkjgwiwssd2q40d2ihppf3x4j5022gbr7i3kpln")))) + (build-system pyproject-build-system) + (native-inputs (list python-autopep8 + python-h2 + python-hpack + python-httpx + python-hyperframe + python-mccabe + python-py-spy + python-pytest + python-pytest-asyncio + python-pytest-mock + python-pytest-xdist + python-coveralls + python-rope + python-setuptools + python-setuptools-scm + python-types-requests + python-types-setuptools)) + (home-page "https://github.com/abhinavsingh/proxy.py") + (synopsis + "\\u26a1 Fast \\u2022 \\U0001fab6 Lightweight \\u2022 \\U0001f51f Dependency \\u2022 \\U0001f50c Pluggable \\u2022 \\U0001f608 TLS interception \\u2022 \\U0001f512 DNS-over-HTTPS \\u2022 \\U0001f525 Poor Mans VPN \\u2022 \\u23ea Reverse & \\u23e9 Forward \\u2022 \\U0001f46e\\U0001f3ff Proxy Server framework \\u2022 \\U0001f310 Web Server framework \\u2022 \\u27b5 \\u27b6 \\u27b7 \\u27a0 PubSub framework \\u2022 \\U0001f477 Work acceptor & executor framework.") + (description + "\\u26a1 Fast \\u2022 \\U0001fab6 Lightweight \\u2022 \\U0001f51f Dependency \\u2022 +\\U0001f50c Pluggable \\u2022 \\U0001f608 TLS interception \\u2022 \\U0001f512 +DNS-over-HTTPS \\u2022 \\U0001f525 Poor Mans VPN \\u2022 \\u23ea Reverse & \\u23e9 +Forward \\u2022 \\U0001f46e\\U0001f3ff Proxy Server framework \\u2022 \\U0001f310 Web +Server framework \\u2022 \\u27b5 \\u27b6 \\u27b7 \\u27a0 @code{PubSub} framework +\\u2022 \\U0001f477 Work acceptor & executor framework.") + (license #f))) + +(define-public python-polyfactory + (package + (name "python-polyfactory") + (version "3.3.0") + (source + (origin + (method url-fetch) + (uri (pypi-uri "polyfactory" version)) + (sha256 + (base32 "16kf4krdnmn218mh1ymdhvvncr3rpf381xnizxig7va3zyv5hwi3")))) + (build-system pyproject-build-system) + (arguments + (list + #:tests? #f + #:phases #~(modify-phases %standard-phases + (delete 'check) + (delete 'sanity-check) + )) + ) + (propagated-inputs (list python-faker python-typing-extensions)) + (native-inputs (list python-hatchling)) + (home-page #f) + (synopsis "Mock data generation factories") + (description "Mock data generation factories.") + (license license:expat))) + +(define-public python-litestar-htmx + (package + (name "python-litestar-htmx") + (version "0.5.0") + (source + (origin + (method url-fetch) + (uri (pypi-uri "litestar_htmx" version)) + (sha256 + (base32 "1ys644z2j5ha94cngx0ddmigrsassr4nfgps6m48fb0pj8x1lbg0")))) + (build-system pyproject-build-system) + (arguments + (list + #:tests? #f + #:phases #~(modify-phases %standard-phases + (delete 'check) + (delete 'sanity-check) + )) + ) + (native-inputs (list python-hatchling)) + (home-page #f) + (synopsis "HTMX Integration for Litestar") + (description "HTMX Integration for Litestar.") + (license license:expat))) + + +(define-public python-flit-scm + (package + (name "python-flit-scm") + (version "1.7.0") + (source + (origin + (method url-fetch) + (uri (pypi-uri "flit_scm" version)) + (sha256 + (base32 "1ckbkykfr7f7wzjzgh0gm7h6v3pqzx2l28rw6dsvl6zk4kxxc6wn")))) + (build-system pyproject-build-system) + (propagated-inputs (list python-flit-core python-setuptools-scm python-tomli python-flit-scm-firstversion)) + (native-inputs (list python-flit-core python-setuptools-scm python-tomli python-flit-scm-firstversion)) + (home-page #f) + (synopsis + "A PEP 518 build backend that uses setuptools_scm to generate a version file from your version control system, then flit to build the package.") + (description + "This package provides a PEP 518 build backend that uses setuptools_scm to +generate a version file from your version control system, then flit to build the +package.") + (license license:expat))) + +(define-public python-flit-scm-firstversion + (package (inherit python-flit-scm) + (version "0.0.1") + (propagated-inputs (list python-flit-core python-setuptools-scm python-tomli)) + (native-inputs (list python-flit-core python-setuptools-scm python-tomli)) + )) + +(define-public python-exceptiongroup + (package + (name "python-exceptiongroup") + (version "1.3.1") + (source + (origin + (method url-fetch) + (uri (pypi-uri "exceptiongroup" version)) + (sha256 + (base32 "069j9qfgjha1qgvsh3zpaikyslikx45004632iyhnnq5qqr28hcb")))) + (build-system pyproject-build-system) + (propagated-inputs (list python-pytest python-typing-extensions)) + (native-inputs (list python-flit-scm python-pytest)) + (home-page #f) + (synopsis "Backport of PEP 654 (exception groups)") + (description "Backport of PEP 654 (exception groups).") + (license license:expat))) + +(define-public python-litestar + (package + (name "python-litestar") + (version "2.21.1") + (source + (origin + (method url-fetch) + (uri (pypi-uri "litestar" version)) + (sha256 + (base32 "0fl6qsa6g3kf6lxl3n0d5cjryns1zx6nin55d2xpfpkwvqw18c18")))) + (build-system pyproject-build-system) + (propagated-inputs (list python-anyio + python-click + python-exceptiongroup + python-httpx + python-importlib-resources + python-litestar-htmx + python-msgspec + python-multidict + python-multipart + python-polyfactory + python-pyyaml + python-rich + python-rich-click + python-sniffio + python-typing-extensions)) + (native-inputs (list python-hatchling)) + (home-page "https://litestar.dev/") + (synopsis + "Litestar - A production-ready, highly performant, extensible ASGI API Framework") + (description + "Litestar - A production-ready, highly performant, extensible ASGI API Framework.") + (license license:expat))) + + +(define-public python-free-proxy + (package + (name "python-free-proxy") + (version "1.1.3") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/jundymek/free-proxy") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 "0h3rpvghl7b0a66ql61q7bwalrxf5l2m3vaa14s3ahczd0c4lb7i")))) + (build-system pyproject-build-system) + (arguments + (list + #:tests? #f + #:phases #~(modify-phases %standard-phases + (delete 'check) + (delete 'sanity-check) + )) + ) + (propagated-inputs (list python-lxml python-requests)) + (native-inputs (list python-setuptools)) + (home-page "https://github.com/jundymek/free-proxy") + (synopsis "Proxy scraper for further use") + (description "Proxy scraper for further use.") + (license license:expat))) + +(define-public python-starlette-context + (package + (name "python-starlette-context") + (version "0.5.1") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/tomwojcik/starlette-context") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 "028sbfr3vzdx37dkhz5vpy9jv1xxwq0mdmaf8yd5m3n8nan5663k")))) + (build-system pyproject-build-system) + (arguments + (list + #:tests? #f + #:phases #~(modify-phases %standard-phases + (delete 'check) + (delete 'sanity-check) + )) + ) + (propagated-inputs (list python-starlette)) + (native-inputs (list python-hatchling)) + (home-page "https://github.com/tomwojcik/starlette-context") + (synopsis + "Middleware for Starlette that allows you to store and access the context data of a request. Can be used with logging so logs automatically use request headers such as x-request-id or x-correlation-id.") + (description + "Middleware for Starlette that allows you to store and access the context data of +a request. Can be used with logging so logs automatically use request headers +such as x-request-id or x-correlation-id.") + (license license:expat))) + +(define-public python-llama-cpp + (package + (name "python-llama-cpp") + (version "f7746900c0b70cd3deab2384ef2a108597eb1744") + (source + (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/abetlen/llama-cpp-python") + (commit version) + (recursive? #t) + )) + (file-name (git-file-name name version)) + (sha256 + (base32 "0pypjj1gy63bav76k8w094gmg0vmg5y60b7ij2smaw9a1bmk6rk6")))) + (build-system pyproject-build-system) + (arguments + (list + #:tests? #f + #:phases #~(modify-phases %standard-phases + (delete 'check) + (delete 'sanity-check) + )) + ) + (propagated-inputs (list python-diskcache python-jinja2 python-numpy + python-typing-extensions)) + (native-inputs (list python-fastapi + python-httpx + python-huggingface-hub + python-pydantic-settings + python-pytest + python-scikit-build-core + python-scipy + python-sse-starlette + python-starlette-context + cmake)) + (home-page "https://github.com/abetlen/llama-cpp-python") + (synopsis "Python bindings for the llama.cpp library") + (description "Python bindings for the llama.cpp library.") + (license license:expat))) + (packages->manifest (list python-getmeajob)) diff --git a/pyproject.toml b/pyproject.toml index 2840634..fa95930 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ dependencies = [ ] [project.scripts] -getmeajob = "getmeajob:getmeajob.main" +getmeajob = "getmeajob.getmeajob:main" [tool.setuptools.packages.find] # matches setuptools.find_packages() behavior where = ["."] diff --git a/requirements.txt b/requirements.txt index 4042b78..964ad37 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ tomli git+https://github.com/speedyapply/JobSpy.git jinja2 +llama-cpp-python -C cmake.args="-DGGML_VULKAN=on" +free-proxy |
