Facebook
From Voluminous Terrapin, 6 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 240
  1. var express = require('express');
  2. var router = express.Router();
  3. var firebase = require('firebase');
  4. var request = require('request');
  5. const cheerio = require('cheerio');
  6. const axios = require('axios');
  7. const schedule = require('node-schedule');
  8. const serverUrlBase = "https://safe-beach-33580.herokuapp.com";
  9.  
  10. const clothesRef = firebase.database().ref('ubrania');
  11. const newDropRef = firebase.database().ref('isNewDrop');
  12. const supremeHtmlRef = firebase.database().ref('supremeHtml');
  13. var clothesObj = [];
  14. var isNewDrop = false;
  15. newDropRef.set(isNewDrop);
  16.  
  17. //przypisuje zmiennej firstItemAtSupremeShop wartość z firebase po starcie serwera.
  18. supremeHtmlRef.on("value", function(snapshot) {
  19.     console.log('html ze sklepu pobrany z firebase: ', snapshot.val());
  20.     firstItemAtSupremeShop = snapshot.val();
  21. }, function (errorObject) {
  22.     console.log("The read failed: " + errorObject.code);
  23. });
  24. router.get('/checkfordrop', function (req, res, next) {
  25.     checkForNewDrop();
  26. });
  27. router.get('/isnewdrop', function (req, res, next) {
  28.     newDropRef.set(isNewDrop);
  29.     res.send(isNewDrop);
  30.     console.log("isNewDrop=" + isNewDrop);
  31. });
  32. router.get('/setisnewdroptofalse', function (req, res, next) {
  33.     isNewDrop = false;
  34.     newDropRef.set(isNewDrop);
  35. });
  36. router.get('/clothes', function (req, res, next) {
  37.     clothesRef.once('value', function (snapshot) {
  38.         res.json(snapshot.val());
  39.     });
  40. });
  41. router.get('/clothes/update', function (req, res, next) {
  42.     request('https://www.supremecommunity.com/season/spring-summer2018/droplists/', function (error, response, html) {
  43.         if (!error && response.statusCode == 200) {
  44.             const $ = cheerio.load(html);
  45.             const url_after_slash = $('.feature.feature-7.boxed.text-center.imagebg.boxedred').parent().attr('href');
  46.             var url = 'https://www.supremecommunity.com' + url_after_slash;
  47.             console.log(url);
  48.             request(url, function (error, response, html) {
  49.                 var newData = [];
  50.                 const $ = cheerio.load(html);
  51.  
  52.                 $('.card-details').each(function (i) {
  53.                     const card = $(this);
  54.                     const name = card.find('.name.item-details').text();
  55.                     const url = 'https://www.supremecommunity.com' + card.find('img').attr('src');
  56.                     const price = card.find('span.label-price').text();
  57.                     var category = card.parent().parent().attr('data-masonry-filter');
  58.                     category = repairCategoryName(category);
  59.                     var sizeArray = chooseSizeArrayByCategory(category);
  60.                     sizeArray = getSpecialSizeArray(name, sizeArray);
  61.                     const colorArray = getSpecialColorArray(name);
  62.                     const nameRegex = getNameRegex(name);
  63.                     const colorRegexArray = getColorRegexArray(name);
  64.  
  65.                     newData.push({
  66.                         name: name,
  67.                         url: url,
  68.                         price: price,
  69.                         category: category,
  70.                         sizeArray: sizeArray,
  71.                         colorArray: colorArray,
  72.                         nameRegex: nameRegex,
  73.                         colorRegexArray: colorRegexArray
  74.                     });
  75.  
  76.                 });
  77.  
  78.                 //dodaje testowe itemy
  79.                 for (var key in itemsForTest) {
  80.                     if (itemsForTest.hasOwnProperty(key)) {
  81.                         const name = key;
  82.                         console.log("testItem name: ", name);
  83.                         const url = "http://icons.iconarchive.com/icons/pelfusion/flat-file-type/512/jpg-icon.png";
  84.                         const price = "bezcenne";
  85.                         var category = itemsForTest[key].category;
  86.                         category = repairCategoryName(category);
  87.                         var sizeArray = chooseSizeArrayByCategory(category);
  88.                         sizeArray = getSpecialSizeArray(name, sizeArray);
  89.                         const colorArray = getSpecialColorArray(name);
  90.                         const nameRegex = getNameRegex(name);
  91.                         const colorRegexArray = getColorRegexArray(name);
  92.  
  93.                         newData.push({
  94.                             name: name,
  95.                             url: url,
  96.                             price: price,
  97.                             category: category,
  98.                             sizeArray: sizeArray,
  99.                             colorArray: colorArray,
  100.                             nameRegex: nameRegex,
  101.                             colorRegexArray: colorRegexArray
  102.                         });
  103.                     }
  104.                 }
  105.                 console.log(newData);
  106.                 clothesObj = newData;
  107.                 clothesRef.set(newData);
  108.  
  109.                 res.sendStatus(200);
  110.             });
  111.         }
  112.     });
  113. });
  114. function chooseSizeArrayByCategory(category) {
  115.     var sizeArrays = {
  116.         jackets: ['Small', 'Medium', 'Large', 'XLarge'],
  117.         shirts: ['Small', 'Medium', 'Large', 'XLarge'],
  118.         tops_sweaters: ['Small', 'Medium', 'Large', 'XLarge'],
  119.         't-shirts': ['Small', 'Medium', 'Large', 'XLarge'],
  120.         sweatshirts: ['Small', 'Medium', 'Large', 'XLarge'],
  121.         pants: ['30', '32', '34', '36'],
  122.         shoes: ['38', '39', '40', '41', '42', '43', '44', '45', '46' ],
  123.         hats: ['7 1/8', '7 1/4', '7 3/8', '7 1/2', '7 5/8', '7 3/4'],
  124.         accessories: ['Small', 'Medium', 'Large', 'XLarge'],
  125.         bags: null,
  126.         skate: null,
  127.         shorts: ['Small', 'Medium', 'Large', 'XLarge'],
  128.     };
  129.     return sizeArrays[category];
  130. }
  131. var itemsForTest = {
  132.     "Supreme®/Hanes® Tagle Tees (3 Pack)": {category: "accessories"},
  133.     "Supreme®/Hanes® Cr Socks (4 Pack)": {category: "accessories"},
  134.     "Studded Logo Belt": {category: "accessories"}
  135. };
  136. var specialSizeAndColor = {
  137.     'Supreme®/LACOSTE Velour Bucket' : {colorArray: ['Black'], colorRegexArray: ['.*B.*l.*a.*c.*k.*'], nameRegex: '.*S.*u.*p.*r.*e.*m.*e.*L.*A.*C.*O.*S.*T.*E.*V.*e.*l.*o.*u.*r.*B.*u.*c.*k.*e.*t.*'},
  138.     'Supreme®/LACOSTE Crewneck Sweatshirt' : {colorArray: ['Black'], colorRegexArray: ['.*B.*l.*a.*c.*k.*'], nameRegex: '.*S.*u.*p.*r.*e.*m.*e.*L.*A.*C.*O.*S.*T.*E.*C.*r.*e.*w.*n.*e.*c.*k.*S.*w.*e.*a.*t.*s.*h.*i.*r.*t.*'},
  139.     'Supreme®/LACOSTE Hooded Sweatshirt' : {colorArray: ['Black'], colorRegexArray: ['.*B.*l.*a.*c.*k.*'], nameRegex: '.*S.*u.*p.*r.*e.*m.*e.*L.*A.*C.*O.*S.*T.*E.*H.*o.*o.*d.*e.*d.*S.*w.*e.*a.*t.*s.*h.*i.*r.*t.*'},
  140.     'Sideline Hooded Sweatshirt' : {colorArray: ['Black'], colorRegexArray: ['.*B.*l.*a.*c.*k.*'], nameRegex: '.*S.*i.*d.*e.*l.*i.*n.*e.*H.*o.*o.*d.*e.*d.*S.*w.*e.*a.*t.*s.*h.*i.*r.*t.*'},
  141.     /*
  142.     'Supreme®/Wilson® Tennis Balls': {colorArray: null, colorRegexArray: null, nameRegex: '.*S.*u.*p.*r.*e.*m.*e.*W.*i.*l.*s.*o.*n.* T.*e.*n.*n.*i.*s.* B.*a.*l.*l.*s.*', sizeArray: null },
  143.     'Supreme®/UNDERCOVER/Public Enemy White House Tee' : {colorArray: ['Black'], colorRegexArray: ['.*B.*l.*a.*c.*k.*'], nameRegex: '.*S.*u.*p.*r.*e.*m.*e.*U.*N.*D.*E.*R.*C.*O.*V.*E.*R.*P.*u.*b.*l.*i.*c.*E.*n.*e.*m.*y.*W.*h.*i.*t.*e.*H.*o.*u.*s.*e.*T.*e.*e.*'},
  144.     'Supreme®/SIGG™ Traveller 0.6L Water Bottle': {colorArray: null, colorRegexArray: null, nameRegex: '.*S.*u.*p.*r.*e.*m.*e.*S.*I.*G.*G.*T.*r.*a.*v.*e.*l.*l.*e.*r.*0.*..*6.*L.*W.*a.*t.*e.*r.*B.*o.*t.*t.*l.*e.*', sizeArray: null },
  145.     'FTW Tee': {colorArray: ['Black'], colorRegexArray: ['.*B.*l.*a.*c.*k.*'], nameRegex: '.*F.*T.*W.*T.*e.*e.*' },
  146.     'Logo Zippo®': {colorArray: ['Red'], colorRegexArray: ['Red'], nameRegex: '.*Zippo.*', sizeArray: null },
  147.     'Studded Logo Belt': {colorArray: ['Red'], colorRegexArray: ['.*R.*e.*d.*'], nameRegex: '.*S.*t.*u.*d.*d.*e.*d.*L.*o.*g.*o.*B.*e.*l.*t.*', sizeArray: null },
  148.     'Illegal Business Hooded Sweatshirt': {colorArray: ['Brown', 'Black', 'Pale Pink', 'White', 'Blue', 'Red', 'Pale Yellow'], colorRegexArray: ['.*Brown', 'Black', '.*Pink', 'White', '(.*Blue)|Royal', 'Red', '.*(Yellow|Lime)'], nameRegex: 'Illegal Business Hooded Sweatshirt' },
  149.  
  150.     'Supreme®/Stone Island® Hooded Sweatshirt': {colorArray: ['Black', 'Orange', 'Red', 'Khaki', 'White', 'Orange', 'Grey'], colorRegexArray: ['Black', '.*Orange.*', 'Red', 'Khaki|Olive', '.*(White|Grey)'], nameRegex: 'Supreme..Stone Island. Hooded Sweatshirt' },
  151.     'Supreme®/Stone Island® Poly Cover Composite Anorak': {colorArray: ['Black', 'Navy', 'Yellow'], colorRegexArray: ['(Black|((Dark)? Grey))', '(Navy|((Dark)? Blue)', '.*(Yellow|Lime|Marigold)'], nameRegex: 'Supreme..Stone Island. (Poly)? (Cover)? Composite Anorak'},
  152.     'Supreme®/Stone Island® S/S Top': {colorArray: ['Black', 'Khaki', 'Red', 'Orange', 'White'], colorRegexArray: ['Black', 'Khaki|Olive', 'Red', 'Orange', 'White'], nameRegex: 'Supreme..Stone Island. S.S Top'},
  153.     'Supreme®/Stone Island® Sweatpant': {colorArray: ['Black', 'Orange', 'Red', 'Khaki', 'White'], colorRegexArray: ['Black', 'Khaki|Olive', 'Red', 'Orange', 'White'], nameRegex: 'Supreme..Stone Island. Sweatpant.*' },
  154.     'Supreme®/Stone Island® Lamy Cover Stampato Puffy Jacket': {colorArray: ['Black', 'White'], colorRegexArray: ['Black', '(White|Ecru)'], nameRegex: 'Supreme..Stone Island. Lamy Cover Stampato Puffy Jacket'},
  155.     'Lock Box': {colorArray: null, sizeArray: null, nameRegex: '.* Lock Box'},
  156.     'Supreme®/Stone Island® Lamy 6-Panel': {colorArray: ['Black', 'White'], sizeArray: null, colorRegexArray: ['Black', '(White|Ecru)'], nameRegex: 'Supreme..Stone Island. Lamy 6.Panel' },
  157.     'Heather Loose Gauge Beanie': {colorArray: ['Burgundy', 'Black', 'Brown', 'Navy', 'Green', 'Purple', 'Salmon'], sizeArray: null, colorRegexArray: [".*(Burgundy|Red)", 'Black', '.*(Brown|Mustard)', 'Navy', 'Green|Teal', 'Purple|Plum', '.*(Pink|Salmon|Peach|Orange)']},
  158.     'Arc Logo L/S Thermal': {colorArray: ['Black', 'White', 'Red', 'Purple', 'Navy', 'Yellow', 'Grey', 'Camo'], colorRegexArray: ['Black', 'White', 'Red', '.*(Purple|Plum)', 'Navy', '.*Yellow', '.*Grey', '.*Camo'] },
  159.     'Side Zip Camp Cap': {colorArray: ['Navy', 'Lime', 'Red', 'Blue', 'Camo', 'Black', 'Pink'], colorRegexArray: ['Navy', '.*(White|Lime)', 'Red', '.*Blue', '.*Camo', 'Black', '.*Pink'] },
  160.     'Shop Jacket': {colorArray: ['Red', 'Black', 'Khaki', 'White', 'Red', 'Navy'] },
  161.     'Split Pique Crewneck': {colorArray: ['Black', 'Khaki', 'Pink'], colorRegexArray: ['Black', '.*(Khaki|Olive)', '.*Pink'] },
  162.     'Daggers L/S Top': {colorArray: ['White', 'Pink', 'Khaki'], colorRegexArray: ['White', '.*(Pink|Salmon)', 'Khaki'] },
  163.     'Daggers Pant': {colorArray: ['White', 'Pink', 'Khaki'],  colorRegexArray: ['White', '.*(Pink|Salmon)', 'Khaki'] },
  164.     'God Bless Plaid Flannel Shirt': {colorArray: ['Yellow', 'Pink', 'Black', 'Blue'], colorRegexArray: ['Yellow', '.*(Pink|Salmon)', 'Black', 'Blue'] },
  165.     'Repeat Beanie': {colorArray: ['Black', 'Red', 'White'] },
  166.     'God Bless Plaid Flannel Shirt': {colorArray: ['Yellow', 'Pink', 'Black', 'Blue'] },
  167.     'Corduroy Work Pant': {colorArray: ['Black', 'White', 'Brown', 'Navy', 'Salmon', 'Red'] },
  168.     'Leaf Beanie': {colorArray: ['Pink', 'Black', 'White', 'Blue', 'Red'] },
  169.  
  170.     "Reflective Excellence Hooded Sweatshirt": {colorArray: ['Green', 'Navy', 'Red', 'White', 'Pink', 'Blue', 'Black'], colorRegexArray: ['.*Green', 'Navy', 'Red', 'White', '.*Pink', "Blue|Royal", 'Black']} */
  171.     "Supreme®/Hanes® Cr Socks (4 Pack)": {nameRegex: 'Supreme®.Hanes® Cr.. Socks .4 Pack.'}
  172. };
  173. function getSpecialSizeArray(name, sizeArray) {
  174.     //console.log(specialSizeAndColor[name]);
  175.     if (specialSizeAndColor[name] !== undefined && specialSizeAndColor[name].sizeArray !== undefined) {
  176.         return specialSizeAndColor[name].sizeArray;
  177.     }
  178.     return sizeArray;
  179. }
  180. function getSpecialColorArray(name) {
  181.     if (specialSizeAndColor[name] !== undefined && specialSizeAndColor[name].colorArray !== undefined) {
  182.         return specialSizeAndColor[name].colorArray;
  183.     }
  184.     return null;
  185. }
  186. function getNameRegex(name) {
  187.     if (specialSizeAndColor[name] !== undefined && specialSizeAndColor[name].nameRegex !== undefined) {
  188.         return specialSizeAndColor[name].nameRegex;
  189.     }
  190.     return null;
  191. }
  192. function getColorRegexArray(name) {
  193.     if (specialSizeAndColor[name] !== undefined && specialSizeAndColor[name].colorRegexArray !== undefined) {
  194.         return specialSizeAndColor[name].colorRegexArray;
  195.     }
  196.     return null;
  197. }
  198. function repairCategoryName(categoryName) {
  199.  
  200.     if (categoryName === 'tops-sweaters') {
  201.         categoryName = 'tops_sweaters';
  202.     }
  203.     return categoryName;
  204. }
  205. /*
  206. Sprawdza zaraz przed dropem czy pojawiły się już nowe itemy na stronie supreme. Porównuje pierwszy item z itemem, który jest w bazie danych jako "pierwszy z brzegu"
  207.  */
  208. const checkForUpdatesBeforeDrop = schedule.scheduleJob('0 58 10 * * 4', function(){
  209.     checkForNewDrop();
  210.  
  211. });
  212. /*
  213. Co minute sprawdza czy na supreme comunnity są jakieś nowe itemy.
  214.  */
  215. const checkForUpdatesEveryMinute = schedule.scheduleJob('*/1 * * * *', async function(){
  216.     console.log('every minute update');
  217.     axios.get(serverUrlBase + '/clothes/update')
  218.         .then(function (response) {
  219.             console.log("every minute update response (probably OK)");
  220.         })
  221.         .catch(function (error) {
  222.             console.log("ERRROR");
  223.             console.log(error);
  224.         });
  225.  
  226. });
  227.  
  228.  
  229. function makeRegex(name){
  230.     name = name.replace(/\s/g, '');
  231.     name = name.replace(/[\W_]+/g, '');
  232.     name = name.split('').join('.*');
  233.     name = ".*" + name;
  234.     name = name + ".*";
  235.     return name;
  236. }
  237.  
  238.  
  239. async function checkForNewDrop () {
  240.     var newItemCheckCounter = 0;
  241.     var isUpdated = false;
  242.  
  243.     while(!isUpdated) {
  244.         console.log("while loop, counter: " + newItemCheckCounter);
  245.         console.log("clothes, counter: " + clothesObj.length);
  246.  
  247.         isUpdated = await getNewDropItem(newItemCheckCounter);
  248.         newItemCheckCounter++;
  249.         newItemCheckCounter=newItemCheckCounter%clothesObj.length;
  250.     }
  251.  
  252.     isNewDrop = true;
  253.     newDropRef.set(isNewDrop);
  254. }
  255.  
  256. function getNewDropItem(i) {
  257.     console.log("function getNewDropItem()");
  258.  
  259.     var itemToSearch = {
  260.         name: clothesObj[i].name,
  261.         category: clothesObj[i].category,
  262.         nameRegexString: makeRegex(clothesObj[i].name),
  263.         nameRegexObj: new RegExp(this.nameRegexString)
  264.     };
  265.  
  266.     console.log("function getNewDropItem()");
  267.     console.log("Name of item we're looking for: "+itemToSearch.name);
  268.     console.log("nameRegexString: "+itemToSearch.nameRegexString);
  269.  
  270.     return new Promise(function(resolve, reject) {
  271.         console.log("promise");
  272.         const url = 'http://www.supremenewyork.com/shop/all/'+itemToSearch.category;
  273.         console.log("Name of category page: "+ url);
  274.         request(url, {timeout: 2000}, function (error, response, html) {
  275.             console.log("request");
  276.             console.log(error);
  277.             if (error){
  278.                 console.log('is timeout error: ', error.code === 'ETIMEDOUT');
  279.                 console.log('is timeout connection error: ', error.connect === 'true');
  280.             }
  281.             if (!error && response.statusCode == 200) {
  282.                 console.log("OK");
  283.                 const $ = cheerio.load(html);
  284.                 var isItemFound = itemToSearch.nameRegexObj.test($);
  285.                 console.log("isItemFound: "+isItemFound);
  286.                 resolve(isItemFound);
  287.             }
  288.             resolve(false);
  289.         });
  290.     });
  291. }
  292.  
  293. module.exports = router;
  294.