Skip to content

Commit f626031

Browse files
authored
Merge pull request #685 from plural/new-api-format-page
New api format page
2 parents 0abd6f7 + f8c0657 commit f626031

File tree

5 files changed

+111
-111
lines changed

5 files changed

+111
-111
lines changed

app/Resources/views/Formats/formats.html.twig

Lines changed: 108 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -13,75 +13,118 @@
1313
<div class="col-sm-12">
1414
<h2>NISEI Supported Formats</h2>
1515
<p>Card Pools and links to deck searches legal in those formats.</p>
16-
<p>See <a href="https://nisei.net/players/supported-formats/">NISEI's Supported Formats page</a> for more information.</p>
16+
<p>See <a href="https://nisei.net/players/supported-formats/">NISEI's Supported Formats page</a> for more information.</p>
1717
</div>
1818
</div>
1919

20-
<div class="row">
21-
<div class="col-sm-6">
22-
<h2>Startup Format</h2>
23-
<h4>Current Ban List</h4>
24-
<p>None</p>
25-
26-
<h4>Corp Decklists</h4>
27-
<ul>
28-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'corp', 'packs':startup_packs}) }}">Any Corp</a></li>
29-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'haas-bioroid', 'packs':startup_packs}) }}"><span class="icon icon-haas-bioroid influence-haas-bioroid"></span> Haas-Bioroid</a></li>
30-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'jinteki', 'packs':startup_packs}) }}"><span class="icon icon-jinteki influence-jinteki"></span> Jinteki</a></li>
31-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'nbn', 'packs':startup_packs}) }}"><span class="icon icon-nbn influence-nbn"></span> NBN</a></li>
32-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'weyland-consortium', 'packs':startup_packs}) }}"><span class="icon icon-weyland-consortium influence-weyland-consortium"></span> Weyland Consortium</a></li>
33-
</ul>
34-
<h4>Runner Decklists</h4>
35-
<ul>
36-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'runner', 'packs':startup_packs}) }}">Any Runner</a></li>
37-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'anarch', 'packs':startup_packs}) }}"><span class="icon icon-anarch influence-anarch"></span> Anarch</a></li>
38-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'criminal', 'packs':startup_packs}) }}"><span class="icon icon-criminal influence-criminal"></span> Criminal</a></li>
39-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'shaper', 'packs':startup_packs}) }}"><span class="icon icon-shaper influence-shaper"></span> Shaper</a></li>
40-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'adam', 'packs':startup_packs}) }}"><span class="icon icon-adam influence-adam"></span> Adam</a></li>
41-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'apex', 'packs':startup_packs}) }}"><span class="icon icon-apex influence-apex"></span> Apex</a></li>
42-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'sunny-lebeau', 'packs':startup_packs}) }}"><span class="icon icon-sunny-lebeau influence-sunny-lebeau"></span> Sunny Lebeau</a></li>
43-
</ul>
44-
<h4>Legal Card Cycles - {{ num_startup_cards }} unique cards</h4>
45-
<ul>
46-
{% for cycle in startup_cycles %}
47-
<li><a href="{{ path('cards_cycle', {cycle_code:cycle.code }) }}">{{ cycle.name }}</a></li>
48-
{% endfor %}
49-
</ul>
50-
</div>
20+
<div class="row" id="formats"></div>
5121

