Filesystem org
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2022-03-07 02:07:16 +03:00
parent 76fdee2cfc
commit fd32ca704a
15 changed files with 3 additions and 2 deletions

31
src/api.js Normal file
View File

@@ -0,0 +1,31 @@
const axios = require('axios')
const { RateLimiter } = require('limiter')
class Api {
constructor () {
this.baseUrl = 'https://api.warframe.market/v1/'
this.delay = process.env.API_DELAY ?? 3000
this.limiter = new RateLimiter({ tokensPerInterval: 1, interval: Number(this.delay) })
}
async _get (url) {
await this.limiter.removeTokens(1)
return axios.get(url)
}
async getOrders (url) {
const response = await this._get(this.baseUrl + 'items/' + url + '/orders')
return response.data.payload.orders.filter(function (order) {
return order.order_type === 'sell' && order.user.status !== 'offline'
})
}
async getSortedOrders (url) {
const orders = await this.getOrders(url)
return orders.sort(function (a, b) {
return a.platinum - b.platinum
})
}
}
module.exports = new Api()

21
src/index.js Normal file
View File

@@ -0,0 +1,21 @@
require('dotenv').config()
const items = require('./items')
const output = require('./output');
(async () => {
for (const item of items) {
console.log(`Looking at ${item.name}`)
let partsPrice = 0
for (const part of item.parts) {
partsPrice += await part.getPrice()
}
const setPrice = await item.set.getPrice()
if (partsPrice < setPrice) {
output.addItem(item.name, partsPrice, setPrice)
}
}
output.submit()
})()

11
src/items/Archwings.js Normal file
View File

@@ -0,0 +1,11 @@
const Item = require('./Item')
module.exports = class Archwings extends Item {
constructor (name) {
super(name)
this.addPart('harness')
this.addPart('wings')
this.addPart('systems')
}
}

11
src/items/Companion.js Normal file
View File

@@ -0,0 +1,11 @@
const Item = require('./Item')
module.exports = class Companion extends Item {
constructor (name) {
super(name)
this.addPart('carapace')
this.addPart('cerebrum')
this.addPart('systems')
}
}

15
src/items/Item.js Normal file
View File

@@ -0,0 +1,15 @@
const Part = require('./Part')
module.exports = class Item {
constructor (name) {
this.name = name
this.set = new Part(name, 'set')
this.parts = []
this.addPart('blueprint')
}
addPart (part, amount) {
this.parts.push(new Part(this.name, part, amount))
}
}

14
src/items/Part.js Normal file
View File

@@ -0,0 +1,14 @@
const Api = require('../api')
module.exports = class Part {
constructor (set, part, amount) {
this.part = part
this.url = `${set}_prime_${part}`
this.amount = amount ?? 1
}
async getPrice () {
const orders = await Api.getSortedOrders(this.url)
return Number(orders[0].platinum) * this.amount
}
}

11
src/items/Primary.js Normal file
View File

@@ -0,0 +1,11 @@
const Item = require('./Item')
module.exports = class Primary extends Item {
constructor (name) {
super(name)
this.addPart('barrel')
this.addPart('receiver')
this.addPart('stock')
}
}

11
src/items/Secondary.js Normal file
View File

@@ -0,0 +1,11 @@
const Item = require('./Item')
module.exports = class Secondary extends Item {
constructor (name) {
super(name)
this.addPart('barrel', 2)
this.addPart('receiver', 2)
this.addPart('link')
}
}

11
src/items/Warframe.js Normal file
View File

@@ -0,0 +1,11 @@
const Item = require('./Item')
module.exports = class Warframe extends Item {
constructor (name) {
super(name)
this.addPart('systems')
this.addPart('neuroptics')
this.addPart('chassis')
}
}

26
src/items/index.js Normal file
View File

