· 4 years ago · Feb 07, 2021, 06:34 PM
1'use strict'
2const axios = require('axios');
3const fs = require ('fs').promises
4const Bottleneck = require ( "bottleneck" ) ;
5const nacl = require ("tweetnacl/nacl-fast")
6
7const timestamp = Math.floor(new Date().getTime() / 1000)
8
9let history = []
10
11async function recording (){
12 let arr = await fs.readFile('result.json', 'utf8')
13 .catch(err => console.log('error in recording'))
14 history = arr
15}
16
17async function main(){
18 await recording();
19 console.log ("document loaded");
20 if (history.length == 0){
21 let HISTORY = await CountingAverage()
22 history = HISTORY
23 console.log ("Загружена актуальная информация")
24 } else {
25 let file = JSON.parse(history)
26 let result = []
27 for (let i = 0; i < 30; i++) {
28 const LastUpdate = file[i].Lastreq
29 const Pop = file[i].Popularity
30 const name = file[i].Name
31 const Firstupd = file[i].DataInfo[file[i].DataInfo.length-1]
32 let TimeOut = parseInt(timestamp)-parseInt(LastUpdate)
33 if (Pop>150 && TimeOut>900) {
34 result.push (await update(Firstupd,file[i],name))
35 }else if (Pop>72 && TimeOut>1800){
36 result.push (await update(Firstupd,file[i],name))
37 }else if (Pop>48 && TimeOut>7200){
38 result.push (await update(Firstupd,file[i],name))
39 }else if (Pop>24 && TimeOut>10800){
40 result.push (await update(Firstupd,file[i],name))
41 }else if (Pop>12 && TimeOut>21600){
42 result.push (await update(Firstupd,file[i],name))
43 }else if (Pop>6 && TimeOut>43200){
44 result.push (await update(Firstupd,file[i],name))
45 }else if (Pop>3 && TimeOut>86400){
46 result.push (await update(Firstupd,file[i],name))
47 }else if (Pop<=3 && TimeOut>86400*2){
48 result.push (await update(Firstupd,file[i],name))
49 }
50 }
51 // console.log (result)
52 }
53}
54
55main()
56
57async function CountingAverage(){
58 async function ReadsFile() {
59 let result = []
60 let file = []
61 let arr = await RequestAllItems()
62 result.push (arr)
63 for (let i = 0; i < result.length; i++) {
64 let item = result[i]
65 for (let i = 0; i < item.length; i++) {
66 // let time =
67 file.push({
68 name:item[i].name,
69 story:item[i].story,
70 lastreq:timestamp
71 })
72 }
73 }
74 // console.log(file)
75 return file
76 }
77
78 async function calcValue(){
79 let file = await ReadsFile()
80 let result = []
81 file.forEach( function (item,i,file) {
82 let bufdate = []
83 let bufprice = []
84 item.story.forEach(function(item,i){
85 bufdate[bufdate.length]=item.date
86 bufprice[bufprice.length]=item.price
87 })
88 result.push({
89 name:item.name,
90 data:bufdate,
91 price:bufprice
92 })
93 });
94 return result
95 }
96
97 // /(604800 AverageNumber/Average.length)).toFixed(2)
98 async function CalcAverageValue(){
99 let file = await calcValue()
100 let result = []
101 for (let i = 0; i < file.length; i++) {
102 let Data = file[i].data
103 let Price = file[i].price
104 let ArrData = []
105 // console.log (Data)
106 for (let i = 0; i < Data.length; i++) {
107 if(Data[i]!=Data[Data.length-1]){
108 let bufdata = Data[i]-Data[i+1]
109 ArrData.push(bufdata)
110 }
111 }
112 // console.log (ArrData)
113 let bufprice = 0
114 for (let i = 0; i < Price.length; i++) {
115 bufprice += Price[i]
116
117 }
118 let Averprice = 0
119 Averprice = bufprice/Price.length
120 let AVG = 0
121 const spred = 0.13
122 for (let i = 0; i < Price.length; i++) {
123 let item = Price[i];
124 if (item/Averprice>(1+spred) || Averprice/item>(1+spred)){
125 item = (item>Averprice)?AVG=Averprice*(1+spred):AVG=Averprice*(i-spred)
126 }
127 AVG = Averprice
128 }
129 result.push ({
130 name:file[i].name,
131 AveragePrice:AVG,
132 arrdata:ArrData
133 })
134 }
135
136 return result
137 }
138
139 async function CalcPopularity(){
140 let lastprice = await ReadsFile()
141 let file = await CalcAverageValue()
142 let result = []
143 for (let i = 0; i < file.length; i++) {
144 let arr = file[i].arrdata
145 let buf = 0
146 let lstprice = lastprice[i].story
147 let respdata = []
148 let resprice = []
149 for (let i = 0; i < lstprice.length; i++) {
150 respdata.push(lstprice[i].date)
151 resprice.push(lstprice[i].price)
152 }
153 for (let i = 0; i < arr.length; i++) {
154 buf=buf+parseInt(arr[i])
155 }
156 if(buf!=0){
157 result.push({
158 Name:file[i].name,
159 AveragePrice:file[i].AveragePrice,
160 Popularity:parseFloat((604800/(buf/arr.length)).toFixed(2)),
161 Lastreq: lastprice[i].lastreq,
162 DataInfo:respdata,
163 PriceInfo:resprice
164 })
165 }
166 }
167 // console.log (result)
168 return result
169
170 }
171 let end = await CalcPopularity()
172 fs.writeFile("history.json", JSON.stringify(end, null, 2))
173 return end
174}
175
176async function RequestAllItems(){
177 async function Getprices (){ //делает запрос на сервер
178 const response = await axios.get ('https://loot.farm/fullprice.json')
179 let resulte = []
180 resulte = response.data
181 // console.log (resulte)
182 console.log ("Запрос всех предметов выполнен")
183 return resulte
184 }
185 async function CheckPrice(){ //обрабатывает результат запроса Getprices, сортирует по цене стима
186 let result = await Getprices()
187 let arrprice = []
188 for (let i = 0; i < result.length; i++) {
189 if (result[i].price < 10000 ) {
190 arrprice.push({
191 price : (Math.round(result[i].price*100 / result[i].rate)),
192 name: (result[i].name)
193 })
194 }
195 }
196 console.log ("Результат запроса обработан согласно заданным параметрам")
197 return arrprice
198 }
199 async function CheckName() { //Возвращает все имена предметов
200 let we = await CheckPrice()
201 let arr = []
202 we.forEach(function(i,item,we) {
203 arr[arr.length] = i.name
204 } )
205 console.log ("Получены имена предметов")
206 return arr
207 }
208
209 const limiter = new Bottleneck({minTime: 200, maxConcurrent: 1})
210
211 async function CreateStory (){
212 console.log ("Получаем историю предметов")
213 let NameCreat = await CheckName()
214 let arr = []
215 for (let i = 0; i < NameCreat.length; i++) {
216 try {
217 const GetNameStory = await limiter.schedule(CheckStory, NameCreat[i] )
218 arr.push ({
219 name: NameCreat[i],
220 story:GetNameStory
221 })
222 } catch (err) {
223 console.log (err)
224 i--
225 }
226 }
227 console.log ("История предметов получена")
228 return arr
229 }
230
231 async function CheckStory(name){
232 let NameUrl = new URL(`https://api.dmarket.com/marketplace-api/v1/last-sales?Title=${name}&GameID=a8db&Currency=USD`)
233 let response = await request (NameUrl.href)
234 // console.log (response)
235 let result = response.data.LastSales.map(val=> { return {date: parseInt(val.Date), price: parseInt(val.Price.Amount)}});
236 // console.log (result)
237 return result
238 }
239
240 async function request (options){
241 const publicKey = "a9c92b8d01ee99145d6da7f60766aff6867eb04097973f69307de33516c5778d";
242 const secretKey = "03685811cbacb4b557b57b49e0f02c08398eb340b3463ea47d33a021bedf5021a9c92b8d01ee99145d6da7f60766aff6867eb04097973f69307de33516c5778d";
243 const method = "GET"
244 const host = "api.dmarket.com"
245 const url = new URL(host + options)
246 const apiUrlPath = url.pathname + url.search
247 const timeStamp = Math.floor(new Date().getTime() / 1000)
248 const signature = sign(`${method}${host}${apiUrlPath}${timeStamp}`)
249 const headers = {
250 "X-Api-Key": publicKey,
251 "X-Request-Sign": "dmar ed25519 " + signature,
252 "X-Sign-Date": timeStamp,
253 'Content-Type': 'application/json',
254 }
255 let req = await axios({
256 "baseURL":options,
257 "headers":headers
258 })
259
260 function sign(string) {
261 const signatureBytes = nacl.sign(new TextEncoder('utf-8').encode(string), hexStringToByte(secretKey));
262 return byteToHexString(signatureBytes).substr(0,128);
263 }
264 function byteToHexString(uInt8arr) {
265 if (!uInt8arr) return '';
266 let hexStr = '';
267 for (let i = 0; i < uInt8arr.length; i++) {
268 let hex = (uInt8arr[i] & 0xff).toString(16)
269 hex = (hex.length === 1) & '0' + hex;
270 hexStr += hex;
271 }
272 return hexStr;
273 }
274
275 function hexStringToByte(str) {
276 if (typeof str !== 'string') {
277 throw new TypeError('Wrong data type passed to convertor. Hexadecimal string is expected');
278 }
279 const uInt8arr = new Uint8Array(str.length / 2);
280 for (let i = 0, j = 0; i < str.length; i += 2, j++) {
281 uInt8arr[j] = parseInt(str.substr(i, 2), 16);
282 }
283 return uInt8arr;
284 }
285 return req
286 }
287
288 let end = await CreateStory();
289 console.log (end)
290 return end
291}
292async function qwe(name) {
293 const limiter = new Bottleneck({minTime: 143, maxConcurrent: 1})
294 let res = await Storycheck(name)
295 async function Storycheck (NAME){
296 // console.log ("Получаем историю предметов")
297 let NameCreat = NAME
298 // console.log (NameCreat)
299 let arr
300 try {
301 const GetNameStory = await limiter.schedule(DataCheck, NameCreat )
302 arr = ({
303 name: NameCreat,
304 story:GetNameStory
305 })
306 } catch (err) {
307 console.log (err)
308 i--
309 }
310 // console.log ("История предметов получена")
311 return arr
312 }
313 async function DataCheck(name){
314 let NameUrl = new URL(`https://api.dmarket.com/marketplace-api/v1/last-sales?Title=${name}&GameID=a8db&Currency=USD`)
315 let response = await require (NameUrl.href)
316 // console.log (response)
317 let result = response.data.LastSales.map(val=> { return {date: parseInt(val.Date), price: parseInt(val.Price.Amount)}});
318 // console.log (result)
319 return result
320 }
321
322 async function require (options){
323 const publicKey = "a9c92b8d01ee99145d6da7f60766aff6867eb04097973f69307de33516c5778d";
324 const secretKey = "03685811cbacb4b557b57b49e0f02c08398eb340b3463ea47d33a021bedf5021a9c92b8d01ee99145d6da7f60766aff6867eb04097973f69307de33516c5778d";
325 const method = "GET"
326 const host = "api.dmarket.com"
327 const url = new URL(host + options)
328 const apiUrlPath = url.pathname + url.search
329 const timeStamp = Math.floor(new Date().getTime() / 1000)
330 const signature = sign(`${method}${host}${apiUrlPath}${timeStamp}`)
331 const headers = {
332 "X-Api-Key": publicKey,
333 "X-Request-Sign": "dmar ed25519 " + signature,
334 "X-Sign-Date": timeStamp,
335 'Content-Type': 'application/json',
336 }
337 let req = await axios({
338 "baseURL":options,
339 "headers":headers
340 })
341
342 function sign(string) {
343 const signatureBytes = nacl.sign(new TextEncoder('utf-8').encode(string), hexStringToByte(secretKey));
344 return byteToHexString(signatureBytes).substr(0,128);
345 }
346 function byteToHexString(uInt8arr) {
347 if (!uInt8arr) return '';
348 let hexStr = '';
349 for (let i = 0; i < uInt8arr.length; i++) {
350 let hex = (uInt8arr[i] & 0xff).toString(16)
351 hex = (hex.length === 1) & '0' + hex;
352 hexStr += hex;
353 }
354 return hexStr;
355 }
356
357 function hexStringToByte(str) {
358 if (typeof str !== 'string') {
359 throw new TypeError('Wrong data type passed to convertor. Hexadecimal string is expected');
360 }
361 const uInt8arr = new Uint8Array(str.length / 2);
362 for (let i = 0, j = 0; i < str.length; i += 2, j++) {
363 uInt8arr[j] = parseInt(str.substr(i, 2), 16);
364 }
365 return uInt8arr;
366 }
367 return req
368 }
369 return res
370}
371async function update(firstupd,itemsNow, itemsname) {
372 let arre = await qwe(itemsname)
373 let arredata = []
374 let arrprice = []
375 let OldData = itemsNow.DataInfo
376 let FinalArr
377 let Oldprice = itemsNow.PriceInfo
378 let Averprice = 0
379
380 if(OldData.length<20){
381 console.log("qweqwe")
382 // for (let i = 0; i < arre.story.length; i++) {
383 // let newprice = arre.story[i].price
384 // let newdat = arre.story[i].date
385 // if(newdat > OldData[0]){
386 // }
387 // }
388 // console.log(OldData)
389 // OldData.forEach(function (item,i) {
390 // arredata.push(item)
391
392 // })
393 // Oldprice.forEach(function (item,i) {
394 // arrprice.push(item)
395 // })
396 }/*else{*/
397 // if (timestamp - OldData[OldData.length-1]>604800) {
398 // for (let i = 0; i < arre.story.length; i++) {
399 // let newdat = arre.story[i].date
400 // let newprice = arre.story[i].price
401 // if(newdat > OldData[0]){
402 // arredata.push(newdat)
403 // arrprice.push(newprice)
404 // }
405 // }
406 // OldData.forEach(function(item,i) {
407 // if (timestamp - item < 604800) {
408 // arredata.push(item)
409 // }
410 // })
411 // Oldprice.forEach(function (item,i) {
412 // arrprice.push(item)
413 // })
414 // }else{
415 // for (let i = 0; i < arre.story.length; i++) {
416 // let newdat = arre.story[i].date
417 // let newprice = arre.story[i].price
418 // if(newdat > OldData[0]){
419 // arredata.push(newdat)
420 // arrprice.push(newprice)
421 // }
422 // }
423 // OldData.forEach(function (item,i) {
424 // arredata.push(item)
425 // })
426 // Oldprice.forEach(function (item,i) {
427 // arrprice.push(item)
428 // })
429 // }
430 // }
431 // let bufprice = 0
432 // for (let i = 0; i < arrprice.length; i++) {
433 // bufprice += arrprice[i]
434 // }
435 // Averprice = bufprice/arrprice.length
436 // let AVG = 0
437 // const spred = 0.13
438 // for (let i = 0; i < arrprice.length; i++) {
439 // let item =arrprice[i];
440 // if (item/Averprice>(1+spred) || Averprice/item>(1+spred)){
441 // item = (item>Averprice)?AVG=Averprice*(1+spred):AVG=Averprice*(i-spred)
442 // }
443 // AVG = Averprice
444 // }
445 // let buf = []
446 // for (let i = 0; i < arredata.length; i++) {
447 // if(arredata[i]!=arredata[arredata.length-1])buf.push(arredata[i]-arredata[i+1])
448 // }
449 // let avd = 0
450 // for (let i = 0; i < buf.length; i++) {
451 // avd+=buf[i]
452 // }
453 // // console.log(avd)
454 // FinalArr = {
455 // "Name": itemsname,
456 // "AveragePrice": Averprice,
457 // "Popularity": parseFloat((604800/(avd/buf.length)).toFixed(2)),
458 // "Lastreq": timestamp,
459 // "DataInfo": arredata,
460 // "PriceInfo": arrprice
461 // }
462 // console.log (FinalArr)
463}
464