52-
<div class="col-sm-6">
53-
<h2>Standard Format</h2>
54-
<h4>Current Ban List</h4>
55-
<p><strong><a href="{{ path('banlists') }}#{{ standard_banlist.code }}">{{ standard_banlist.name }}</a></strong>, active as of <strong>{{ standard_banlist.dateStart|date("Y-m-d") }}</strong></p>
56-
57-
<h4>Corp Decklists</h4>
58-
<ul>
59-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'corp', 'packs':standard_packs}) }}">Any Corp</a></li>
60-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'haas-bioroid', 'packs':standard_packs}) }}"><span class="icon icon-haas-bioroid influence-haas-bioroid"></span> Haas-Bioroid</a></li>
61-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'jinteki', 'packs':standard_packs}) }}"><span class="icon icon-jinteki influence-jinteki"></span> Jinteki</a></li>
62-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'nbn', 'packs':standard_packs}) }}"><span class="icon icon-nbn influence-nbn"></span> NBN</a></li>
63-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'weyland-consortium', 'packs':standard_packs}) }}"><span class="icon icon-weyland-consortium influence-weyland-consortium"></span> Weyland Consortium</a></li>
64-
</ul>
65-
66-
<h4>Runner Decklists</h4>
67-
<ul>
68-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'runner', 'packs':standard_packs}) }}">Any Runner</a></li>
69-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'anarch', 'packs':standard_packs}) }}"><span class="icon icon-anarch influence-anarch"></span> Anarch</a></li>
70-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'criminal', 'packs':standard_packs}) }}"><span class="icon icon-criminal influence-criminal"></span> Criminal</a></li>
71-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'shaper', 'packs':standard_packs}) }}"><span class="icon icon-shaper influence-shaper"></span> Shaper</a></li>
72-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'adam', 'packs':standard_packs}) }}"><span class="icon icon-adam influence-adam"></span> Adam</a></li>
73-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'apex', 'packs':standard_packs}) }}"><span class="icon icon-apex influence-apex"></span> Apex</a></li>
74-
<li><a href="{{ path('decklists_list', {type:'find', 'faction':'sunny-lebeau', 'packs':standard_packs}) }}"><span class="icon icon-sunny-lebeau influence-sunny-lebeau"></span> Sunny Lebeau</a></li>
75-
</ul>
76-
77-
<h4>Legal Card Cycles - {{ num_standard_cards }} unique cards</h4>
78-
<ul>
79-
{% for cycle in standard_cycles %}
80-
<li><a href="{{ path('cards_cycle', {cycle_code:cycle.code }) }}">{{ cycle.name }}</a></li>
81-
{% endfor %}
82-
</ul>
83-
</div>
84-
</div>
8522
</div>
8623
</div>
24+
<script>
25+
function makeIdMap(json) {
26+
const out = new Map();
27+
json.data.forEach(d => {
28+
out.set(d.id, d);
29+
});
30+
return out;
31+
}
32+
33+
async function buildFormatsView() {
34+
const desiredFormats = new Set(['eternal', 'standard', 'startup']);
35+
36+
const [r1, r2, r3, r4, r5] = await Promise.all(
37+
[
38+
fetch('{{ v3_api_url }}/api/v3/public/snapshots?filter[active]=true').then(data => data.json()),
39+
fetch('{{ v3_api_url }}/api/v3/public/restrictions').then(data => data.json()),
40+
fetch('{{ v3_api_url }}/api/v3/public/card_cycles?sort=-date_release').then(data => data.json()),
41+
fetch('{{ v3_api_url }}/api/v3/public/card_sets?sort=-date_release').then(data => data.json()),
42+
fetch('{{ v3_api_url }}/api/v3/public/formats').then(data => data.json()),
43+
]
44+
);
45+
46+
const restrictions = makeIdMap(r2);
47+
const cyclesById = makeIdMap(r3);
48+
const sets = r4.data;
49+
const setsById = makeIdMap(r4);
50+
const formatsById = makeIdMap(r5);
51+
52+
// Support our supported formats in descending order by name.
53+
const formats = r1.data
54+
.filter(snapshot => desiredFormats.has(snapshot.attributes.format_id))
55+
.sort((a, b) => (a.attributes.format_id < b.attributes.format_id) ? 1 : -1);
56+
57+
// Each Format is a column, with the following struction:
58+
// - Name
59+
// - Banlist (if any)
60+
// - Corp & Runner Decklist Search Links
61+
// - Legal Card Count
62+
// - Legal Cycles and Sets (if a cycle is incomplete)
63+
formats.forEach(format => {
64+
const legalCycleIds = new Set(format.attributes.card_cycle_ids);
65+
const incompleteCycleIds = new Set();
66+
// TODO(plural): Accommodate multiple sets from an incomplete cycle and sort them by descending release date.
67+
const incompleteSetIds = new Set();
68+
format.attributes.card_set_ids.forEach(s => {
69+
if (!legalCycleIds.has(setsById.get(s).attributes.card_cycle_id)) {
70+
incompleteCycleIds.add(setsById.get(s).attributes.card_cycle_id);
71+
incompleteSetIds.add(s);
72+
}
73+
});
74+
75+
$('#formats').append(`<div class="col-sm-4" id="${format.id}"><h2>${formatsById.get(format.attributes.format_id).attributes.name} Format</h2></div>`);
76+
$(`#${format.id}`).append(`<h4>Current Ban List</h4>`);
77+
if (format.attributes.restriction_id) {
78+
const r = restrictions.get(format.attributes.restriction_id);
79+
$(`#${format.id}`).append(`<p><strong><a href="#">${r.attributes.name}</a></strong><br />active as of <strong>${r.attributes.date_start}</strong></p>`);
80+
} else {
81+
$(`#${format.id}`).append(`<p><strong>None<br />&nbsp;</p>`);
82+
}
83+
84+
$(`#${format.id}`).append(`<h4>Corp Decklists</h4>`);
85+
$(`#${format.id}`).append(`<ul id="${format.id}_corp_decklists"></ul>`);
86+
// TODO(plural): Wire up current restriction in the decklist search after making a legacy code for that as well.
87+
const packs = format.attributes.card_set_ids.map(s => setsById.get(s).attributes.legacy_code).sort();
88+
$(`#${format.id}_corp_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'corp', 'packs': packs})}">Any Corp</a></li>`);
89+
$(`#${format.id}_corp_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'h', 'packs': packs})}"><span class="icon icon-haas-bioroid influence-haas-bioroid"></span> Haas-Bioroid</a></li>`);
90+
$(`#${format.id}_corp_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'j', 'packs': packs})}"><span class="icon icon-jinteki influence-jinteki"></span> Jinteki</a></li>`);
91+
$(`#${format.id}_corp_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'n', 'packs': packs})}"><span class="icon icon-nbn influence-nbn"></span> NBN</a></li>`);
92+
$(`#${format.id}_corp_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'w', 'packs': packs})}"><span class="icon icon-weyland-consortium influence-weyland-consortium"></span> Weyland Consortium</a></li>`);
93+
94+
$(`#${format.id}`).append(`<h4>Runner Decklists</h4>`);
95+
$(`#${format.id}`).append(`<ul id="${format.id}_runner_decklists"></ul>`);
96+
$(`#${format.id}_runner_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'runner', 'packs': packs})}">Any Runner</a></li>`);
97+
$(`#${format.id}_runner_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'a', 'packs': packs})}"><span class="icon icon-anarch influence-anarch"></span> Anarch</a></li>`);
98+
$(`#${format.id}_runner_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'c', 'packs': packs})}"><span class="icon icon-criminal influence-criminal"></span> Criminal</a></li>`);
99+
$(`#${format.id}_runner_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'s', 'packs': packs})}"><span class="icon icon-shaper influence-shaper"></span> Shaper</a></li>`);
100+
101+
// Even though there are mini-faction cards in other sets, the IDs are only in Data & Destiny.
102+
if (legalCycleIds.has('data_and_destiny')) {
103+
$(`#${format.id}_runner_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'d', 'packs': packs})}"><span class="icon icon-adam influence-adam"></span> Adam</a></li>`);
104+
$(`#${format.id}_runner_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'p', 'packs': packs})}"><span class="icon icon-apex influence-apex"></span> Apex</a></li>`);
105+
$(`#${format.id}_runner_decklists`).append(`<li><a href="${Routing.generate('decklists_list', {type:'find', 'faction':'u', 'packs': packs})}"><span class="icon icon-sunny-lebeau influence-sunny-lebeau"></span> Sunny Lebeau</a></li>`);
106+
}
107+
108+
$(`#${format.id}`).append(`<h4>Legal Card Cycles - <a href="${Routing.generate('cards_find', {q: 'e:' + packs.join('|') } )}">${format.attributes.num_cards} Unique Cards</a></h4>`);
109+
110+
$(`#${format.id}`).append(`<ul id="${format.id}_cycles"></ul>`);
111+
cyclesById.forEach((cycle, cycle_id) => {
112+
if (legalCycleIds.has(cycle.id)) {
113+
$(`#${format.id}_cycles`).append(`<li><a href="${Routing.generate('cards_cycle', {cycle_code: cycle.attributes.legacy_code})}">${cycle.attributes.name}</a></li>`);
114+
} else if (incompleteCycleIds.has(cycle.id)) {
115+
const incompleteListId = `${format.id}_cycles_${cycle.id}`;
116+
if (!$(`#${incompleteListId}`).length) {
117+
$(`#${format.id}_cycles`).append(`<li>${cycle.attributes.name}<ul id=${incompleteListId}></ul></li>`);
118+
}
119+
sets.forEach(set => {
120+
if (set.attributes.card_cycle_id == cycle.id && incompleteSetIds.has(set.id)) {
121+
$(`#${incompleteListId}`).append(`<li><a href="${Routing.generate('cards_list', {pack_code: set.attributes.legacy_code})}">${set.attributes.name}</a></li>`);
122+
}
123+
});
124+
}
125+
});
126+
});
127+
}
128+
buildFormatsView();
129+
</script>
87130
{% endblock %}

