Skip to content

Commit 72de692

Browse files
committed
initial export from ampache
1 parent 137d16b commit 72de692

File tree

12 files changed

+592
-2
lines changed

12 files changed

+592
-2
lines changed

.gitattributes

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
# Auto detect text files and perform LF normalization
2-
* text=auto
1+
/tests export-ignore
2+
/examples export-ignore

.github/workflows/qa.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: qa
2+
3+
on:
4+
push:
5+
branches: [ release, master ]
6+
pull_request:
7+
branches: [ release, master ]
8+
9+
jobs:
10+
build:
11+
runs-on: ${{ matrix.os }}
12+
strategy:
13+
matrix:
14+
os: ['ubuntu-latest']
15+
php: ['8.2', '8.3']
16+
continue-on-error: ${{ matrix.php == '8.3' }}
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Setup PHP
21+
uses: shivammathur/setup-php@v2
22+
with:
23+
php-version: ${{ matrix.php }}
24+
25+
- name: Validate composer.json and composer.lock
26+
run: composer validate
27+
28+
- name: Install dependencies
29+
if: ${{ matrix.php != '8.3' }}
30+
uses: nick-fields/retry@v3
31+
with:
32+
timeout_minutes: 5
33+
max_attempts: 3
34+
command: composer update --no-interaction --no-progress
35+
36+
- name: Install Dependencies (ignore platform)
37+
if: ${{ matrix.php == '8.3' }}
38+
uses: nick-fields/retry@v3
39+
with:
40+
timeout_minutes: 5
41+
max_attempts: 3
42+
command: composer update --no-interaction --no-progress --ignore-platform-req=php
43+
44+
- name: Run test suite
45+
run: composer run-script qa
46+
env:
47+
PHP_CS_FIXER_IGNORE_ENV: 1
48+

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/.idea
2+
/build
3+
/vendor/
4+
composer.lock
5+
.php-cs-fixer.cache
6+
.phpunit.result.cache

.php-cs-fixer.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
$finder = PhpCsFixer\Finder::create()
4+
->in('examples/')
5+
->in('src/')
6+
->in('tests/')
7+
;
8+
9+
return (new PhpCsFixer\Config())
10+
->setRules([
11+
'@PSR12' => true,
12+
'array_syntax' => [
13+
'syntax' => 'short'
14+
],
15+
'binary_operator_spaces' => [
16+
'operators' => ['=' => 'align']
17+
],
18+
'blank_line_after_namespace' => true,
19+
'blank_line_before_statement' => [
20+
'statements' => ['declare', 'return']
21+
],
22+
'blank_line_between_import_groups' => true,
23+
'concat_space' => [
24+
'spacing' => 'one'
25+
],
26+
'constant_case' => true,
27+
'braces_position' => [
28+
'functions_opening_brace' => 'next_line_unless_newline_at_signature_end',
29+
'allow_single_line_empty_anonymous_classes' => true,
30+
'allow_single_line_anonymous_functions' => true
31+
],
32+
'declare_equal_normalize' => [
33+
'space' => 'none'
34+
],
35+
'elseif' => true,
36+
'encoding' => true,
37+
'full_opening_tag' => true,
38+
'line_ending' => true,
39+
'lowercase_cast' => true,
40+
'method_argument_space' => true,
41+
'multiline_comment_opening_closing' => true,
42+
'no_break_comment' => false,
43+
'no_trailing_whitespace' => true,
44+
'no_trailing_whitespace_in_comment' => true,
45+
'no_whitespace_in_blank_line' => true,
46+
'return_type_declaration' => [
47+
'space_before' => 'none',
48+
],
49+
'single_blank_line_at_eof' => true,
50+
'strict_param' => false,
51+
'visibility_required' => true,
52+
'no_unused_imports' => true,
53+
])
54+
->setIndent(" ")
55+
->setFinder($finder)
56+
->setLineEnding("\n")
57+
->setUsingCache(true)
58+
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
59+
;
60+

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Discogs
2+
3+
## 0.0.1