@@ -0,0 +1,26 @@
const items = require('./items.json')
const Warframe = require('./Warframe')
// const Primary = require('./Primary')
// const Secondary = require('./Secondary')
const Companion = require('./Companion')
const Archwings = require('./Archwings')
const result = []
items.warframes.forEach((name) => {
result.push(new Warframe(name))
})
// items.primaries.forEach((name) => {
// result.push(new Primary(name))
// })
items.companions.forEach((name) => {
result.push(new Companion(name))
})
items.archwings.forEach((name) => {
result.push(new Archwings(name))
})
module.exports = result

22
src/items/items.json Normal file
View File

@@ -0,0 +1,22 @@
{
"warframes": [
"ash", "atlas", "banshee", "chroma", "ember",
"equinox", "frost", "gara", "harrow", "hydroid",
"inaros", "ivara", "limbo", "loki", "mag",
"mesa", "mirage", "nekros", "nezha", "nidus",
"nova", "nyx", "oberon", "octavia", "rhino",
"saryn", "titania", "trinity", "valkyr", "vauban",
"volt", "wukong", "zephyr"
],
"primaries": [
"astilla", "baza", "boar", "boltor", "braton",
"burston", "corinth", "larton", "panthera",
"rubico", "scourge", "soma", "stradavar",
"strun", "sybaris", "tenora", "tiberon", "tigris",
"vectis", "zhuge"
],
"companions": [
"carrier", "dethcube", "helios", "wyrm"
],
"archwings": ["odonata"]
}

10
src/output/OutputItem.js Normal file
View File

@@ -0,0 +1,10 @@
module.exports = class OutputItem {
constructor (name, parts, set) {
this.name = name + ' prime'
this.parts = parts
this.set = set
this.link = `https://warframe.market/items/${name}_prime_set`
this.difference = set - parts
}
}

39
src/output/index.js Normal file
View File

@@ -0,0 +1,39 @@
const fs = require('fs')
const Handlebars = require('handlebars')
const OutputItem = require('./OutputItem')
class Output {
constructor () {
this.items = []
this.timestamp = null
}
addItem (...p) {
this.items.push(new OutputItem(...p))
}
async compileTemplate () {
const templateFile = await fs.readFileSync('./src/output/template.hbs', 'utf8')
const template = Handlebars.compile(templateFile)
return template(this)
}
async writeToFile (content) {
const filename = './public/index.html'
try {
await fs.unlinkSync(filename)
} catch {
console.log('File probably doesnt exist')
}
fs.writeFileSync(filename, content, 'utf8')
}
async submit () {
this.timestamp = new Date()
const content = await this.compileTemplate()
await this.writeToFile(content)
}
}
module.exports = new Output()

77
src/output/template.hbs Normal file
View File

@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Warframe Market Gaps</title>
<!-- Yandex.Metrika counter -->
<script type="text/javascript" >
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(87671663, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true
});
</script>
<noscript><div><img src="https://mc.yandex.ru/watch/87671663" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->
</head>
<body>
<div class="hero">
<img id="gunner1" src="./assets/gunner1.png">
<div class="main">
<img class="logo" src="./assets/warframe_logo.png">
<div class="text">
<h1>Market Gaps</h1>
<p>Find a profitable difference between the price of the set and the price of the sum of it's parts.</p>
</div>
</div>
<img id="gunner2" src="./assets/gunner2.png">
</div>
<div class="main-column">
<div class="controls">
<label for="min-difference">Filter by difference:</label>
<input type="range" min="1" max="60" value="1" id="min-difference">
<span id="filter-value">1</span>
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Parts price</th>
<th>Set price</th>
<th>Difference</th>
</tr>
</thead>
<tbody id="items">
{{#each items}}
<tr data-difference="{{this.difference}}">
<td class="name">
<a href="{{this.link}}" target="_blank">
{{this.name}}
</a>
</td>
<td>{{this.parts}}</td>
<td>{{this.set}}</td>
<td>{{this.difference}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="timestamp">
Generated at {{timestamp}}
</div>
<script src="index.js"></script>
</body>
</html>