app/config/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ twig:
4747
debug: '%kernel.debug%'
4848
strict_variables: '%kernel.debug%'
4949
globals:
50+
v3_api_url: '%v3_api_url%'
5051
card_image_url: '%card_image_url%'
5152
texts: '@AppBundle\Service\TextProcessor'
5253
supported_locales: "%supported_locales%"

app/config/parameters.yml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@ parameters:
4343
oauth_test_redirect_uri: ~
4444
images_path: ~
4545
card_image_url: 'https://assets.netrunnerdb.com/v1/'
46+
v3_api_url: 'https://api-preview.netrunnerdb.com/'
4647
slack_webhook_url: ~
4748
slack_webhook_channel: ~

docker/dev-parameters.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ parameters:
4242
oauth_test_client_secret: ~
4343
oauth_test_redirect_uri: ~
4444
images_path: ~
45+
v3_api_url: 'http://localhost:3000'
4546
card_image_url: 'https://static.nrdbassets.com/v1'

src/AppBundle/Controller/FormatsController.php

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,54 +13,8 @@ class FormatsController extends Controller
1313
*/
1414
public function getAction(EntityManagerInterface $entityManager)
1515
{
16-
$q = $entityManager->createQuery("SELECT c FROM AppBundle:Cycle c where c.code IN ('system-gateway', 'system-update-2021', 'ashes', 'borealis') ORDER BY c.position DESC");
17-
$startup_cycles = $q->getResult();
18-
$startup_packs = array();
19-
foreach ($startup_cycles as $cycle) {
20-
foreach ($cycle->getPacks() as $pack) {
21-
$startup_packs[] = $pack->getCode();
22-
}
23-
}
24-
25-
$q = $entityManager->createQuery("SELECT c FROM AppBundle:Cycle c WHERE c.rotated = 0 AND c.code NOT IN ('draft', 'napd') ORDER BY c.position DESC");
26-
$standard_cycles = $q->getResult();
27-
28-
$standard_packs = array();
29-
foreach ($standard_cycles as $cycle) {
30-
foreach ($cycle->getPacks() as $pack) {
31-
$standard_packs[] = $pack->getCode();
32-
}
33-
}
34-
35-
$standard_banlist = $entityManager->getRepository('AppBundle:Mwl')->findOneBy(["active" => 1]);
36-
37-
$dbh = $entityManager->getConnection();
38-
$num_standard_cards = $dbh->executeQuery(
39-
"SELECT COUNT(DISTINCT card.title) as num_cards"
40-
. " FROM card"
41-
. " JOIN pack ON card.pack_id = pack.id"
42-
. " JOIN cycle ON pack.cycle_id = cycle.id"
43-
. " WHERE cycle.rotated = 0 AND cycle.code NOT IN ('draft', 'napd')"
44-
)->fetch(\PDO::FETCH_ASSOC)['num_cards'];
45-
$num_startup_cards = $dbh->executeQuery(
46-
"SELECT COUNT(DISTINCT card.title) as num_cards"
47-
. " FROM card"
48-
. " JOIN pack ON card.pack_id = pack.id"
49-
. " JOIN cycle ON pack.cycle_id = cycle.id"
50-
. " WHERE cycle.code IN ('system-gateway', 'system-update-2021', 'ashes', 'borealis')"
51-
)->fetch(\PDO::FETCH_ASSOC)['num_cards'];
52-
53-
54-
5516
return $this->render('/Formats/formats.html.twig', [
5617
'pagetitle' => "Play Formats",
57-
'startup_cycles' => $startup_cycles,
58-
'startup_packs' => $startup_packs,
59-
'num_startup_cards' => $num_startup_cards,
60-
'standard_cycles' => $standard_cycles,
61-
'standard_packs' => $standard_packs,
62-
'standard_banlist' => $standard_banlist,
63-
'num_standard_cards' => $num_standard_cards,
6418
]);
6519
}
6620
}

0 commit comments

Comments
 (0)