composer.json

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"name": "lachlan-00/discogs",
3+
"type": "library",
4+
"description": "A PHP library for accessing the Discogs API",
5+
"keywords": ["discogs", "library", "php", "api"],
6+
"homepage": "https://github.com/lachlan-00/DiscogsPHP",
7+
"license": "MIT",
8+
"authors": [
9+
{
10+
"name": "Lachlan de Waard",
11+
"email": "[email protected]",
12+
"homepage": "https://github.com/lachlan-00",
13+
"role": "Developer"
14+
}
15+
],
16+
"require": {
17+
"php": ">=8.2",
18+
"rmccue/requests": "^2.0"
19+
},
20+
"require-dev": {
21+
"friendsofphp/php-cs-fixer": "^3.49",
22+
"phpstan/phpstan": "^1.10",
23+
"phpunit/phpunit": "^11",
24+
"rector/rector": "^1"
25+
},
26+
"scripts": {
27+
"qa": "composer run-script cs:check",
28+
"stan": "vendor/bin/phpstan analyse",
29+
"stan-baseline": "vendor/bin/phpstan --generate-baseline",
30+
"tests": "vendor/bin/phpunit -c phpunit.xml",
31+
"cs:fix": "vendor/bin/php-cs-fixer fix",
32+
"cs:check": "vendor/bin/php-cs-fixer fix --dry-run -vv",
33+
"rector:dry": "rector process -n",
34+
"rector:fix": "rector process"
35+
},
36+
"scripts-descriptions": {
37+
"coverage": "Generates the code-coverage report into the build/coverage directory",
38+
"qa": "Runs several qa-related tests",
39+
"stan": "Performs static analysis",
40+
"stan-baseline": "Regenerate phpstan baseline",
41+
"tests": "Executes the unit tests",
42+
"syntax": "Performs php syntax checks",
43+
"cs:fix": "Performs code-style corrections on the whole codebase",
44+
"cs:check": "Performs a code-style dry-run on the whole codebase",
45+
"rector:dry": "Performs rector code-migrations dry-run",
46+
"rector:fix": "Applies pending rector code-migrations"
47+
},
48+
"suggest": {
49+
},
50+
"autoload": {
51+
"psr-0": {
52+
"Discogs": "src/"
53+
}
54+
}
55+
}

