Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Gummibeer committed Nov 18, 2022
1 parent f832430 commit 1ede16f
Show file tree
Hide file tree
Showing 661 changed files with 1,488 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* text=auto
generate.php export-ignore
15 changes: 15 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: 2
updates:
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
reviewers:
- "Gummibeer"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
reviewers:
- "Gummibeer"
24 changes: 24 additions & 0 deletions .github/workflows/pest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: pest

on:
push:

jobs:
pest:
name: P${{ matrix.php }} - ${{ matrix.dependency-version }}
timeout-minutes: 15
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: [8.1]
dependency-version: [prefer-lowest, prefer-stable]

steps:
- uses: actions/[email protected]
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- name: Install dependencies
run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest
- run: vendor/bin/pest
16 changes: 16 additions & 0 deletions .github/workflows/phpcs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: phpcs

on:
push:

jobs:
phpcs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/[email protected]
- uses: shivammathur/setup-php@v2
with:
php-version: 8.1
- run: composer install --no-interaction --no-scripts
- run: vendor/bin/pint --test
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
phpunit.xml
.phpunit.result.cache
composer.lock
vendor/
.coverage/
File renamed without changes.
52 changes: 51 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,51 @@
# sourcebans-sdk
# SourceBans++ SDK

[![Latest Version](http://img.shields.io/packagist/v/astrotomic/sourcebans-sdk.svg?label=Release&style=for-the-badge)](https://packagist.org/packages/astrotomic/sourcebans-sdk)
[![MIT License](https://img.shields.io/github/license/Astrotomic/sourcebans-sdk.svg?label=License&color=blue&style=for-the-badge)](https://github.com/Astrotomic/sourcebans-sdk/blob/master/LICENSE.md)
[![Offset Earth](https://img.shields.io/badge/Treeware-%F0%9F%8C%B3-green?style=for-the-badge)](https://forest.astrotomic.info)
[![Larabelles](https://img.shields.io/badge/Larabelles-%F0%9F%A6%84-lightpink?style=for-the-badge)](https://larabelles.com)

[![Total Downloads](https://img.shields.io/packagist/dt/astrotomic/sourcebans-sdk.svg?label=Downloads&style=flat-square)](https://packagist.org/packages/astrotomic/sourcebans-sdk)
[![PHP Version](https://img.shields.io/packagist/dependency-v/astrotomic/sourcebans-sdk/php?style=flat-square)](https://packagist.org/packages/astrotomic/sourcebans-sdk)
[![Laravel Version](https://img.shields.io/packagist/dependency-v/astrotomic/sourcebans-sdk/illuminate/support?style=flat-square&label=Laravel)](https://packagist.org/packages/astrotomic/sourcebans-sdk)

## Installation

```bash
composer require astrotomic/sourcebans-sdk
```

## Usage

```php
$sourcebans = app(\Astrotomic\SourceBansSdk\SourceBansConnector::class);

$bans = $sourcebans->queryBans();
```

## Contributing

Please see [CONTRIBUTING](https://github.com/Astrotomic/.github/blob/master/CONTRIBUTING.md) for details. You could also be interested in [CODE OF CONDUCT](https://github.com/Astrotomic/.github/blob/master/CODE_OF_CONDUCT.md).

### Security

If you discover any security related issues, please check [SECURITY](https://github.com/Astrotomic/.github/blob/master/SECURITY.md) for steps to report it.

## Credits

- [Tom Witkowski](https://github.com/Gummibeer)
- [All Contributors](../../contributors)

## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

## Treeware

You're free to use this package, but if it makes it to your production environment I would highly appreciate you buying the world a tree.

It’s now common knowledge that one of the best tools to tackle the climate crisis and keep our temperatures from rising above 1.5C is to [plant trees](https://www.bbc.co.uk/news/science-environment-48870920). If you contribute to my forest you’ll be creating employment for local families and restoring wildlife habitats.

You can buy trees at [ecologi.com/astrotomic](https://forest.astrotomic.info)

Read more about Treeware at [treeware.earth](https://treeware.earth)
83 changes: 83 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"name": "astrotomic/sourcebans-sdk",
"description": "Interact with SourceBans++ API.",
"license": "MIT",
"authors": [
{
"name": "Tom Witkowski",
"email": "[email protected]",
"homepage": "https://astrotomic.info",
"role": "Developer"
}
],
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/Gummibeer"
},
{
"type": "other",
"url": "https://forest.astrotomic.info"
}
],
"require": {
"php": "^8.1",
"ext-json": "*",
"illuminate/support": "^9.0",
"sammyjo20/saloon": "^1.5.2",
"sammyjo20/saloon-laravel": "^1.5.0",
"spatie/laravel-data": "^2.0",
"symfony/dom-crawler": "^6.1",
"xpaw/steamid": "^2.0"
},
"require-dev": {
"astrotomic/phpunit-assertions": "^0.10.0",
"laravel/pint": "^1.2",
"orchestra/testbench": "^7.0",
"pestphp/pest": "^1.21",
"pestphp/pest-plugin-laravel": "^1.2"
},
"autoload": {
"psr-4": {
"Astrotomic\\SourceBansSdk\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
},
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"composer-normalize": {
"indent-size": 4,
"indent-style": "space"
},
"laravel": {
"providers": [
"Astrotomic\\SourceBansSdk\\SourceBansSdkServiceProvider"
]
}
},
"scripts": {
"post-autoload-dump": [
"@composer normalize --ansi --no-interaction --quiet",
"@composer validate --strict --ansi --no-interaction",
"@composer thanks --ansi --no-interaction --quiet",
"@php vendor/bin/testbench package:discover --ansi"
],
"fix": "@php vendor/bin/pint",
"normalize": "echo 'composer global require ergebnis/composer-normalize'",
"phpstan": "@php vendor/bin/phpstan analyse --memory-limit=2G",
"test": "@php -d memory_limit=-1 vendor/bin/pest",
"test-coverage": "XDEBUG_MODE=coverage php -d memory_limit=-1 vendor/bin/pest --coverage-html=.coverage",
"thanks": "echo 'composer global require symfony/thanks'"
}
}
21 changes: 21 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
executionOrder="random"
>
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
</coverage>
<php>
<env name="STEAM_API_KEY" value=""/>
</php>
</phpunit>
36 changes: 36 additions & 0 deletions src/Data/Ban.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Astrotomic\SourceBansSdk\Data;

use Astrotomic\SourceBansSdk\Enums\BanStatus;
use Carbon\CarbonImmutable;
use Carbon\CarbonInterval;
use Spatie\LaravelData\Data;
use SteamID;

final class Ban extends Data
{
public function __construct(
public readonly SteamID $steam_id,
public readonly CarbonImmutable $invoked_on,
public readonly ?CarbonInterval $ban_length,
public readonly ?CarbonImmutable $expires_on,
public readonly ?string $ban_reason,
public readonly ?string $unban_reason,
public readonly int $total_bans,
) {
}

public function status(): BanStatus
{
if ($this->expires_on !== null && $this->expires_on->isPast()) {
return BanStatus::Expired;
}

if ($this->unban_reason !== null) {
return BanStatus::Unbanned;
}

return BanStatus::Banned;
}
}
10 changes: 10 additions & 0 deletions src/Enums/BanStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Astrotomic\SourceBansSdk\Enums;

enum BanStatus: string
{
case Banned = 'banned';
case Expired = 'expired';
case Unbanned = 'unbanned';
}
7 changes: 7 additions & 0 deletions src/Exceptions/BadGatewayException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Astrotomic\SourceBansSdk\Exceptions;

class BadGatewayException extends ServerException
{
}
27 changes: 27 additions & 0 deletions src/Exceptions/BadResponseException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Astrotomic\SourceBansSdk\Exceptions;

use Sammyjo20\Saloon\Exceptions\SaloonRequestException;
use Sammyjo20\Saloon\Http\SaloonResponse;
use Throwable;

class BadResponseException extends SaloonRequestException
{
final public function __construct(SaloonResponse $response, string $message = '', int $code = 0, ?Throwable $previous = null)
{
parent::__construct($response, $message, $code, $previous);
}

public static function fromResponse(SaloonResponse $response): static
{
$body = $response->toPsrResponse()->getBody()->getContents();

return new static($response, $body, $response->status(), $response->getGuzzleException());
}

public function getResponse(): SaloonResponse
{
return $this->getSaloonResponse();
}
}
7 changes: 7 additions & 0 deletions src/Exceptions/ClientException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Astrotomic\SourceBansSdk\Exceptions;

class ClientException extends BadResponseException
{
}
7 changes: 7 additions & 0 deletions src/Exceptions/ServerException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Astrotomic\SourceBansSdk\Exceptions;

class ServerException extends BadResponseException
{
}
70 changes: 70 additions & 0 deletions src/Extractors/Banlist/DefaultExtractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace Astrotomic\SourceBansSdk\Extractors\Banlist;

use Astrotomic\SourceBansSdk\Data\Ban;
use Astrotomic\SourceBansSdk\Extractors\Extractor;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Fluent;
use Illuminate\Support\Str;
use SteamID;
use Symfony\Component\DomCrawler\Crawler;

class DefaultExtractor extends Extractor
{
public function canHandle(Crawler $crawler): bool
{
$css = $crawler->filter('head link[rel=stylesheet]')->each(fn (Crawler $link) => $link->attr('href'));

return collect($css)->contains(
fn (string $href) => str_starts_with(trim($href, '/'), 'themes/default/css')
);
}

public function handle(Crawler $crawler): ?LengthAwarePaginator
{
$tables = $crawler->filter('#banlist table tr.opener + tr td div.opener table');

if ($tables->count() === 0) {
return null;
}

$bans = $tables->each(function (Crawler $table): ?Ban {
$data = new Fluent();

$table->filter('tr:not(:first-child)')->each(function (Crawler $row) use ($data): void {
$cells = $row->filter('td');

$key = Str::slug($cells->eq(0)->innerText(), '_');
$value = rescue(fn () => $cells->eq(1)->innerText(), report: false);

$data->{$key} = $value;
});

return rescue(
callback: fn () => new Ban(
steam_id: new SteamID($data->steam_id),
invoked_on: $this->toCarbonImmutable($data->invoked_on),
ban_length: $this->toCarbonInterval($data->banlength),
expires_on: $this->toCarbonImmutable($data->expires_on),
ban_reason: $data->reason ?: null,
unban_reason: $data->unban_reason ?: null,
total_bans: (int) $data->total_bans,
),
report: false
);
});

$pagination = $this->paginationFromString(
$crawler->filter('#banlist table + #banlist-nav')->innerText()
);

return new LengthAwarePaginator(
items: collect($bans)
->filter()
->values(),
total: $pagination['total'],
perPage: $pagination['end'] - $pagination['start'],
);
}
}
Loading

0 comments on commit 1ede16f

Please sign in to comment.