Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
Global refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
monosans committed Feb 8, 2024
1 parent 5e4949d commit dd678aa
Show file tree
Hide file tree
Showing 28 changed files with 1,658 additions and 184 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**
!nitro_generator_checker/**/*.py
!poetry.lock
!pyproject.toml
5 changes: 5 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
version: 2
updates:
- package-ecosystem: docker
directory: /
schedule:
interval: daily
time: "00:30"
- package-ecosystem: github-actions
directory: /
schedule:
Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true
jobs:
auto-merge-dependabot:
runs-on: ubuntu-latest
if: ${{ github.actor == 'dependabot[bot]' }}
steps:
- id: dependabot-metadata
uses: dependabot/fetch-metadata@v1
- if: ${{ steps.dependabot-metadata.outputs.update-type != 'version-update:semver-major' && steps.dependabot-metadata.outputs.package-ecosystem != 'docker' }}
run: gh pr merge --auto --delete-branch --squash "${PR_URL}"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
auto-merge-updates:
runs-on: ubuntu-latest
if: ${{ github.actor_id == '158570872' }}
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,30 @@ jobs:
steps:
- uses: actions/checkout@v4
- run: pipx run pre-commit run --all-files --show-diff-on-failure
build:
strategy:
matrix:
os:
- ubuntu
- macos
- windows
fail-fast: false
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v4
- run: pipx install poetry
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: poetry
check-latest: true
- run: poetry install --only=main,nuitka --sync --no-root --extras=non-termux --no-interaction
- run: poetry run --no-interaction python -m nuitka --onefile --python-flag='-m' --prefer-source-code --assume-yes-for-downloads nitro_generator_checker
- uses: actions/upload-artifact@v4
with:
name: artifact-${{ matrix.os }}
path: |
config.toml
nitro_generator_checker.bin
nitro_generator_checker.exe
if-no-files-found: error
3 changes: 3 additions & 0 deletions .github/workflows/update-dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ jobs:
strategy:
matrix:
include:
- cmd: pipx run poetry lock --no-interaction
commit-msg: Update poetry.lock
branch: update/poetry-lock
- cmd: pipx run pre-commit autoupdate
commit-msg: Update .pre-commit-config.yaml
branch: update/pre-commit-config
Expand Down
63 changes: 63 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# hadolint global ignore=DL3008,DL3013,DL4006
FROM docker.io/python:3.12-slim-bookworm as python-base-stage

ENV \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_NO_CACHE_DIR=1 \
PIP_NO_COLOR=1 \
PIP_NO_INPUT=1 \
PIP_PROGRESS_BAR=off \
PIP_ROOT_USER_ACTION=ignore \
PIP_UPGRADE=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1

WORKDIR /app


FROM python-base-stage as python-build-stage

ENV \
POETRY_NO_ANSI=1 \
POETRY_NO_CACHE=1 \
POETRY_NO_INTERACTION=1

RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -rf /var/lib/apt/lists/* \
&& pip install poetry poetry-plugin-export

COPY ./poetry.lock ./pyproject.toml ./

RUN poetry export --without-hashes --only=main --extras=non-termux | \
pip wheel --wheel-dir /usr/src/app/wheels -r /dev/stdin


FROM python-base-stage as python-run-stage

RUN apt-get update \
&& apt-get install -y --no-install-recommends -y tini \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -rf /var/lib/apt/lists/*

COPY --from=python-build-stage /usr/src/app/wheels /wheels/

RUN pip install --no-index --find-links /wheels/ /wheels/* \
&& rm -rf /wheels/

ARG GID UID

# hadolint ignore=SC3028
RUN groupadd --gid "${GID}" --system app \
&& useradd --gid app --no-log-init --system --uid "${UID}" app

ENV IS_DOCKER=1

COPY . .

USER app

ENTRYPOINT ["tini", "--"]

CMD ["python", "-m", "nitro_generator_checker"]
40 changes: 38 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,49 @@ Discord Nitro codes generator and checker with built-in proxy grabber. Saves wor

## Installation and usage

- Install [Python](https://python.org/downloads). The minimum version required is 3.7.
### Standalone executable

This is the easiest way, but it is only available for x64 Windows, macOS and Linux. Just download the archive for your OS from [nightly.link](https://nightly.link/monosans/nitro-generator-checker/workflows/ci/main?preview), unzip it, edit `config.toml` and run the executable.

If Windows Defender detects an executable file as a virus, please read [this](https://github.com/Nuitka/Nuitka/issues/2495#issuecomment-1762836583).

### Docker

- [Install `Docker Compose`](https://docs.docker.com/compose/install/).
- Download and unpack [the archive with the program](https://github.com/monosans/nitro-generator-checker/archive/refs/heads/main.zip).
- Edit `config.ini` to your preference.
- Edit `config.toml` to your preference.
- Run the following commands:
```bash
docker compose build --pull
docker compose up --no-log-prefix
```

### Running from source code

#### Desktop

- Install [Python](https://python.org/downloads). The minimum version required is 3.8.
- Download and unpack [the archive with the program](https://github.com/monosans/nitro-generator-checker/archive/refs/heads/main.zip).
- Edit `config.toml` to your preference.
- Run the script that installs dependencies and starts `nitro-generator-checker`:
- On Windows run `start.cmd`
- On Unix-like operating systems run `start.sh`

#### Termux

To use `nitro-generator-checker` in Termux, knowledge of the Unix command-line interface is required.

- Download Termux from [F-Droid](https://f-droid.org/en/packages/com.termux/). [Don't download it from Google Play](https://github.com/termux/termux-app#google-play-store-deprecated).
- Run the following command (it will automatically update Termux packages, install Python, and download and install `nitro-generator-checker`):
```bash
bash <(curl -fsSL 'https://raw.githubusercontent.com/monosans/nitro-generator-checker/main/install-termux.sh')
```
- Edit `~/nitro-generator-checker/config.toml` to your preference using a text editor (vim/nano).
- To run `nitro-generator-checker` use the following command:
```bash
cd ~/nitro-generator-checker && sh start-termux.sh
```

## License

[MIT](LICENSE)
16 changes: 0 additions & 16 deletions config.ini

This file was deleted.

15 changes: 15 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# How many codes to check concurrently?
# Windows supports maximum of 512.
# On *nix operating systems, this restriction is much looser.
# The limit on *nix can be seen with the command `ulimit -Hn`.
# Try different values and see which ones give you the best performance.
max_connections = 512

# Leave blank if you want the nitro codes to be only saved to the file_name.
webhook_url = ""

# The number of seconds to wait for a request to the Discord API.
timeout = 10

# Path to the file where valid codes are to be saved.
file_name = "./nitro_codes.txt"
12 changes: 12 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
services:
app:
image: nitro_generator_checker
build:
context: .
args:
- GID=${GID:-1000}
- UID=${UID:-1000}
tty: true
volumes:
- ./config.toml:/app/config.toml
- ./nitro_codes.txt:/app/nitro_codes.txt
17 changes: 17 additions & 0 deletions install-termux.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/sh

set -eu

project_name="nitro-generator-checker"
base_path="${HOME}"
install_path="${base_path}/${project_name}"
download_path="${TMPDIR}/${project_name}.zip"

[ -d "${install_path}" ] && rm -rf --interactive=once "${install_path}"
pkg upgrade --yes -o Dpkg::Options::='--force-confdef'
pkg install --yes python python-pip
curl -fsSLo "${download_path}" "https://github.com/monosans/${project_name}/archive/refs/heads/main.zip"
unzip -d "${base_path}" "${download_path}"
rm -f "${download_path}"
mv "${install_path}-main" "${install_path}"
printf "%s installed successfully.\nRun 'cd %s && sh start-termux.sh'.\n" "${project_name}" "${install_path}"
Empty file added nitro_codes.txt
Empty file.
46 changes: 33 additions & 13 deletions nitro_generator_checker/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,29 @@
import asyncio
import logging
import sys
from configparser import ConfigParser
from typing import TYPE_CHECKING, Dict

import aiofiles
import rich.traceback
from aiohttp import ClientSession, DummyCookieJar, TCPConnector
from rich.console import Console
from rich.logging import RichHandler
from typing_extensions import Any

from . import http
from .nitro_checker import NitroChecker
from .utils import bytes_decode

if sys.version_info >= (3, 11):
try:
import tomllib
except ImportError:
# Help users on older alphas
if not TYPE_CHECKING:
import tomli as tomllib
else:
import tomli as tomllib


def set_event_loop_policy() -> None:
if sys.platform == "win32":
Expand All @@ -29,7 +42,13 @@ def set_event_loop_policy() -> None:
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())


def configure_logging(console: Console) -> None:
async def read_config(file: str, /) -> Dict[str, Any]:
async with aiofiles.open(file, "rb") as f:
content = await f.read()
return tomllib.loads(bytes_decode(content))


def configure_logging(*, console: Console) -> None:
rich.traceback.install(
console=console, width=None, extra_lines=0, word_wrap=True
)
Expand All @@ -49,19 +68,20 @@ def configure_logging(console: Console) -> None:
)


async def read_config(file: str) -> ConfigParser:
async with aiofiles.open(file, "rb") as f:
content = await f.read()
cfg = ConfigParser(interpolation=None)
cfg.read_string(bytes_decode(content))
return cfg


async def main() -> None:
console = Console()
configure_logging(console)
cfg = await read_config("config.ini")
await NitroChecker.run_from_configparser(cfg, console=console)
configure_logging(console=console)
cfg = await read_config("config.toml")
async with ClientSession(
connector=TCPConnector(ssl=http.SSL_CONTEXT),
headers=http.HEADERS,
cookie_jar=DummyCookieJar(),
raise_for_status=True,
fallback_charset_resolver=http.fallback_charset_resolver,
) as session:
await NitroChecker.from_mapping(
cfg, console=console, session=session
).run()


if __name__ == "__main__":
Expand Down
12 changes: 6 additions & 6 deletions nitro_generator_checker/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@


class Counter:
__slots__ = ("total", "valid")
__slots__ = ("_total", "_valid")

def __init__(self) -> None:
self.total = 0
self.valid = 0
self._total = 0
self._valid = 0

def add_total(self) -> None:
self.total += 1
self._total += 1

def add_valid(self) -> None:
self.valid += 1
self._valid += 1

def as_rich_table(self) -> Table:
table = Table("Total", "Valid")
table.add_row(str(self.total), str(self.valid))
table.add_row(str(self._total), str(self._valid))
return table
13 changes: 13 additions & 0 deletions nitro_generator_checker/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import charset_normalizer
from aiohttp import ClientResponse, hdrs

from .utils import bytes_decode

SSL_CONTEXT = ssl.create_default_context(cafile=certifi.where())
HEADERS: MappingProxyType[str, str] = MappingProxyType({
hdrs.USER_AGENT: (
Expand All @@ -15,5 +17,16 @@
})


class NoCharsetHeaderError(Exception):
pass


def fallback_charset_resolver(r: ClientResponse, b: bytes) -> str: # noqa: ARG001
return charset_normalizer.from_bytes(b)[0].encoding


def get_response_text(*, response: ClientResponse, content: bytes) -> str:
try:
return content.decode(response.get_encoding())
except (NoCharsetHeaderError, UnicodeDecodeError):
return bytes_decode(content)
Loading

0 comments on commit dd678aa

Please sign in to comment.