examples/search.php

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?php
2+
3+
use AmpacheDiscogs\Discogs;
4+
5+
require dirname(__DIR__) . '/vendor/autoload.php';
6+
7+
// your own username nad password are required to use the Discogs API
8+
$username = null;
9+
$password = null;
10+
$discogs = new Discogs($username, $password);
11+
12+
$media_info = [
13+
[
14+
'album' => 'The Shape',
15+
'albumartist' => 'Code 64',
16+
],
17+
[
18+
'album' => null,
19+
'artist' => 'Code 64',
20+
],
21+
[
22+
'album' => 'nothingishereandneverwillbe',
23+
'artist' => 'nothingishereandneverwillbe',
24+
],
25+
];
26+
27+
foreach ($media_info as $media) {
28+
echo "Checking: " . print_r($media, true) . PHP_EOL;
29+
$results = [];
30+
try {
31+
if (isset($media['artist']) && ($media['artist'] !== '' && $media['artist'] !== '0') && !in_array('album', $media)) {
32+
$artists = $discogs->search_artist($media['artist']);
33+
if (isset($artists['results']) && count($artists['results']) > 0) {
34+
foreach ($artists['results'] as $result) {
35+
if ($result['title'] === $media['artist']) {
36+
$artist = $discogs->get_artist((int)$result['id']);
37+
if (isset($artist['images']) && count($artist['images']) > 0) {
38+
$results['art'] = $artist['images'][0]['uri'];
39+
}
40+
41+
if (!empty($artist['cover_image'])) {
42+
$results['art'] = $artist['cover_image'];
43+
}
44+
45+
// add in the data response as well
46+
$results['data'] = $artist;
47+
break;
48+
}
49+
}
50+
}
51+
}
52+
53+
if (!empty($media['albumartist']) && !empty($media['album'])) {
54+
/**
55+
* https://api.discogs.com/database/search?type=master&release_title=Ghosts&artist=Ladytron&per_page=10&key=key@secret=secret
56+
*/
57+
$albums = $discogs->search_album($media['albumartist'], $media['album']);
58+
if (empty($albums['results'])) {
59+
$albums = $discogs->search_album($media['albumartist'], $media['album'], 'release');
60+
}
61+
62+
// get the album that matches $artist - $album
63+
if (!empty($albums['results'])) {
64+
/**
65+
* @var array{
66+
* country: string,
67+
* year: string,
68+
* format: string[],
69+
* label: string[],
70+
* type: string,
71+
* genre: string[],
72+
* style: string[],
73+
* id: ?int,
74+
* barcode: string[],
75+
* master_id: int,
76+
* master_url: string,
77+
* uri: string,
78+
* catno: string,
79+
* title: string,
80+
* thumb: string,
81+
* cover_image: string,
82+
* resource_url: string,
83+
* community: object,
84+
* format_quantity: ?int,
85+
* formats: ?object,
86+
* } $albumSearch
87+
*/
88+
foreach ($albums['results'] as $albumSearch) {
89+
if ($media['albumartist'] . ' - ' . $media['album'] === $albumSearch['title']) {
90+
$album = $albumSearch;
91+
break;
92+
}
93+
}
94+
95+
// look up the master release if we have one or the first release
96+
if (!isset($album['id'])) {
97+
/**
98+
* @var array{
99+
* id: ?int,
100+
* main_release: int,
101+
* most_recent_release: int,
102+
* uri: string,
103+
* versions_uri: string,
104+
* main_release_uri: string,
105+
* most_recent_release_uri: string,
106+
* num_for_sale: int,
107+
* lowest_price: int,
108+
* images: object,
109+
* genres: string[],
110+
* styles: string[],
111+
* year: int,
112+
* tracklist: object,
113+
* artists: object,
114+
* title: string,
115+
* data-quality: string,
116+
* videos: object,
117+
* } $album
118+
*/
119+
$album = (($albums['results'][0]['master_id'] ?? 0) > 0)
120+
? $discogs->get_album((int)$albums['results'][0]['master_id'])
121+
: $discogs->get_album((int)$albums['results'][0]['id'], 'releases');
122+
}
123+
124+
// fallback to the initial search if we don't have a master
125+
if (!isset($album['id'])) {
126+
$album = $albums['results'][0];
127+
}
128+
129+
if (isset($album['images']) && count($album['images']) > 0) {
130+
$results['art'] = $album['images'][0]['uri'];
131+
}
132+
133+
if (!empty($album['cover_image'])) {
134+
$results['art'] = $album['cover_image'];
135+
}
136+
137+
$genres = [];
138+
foreach ($albums['results'] as $release) {
139+
if (!empty($release['genre'])) {
140+
$genres = array_merge($genres, $release['genre']);
141+
}
142+
}
143+
144+
if (!empty($release['style'])) {
145+
$genres = array_merge($genres, $release['style']);
146+
}
147+
148+
if ($genres !== []) {
149+
$results['genre'] = array_unique($genres);
150+
}
151+
152+
// add in the data response as well
153+
$results['data'] = $album;
154+
}
155+
}
156+
157+
print_r($results);
158+
} catch (Exception $exception) {
159+
print_r($exception->getMessage());
160+
}
161+
}

phpstan-baseline.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
parameters:
2+
ignoreErrors: []
3+

phpstan.neon

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
parameters:
2+
level: 8
3+
paths:
4+
- src
5+
includes:
6+
- phpstan-baseline.neon

phpunit.xml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.2/phpunit.xsd"
5+
backupGlobals="true"
6+
colors="true"
7+
displayDetailsOnTestsThatTriggerDeprecations="true"
8+
displayDetailsOnTestsThatTriggerErrors="true"
9+
displayDetailsOnTestsThatTriggerNotices="true"
10+
displayDetailsOnTestsThatTriggerWarnings="true"
11+
displayDetailsOnIncompleteTests="true"
12+
displayDetailsOnSkippedTests="true"
13+
displayDetailsOnPhpunitDeprecations="true"
14+
>
15+
<testsuites>
16+
<testsuite name="default">
17+
<directory>tests</directory>
18+
</testsuite>
19+
</testsuites>
20+
<source restrictNotices="true" restrictWarnings="true" ignoreIndirectDeprecations="true">
21+
<include>
22+
<directory>src</directory>
23+
</include>
24+
<exclude />
25+
</source>
26+
</phpunit>

0 commit comments

Comments
 (0)