Samarth Jajoo
hacker

@jajoosam (523)
16 y/o maker of things! sam.jajoo.fun
Pinned
Announcing contest SPACE ๐Ÿ†
It's time for another contest! We're not gonna make this one super huge, but promise that it is going to be real good fun to build entries for this one! So what do you have build? **Web Repls**! But, not just plain old web repls - this contest needs you to make webapps in a certain format! Let's start by taking a look at an example: [https://dadjokes--jajoosam.repl.co](https://dadjokes--jajoosam.repl.co/) ![](https://i.imgur.com/mqqkBvs.gif) Every time you hit space, the app loads a new dad joke, and a new image ๐Ÿ‘ด ๐Ÿ–ผ๏ธ That's why the contest is named `<SPACE>` - you gotta make a repl which when the user hits space! This could be updating an image, text (even both!) - or anything that feels like the main content of the repl. We also recommend that you update the app automatically every so often (you'll see why soon!) You can use any APIs you want, try [Web Scraping](https://repl.it/talk/learn/Get-started-with-Web-Scraping/8930), or just make a list of your own! ## Get started with examples You can check out the source for any of these and fork them to get started ๐Ÿ‘‡ - [Dad Jokes - Node.js + Express](https://repl.it/@jajoosam/dadjokes) - [One more Shibe - HTML](https://repl.it/@jajoosam/shibes) - [Inspiring Kotes - Python + Flask](https://repl.it/@jajoosam/Inspiring-Kotes) ## Okay, but what do we get? The winning entry gets a $50 Amazon giftcard + 3 free months of Hacker Plan ๐Ÿ’ฅ Along with that, we're also gonna put up a big screen at Repl.it HQ - and put up some of the coolest entries there! We recommend you to update the app every 5s so that our screen keeps showing new things โœจ As we're working on making repl.it - we'll also have fun when we see the creations y'all have made! Get going - you have a week from now - until *June 12th*! **Update - the deadline is now extended to June 20th, 00:00 PST** ๐Ÿ˜„
25
posted to Challenge by jajoosam (523) 12 days ago
โ–ฒ
14
Repl Stats ๐Ÿ“Š (beta!)
So many of us make websites on repl.it - and share them all over the internet. However, to know how many people visited your website and to learn about your traffic, you have to add heavy, sometimes privacy invasive scripts to your website ๐Ÿ˜ž ## Introducing Repl Stats ๐Ÿ“Š (beta!) Learn about how many hits your web app got - without needing to add any scripts. If it's on repl.it - It'll just work (works for repl.run too!) ๐Ÿ˜‰ To try it out just go to https://stats.repl.co/# {repl.hostname} You don't want to include the protocol (`https` or `http`) - so an example would look like this: https://stats.repl.co/#www.lyrics.rip It's not too much right now, just a graph of all hits like this one ๐Ÿ‘‡ ![Screen Shot 2019-06-05 at 5.19.48 PM](https://storage.googleapis.com/replit/images/1559780427595_b7aaa4351154336e2a15778dd44a94a0.pn) But, I wanted to share this to see if y'all would want this, and if you would, what more features would you like to see? โœจ *(note: right now, that stats update daily - not in realtime)*
10
posted to Announcements by jajoosam (523) 11 days ago
โ–ฒ
38
The Repl.it Chrome Extension ๐ŸŒ
Hey everyone, One of the coolest things about repl.it is how fast and simple it is to experiment with others' code. I've been working on a chrome extension which allows you to run code all over the web on repl.it, with just one click. The chrome extension adds prompts to NPM Packages and Github Gists - letting you try out examples as soon as you see them. ![Gist + NPM demo](https://storage.googleapis.com/replit/images/1554287819263_b57c54681794c790cff4bb6eea83602f.gi) But, that's not all! The chrome extension lets you run literally *everything* on repl.it! Just select some code, enter a language and boom ๐Ÿคฏ ![Right click run demo](https://storage.googleapis.com/replit/images/1554287926512_0df04df5f9eb5c6d4bf7db61e74131a8.gi) ๐Ÿš€๐Ÿš€๐Ÿš€ Get it now on the [Chrome Webstore](https://chrome.google.com/webstore/detail/replit/kihnihckibjknmebghcjpmemaginnipl) I'm looking forward to hearing ideas + feedback from y'all :)
19
posted to Announcements by jajoosam (523) 2 months ago
Nodejs
Nodejs
โ–ฒ
7
SPongebob AS a SERVICe
yOu'Ve aLWaYs needEd thIs hTtPS://SaAS.4TY2.fUn ![](https://saas.4ty2.fun/spongebob.gif) here aRe some eXtRa cHaRS BECaUsE THere IS A Min LiMIt OF 100
3
posted to Share by jajoosam (523) 27 days ago
Express
Express
โ–ฒ
85
Build a WhatsApp bot in 30 minutes ๐Ÿ•
A few months ago, I'd started making chatbots on [Telegram](https://t.me) - I'd seen APIs for WhatsApp but they were unoffical and there was a chance for getting your number blocked ๐Ÿ“ฑ โŒ A while ago, I saw that [Twilio](https://twilio.com) had an official WhatsApp API. 30 minutes later, I made a [Wikipedia bot on WhatsApp](https://wikibot.4ty2.fun) ๐Ÿ‘‡ ![](https://wikibot.surge.sh/Untitled-b9da3f92-94c0-4f97-8afb-787110d8a9d3.png) This is a tutorial to help you make a something like this, your own chatbots on WhatsApp - these bots are immediately available to 2 billion users, and there are so many things possible ๐ŸŽ“ I can't wait to see what you make! Now, let's get started ๐Ÿƒโ€โ™‚๏ธ ## ๐Ÿ”‘ Accounts and Keys First, Sign up for [Twilio](https://www.twilio.com/try-twilio) - it's free and you won't need a credit card ๐Ÿ’ณ ![](https://wikibot.surge.sh/screely-1535885763017-fc654067-9557-4bf7-98b5-4337911ff4ba.png) Once you're done verifying your phone number, select Procuts > Programmable SMS and then continue to name your project. ![](https://wikibot.surge.sh/screely-1535885937977-c5a924ec-8cc3-4430-9345-9b5e1dc74ef3.png) Feel free to skip steps for adding teammates - you won't need that for now. You must now take note of some authentication keys you'll need for building the WhatsApp bot ๐Ÿ‘‡ ![](https://wikibot.surge.sh/screely-1535886250966-f68b6cfb-c104-4adf-80e7-4e3f9bd15b5b.png) The final step - setup your WhatsApp Sandbox [here](https://www.twilio.com/console/sms/whatsapp/sandbox) - choose any number, and join your sandbox following instructions on the page. ![](https://wikibot.surge.sh/screely-1535886798623-1dac1ba9-c362-4e49-87ab-7bbb6138e8c7.png) Aaaaaand you're done with credential setup! Don't worry, that was the toughest part of this tutorial ๐Ÿ˜› ## ๐Ÿš€ Getting Started So that we don't spend too much time on setup, I've created an environment (with repl.it!) you can use within your browser. Head over [here](https://repl.it/@jajoosam/wikibot-start), and wait for a couple of seconds to fork it. Next, open up `server.js` and put in your Account SID and Auth Token, on lines `7` and `8` ```javascript const accountSid ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //Account SID const authToken ="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // Auth Token ``` You can see, this environment already has dependencies installed, and an `express` server set up. We still need to give Twilio a URL to send incoming messages to, though ๐Ÿ”— Let's go back to the [WhatsApp Sandbox](https://www.twilio.com/console/sms/whatsapp/sandbox), and put in a webhook URL for incoming messages. ![](https://wikibot.surge.sh/Untitled-3ed5263b-c6d8-492b-ba08-b4644ab502cf.png) This URL must be what you see on the preview panel of your [repl.it](http://repl.it) project + `/incoming` ![](https://wikibot.surge.sh/Untitled-1779b21f-9100-4942-b732-320dc48c5f76.png) We can now finally read messages that are sent to the bot. Add a simple `console.log()` in your webhook handler ๐Ÿ‘‡ ```javascript app.post('/incoming', (req, res) => { console.log(req.body) }); ``` When you send a message to your bot, you should be able to see something like this in your repl console ๐Ÿ‘จโ€๐Ÿ’ป ![](https://wikibot.surge.sh/Untitled-163eb09e-e6ab-4910-badb-d8aa0aa789f7.png) Building an echo bot would look something like this, using `twiml` to write a message ๐Ÿ‘‡ ```javascript app.post('/incoming', (req, res) => { const twiml = new MessagingResponse(); twiml.message(req.body.Body); res.writeHead(200, {'Content-Type': 'text/xml'}); res.end(twiml.toString()); }); ``` But, since we're actually trying to build a useful bot - let's use informative APIs! ## ๐ŸŒ Fetching Information DuckDuckGo has an amazing, free instant answer API. It takes in a query and returns back a summary from WikiPedia and more. A few examples ๐Ÿ‘‰ [WikiPedia](https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q=WikiPedia), [Macbook Air](https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q=MacBook%20Air), [Twilio](https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q=Twilio) I spent some time creating a decent parser which usually returns information from this API. Try pasting this code in your [repl.it](http://repl.it) project, and your [console](https://dsh.re/f7477c) should have stuff about Trump in it ๐Ÿ˜› ```javascript var base = 'https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q='; var query = 'Donald Trump'; request(base + query, function (error, response, body) { body = JSON.parse(body) if(body["Abstract"] == ""){ body["Abstract"]= body["RelatedTopics"][0]["Text"] } var msg = body["Heading"]+"\n\n"+body["Abstract"]; console.log(msg) }); ``` Pretty straight forward, right? ๐Ÿ˜„ ## ๐Ÿ› ๏ธ Putting it all together To make our actual bot, all we need to do is get the query from our request - which we can get as `req.body.Body` - and use `twmil` to send across the data we collected in `msg` ```javascript app.post('/incoming', (req, res) => { const twiml = new MessagingResponse(); var base = 'https://api.duckduckgo.com/?skip_disambig=1&format=json&pretty=1&q='; var query = req.body.Body; request(base + query, function (error, response, body) { body = JSON.parse(body) if(body["Abstract"] == ""){ body["Abstract"]= body["RelatedTopics"][0]["Text"] } var msg = twiml.message(body["Heading"]+"\n\n"+body["Abstract"]); res.writeHead(200, {'Content-Type': 'text/xml'}); res.end(twiml.toString()); }); }); ``` You now have a fully functionaing WhatsApp bot! Send anything you want to know about your bot ๐Ÿค– and you should see it respond super fast ๐Ÿ’ฌ โšก Adding welcome messages and a little formatting is quite simple, look at the final [repl](https://repl.it/@jajoosam/wikibot) to see how I did it ๐Ÿ‘จโ€๐Ÿ’ป ## ๐Ÿ”— Sharing the bot For others to use this bot, they'll need to join your sandbox first - and send a message just like you did earlier ๐Ÿ‘‰ `join <two-words>` You can create links with this text too - For example this link lets you join my bot ๐Ÿ‘‡ ``` https://wa.me/14155238886?text=join ultramarine-tapir ``` `14155238886` is my bot's number, while `ultramarine-tapir` is the sandbox phrase. ## โšก What's next? Now that you know how to build a bot on WhatsApp, try sending notifications to yourself, and building more useful tools! Twilio has loads of [other mediums](https://www.twilio.com/channels) to message through too! All code for my WikiBot is on [Github](https://github.com/jajoosam/wikibot)! I'm a 15 year old maker ๐Ÿ‘จโ€๐Ÿ’ป For more cool things to make and to stay update with my progress, sign up for [my newsletter ๐Ÿ“ง](https://buttondown.email/jajoosam)
14
posted to Learn by jajoosam (523) 8 months ago
โ–ฒ
24
Make your first Pygame ๐ŸŽฎ
## Make games the easy way, and forget about the setup ๐Ÿ˜Œ ![](https://tiresome-aunt.surge.sh/ezgif-9aa456d6-a2de-4d54-a2b3-6828c507544d.com-video-to-gif_(1).gif) [Demo + Code](https://repl.it/@jajoosam/paddleBasket) โฏ๏ธ ๐Ÿ‘จโ€๐Ÿ’ป I've heard coding in python is quite delightful! And I agreed once I made my first python app that didn't just run on the terminal - a game made with [Pygame](https://www.pygame.org/). You'd usually have to spend a while getting set up, installing Pygame, dependencies and then have to spend time compiling an executable before sharing your game. But with [replit's new GFX system](https://repl.it/talk/announcements/Replit-GFX-Public-Beta-Build-Games-and-GUI-Apps/11545) - there's absolutely no need for that โœŒ๏ธ This is a tutorial to get started with Pygame, and make a simple game within 30 minutes! ## ๐Ÿ› ๏ธ Getting our environment running Head over to [repl.it](http://repl.it) and once you're logged in, hit `new repl โ†’ Pygame` to create the repl where we're going to be making our game. ![](https://tiresome-aunt.surge.sh/-7158aee6-09d3-41ef-a559-42f5cb010b22untitled) That's it ๐Ÿ˜‰ ## ๐ŸŽฒ Understanding the game Before we start coding, let's understand what we're making ๐Ÿ› ๏ธ Our game concept is pretty straightforward - there's a paddle - a simple rectangle that moves left or right in the screen, attempting to catch balls falling from the top of the screen. A higher score is more number of balls caught โšพ ## ๐Ÿ‘จโ€๐Ÿ’ป Initializing pygame You can go right ahead and paste this code in your repl! ```python # adding libraries we're going to use import pygame from random import randint pygame.init() # initializing variables to account for the number of balls caught, and total dropped score = 0 total = 0 myfont = pygame.font.SysFont('monospace', 50) # creating a font to write the score in # Making dictionaries with settings for everything. display = { "width": 800, "height": 600 } paddle = { "width": 200, "height": 20, "x": 300, "y": 580, "velocity": 10 } ball = { "radius": 15, "y": 30, "x": randint(0, display["width"]), "velocity": 20 } # creating a window, and launching our game win = pygame.display.set_mode((display["width"], display["height"])) # 800 width, 600 height ``` I've added comments to explain what each line does ๐Ÿ˜„ Make sure to paste in the dictionaries too, they'll be super useful soon! ## ๐Ÿ‘พ The paddle Our paddle is going to be just a little rectangle that moves when we hit the arrow keys. Before we can start making it, we need to create the main loop. Pygame will run the code inside this loop continuously, to update the screen based on inputs. Paste all this in! ```python while True: pygame.time.delay(100) win.fill((255, 255, 255)) for event in pygame.event.get(): if event.type == pygame.QUIT: break keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: paddle["x"] -= paddle["velocity"] if keys[pygame.K_RIGHT]: paddle["x"] += paddle["velocity"] pygame.draw.rect(win, (255, 0, 0), (paddle["x"], paddle["y"], paddle["width"], paddle["height"])) pygame.display.update() ``` โ€‹ ```python pygame.quit() ``` Don't worry, I'm not just going to leave you like that xD Let's break this up into smaller blocks to explain what everything does! Let's talk about everything inside the while loop, which will run forever - since `True` will always remain `True` ๐Ÿ˜ฎ ```python pygame.time.delay(100) win.fill((255, 255, 255)) ``` We're adding the delay so that the loop doesn't run too often, and there's some gap between each cycle - keeping our repl from crashing. `100` is delay in milliseconds, causing the loop to run 10 times a second. `win.fill()` takes a color in `RGB` as it's argument - and `255, 255, 255` represents white, filling our window with white before we draw anything onto it ๐Ÿ–Œ๏ธ ```python for event in pygame.event.get(): if event.type == pygame.QUIT: break ``` This piece of code goes over all events that pygame gives us, and breaks the loop if Pygame has been quit. When the loop breaks, we go to the line which says `pygame.quit()`- you know what that does ๐Ÿ˜› ```python keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: paddle["x"] -= paddle["velocity"] if keys[pygame.K_RIGHT]: paddle["x"] += paddle["velocity"] ``` To get this - lets first clear out our understanding about the coordinate grid - it doesn't start at the center in pygame! In fact, the top left corner is `0, 0` and `x` increases as you go right, while `y` increases as you move down. This block of code gets all currently pressed keys, and checks whether the left or right keys are pressed. If they are, it changes the `x` coordinates of the paddle - reducing if โฌ…๏ธ is pressed, and increasing if โžก๏ธ is pressed by the velocity we set in the `paddle` dictionary. Try changing the `velocity` to see what happens ๐Ÿค” ```python pygame.draw.rect(win, (255, 0, 0), (paddle["x"], paddle["y"], paddle["width"], paddle["height"])) pygame.display.update() ``` This is where we actually draw our paddle to the screen - in the window called `win`, red in color (`255, 0, 0` RGB) - at `paddle[x]` on the x axis, and `paddle[y]` on the y axis. We've also set the width and height in the `paddle` dictionary, feel free to mess around with it! Finally, `pygame.display.update()` updates the entire screen with what we've drawn in this cycle of the loop! Try running the code, and hitting the left and right arrow keys! You should see a little rectangle moving around ๐Ÿ‘‡ ![](https://tiresome-aunt.surge.sh/CleanShot_2019-03-13_at_19-ac9eb692-26e2-421e-b279-84978459c836.38.32.gif) ## โšฝ Generating falling circles Let's bring up the `ball` dictionary up again ๐Ÿ‘‡ ```python ball = { "radius": 15, "y": 30, "x": randint(0, display["width"]), "velocity": 20 } ``` What does the `"x"` line do? We're selecting a random x co-ordinate between `0` and `display["width"]` (currently 800) - using the `randint` function we imported right at the start of our code. Add this inside your while loop, right before you draw the paddle to the screen: ```python ball["y"] += ball["velocity"] pygame.draw.circle(win, (0, 0, 255), (ball["x"], ball["y"]), ball["radius"]) ``` We're increasing the y co-ordinate of the ball by its `velocity` and drawing the ball again in every cycle of the loop. ## ๐Ÿ† When do you actually score a point, though? The final part of our game would be checking if the ball hits the paddle when it's at the bottom of the screen. Collision detection is going to be essential to most of the games you're going to make in the future, so let's go over it here! ```python if ball["y"] + ball["radius"] >= paddle["y"]: if ball["x"] > paddle["x"] and ball["x"] < paddle["x"] + paddle["width"]: score += 1 total += 1 ball["y"] = 0 ball["x"] = randint(0, display["width"]) ``` First up, we're learning if the ball has hit the level of the paddle - by checking if the ball's radius + it's position on the y axis is equal to the position of the paddle. ```python if ball["x"] > paddle["x"] and ball["x"] < paddle["x"] + paddle["width"] ``` With this long condition, we're testing if - The ball's position on the X axis is greater than the paddle's position on the X axis AND - The ball's position on the X axis is lesser than the sum of the paddle's position on the X axis and its width If this condition is true, it means that the ball has landed on the paddle, and we increase the score ๐Ÿ™Œ Maybe this image helps a bit ๐Ÿคž ![](https://tiresome-aunt.surge.sh/-98fcc7ff-0ac4-4a09-8d46-2e06394d73b8untitled) After this, regardless of whether a point has beens scored or not, we add one to the total number of balls landed - and reset the ball's position, setting the ball's y co-ordinate to 0, and generate a random position for the X axis. Lastly, we're going to write the score on the screen ๐Ÿ… ```python textsurface = myfont.render("score: {0}/{1}".format(score, total), False, (0, 0, 0)) win.blit(textsurface, (10, 10)) ``` We create a new [surface](https://www.pygame.org/docs/ref/surface.html) where we write the text using python's [format](https://www.programiz.com/python-programming/methods/string/format) function, replacing `{0}` with the socre, and `{1}` with the total. We're writing this in black (`0, 0, 0` RGB). `win.blit(textsurface, (10, 10))` merges the text with the main window, at co-ordinates `10, 10`. And that's the game - the full thing ๐Ÿคฏ ## ๐Ÿ”ฎ Things to try - Changing the contents of the dictionary and seeing what happens โ“ - Make multiple balls fall at the same time ๐Ÿ”ด ๐Ÿ”ต โšซ - Make the paddle move up and down too ๐Ÿš€ - Adding poison balls - the game stops when your paddle hits one ๐Ÿ˜ต Be sure to put down any questions or improvements down in the comments ๐Ÿ’ฌ And here's all the code for you to go over again - I highly recommend going through this to help you understand the flow of the program, and the sequencing of everything if you were even a little confused by this guide ๐Ÿ˜… https://repl.it/@jajoosam/paddleBasket
3
posted to Learn by jajoosam (523) 3 months ago
HTML, CSS, JS
HTML, CSS, JS
โ–ฒ
33
๐Ÿ•ต๏ธโ€โ™‚๏ธ A scavenger hunt with image classification ๐Ÿ–ผ๏ธ
hey hey hey hey hey I'm back with something I think y'all will find interesting! I built a game based on image classification - you have to get objects from around your house - whatever the app tells you to get, you fetch! ## [Play here](https://hunt.4ty2.fun?ref=repltalk) ๐ŸŽฎ Check out [this demo video](https://youtu.be/kdGipA-VDj4) I made ๐ŸŽฅ - I go over using the app, and the tools I used to make it! ![demo gif](https://storage.googleapis.com/replit/images/1548248878277_61c6e20eadf9da4da8e8967685a61f08.gi) ### How does this work? 4ty2 hunt has two main dependencies - [ml5](https://ml5js.org) and [p5](https://p5js.org) - p5 lets you do cool things with graphics (like getting the video stream from the webcam, super easily) - but ml5 is the real core of this app! ml5.js lets us run machine learning models, and train them as well, right in our browser. But the reason it exists is to make ML projects, like this mindblowingly simple ๐Ÿคฏ The whole of my game comes down to me writing about `150` lines of JS - that's it. ml5 allows me to pass the webcam's video stream as a parameter, and keeps telling me what it sees. I'm using the mobile-net model for this, which uses the [image-net](http://image-net.org/index) dataset - around 15 million labelled images. Besed on that huge chunk of data, this model predicts what it sees! ### Challenging you Image Net has 1000 different labels through which objects are classified - some of them include things like `Komodo Dragon`s, `Great White Shark`s, and `Ostrich`es - you know, things that can't be found in *most* homes ๐Ÿ˜› So, I manually went through loads of the labels, trying to label things most of us could find. ![me going whaaaaaat?](https://storage.googleapis.com/replit/images/1548250013223_d4e633164513cafa87953e8e9e755ae1.pn) Clearly, I was a little sleep deprived - and I probably made some mistakes. Let me know if you find some weird labels - I'm @jajoosam on the Discord ๐Ÿ’ฌ ### Easy machine learning with JS Machine Learning is pretty complex, but that doesn't mean making projects with it has to be too! I have gained a lot of appreciation for [ml5.js](https://ml5js.org) - it's an amazing way to integrate ML into your projects. I learnt all the tech behind making this project from [Dan Shiffman's videos on ml5 ](https://www.youtube.com/watch?v=jmznx0Q1fP0)- and I highly recommend you check them out if you found this interesting! He's a great, super energetic teacher ๐Ÿ‘จโ€๐Ÿซ ![SelfassuredScrawnyKusimanse-small](https://storage.googleapis.com/replit/images/1548250591304_1f59b29dfc20b7f8c93d6323da1a4c72.gi) Before building this project, I followed the [first video](https://www.youtube.com/watch?v=yNkAuWz5lnY) of the series to build [this](https://ml5-mobilenet.jajoosam.repl.co) Super excited to hear what y'all think about this!
8
posted to Share by jajoosam (523) 5 months ago
Nodejs
Nodejs
โ–ฒ
47
Starbot
Starbot adds support for appreciation in a discord community! You can give people who helped you stars, and the bot will note it - also creating a leaderboard, and some sort of karma points in the community. When you give a star - it reduces the number you have by one. But everyone starts off with `20` ๐Ÿ˜„ Here's a demo ๐Ÿ‘‡ ![](https://i.imgur.com/suV9ooj.gif) Send a message tagging user(s) like this: `Thanks @amasad and @hayaodeh for creating repl.it โญ` And send only a โญ to see the count ๐Ÿ† Try it out now in the [#bot-usage channel](https://discordapp.com/channels/437048931827056642/439586718681792552) ๐Ÿ’ฌ There's a full API to access the star count available - send `โญ API` - and to see help in the Discord, send `โญ Help` Starbot can also work in other Discord communities - add it to your own for $5: https://bmc.xyz/l/starbot
10
posted to Share by jajoosam (523) 7 months ago
โ–ฒ
33
Build your very own URL shortener ๐Ÿ”—๐Ÿš€
## Build a tiny URL shortener, using a remote database ![](https://boring-lamport-1b901a.netlify.com/2018-12-2214-5f2c1bbe-59a2-4ba7-9544-438b1ab5e1dd.39.01.gif) [Demo](https://l.4ty2.fun) โฏ๏ธ [Code](https://repl.it/@jajoosam/tyni) ๐Ÿ‘จโ€๐Ÿ’ป Setting up a URL shortener is a lot of work - either you have to pay, or spend hours setting up your own server. This is a guide to making your own URL shortener with [repl.it](http://repl.it) - using `express`, and a remote database - all on `node.js` ## ๐Ÿ› ๏ธ Getting our environment running First up, fork the [https://repl.it/@jajoosam/tyni-starter](https://repl.it/@jajoosam/tyni-starter) repl, so that you have a running project. Next, create a new file - `.env` ![](https://boring-lamport-1b901a.netlify.com/Untitled-675a864b-7c8c-487d-8ca7-595eb8af67ba.png) A `.env` file can store secrets for you, that no one else will be able to see. This is where we want to store our token for accessing the remote database. ## ๐Ÿ“ Making our database We're going to be using [jsonstore.io](http://jsonstore.io) for storing all our URLs. Head over to [jsonstore.io/get-token](https://www.jsonstore.io/get-token) - and copy the token you see - this is the secret we want to store in our `.env` file. Open up your `.env` file, and set `KEY` to your token, like this ๐Ÿ‘‡ ```bash KEY=yourTokenGoesHere ``` Remember to keep **no whitespace**, or your token might not be recognized right! When you open `index.js` you'll see that I've already initialized the database, and a small web server for you. Now let's get to making our API so we can shorten them URLs ๐Ÿš€ ## ๐Ÿ‘จโ€๐Ÿ’ป The API There are two parts to our URL shortener: 1. Storing the short link, corresponding to the long URL - in our database. 2. Redirecting visitors from the short link to the long link Both of these are super simple to implement, thanks to the `express` server we're using - we'll just be collecting `get` requests for both of the tasks. For adding links to our database, we have a special endpoint - requests to it have two parts: the long URL, and the short path. ```javascript app.get('/shorten', (req, res) => { db.write(req.query.key, {"url": req.query.url}); res.status(200); }); ``` Adding this to our code lets us correspond the short path (`key`) to the long `url`, and then we finally send a successful response. For the second task, we'll just be collecting the short path (`key`) from a request, finding the corresponding URL in our database, and then redirecting our visitor โฌ‡๏ธ ```javascript app.get('/:key', (req, res) => { db.read(req.params.key + "/url").then( (url) => { res.redirect(url); }); }); ``` That's prety much it - we have a fully functional URL shortener ๐Ÿคฏ - check it out for yourself, open a new URL which looks like this ๐Ÿ”— ``` https://tyni.jajoosam.repl.co/shorten?key=yay&url=https://dsh.re/50854 ``` Now, going to [`http://tyni.jajoosam.repl.co/yay`](http://tyni.jajoosam.repl.co/yay) will be nice to see ๐Ÿ‘‡ ![](https://boring-lamport-1b901a.netlify.com/1-8380b52f-92c2-4acc-87dc-64011c6fd502.jpg) Of course, you'll be replacing `tyni.jajoosam` in those URLs with your own repl! ## โœจ The Frontend Our URL shortener does work, but it's tedious, having to type out a huge URL before shortening it - we can make the whole process much simpler with a simple frontend. I've already created this - and gone for a neat and minimal look using [wing.css](https://github.com/kbrsh/wing) ![](https://boring-lamport-1b901a.netlify.com/Untitled-0fa3af54-ddae-46ca-abdf-4fcbcb218f8b.png) You just have to add code to send visitors to the hompage in the `static` folder ๐Ÿ  ```javascript app.get('/', (req, res) => { res.sendFile("static/index.html", {root: __dirname});; }); ``` If you browse through the `static` folder, you'll find a simple `HTML` file with a form, `CSS` to style our page, and most importantly, `JS` to send requests to our URL shortening API. The `HTML` is quite straightforward, we're asking for the long URL, and *optionally* a short path. Open up `script.js` and you'll see the `shorten()` function. Here's what the JS file does (*I've also annotated the code with comments*) ๐Ÿ‘‡ ๐Ÿ” Getting the path(`key`) and the long `url` from the form. ๐Ÿ“ Possibly generating a random 5 character hash as our path (in case there's no path entered) ๐Ÿ”— Sending a get request to our API, with our `key` and `url` as parameters ๐Ÿ–ฅ๏ธ Displaying the shortened URL on our page ## ๐ŸŒ Getting our custom domain Sure, our links are shorter - but we still don't have them on our own domain, and the `repl.co` links can be pretty long ๐Ÿ‘€ Luckily for us, the folks at [repl.it](http://repl.it) recently allowed custom domains to be used! That means this project could be something you actually use all the time ๐Ÿ˜„ Check out `dotcomboom`'s guide on [using custom domains](https://repl.it/talk/learn/How-to-use-a-custom-domain/8834), it should only take a few minutes. It also teaches you about getting free domains ๐Ÿ’ธ Be sure to put down any questions or improvements down in the comments ๐Ÿ’ฌ - and here's all the code for you to go over again ๐Ÿค– https://repl.it/@jajoosam/tyni
11
posted to Learn by jajoosam (523) 6 months ago
HTML, CSS, JS
HTML, CSS, JS
โ–ฒ
24
A smart background removal tool ๐ŸŽจ
[colorSpace](https://color.4ty2.fun/?ref=repltalk) is a smart background removal tool based completely on the front end, so your pictures never leave your computer. ![demo](https://storage.googleapis.com/replit/images/1547265356292_3848cfe46c9f10fb81ef0a1e7e97417d.gi) It gets colors in an image through the HTML canvas, converts them to the [L*a*b](https://en.wikipedia.org/wiki/CIELAB_color_space) colorspace (makes difference measures intuitive to human vision) - and measures the euclidian difference between colors, and purges them from an image based on the threshold. More in [this tweet](https://twitter.com/jajoosam/status/1083764001375346688)!
10
posted to Share by jajoosam (523) 5 months ago
โ–ฒ
15
Running cron jobs with repl.it ๐Ÿค– ๐Ÿ•’
Have any of you ever tried to run cron jobs, or scheduled tasks with replit? Since repls sleep, you can't use inbuilt timer functions - meaning you'd have to use something like [Uptime Robot](https://uptimerobot.com) to ping your site every `x` minutes. But - Uptime Robot always repeatedly pings your website, even if you only want to schedule a one time task, and you have to manually add a url to ping on their website. Introducing [**kron**](https://kron.4ty2.fun) โœจโœจโœจ kron lets you schedule tasks using a simple get request. It's as simple as this ๐Ÿ‘‡ ``` https://kron.4ty2.fun/?time=3600&url=https://google.com ``` Send a request there, and 1 hour (`3600` seconds) after this request is sent, `https://google.com` will recieve a `get` request from `https://kron.4ty2.fun`. Check out more details on the github [repo](https://github.com/jajoosam/kron) - and let me know if you have any questions. Also - would y'all like to see a tutorial on this, along with a full example app?
4
posted to Announcements by jajoosam (523) 3 months ago
HTML, CSS, JS
HTML, CSS, JS
โ–ฒ
16
Santafy your images ๐ŸŽ…
![ezgif.com-video-to-gif](https://storage.googleapis.com/replit/images/1545801167135_cb49d8067df821702ed38ed513ac1811.gi) Santafy automatically adds santa hats to people in your pictures! All processing is done front end - your images remain on your computer at all times ๐Ÿ˜„ I hope it is still Xmas somewhere ๐ŸŽ„ https://santa.4ty2.fun
15
posted to Share by jajoosam (523) 6 months ago
โ–ฒ
16
Build an ML app, with just a little JavaScript ๐Ÿค–
## Making a feature extractor with ml5.js and p5.js ![](https://ecstatic-rosalind-da34e4.netlify.com/main.gif) [Demo](https://feature-extractor--jajoosam.repl.co) โฏ๏ธ [Code](https://repl.it/@jajoosam/feature-extractor) ๐Ÿ‘จโ€๐Ÿ’ป [Video Walkthrough](https://ecstatic-rosalind-da34e4.netlify.com/feature-extractor-demo-compressed-3e7aac1a-1c37-4448-92ab-140b5dd84056.mp4) ๐ŸŽฆ Machine Learning is a super cool way to build AI apps - but I won't lie, it is a lot of math. Luckily, thanks to [ml5.js](https://ml5js.org) - we don't need to spend months understanding ML, we can apply it and develop some cool uses in our app within just a few hours ๐Ÿ˜„ This is a guide to build a feature extractor - something that can get a video stream from your webcam and predict what it sees, once it is trained with a little bit of data - just like in the video above! ## ๐Ÿด Forking the frontend I don't want to waste too much of your time with the frontend I used for this app - I think it'd be much better if I skipped right to the JavaScript, and logic. You should fork this repl - [https://repl.it/@jajoosam/feature-extractor-start](https://repl.it/@jajoosam/feature-extractor-start) - so that you have the HTML already there! It's essentially just a few `div`s for holding the video and some other text, along with some buttons to control our app! I've commented everything (except the CSS ๐Ÿ˜›) - so you should be able to go through the frontend and understand the basic layout of the app in a few minutes. Once you're done, head over to `script.js` ![](https://ecstatic-rosalind-da34e4.netlify.com/Untitled-8e918105-6ae0-4591-8362-7ed6e7068460.png) ## โœ๏ธ Declaring the variables We're going to have quite a few variables to declare, so the first thing we're going to do is create them. Our app is going to have a lot of functions, and it's important that all of them can access the variables - which is why we shall declare right at the start of our code ```javascript var featureExtractor, classifier, video, loss, redCount, blueCount; redCount = blueCount = 0; ``` I'll give you an overview of what these are for, but you'll understand them much better as we continue building our app. `featureExtractor` and `classifier` are variables we're going to store and initialize machine learning models in. `video` is where we're storing the webcam stream, while `loss` lets us know the progress of how far our on feature extractor has been trained. Finally, `blueCount` and `redCount` are counters for how many images there are in each category - and we initalize both of them with a value of `0`, in the next line. ## ๐Ÿ› ๏ธ The `setup()` `setup()` is a function which shall fire up as soon as our code is ready to run. Bacause of using [p5.js](https://p5js.org), our code is pretty readable and easy to understand here. ```javascript function setup() { // Tells p5 to not automatically create a canvas element. noCanvas(); // Starts capturing a video feed from the webcam video = createCapture(VIDEO); // Puts the video stream into the div in our html, with ID `video` video.parent('video'); // Initializes a feature extractor, yet to be trained - from ml5.js featureExtractor = ml5.featureExtractor('MobileNet'); classifier = featureExtractor.classification(video); // What we're doing next - setting up buttons! setupButtons(); } ``` This code goes in your `script.js` file right after you declare variables - essentially, it gets a video stream and displays it on our page, inside a `div` with the ID `video`. We also make some functions using the ml5.js library here, and pass the captured video as a parameter - you'll see what we do with these soon, but there's still a little more setup left! As you can see, at the end of `setup()`, we call `setupButtons()` - the function we're going to make next. Here, we're adding event listeners to buttons in our HTML - so we can run functions when they're clicked. Here's all the code we write for the `setupButtons()` function ๐Ÿ‘‡ ```javascript // A function to create the buttons function setupButtons() { buttonA = select('#red'); buttonB = select('#blue'); โ€‹ โ€‹ buttonA.mousePressed(function() { โ€‹ redCount++; โ€‹ classifier.addImage('red'); โ€‹ select('#redCount').html(redCount); โ€‹ }); โ€‹ โ€‹ buttonB.mousePressed(function() { โ€‹ blueCount++; โ€‹ classifier.addImage('blue'); โ€‹ select('#blueCount').html(blueCount); โ€‹ }); โ€‹ train = select('#train'); train.mousePressed(function() { classifier.train(function(lossValue) { // This is where we're actually training our model if (lossValue) { loss = lossValue; select('#info').html('Loss: ' + loss); } else { select('#info').html('Done Training! Final Loss: ' + loss); select('#train').style("display", "none"); select('#predict').style("display", "inline"); } }); }); // Predict Button buttonPredict = select('#predict'); buttonPredict.mousePressed(classify); } ``` That's the largest art of our app, and I'm going to break it up into several parts to make it easier to explain! ## ๐Ÿง™โ€โ™‚๏ธbUt wHaT Do tHeSe bUtToNs dO?!?!?! DON'T PANIC. Let's start off with this block: ```javascript buttonA = select('#red'); buttonB = select('#blue'); buttonA.mousePressed(function() { redCount++; classifier.addImage('red'); select('#redCount').html(redCount); }); buttonB.mousePressed(function() { blueCount++; classifier.addImage('blue'); select('#blueCount').html(blueCount); }); ``` `buttonA` and `buttonB` are nothing but the two different buttons we have in our app! ![](https://ecstatic-rosalind-da34e4.netlify.com/Untitled-c85ebc09-ab40-4060-a9ce-98966a9fe021.png) With `.mousePressed()` we're defining what happens when any of these buttons are pressed - which is: - Increase the count by 1, using the `++` operator - Capture the current frame from the webcam videom and add it to the classifier, with `classifier.addImage()` - Update the count on our app by changing the button's text, with `.html()` Next up, we have this whole block - where we train the classifer itself: ```javascript train = select('#train'); train.mousePressed(function() { classifier.train(function(lossValue) { // This is where we're actually training our model if (lossValue) { loss = lossValue; select('#info').html('Loss: ' + loss); } else { select('#info').html('Done Training! Final Loss: ' + loss); select('#train').style("display", "none"); select('#predict').style("display", "inline"); } }); }); ``` When the `Train ๐Ÿš‹` button on our app is pressed, we call `classifier.train()` - and with each iteration, the function we supply there is called - which is why we see the *[Loss](https://ml-cheatsheet.readthedocs.io/en/latest/loss_functions.html)* value keep changing. ![](https://ecstatic-rosalind-da34e4.netlify.com/CleanShot-2019-01-26-at-18-6a9809c8-75a3-4b88-b1ee-3931aa15d08c.04.57.gif) When the *Loss* value is `0`, then we hid the `Train ๐Ÿš‹` button, and show the previously hidden `Predict ๐Ÿ”ฎ` button! The last 2 lines of the `setupButtons()` function are about the predict button: ```javascript buttonPredict = select('#predict'); buttonPredict.mousePressed(classify); ``` It seems like we're calling this `classify` function - which is what we're going to build next! Keep going, we're almost done ๐Ÿ’ฏ ## ๐Ÿ”ฎ Predictions, and showing results Our `classifier()` function is pretty straightforward - this is all we do: ```javascript function classify() { classifier.classify(gotResults); } ``` We're just telling the ml5 `classifier` to classify the current frame in either of the categories (๐Ÿ”ด or ๐Ÿ”ต), and send the results to the `gotResults` function - which brings us to the final part of our app! As long as the classifier doesn't send us an error, we change the entire page's background color to either `red` or `blue` - and then call `classify()` again, which keeps our code running forever, and the predictions keep coming! ```javascript function gotResults(err, result) { if (err) { console.log(err); } select("body").style("background", result); classify(); } ``` That's all the code we have to write to build the example feature extractor. I highly recommend going through the final code so that you can see how everything fits together well - I know there are quite a few functions too keep track of, but I've commented everything to make it easier ๐Ÿ˜… https://repl.it/@jajoosam/feature-extractor Now go ahead, try it out! Here are some things I did to see if the feature extractor would work (it did!) ๐Ÿ‘‡ - Keep my head in the left in ๐Ÿ”ด, and right in ๐Ÿ”ต - Make a โœŒ๏ธ in ๐Ÿ”ด, and a โœ‹ in ๐Ÿ”ต - Wear different colored ๐Ÿ‘•s in ๐Ÿ”ด and ๐Ÿ”ต Let me know other cool things it worked with ๐Ÿ‘€ ## โœจ okay, but what do I **MAKE** with this? There are SOOOOO MANY THINGS you could do! A feature extractor gives you the ability to add this whole other, mysterious way of controlling, and getting input in your app! Here are a few ideas ๐Ÿ’ก - A gesture controlled game, right in the browser ๐ŸŽฎ - A mood tracker - leave the tab open all day, and train it with different face expressions ๐Ÿค” - Build your own **[hotdog or not](https://www.youtube.com/watch?v=pqTntG1RXSY)** app ๐ŸŒญ - Build an app which only lets you message others with gestures ๐Ÿ’ฌ ## ๐Ÿ‘จโ€๐Ÿซ what else is there? ml5.js can do crazy things! You can integrate image classification into your own app [like I did](https://repl.it/talk/challenge/male-A-scavenger-hunt-with-image-classification/10185), find similar words which fit into a text, get a precise skeleton of human bodies and even transfer the styles in images - look at what my picture looks like, when composed with the style of a cool painting ๐Ÿ–Œ๏ธ ![mepaint](https://ecstatic-rosalind-da34e4.netlify.com/mepaint.png) You should take a look at the many [examples on the ml5.js website](https://ml5js.org/docs/quick-start) - or take a look at [Dan Shiffman's videos on ml5.js](https://www.youtube.com/playlist?list=PLRqwX-V7Uu6YPSwT06y_AEYTqIwbeam3y), he covers loads of things you can do with it - and explains everything with a ton of energy. I highly recommend watching his videos on the [Coding Train](https://www.youtube.com/user/shiffman) YouTube! If you have any questions or need any help with your ml5 submission, feel free to ping me @jajoosam on the Discord, or leave something in the comments :)
1
posted to Learn by jajoosam (523) 5 months ago
โ–ฒ
17
Chat on the terminal
# Chat on the terminal ## Build a realtime chat in your terminal ๐Ÿ’ฌ ![](https://i.imgur.com/OqMNLC2.gif) [Demo](https://chat.jajoosam.repl.run) โฏ๏ธ [Code](https://repl.it/@jajoosam/chat) ๐Ÿ‘จโ€๐Ÿ’ป This is a quick tutorial which helps you build a realtime chat on your terminal - using [socket.io](https://socket.io) - we can build and test super quick thanks to [repl.it](https://repl.it)'s [repl.run](http://repl.run) platform - which displays a terminal on the web ๐ŸŒ ๐Ÿ‘จโ€๐Ÿ’ป ## โš™๏ธ Dependencies We're only using one external dependency in this project - [socket.io](http://socket.io), which helps us communicate realtime between several clients and a server. Along with this, we'll be using node's built in `readline` which lets us collect input from the terminal. ## ๐Ÿ’ Setting up the server Because we're using [socket.io](http://socket.io) - we need to spin up a small server to relay messages too! Just fork this, and you'll be all set ๐Ÿ‘‰ [repl.it/@jajoosam/chat-server](https://repl.it/@jajoosam/chat-server) ```javascript io.on('connection', function (socket) { socket.on('message', function(data) { io.emit("msg", data); }); }); ``` This small block of code listens for any `message`s from any user, and then broadcasts that message to all the users - that simple โœจ ## ๐Ÿ’ฌ Let's get chatting Let's start off by forking [this repl](https://repl.it/@jajoosam/chat-starter) - I've already declared dependencies to make things simple. On `line 3`, replace the `url` with that of the server you just created. Whenever a user connects, let's ask them for their name. Put this code inside the `socket.connect` block. ```javascript rl.question(`What's your name? `, (answer) => { socket.emit("message", `๐Ÿ‘ค : ${answer} has joined the chat`); id = answer; chat(); }); ``` We're sending a message which says a new user has joined the chat, and storing their name for later reference. As you can see - we're also calling the `chat` function, which is currently empty - let's change that! ```javascript rl.question("ยป ", (answer) => { // "ยป " Gives a prompt for the user socket.emit("message", `${id}: ${answer}`); chat(); }); ``` We're prompting for a user to type out a message, then sending it back to the server - also at the end - we're calling `chat` again in case they want to send more messages โŒจ๏ธ ## ๐Ÿ–จ๏ธ Printing out messages If you try running this code now, you'll see that no message you type is printed in the terminal. Let's create a new event listener inside `socket.connect` to listen for messages ๐Ÿ‘‡ ```javascript socket.on('msg', function(data){ console.log("\n" + data); chat(); }); ``` Whenever the server broadcasts a new message to us, we print it out to the `console` - and call `chat` again - so that our user can keep sending messages! ## ๐Ÿ› ๏ธ Hacking this It was pretty simple to build this chat - but it doesn't seem like a conventional one in many ways. Luckily, you can change that ๐Ÿ˜„ **Here are some ideas to tinker with this project ๐Ÿ‘‡** - Let everyone know when a user is typing โŒจ๏ธ - Don't print out messages sent by the same user repeatedly ๐Ÿ”„ - Add color + formatting to the chat with [chalk](https://github.com/chalk/chalk) ๐ŸŒˆ - Take realtime to the next level by broadcasting every character as it's typed ๐Ÿ’ก Check out [this](https://github.com/aviaryan/chattt) open source project for more ideas! Here's the code for the completed project (with a few tweaks!) - feel free to refer to it ๐Ÿ‘จโ€๐Ÿ’ป [https://repl.it/@jajoosam/chat](https://repl.it/@jajoosam/chat) Now, go ahead and share what you've built on [repl talk](https://repl.it/talk/share), and tag me - [@jajoosam](https://repl.it/@jajoosam) ๐Ÿ‘ค
3
posted to Learn by jajoosam (523) 7 months ago
Nodejs
Nodejs
โ–ฒ
10
Make an instrumental version of your Spotify playlist!
[wordLess](https://wordless.4ty2.fun?ref=repltalk) finds instrumentals for songs from your spotify playlist, and loads them up into a shareable page. More in [this](https://twitter.com/jajoosam/status/1086299965247242240) tweet! Check it out ๐Ÿ‘‰ [https://wordless.4ty2.fun](https://wordless.4ty2.fun?ref=repltalk) [Demo ๐ŸŽฅ](https://dsc.cloud/Jajoosam/wl-demo.mp4)
2
posted to Share by jajoosam (523) 5 months ago
Nodejs
Nodejs
โ–ฒ
13
A blog on the terminal
I tried to build the most hacker like blog possible - let me know what you think! Check it out at [repl.run](https://blog.jajoosam.repl.run/) Guide to building your own is dropping soon :)
6
posted to Share by jajoosam (523) 7 months ago
Nodejs
Nodejs
โ–ฒ
7
An e-book downloader, with repl.run ๐Ÿ“–
Check out the repl.run page [here](https://libert-cli.jajoosam.repl.run/)! Scraping content from libgen, and matching to information from google books for accuracy! So cool that I can share apps that run on the terminal! BTW, this is how [libert.ml](https://libert-cli.jajoosam.repl.run/) started!
0
posted to Share by jajoosam (523) 8 months ago
โ–ฒ
6
Get started with Web Scraping ๐Ÿค–
## Learn to scrape the web by creating your own quotes website ๐Ÿค– ๐Ÿค” ![](https://dsc.cloud/Jajoosam/Ece4h5VzbOGNas2PsmkDr2hD23DCJwOm6b7zUeNt3S7jit1pK8MXoHGenIrPDpVNFUtbaMBivWbLFJuHq5WgnNRM9xZS4djo8TnD.gif) [Demo](https://quote-scraper.jajoosam.repl.co) โฏ๏ธ [Code](https://repl.it/@jajoosam/quote-scraper) ๐Ÿ‘จโ€๐Ÿ’ป There's so much information on the web, but so few APIs ๐Ÿ˜• Web Scraping lets you get content from any webpage, extracting information from `HTML` selectors. This is a super simple guide to help you scrape the web with `Node.js` , in less than 20 minutes ๐Ÿ•’ We'll learn to use developer tools to see `HTML` selectors, extract the content in `Node.js` with `x-ray` - and use `pug` to render quotes we get! ## ๐Ÿ› ๏ธ Setup Um, there's none really. Just load up this repl - [repl.it/@jajoosam/quote-scraper-starter](https://repl.it/@jajoosam/quote-scraper-starter) โœจ ![](https://dsc.cloud/Jajoosam/oeCd23rkkJ1pvV0hrCioQJlzUw3dCHBTodyhvq0g8AjxC9GAUmEbVUBKRs194SHrOyccgcDxcwPgj3cSDp2J3ddfk6aNoAETKNBb.png) We'll talk about all the tools and dependencies we use as we continue! ## ๐Ÿ“Š Understanding Structure [Quotesondesign.com](http://quotesondesign.com) has some nice quotes - and is an easy introduction to scraping stuff on the web. Another great part - it loads up a random quote each time! Open the website up, right click on the quote, and then hit `Inspect` ๐Ÿ‘‡ ![](https://dsc.cloud/Jajoosam/gnFthrFnWt45BA1AtRUTTzOEr1PdUwIM4RODxVWydpLZAeVDXkgkw6JCtbTF0EYXUpA6ypZ0eZPNkqt18WN7A2TbiFojxRYd9GnY.gif) You can now see a view of the entire document ๐Ÿ“œ Go ahead and click all the small triangles to expand this view. You'll be able to see that the quote itself is inside a paragraph, in a `div` with id `quote-content`, while the author's name has an id of `quote-title`. ![](https://dsc.cloud/Jajoosam/NRMd90XWrYqR38kgs1EgPmlTlJ77jwxduW5bkBce6BRHkd8qjumaKzRQnNwRL5BVLC3IDnGydTAAx3yH5r2y2faJIyP2p9wB1y7L.png) ## โฌ‡๏ธ Getting the quotes To scrape information from a web page, you generally request its `HTML`, and then extract the content you want with selctors, like `id`s, `classes`, and `HTML tags`. When we inspected [Quotesondesign.com](http://quotesondesign.com), we saw that the quote itself was in a `div`, with `id=quote-content`, nested inside a `<p>` (Paragraph element) - while the author's name was inside an element with `id=quote-title`. Having this information makes scraping super easy ๐Ÿ™Œ - we'll use a library called [x-ray](https://github.com/matthewmueller/x-ray) - which makes our job very straightforward! It's already installed in the repl you're using. Try adding this code to your `index.js` file ๐Ÿ‘‡ ```javascript x('https://quotesondesign.com', { quote: "#quote-content p", author: "#quote-title" } )(function(err, result){ console.log(result) }); ``` Run your code, and the console on the bottom right will look something like this ๐Ÿ‘€ ![](https://dsc.cloud/Jajoosam/lIGAkvplrgDFKSO4zs9JQMJDi2k62rMb2avtZ0vKWR0o1CyBDOxKnln0HGNG9pLenZmjjYiI6gWYuBvGVraFG8BjSHlwxIJFHJ8H.png) `x-ray` gives you a nice `json` object, which you can now render! You've now successfully scraped the web ๐ŸŽ‰ ## ๐Ÿ“œ Render those quotes If you see the file tree in the sidebar, you'll see `quotes.pug` - a template which can render quotes passed to it. We're using the [pug](https://pugjs.org/api/getting-started.html) templating engine to do this - which we've initialized on line `6` One thing to note is that `pug` is whitespace sensitive: `HTML` tags are nested inside each other with tabs โŒจ๏ธ ![](https://dsc.cloud/Jajoosam/9jGShYBQ9zFliv41bjmwWfHHZJCeU0jxph9ISkihBWby28iyasRysT7IrEHgYAlgJyW1qQvgH0kR6liVNVDua2zjYHGtnxL9I80X.png) All we have to do now is pass the quote we get from `x-ray` to `pug`! This is very easy to do on our `express` server, just change your `app.get` block to this ๐Ÿ‘จโ€๐Ÿ’ป ``` app.get('/', (req, res) => { x('https://quotesondesign.com', { quote: "#quote-content p", author: "#quote-title" } )(function(err, result){ res.render('quote', result) console.log(result) }); }); ``` Run your repl, and this is what you'll see ๐Ÿ˜ฎ ![](https://dsc.cloud/Jajoosam/6O4MLq9QgQ4gbz69cYamgIEpqUwnoDEsU88pLw0MIZKZLSo6Mceup0RYh6VApkzXJeZpqIRb6ktnx3YLPMjqWOHSdr97FH4KZ4QS.png) Pretty neat, huh? We've not written any css of our own, the page looks readable just because of the simple [sakura.css](https://oxal.org/projects/sakura/) library. Remove line `4` in `quote.pug` and get ready for ugly ๐Ÿคฎ ## โšก Putting your skill to use There is a lot you can do with web scraping - and this guide has given you all the basic knowledge you need. I'm excited to see what you do with this ๐Ÿ˜„ **Here are a few cool things to try ๐Ÿ‘‡** - Scrape different data points - weather, latest news, bitcoin price ๐Ÿ˜› - and make a dashboard for yourself - Scrape [IMDb](https://imdb.com) to get a list of all movies currently in theatres ๐ŸŽฆ - Scrape [Repl Talk](https://repl.it/talk) and make an API for it ๐Ÿ‘จโ€๐Ÿ’ป Whatever you build, be sure to share it in the comments ๐Ÿ’ฌ [Here](https://blog.jajoosam.repl.run)'s what the final code looks like, feel free to refer to it ๐Ÿ‘‡ [https://repl.it/@jajoosam/quote-scraper](https://repl.it/@jajoosam/quote-scraper)
0
posted to Learn by jajoosam (523) 7 months ago
HTML, CSS, JS
HTML, CSS, JS
โ–ฒ
2
Search for rhymes, but with your voice ๐Ÿ—ฃ๏ธ
I tried exploring the annyang library to experiment with speech recognition in a very simple web app! Let me know if you think this is cool - I'd love to create a tutorial :) You gotta open the repl on an external page, with https ๐Ÿ‘‰ https://rhyme.4ty2.fun
0
posted to Share by jajoosam (523) 8 months ago
HTML, CSS, JS
HTML, CSS, JS
โ–ฒ
1
Bruteforce method to approximate Pi!
I created an interactive demo of a simple monte carlo integration in order to derive ฯ€ - let me know what you think ๐Ÿ˜„ https://pi.4ty2.fun ![mc demo](https://storage.googleapis.com/replit/images/1540660616027_a55a418f1d82f2f062b1224d1337d4cf.gi)
0
posted to Share by jajoosam (523) 8 months ago