├── server ├── .gitignore ├── scripts │ ├── features │ │ ├── codeforces │ │ │ ├── skeleton.cpp │ │ │ ├── contests │ │ │ │ └── Codeforces_Round_1368 │ │ │ │ │ ├── taskB │ │ │ │ │ ├── in0.txt │ │ │ │ │ ├── in1.txt │ │ │ │ │ ├── out1.txt │ │ │ │ │ ├── out0.txt │ │ │ │ │ └── sol.cpp │ │ │ │ │ ├── taskC │ │ │ │ │ ├── in0.txt │ │ │ │ │ ├── out0.txt │ │ │ │ │ └── sol.cpp │ │ │ │ │ ├── taskD │ │ │ │ │ ├── out1.txt │ │ │ │ │ ├── in0.txt │ │ │ │ │ ├── out0.txt │ │ │ │ │ ├── in1.txt │ │ │ │ │ ├── out2.txt │ │ │ │ │ ├── in2.txt │ │ │ │ │ └── sol.cpp │ │ │ │ │ ├── taskF │ │ │ │ │ ├── in0.txt │ │ │ │ │ ├── in1.txt │ │ │ │ │ ├── out0.txt │ │ │ │ │ ├── out1.txt │ │ │ │ │ └── sol.cpp │ │ │ │ │ ├── taskG │ │ │ │ │ ├── out0.txt │ │ │ │ │ ├── out1.txt │ │ │ │ │ ├── out2.txt │ │ │ │ │ ├── in1.txt │ │ │ │ │ ├── in0.txt │ │ │ │ │ ├── in2.txt │ │ │ │ │ └── sol.cpp │ │ │ │ │ ├── taskH1 │ │ │ │ │ ├── out0.txt │ │ │ │ │ ├── in0.txt │ │ │ │ │ └── sol.cpp │ │ │ │ │ ├── taskA │ │ │ │ │ ├── out0.txt │ │ │ │ │ ├── in0.txt │ │ │ │ │ └── sol.cpp │ │ │ │ │ ├── taskH2 │ │ │ │ │ ├── out0.txt │ │ │ │ │ ├── in0.txt │ │ │ │ │ └── sol.cpp │ │ │ │ │ └── taskE │ │ │ │ │ ├── out0.txt │ │ │ │ │ ├── in0.txt │ │ │ │ │ └── sol.cpp │ │ │ ├── test.json │ │ │ ├── README.MD │ │ │ └── index.js │ │ └── index.js │ ├── detectCommand.js │ └── createChatObject.js ├── data │ └── conversation.txt ├── router │ └── index.js ├── Makefile ├── package.json └── index.js ├── extension ├── media │ └── images │ │ ├── bot-icon1.png │ │ ├── bot-image.png │ │ ├── chat-bot1.png │ │ └── chat-bot2.png ├── scripts │ ├── front │ │ ├── handleFeatures.js │ │ ├── features │ │ │ ├── codeforces.js │ │ │ └── contestSchedular.js │ │ ├── chatSystem.js │ │ ├── draggable.js │ │ ├── content.js │ │ └── std.js │ └── background │ │ ├── std.js │ │ ├── background.js │ │ └── features │ │ └── contestSchedular.js ├── manifest.json └── css │ └── botBox.css ├── docs ├── features │ ├── README.MD │ ├── contest schedular │ │ └── README.md │ └── codeforces │ │ └── README.MD └── README.md └── README.md /server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /server/scripts/features/codeforces/skeleton.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskB/in0.txt: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskB/in1.txt: -------------------------------------------------------------------------------- 1 | 3 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskC/in0.txt: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskD/out1.txt: -------------------------------------------------------------------------------- 1 | 51 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskF/in0.txt: -------------------------------------------------------------------------------- 1 | 3 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskG/out0.txt: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskG/out1.txt: -------------------------------------------------------------------------------- 1 | 6 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskG/out2.txt: -------------------------------------------------------------------------------- 1 | 133 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskH1/out0.txt: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskA/out0.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 7 3 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskB/out1.txt: -------------------------------------------------------------------------------- 1 | codeforcesss -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskD/in0.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 123 3 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskD/out0.txt: -------------------------------------------------------------------------------- 1 | 15129 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskF/in1.txt: -------------------------------------------------------------------------------- 1 | 4 2 | 3 | 1 -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskF/out0.txt: -------------------------------------------------------------------------------- 1 | 2 | 0 3 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskB/out0.txt: -------------------------------------------------------------------------------- 1 | codeforces 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskD/in1.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 1 3 5 3 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskD/out2.txt: -------------------------------------------------------------------------------- 1 | 1099509530625 2 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskD/in2.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 349525 699050 3 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskG/in1.txt: -------------------------------------------------------------------------------- 1 | 2 3 2 | ULR 3 | DLR 4 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskA/in0.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 1 2 3 3 | 5 4 100 4 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskF/out1.txt: -------------------------------------------------------------------------------- 1 | 2 | 2 1 3 3 | 4 | 0 5 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskG/in0.txt: -------------------------------------------------------------------------------- 1 | 2 4 2 | UUUU 3 | DDDD 4 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskH2/out0.txt: -------------------------------------------------------------------------------- 1 | 7 2 | 7 3 | 9 4 | 4 5 | 9 6 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskE/out0.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 3 4 3 | 4 4 | 4 5 6 7 5 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskH1/in0.txt: -------------------------------------------------------------------------------- 1 | 4 5 0 2 | BBRR 3 | RBBR 4 | BBBBB 5 | RRRRR 6 | -------------------------------------------------------------------------------- /extension/media/images/bot-icon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devanshusingla/ChromeBot/HEAD/extension/media/images/bot-icon1.png -------------------------------------------------------------------------------- /extension/media/images/bot-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devanshusingla/ChromeBot/HEAD/extension/media/images/bot-image.png -------------------------------------------------------------------------------- /extension/media/images/chat-bot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devanshusingla/ChromeBot/HEAD/extension/media/images/chat-bot1.png -------------------------------------------------------------------------------- /extension/media/images/chat-bot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devanshusingla/ChromeBot/HEAD/extension/media/images/chat-bot2.png -------------------------------------------------------------------------------- /server/data/conversation.txt: -------------------------------------------------------------------------------- 1 | {"chatter":"bot","text":"cleaned up!"},{"chatter":"user","text":"wwo"},{"chatter":"user","text":"fk"} -------------------------------------------------------------------------------- /server/router/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | 4 | module.exports = router; 5 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/test.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path" : "./scripts/features/codeforces/contests" 4 | } 5 | ] -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskG/in2.txt: -------------------------------------------------------------------------------- 1 | 6 6 2 | ULRUUU 3 | DUUDDD 4 | UDDLRU 5 | DLRLRD 6 | ULRULR 7 | DLRDLR 8 | -------------------------------------------------------------------------------- /server/Makefile: -------------------------------------------------------------------------------- 1 | all: clean 2 | 3 | clean: 4 | echo '{"chatter":"bot","text":"Hey buddy!"},{"chatter":"bot","text":"wanna do something?"}' > data/conversation.txt -------------------------------------------------------------------------------- /docs/features/README.MD: -------------------------------------------------------------------------------- 1 | # Features provided : 2 | 3 | 1. [Codeforces bot](./codeforces/README.MD) 4 | Author : [Yatharth Goswami](https://github.com/yatharth0610) -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskH2/in0.txt: -------------------------------------------------------------------------------- 1 | 4 5 4 2 | BBRR 3 | RBBR 4 | BBBBB 5 | RRRRR 6 | L 2 3 7 | R 3 4 8 | U 1 5 9 | D 1 5 10 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskC/out0.txt: -------------------------------------------------------------------------------- 1 | 12 2 | 1 0 3 | 2 0 4 | 0 1 5 | 1 1 6 | 2 1 7 | 3 1 8 | 0 2 9 | 1 2 10 | 2 2 11 | 3 2 12 | 1 3 13 | 2 3 14 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskE/in0.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 4 6 3 | 1 2 4 | 1 3 5 | 2 3 6 | 2 4 7 | 3 4 8 | 3 4 9 | 7 6 10 | 1 2 11 | 1 3 12 | 2 4 13 | 2 5 14 | 3 6 15 | 3 7 16 | -------------------------------------------------------------------------------- /extension/scripts/front/handleFeatures.js: -------------------------------------------------------------------------------- 1 | function handleFeature(res) { 2 | if (res.featureName === "hello") { 3 | newChat({ 4 | chatter: "bot", 5 | text: "Hello!", 6 | }); 7 | } else if (res.featureName === "codeforces") { 8 | codeforces(res); 9 | } else if (res.featureName === "contestSchedular") { 10 | contestSchedular(res); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /docs/features/contest schedular/README.md: -------------------------------------------------------------------------------- 1 | ## Contest Schedular 2 | 3 | It is a utility to set alarm for upcoming contests. 4 | 5 | ### How to use 6 | 7 | enter the command `contests` and it will open a website listing contests. Click on the any of the contests (not on link, the empty spaces), and will set alarm for 15 min before the contest. You can click it again to cancel the alarm. 8 | -------------------------------------------------------------------------------- /server/scripts/features/index.js: -------------------------------------------------------------------------------- 1 | /*************************************** 2 | * AUTHOR : Yatharth Goswami * 3 | * Email : yatharthgoswami15@gmail.com * 4 | * Github Username : yatharth0610 * 5 | ****************************************/ 6 | 7 | const express = require("express"); 8 | const router = express.Router(); 9 | 10 | router.use( 11 | "/codeforces", 12 | (req, res, next) => { 13 | console.log("codeforces requested"); 14 | next(); 15 | }, 16 | require("./codeforces"), 17 | (req, res) => res.send("Successfully Saved!") 18 | ); 19 | 20 | module.exports = router; 21 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskA/sol.cpp: -------------------------------------------------------------------------------- 1 | /************************************ 2 | / AUTHOR : YATHARTH GOSWAMI / 3 | / ALIAS : hacker_yg / 4 | / INSTITUTE : IIT Kanpur / 5 | ************************************/ 6 | // TEMPLATE // 7 | 8 | #include 9 | 10 | #define ll long long 11 | #define MOD 1000000007 12 | #define pb push_back 13 | #define mp make_pair 14 | #define F first 15 | #define S second 16 | 17 | using namespace std; 18 | 19 | int main(){ 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskB/sol.cpp: -------------------------------------------------------------------------------- 1 | /************************************ 2 | / AUTHOR : YATHARTH GOSWAMI / 3 | / ALIAS : hacker_yg / 4 | / INSTITUTE : IIT Kanpur / 5 | ************************************/ 6 | // TEMPLATE // 7 | 8 | #include 9 | 10 | #define ll long long 11 | #define MOD 1000000007 12 | #define pb push_back 13 | #define mp make_pair 14 | #define F first 15 | #define S second 16 | 17 | using namespace std; 18 | 19 | int main(){ 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskC/sol.cpp: -------------------------------------------------------------------------------- 1 | /************************************ 2 | / AUTHOR : YATHARTH GOSWAMI / 3 | / ALIAS : hacker_yg / 4 | / INSTITUTE : IIT Kanpur / 5 | ************************************/ 6 | // TEMPLATE // 7 | 8 | #include 9 | 10 | #define ll long long 11 | #define MOD 1000000007 12 | #define pb push_back 13 | #define mp make_pair 14 | #define F first 15 | #define S second 16 | 17 | using namespace std; 18 | 19 | int main(){ 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskD/sol.cpp: -------------------------------------------------------------------------------- 1 | /************************************ 2 | / AUTHOR : YATHARTH GOSWAMI / 3 | / ALIAS : hacker_yg / 4 | / INSTITUTE : IIT Kanpur / 5 | ************************************/ 6 | // TEMPLATE // 7 | 8 | #include 9 | 10 | #define ll long long 11 | #define MOD 1000000007 12 | #define pb push_back 13 | #define mp make_pair 14 | #define F first 15 | #define S second 16 | 17 | using namespace std; 18 | 19 | int main(){ 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskE/sol.cpp: -------------------------------------------------------------------------------- 1 | /************************************ 2 | / AUTHOR : YATHARTH GOSWAMI / 3 | / ALIAS : hacker_yg / 4 | / INSTITUTE : IIT Kanpur / 5 | ************************************/ 6 | // TEMPLATE // 7 | 8 | #include 9 | 10 | #define ll long long 11 | #define MOD 1000000007 12 | #define pb push_back 13 | #define mp make_pair 14 | #define F first 15 | #define S second 16 | 17 | using namespace std; 18 | 19 | int main(){ 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskF/sol.cpp: -------------------------------------------------------------------------------- 1 | /************************************ 2 | / AUTHOR : YATHARTH GOSWAMI / 3 | / ALIAS : hacker_yg / 4 | / INSTITUTE : IIT Kanpur / 5 | ************************************/ 6 | // TEMPLATE // 7 | 8 | #include 9 | 10 | #define ll long long 11 | #define MOD 1000000007 12 | #define pb push_back 13 | #define mp make_pair 14 | #define F first 15 | #define S second 16 | 17 | using namespace std; 18 | 19 | int main(){ 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskG/sol.cpp: -------------------------------------------------------------------------------- 1 | /************************************ 2 | / AUTHOR : YATHARTH GOSWAMI / 3 | / ALIAS : hacker_yg / 4 | / INSTITUTE : IIT Kanpur / 5 | ************************************/ 6 | // TEMPLATE // 7 | 8 | #include 9 | 10 | #define ll long long 11 | #define MOD 1000000007 12 | #define pb push_back 13 | #define mp make_pair 14 | #define F first 15 | #define S second 16 | 17 | using namespace std; 18 | 19 | int main(){ 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskH1/sol.cpp: -------------------------------------------------------------------------------- 1 | /************************************ 2 | / AUTHOR : YATHARTH GOSWAMI / 3 | / ALIAS : hacker_yg / 4 | / INSTITUTE : IIT Kanpur / 5 | ************************************/ 6 | // TEMPLATE // 7 | 8 | #include 9 | 10 | #define ll long long 11 | #define MOD 1000000007 12 | #define pb push_back 13 | #define mp make_pair 14 | #define F first 15 | #define S second 16 | 17 | using namespace std; 18 | 19 | int main(){ 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/contests/Codeforces_Round_1368/taskH2/sol.cpp: -------------------------------------------------------------------------------- 1 | /************************************ 2 | / AUTHOR : YATHARTH GOSWAMI / 3 | / ALIAS : hacker_yg / 4 | / INSTITUTE : IIT Kanpur / 5 | ************************************/ 6 | // TEMPLATE // 7 | 8 | #include 9 | 10 | #define ll long long 11 | #define MOD 1000000007 12 | #define pb push_back 13 | #define mp make_pair 14 | #define F first 15 | #define S second 16 | 17 | using namespace std; 18 | 19 | int main(){ 20 | 21 | return 0; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chrome-bot", 3 | "version": "1.0.0", 4 | "description": "server for chrome bot extension", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "axios": "^0.19.2", 14 | "body-parser": "^1.19.0", 15 | "cheerio": "^1.0.0-rc.3", 16 | "child_process": "^1.0.2", 17 | "cors": "^2.8.5", 18 | "express": "^4.17.1", 19 | "fs": "0.0.1-security", 20 | "nodemon": "^2.0.12" 21 | }, 22 | "devDependencies": { 23 | "check-dependencies": "^1.1.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /server/scripts/detectCommand.js: -------------------------------------------------------------------------------- 1 | function detectCommand(req, res, next) { 2 | let userInput = req.body.text; 3 | 4 | if (userInput === "clr") { 5 | res.locals.chatObj.clear(); 6 | next(); 7 | } else if (userInput === "hello") { 8 | res.set("Content-Type", "application/json"); 9 | res.json({ type: "feature", featureType: "noArg", featureName: "hello" }); 10 | } else if (userInput === "cf") { 11 | res.set("Content-Type", "application/json"); 12 | res.json({ 13 | type: "feature", 14 | featureType: "interactive", 15 | featureName: "codeforces", 16 | }); 17 | } else if (userInput === "contests") { 18 | res.set("Content-Type", "application/json"); 19 | res.json({ 20 | type: "feature", 21 | featureType: "noArg", 22 | featureName: "contestSchedular", 23 | }); 24 | } else next(); 25 | } 26 | 27 | module.exports = detectCommand; 28 | -------------------------------------------------------------------------------- /extension/scripts/front/features/codeforces.js: -------------------------------------------------------------------------------- 1 | /*************************************** 2 | * AUTHOR : Yatharth Goswami * 3 | * Email : yatharthgoswami15@gmail.com * 4 | * Github Username : yatharth0610 * 5 | ****************************************/ 6 | 7 | function codeforces() { 8 | const url = featureURL + "codeforces/"; 9 | chrome.runtime.sendMessage({message : "getUrl"}, (response) => { 10 | 11 | let xhr = new XMLHttpRequest(); 12 | 13 | xhr.onload = () => { 14 | console.log(xhr.response); 15 | if (xhr.response === "success") { 16 | newChat({ 17 | chatter : "bot", 18 | text : "Files saved successfully!", 19 | }) 20 | } 21 | else { 22 | newChat({ 23 | chatter : "bot", 24 | text : "Oops, Error Encountered!", 25 | }) 26 | } 27 | }; 28 | 29 | xhr.open("POST", url + "cf-bot", true); 30 | xhr.setRequestHeader("Content-Type", "application/json"); 31 | xhr.send(JSON.stringify({"contestUrl" : response.message})); 32 | }) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /extension/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Chrome Bot", 3 | "version": "1.0", 4 | "description": "A simple bot for chrome", 5 | "manifest_version": 2, 6 | "browser_action": { 7 | "default_icon": "media/images/bot-icon1.png" 8 | }, 9 | "icons": { "48": "media/images/bot-icon1.png" }, 10 | "content_scripts": [ 11 | { 12 | "matches": [""], 13 | "run_at": "document_start", 14 | "js": [ 15 | "scripts/front/std.js", 16 | "scripts/front/handleFeatures.js", 17 | "scripts/front/chatSystem.js", 18 | "scripts/front/draggable.js", 19 | "scripts/front/content.js", 20 | "scripts/front/features/codeforces.js", 21 | "scripts/front/features/contestSchedular.js" 22 | ], 23 | "css": ["/css/botBox.css"] 24 | } 25 | ], 26 | "permissions": ["activeTab", "tabs", "storage", "alarms"], 27 | "background": { 28 | "scripts": [ 29 | "scripts/background/std.js", 30 | "scripts/background/background.js", 31 | "scripts/background/features/contestSchedular.js" 32 | ], 33 | "persistent": false 34 | }, 35 | "web_accessible_resources": ["media/*"] 36 | } 37 | -------------------------------------------------------------------------------- /extension/scripts/background/std.js: -------------------------------------------------------------------------------- 1 | function MsgPassing(featureName, type = "feature", target = "front") { 2 | class MsgPassingClass { 3 | constructor(type, target, featureName) { 4 | this.type = type; 5 | this.featureName = featureName; 6 | this.target = target; 7 | this.listeners = {}; 8 | } 9 | 10 | sendMessage(tabID, msg, params, response) { 11 | chrome.tabs.sendMessage( 12 | tabID, 13 | { 14 | type: this.type, 15 | featureName: this.featureName, 16 | target: this.target, 17 | msg: msg, 18 | params: params, 19 | }, 20 | response 21 | ); 22 | } 23 | 24 | addListener(msg, action) { 25 | this.listeners[msg] = action; 26 | } 27 | 28 | listen() { 29 | chrome.runtime.onMessage.addListener((req, sender, sendRes) => { 30 | if ( 31 | req.type === this.type && 32 | req.featureName === this.featureName && 33 | req.target === "background" 34 | ) { 35 | if (this.listeners[req.msg]) 36 | this.listeners[req.msg](req.params, sender, sendRes); 37 | else { 38 | console.error(`unknown message "${req.msg}"`); 39 | } 40 | } 41 | }); 42 | } 43 | } 44 | 45 | return new MsgPassingClass(type, target, featureName); 46 | } 47 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const bodyParser = require("body-parser"); 3 | const app = express(); 4 | const cors = require("cors"); 5 | 6 | const CreateChatObject = require("./scripts/createChatObject"); 7 | const detectCommand = require("./scripts/detectCommand"); 8 | const feature = require("./scripts/features/index"); 9 | 10 | const port = 3000; 11 | 12 | app.use(bodyParser.urlencoded({ extended: true })); 13 | app.use(bodyParser.json()); 14 | app.use( 15 | cors({ 16 | allowedHeaders: ["sessionId", "Content-Type"], 17 | exposedHeaders: ["sessionId"], 18 | origin: "*", 19 | methods: "GET,HEAD,PUT,PATCH,POST,DELETE", 20 | preflightContinue: false, 21 | }) 22 | ); 23 | app.use( 24 | "/feature", 25 | (req, res, next) => { 26 | console.log("feature requested"); 27 | next(); 28 | }, 29 | feature 30 | ); 31 | 32 | var chatObj = new CreateChatObject(5); 33 | 34 | app.get("/chat", (req, res) => { 35 | console.log("get-request"); 36 | res.json(chatObj.chats); 37 | }); 38 | 39 | app.post( 40 | "/chat", 41 | (req, res, next) => { 42 | console.log("post-request"); 43 | console.log(req.body); 44 | 45 | chatObj.add_chat(req.body); 46 | res.locals.chatObj = chatObj; 47 | 48 | next(); 49 | }, 50 | detectCommand, 51 | (req, res) => res.send("Successfully processed") 52 | ); 53 | 54 | app.listen(port, () => console.log(`listening on port ${port}`)); 55 | -------------------------------------------------------------------------------- /docs/features/codeforces/README.MD: -------------------------------------------------------------------------------- 1 | # Usage 2 | 1. First of all put your template in the skeleton.cpp file in this folder. By default skeleton.cpp will be empty. 3 | 2. Go to the outer directory which contains the main server and run : 4 | ``` 5 | node index.js or nodemon index.js 6 | ``` 7 | 3. Open the extension in the contest you want to be scraped and type cf on the input box to the bot. 8 | ```bash 9 | # The bot will parse all the problems of the contest 10 | # download their testcases 11 | # create multiple directories taskA taskB taskC taskD taskE depending on the number of problems in contest 12 | # each directory created will have 13 | # in0.txt out0.txt 14 | # in1.txt out1.txt and so on 15 | # which represent the testcases downloaded 16 | # and finally you will get the tasks directory opened in vscode 17 | ``` 18 | # Saving the tasks : 19 | 1. By default the tasks will get saved inside ./server/scripts/features/codeforces/contests inside the folder "Codeforces_Round_" where number represents the contest number. 20 | A sample scraped round directory has already been provided alongside to take a look at how the rounds will be saved. 21 | 2. To change this location we have provided a test.json file which contains a key called "path". Change the value corresponding to this key and then these tasks will be saved to that particular directory inside the folder by the name "Codeforces_Round_". 22 | 23 | # Author 24 | [Yatharth Goswami](https://github.com/yatharth0610) 25 | **Email** : yatharthgoswami15@gmail.com 26 | -------------------------------------------------------------------------------- /server/scripts/createChatObject.js: -------------------------------------------------------------------------------- 1 | function CreateChatObject( 2 | maxChats, 3 | chatHistoryFile = "data/conversation.txt", 4 | defMsg, 5 | cleanMsg 6 | ) { 7 | if (!defMsg) 8 | defMsg = [ 9 | { chatter: "bot", text: "Hey buddy!" }, 10 | { chatter: "bot", text: "Wanna do something" }, 11 | ]; 12 | 13 | if (!cleanMsg) cleanMsg = [{ chatter: "bot", text: "cleaned up!" }]; 14 | 15 | const fs = require("fs"); 16 | 17 | let data; 18 | data = fs.readFileSync(chatHistoryFile, "utf-8"); 19 | data = "[" + data + "]"; 20 | let jsonData = JSON.parse(data); 21 | jsonData.slice(Math.max(jsonData.length - maxChats, 0)); 22 | 23 | this.maxChats = maxChats; 24 | this.chats = JSON.parse(JSON.stringify(jsonData)); 25 | this.defMsg = JSON.parse(JSON.stringify(defMsg)); 26 | this.cleanMsg = JSON.parse(JSON.stringify(cleanMsg)); 27 | this.chatHistoryFile = chatHistoryFile; 28 | this.add_chat = (chat) => { 29 | let fs = require("fs"); 30 | fs.appendFileSync(this.chatHistoryFile, "," + JSON.stringify(chat)); 31 | if (this.chats.length === this.maxChats) { 32 | this.chats.shift(); 33 | } 34 | this.chats.push(chat); 35 | }; 36 | this.clear = () => { 37 | let str = JSON.stringify(this.cleanMsg); 38 | this.chats = JSON.parse(str); 39 | if (str[0] === "[") str = str.substring(1, str.length - 1); 40 | fs.truncateSync(this.chatHistoryFile, 0); 41 | fs.writeFileSync(this.chatHistoryFile, str); 42 | }; 43 | } 44 | 45 | module.exports = CreateChatObject; 46 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/README.MD: -------------------------------------------------------------------------------- 1 | # Usage 2 | 1. First of all put your template in the skeleton.cpp file in this folder. By default skeleton.cpp will be empty. 3 | 2. Go to the outer directory which contains the main server and run : 4 | ``` 5 | node index.js or nodemon index.js 6 | ``` 7 | 3. Open the extension in the contest you want to be scraped and type cf on the input box to the bot. 8 | ```bash 9 | # The bot will parse all the problems of the contest 10 | # download their testcases 11 | # create multiple directories taskA taskB taskC taskD taskE depending on the number of problems in contest 12 | # each directory created will have 13 | # in0.txt out0.txt 14 | # in1.txt out1.txt and so on 15 | # which represent the testcases downloaded 16 | # and finally you will get the tasks directory opened in vscode 17 | ``` 18 | # Saving the tasks : 19 | 1. By default the tasks will get saved inside ./server/scripts/features/codeforces/contests inside the folder "Codeforces_Round_" where number represents the contest number. 20 | A sample scraped round directory has already been provided alongside to take a look at how the rounds will be saved. 21 | 2. To change this location we have provided a test.json file which contains a key called "path". Change the value corresponding to this key and then these tasks will be saved to that particular directory inside the folder by the name "Codeforces_Round_". 22 | 23 | # Author 24 | [Yatharth Goswami](https://github.com/yatharth0610) 25 | **Email** : yatharthgoswami15@gmail.com 26 | 27 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ## Adding your features. 2 | 3 | You can also add your own features in this bot. You can exploit server to add things to your system and the chrome extension to change display of browser or gain information about the browser, current open website, etc. 4 | 5 | Mainly it will involve following steps:- 6 | 7 | 1. Detect your command through `server/scripts/detectCommand.js`. If detected send json response with 8 | 9 | - `type` attribute having value `feature` 10 | - `featureName` attribute having a unique name for your feature to detect it in extension code. 11 | - `featureType` attribute to make extension if feature wants to access resources or is providing resources. 12 | 13 | 2. Detect first response of feature detected by server, by using featureName in `extension/scripts/front/handleFeatures.js` and call a function representing your feature present in separate javascript file, say feature.js, in `extension/scripts/front/features`. 14 | 15 | 3. You can send multiple get, post, etc requests from the feature.js to server with url as `featureURL + "feature name/..."` and the server can detect these requests and send responses. 16 | 17 | 4. These requests will be detected using express router. The server implementation of your feature will be stored in a folder named with your feature inside `server/scripts/features`. It will contain an `index.js` file which will export express router detecting the various requests pertaining to your feature. 18 | 19 | 5. Add your file (feature.js) in `manifest.json` where other content scripts are present. 20 | 21 | 6. You can always use other resources like from `chatSystem.js, std.js` present in extension or other feature api's by sending xmlHttpRequests to that feature. 22 | 23 | **NOTE:** As an example please see the codeforces feature [link here](./features/README.MD) 24 | -------------------------------------------------------------------------------- /extension/scripts/front/chatSystem.js: -------------------------------------------------------------------------------- 1 | /***************************************************** 2 | * 3 | * Implements chat system for bot 4 | * 5 | *****************************************************/ 6 | 7 | function textBox(chats) { 8 | let box = document.createElement("div"); 9 | setAttributes(box, { class: "bot-chat-box", id: "bot-chat-box" }); 10 | if (!chats) return box; 11 | for (var chat of chats) { 12 | var chatElement = document.createElement("div"); 13 | if (chat.chatter === "bot") { 14 | setAttributes(chatElement, { class: "bot-chat-bot" }); 15 | } else if (chat.chatter === "user") { 16 | setAttributes(chatElement, { class: "bot-chat-user" }); 17 | } 18 | chatElement.innerHTML = chat.text; 19 | box.appendChild(chatElement); 20 | } 21 | 22 | return box; 23 | } 24 | 25 | function displayChats(chats) { 26 | var oldChatBody = document.getElementById("bot-chat-box"); 27 | var newChatBody = textBox(chats); 28 | if (oldChatBody) { 29 | newChatBody.appendChild(oldChatBody.lastChild); 30 | oldChatBody.parentNode.replaceChild(newChatBody, oldChatBody); 31 | } 32 | } 33 | 34 | function getChats() { 35 | let getreq = new XMLHttpRequest(); 36 | 37 | getreq.onload = () => displayChats(JSON.parse(getreq.response)); 38 | 39 | getreq.open("GET", chatURL, true); 40 | getreq.setRequestHeader("Content-Type", "application/json"); 41 | getreq.send(); 42 | } 43 | 44 | function newChat(chat) { 45 | let postreq = new XMLHttpRequest(); 46 | 47 | postreq.onload = () => { 48 | getChats(); 49 | if ( 50 | postreq.getResponseHeader("Content-Type") === 51 | "application/json; charset=utf-8" 52 | ) { 53 | let jsonRes = JSON.parse(postreq.response); 54 | if (jsonRes.type === "feature") { 55 | handleFeature(jsonRes); 56 | } 57 | } 58 | }; 59 | postreq.open("POST", chatURL, true); 60 | postreq.setRequestHeader("Content-Type", "application/json"); 61 | postreq.send(JSON.stringify(chat)); 62 | } 63 | -------------------------------------------------------------------------------- /extension/scripts/front/draggable.js: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | * 3 | * MAKE BOT DRAGGABLE 4 | * 5 | **************************************************************************/ 6 | 7 | var dragItem, dragHandle; 8 | var active = false; 9 | var currentX; 10 | var currentY; 11 | var initialX; 12 | var initialY; 13 | 14 | function dragStart(e) { 15 | e.preventDefault(); 16 | 17 | chrome.storage.local.get(["xOffset", "yOffset"], function (result) { 18 | var xOffset = result["xOffset"]; 19 | var yOffset = result["yOffset"]; 20 | if (e.type === "touchstart") { 21 | initialX = e.touches[0].clientX - xOffset; 22 | initialY = e.touches[0].clientY - yOffset; 23 | } else { 24 | initialX = e.clientX - xOffset; 25 | initialY = e.clientY - yOffset; 26 | } 27 | }); 28 | 29 | if (e.target === dragHandle) { 30 | active = true; 31 | } 32 | } 33 | 34 | function dragEnd(e) { 35 | active = false; 36 | } 37 | 38 | function drag(e) { 39 | if (active) { 40 | if (e.type === "touchmove") { 41 | currentX = e.touches[0].clientX - initialX; 42 | currentY = e.touches[0].clientY - initialY; 43 | } else { 44 | currentX = e.clientX - initialX; 45 | currentY = e.clientY - initialY; 46 | } 47 | 48 | chrome.storage.local.set({ 49 | xOffset: currentX, 50 | yOffset: currentY, 51 | }); 52 | 53 | setTranslate(currentX, currentY, dragItem); 54 | } 55 | } 56 | 57 | function setTranslate(xPos, yPos, el) { 58 | el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)"; 59 | } 60 | 61 | function make_draggable(dragitem, draghandle) { 62 | dragItem = dragitem; 63 | dragHandle = draghandle; 64 | var body = document.getElementsByTagName("body")[0]; 65 | 66 | if (!body) return; 67 | dragHandle.addEventListener("touchstart", dragStart, false); 68 | body.addEventListener("touchend", dragEnd, false); 69 | body.addEventListener("touchmove", drag, false); 70 | 71 | dragHandle.addEventListener("mousedown", dragStart, false); 72 | body.addEventListener("mouseup", dragEnd, false); 73 | body.addEventListener("mousemove", drag, false); 74 | } 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chrome Bot 2 | 3 | It is a chrome extension to provide interface of bot which can perform some tasks through commands. You can even add your commands and if it works we would be happy to include it :stuck_out_tongue:. 4 | 5 | You can also drag the bot by clicking on it and may play with it even ( try dragging ). 6 | 7 | ## Installation 8 | 9 | ### Clone this repository in your computer. 10 | 11 | It can be done as:- 12 | 13 | 1. Create an empty directory and change into that directory. 14 | 2. Enter the following code: 15 | 16 | ``` 17 | git init 18 | git clone https://github.com/devanshusingla/ChromeBot.git 19 | ``` 20 | 21 | This will create a folder named **ChromeBot**. 22 | 23 | ### Install needed node modules. 24 | 25 | Its server is built on top of nodejs. If you don't have node already installed, install it before following steps: 26 | 27 | 1. Change to **Chromebot/server**. 28 | 2. run `npm install`. 29 | 30 | ### Add it as extension in Chrome browser. 31 | 32 | 1. Open a Chrome window and select **settings > More tools > Extensions**. This will open the Extension's window. 33 | 2. Now turn on the **Developer Mode** through the toggle button present at top right of the window. 34 | 3. Three options would have appeared. Click the **Load unpacked** option. 35 | 4. Now change to the **ChromeBot** directory and select the extension folder and click on **Open** button. 36 | 5. This will create an extension named **ChromeBot**. Enable the extension if not enabled by default and an icon would appear in the Extension toolbar. 37 | 38 | **Note:** _Bot will only open after entire page has been loaded._ 39 | 40 | **Note:** _Bot wouldn't open on the homepage of window, for eg:- google search page on starting chrome window._ 41 | 42 | ## Usage 43 | 44 | ### Starting server 45 | 46 | 1. Open terminal and change to **ChromeBot/server**. 47 | 2. run command nodemon index.js/node index.js. 48 | 49 | ### Starting extension 50 | 51 | In your open chrome window, simply click the icon of this extension and it will start the bot. 52 | 53 | ## Further 54 | 55 | Plz check the [docs](https://github.com/devanshusingla/ChromeBot/tree/dev/docs) folder for more information. 56 | 57 | ## Authors 58 | 59 | [Devanshu Singla](https://github.com/devanshusingla) and [Yatharth Goswami](https://github.com/yatharth0610). 60 | 61 | ## Contributors 62 | -------------------------------------------------------------------------------- /extension/scripts/background/background.js: -------------------------------------------------------------------------------- 1 | chrome.browserAction.onClicked.addListener(toggleButton); 2 | chrome.tabs.onUpdated.addListener(sendMessage); 3 | chrome.tabs.onDetached.addListener(sendMessage); 4 | chrome.tabs.onAttached.addListener(sendMessage); 5 | chrome.tabs.onHighlighted.addListener(sendMessage); 6 | chrome.windows.onFocusChanged.addListener(sendMessage); 7 | 8 | chrome.storage.local.set({ 9 | buttonState: false, 10 | activeTabId: null, 11 | xOffset: 0, 12 | yOffset: 0, 13 | feauture: null, 14 | }); 15 | 16 | var tabsCallCount = 0; 17 | 18 | chrome.runtime.onMessage.addListener(function (req, sender, sendResponse) { 19 | sendResponse({ message: sender.url }); 20 | }); 21 | 22 | function toggleButton() { 23 | chrome.storage.local.get("buttonState", function (result) { 24 | chrome.storage.local.set({ buttonState: !result["buttonState"] }); 25 | sendMessage(); 26 | }); 27 | } 28 | 29 | function sendMessage() { 30 | tabsCallCount++; 31 | if (tabsCallCount <= 1) { 32 | chrome.storage.local.get(["activeTabId", "buttonState"], function (result) { 33 | var id = result["activeTabId"]; 34 | if (id) { 35 | chrome.tabs.get(id, function (tab) { 36 | if (chrome.runtime.lastError) 37 | console.log(chrome.runtime.lastError.message); 38 | if (tab) { 39 | chrome.tabs.sendMessage(tab.id, { 40 | todo: "destroyBot", 41 | }); 42 | } 43 | }); 44 | } 45 | var startBot = result["buttonState"]; 46 | var todo = startBot ? "launchBot" : "destroyBot"; 47 | 48 | function activateBot() { 49 | chrome.tabs.query( 50 | { active: true, currentWindow: true }, 51 | function (tabs) { 52 | if (chrome.runtime.lastError) { 53 | console.log("background query error"); 54 | window.setTimeout(() => activateBot(), 100); 55 | } 56 | if (tabs && tabs[0]) { 57 | chrome.storage.local.set({ activeTabId: tabs[0].id }); 58 | tabsCallCount--; 59 | chrome.tabs.sendMessage(tabs[0].id, { 60 | todo: todo, 61 | }); 62 | } 63 | } 64 | ); 65 | } 66 | 67 | activateBot(); 68 | }); 69 | } else { 70 | tabsCallCount--; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /extension/scripts/front/features/contestSchedular.js: -------------------------------------------------------------------------------- 1 | const Schedular = MsgPassing("contestSchedular"); 2 | 3 | function contestSchedular() { 4 | Schedular.sendMessage("create"); 5 | } 6 | 7 | Schedular.sendMessage("created"); 8 | 9 | Schedular.addListener("scrape", (req, sender, sendRes) => { 10 | window.addEventListener("DOMContentLoaded", () => { 11 | let contests = Array.from(document.getElementById("contests").children); 12 | contests.forEach((contest) => { 13 | if (contest.getAttribute("class").includes("row contest coming")) { 14 | contest.addEventListener("click", () => 15 | Schedular.sendMessage( 16 | "set-alarm", 17 | contest 18 | .getElementsByClassName("data-ace")[0] 19 | .getAttribute("data-ace") 20 | ) 21 | ); 22 | } 23 | }); 24 | newChat({ 25 | chatter: "bot", 26 | text: "I will remind you of contest", 27 | }); 28 | setTimeout( 29 | () => 30 | newChat({ 31 | chatter: "bot", 32 | text: "Just click the contest you want to set reminder of", 33 | }), 34 | 1000 35 | ); 36 | }); 37 | }); 38 | 39 | Schedular.addListener("alarm-present", (req, sender, sendRes) => { 40 | if (!req.present) 41 | newChat({ 42 | chatter: "bot", 43 | text: `Alarm set for "${req.title}"`, 44 | }); 45 | else { 46 | if ( 47 | confirm( 48 | `alarm is already set for "${req.title}". Do you want to remove the alarm?` 49 | ) 50 | ) 51 | Schedular.sendMessage("remove-alarm", { 52 | alarmMsg: req.alarmMsg, 53 | title: req.title, 54 | }); 55 | } 56 | }); 57 | 58 | Schedular.addListener("alarm-clear-status", (req, sender, sendRes) => { 59 | if (req.wasCleared) { 60 | newChat({ 61 | chatter: "bot", 62 | text: `alarm for "${req.title}" was removed`, 63 | }); 64 | } else { 65 | newChat({ 66 | chatter: "bot", 67 | text: `sorry! but alarm for ${req.title} was not removed`, 68 | }); 69 | } 70 | }); 71 | 72 | Schedular.addListener("buzz", (req, sender, sendRes) => { 73 | if ( 74 | confirm( 75 | `The contest ${req.title} is going to start would you like to go to the site (${req.url})?` 76 | ) 77 | ) { 78 | sendRes(req.url); 79 | } else { 80 | sendRes(); 81 | } 82 | }); 83 | 84 | Schedular.listen(); 85 | -------------------------------------------------------------------------------- /extension/scripts/background/features/contestSchedular.js: -------------------------------------------------------------------------------- 1 | let contestSchedularObj = { created: false }; 2 | 3 | const Schedular = MsgPassing("contestSchedular"); 4 | 5 | Schedular.addListener("create", (req, sender, sendResponse) => { 6 | chrome.tabs.create({ url: "https://clist.by/", active: true }, (tab) => { 7 | contestSchedularObj.created = true; 8 | }); 9 | }); 10 | 11 | Schedular.addListener("created", (req, sender, sendResponse) => { 12 | if (contestSchedularObj.created) { 13 | Schedular.sendMessage(sender.tab.id, "scrape"); 14 | contestSchedularObj.created = false; 15 | } 16 | }); 17 | 18 | Schedular.addListener("set-alarm", (req, sender, sendResponse) => { 19 | let contest = JSON.parse(req); 20 | let alarmMsg = JSON.stringify({ 21 | featureName: "contestSchedular", 22 | params: req, 23 | }); 24 | chrome.alarms.get( 25 | JSON.stringify({ featureName: "contestSchedular", params: req }), 26 | (alarm) => { 27 | if (alarm) { 28 | Schedular.sendMessage(sender.tab.id, "alarm-present", { 29 | present: true, 30 | title: contest.title, 31 | alarmMsg: alarmMsg, 32 | }); 33 | } else { 34 | chrome.alarms.create(alarmMsg, { 35 | when: new Date(contest.time.start).setMinutes( 36 | new Date(contest.time.start).getMinutes() - 15 37 | ), 38 | }); 39 | Schedular.sendMessage(sender.tab.id, "alarm-present", { 40 | present: false, 41 | title: contest.title, 42 | alarmMsg: alarmMsg, 43 | }); 44 | } 45 | } 46 | ); 47 | }); 48 | 49 | Schedular.addListener("remove-alarm", (req, sender, sendResponse) => { 50 | chrome.alarms.clear(req.alarmMsg, (wasCleared) => { 51 | Schedular.sendMessage(sender.tab.id, "alarm-clear-status", { 52 | wasCleared: wasCleared, 53 | title: req.title, 54 | }); 55 | }); 56 | }); 57 | 58 | chrome.alarms.onAlarm.addListener((alarm) => { 59 | let alarmObj = JSON.parse(alarm.name); 60 | if (alarmObj.featureName === "contestSchedular") { 61 | var contest = JSON.parse(alarmObj.params); 62 | chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { 63 | if (tabs[0]) { 64 | Schedular.sendMessage( 65 | tabs[0].id, 66 | "buzz", 67 | { title: contest.title, url: contest.desc.substring(4) }, 68 | (res) => { 69 | if (res) chrome.tabs.create({ url: res, active: true }); 70 | } 71 | ); 72 | } 73 | }); 74 | } 75 | }); 76 | 77 | Schedular.listen(); 78 | -------------------------------------------------------------------------------- /extension/scripts/front/content.js: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | * 3 | * MAIN CODE 4 | * 5 | ************************************************************************************/ 6 | 7 | chrome.runtime.onMessage.addListener(function (req, sender, sendResponse) { 8 | if (req.todo === "launchBot") { 9 | let temp = document.getElementsByClassName("bot-outer-box"); 10 | if (temp.length === 0) { 11 | chrome.storage.local.get(["xOffset", "yOffset"], function (result) { 12 | var div = document.createElement("div"); 13 | setAttributes(div, { class: "bot-outer-box", id: "outer-box-bot" }); 14 | var xOffset = result["xOffset"]; 15 | var yOffset = result["yOffset"]; 16 | 17 | setTranslate(xOffset, yOffset, div); 18 | 19 | var conversation = textBox(); 20 | 21 | var inputBox = document.createElement("div"); 22 | setAttributes(inputBox, { 23 | class: "bot-input-box", 24 | id: "bot-input-box", 25 | }); 26 | 27 | var input = document.createElement("INPUT"); 28 | setAttributes(input, { 29 | class: "bot-input", 30 | id: "message-bot", 31 | type: "text", 32 | placeholder: "How can I help you", 33 | autocomplete: "off", 34 | }); 35 | 36 | input.addEventListener("DOMContentLoaded", () => { 37 | this.focus(); 38 | this.select(); 39 | }); 40 | 41 | input.addEventListener("keyup", function (e) { 42 | if (e.keyCode === 13) { 43 | e.preventDefault(); 44 | var x = input.value; 45 | input.value = ""; 46 | newChat({ 47 | chatter: "user", 48 | text: x, 49 | }); 50 | } 51 | }); 52 | 53 | conversation.appendChild(input); 54 | 55 | var botImage = document.createElement("img"); 56 | setAttributes(botImage, { 57 | src: chrome.runtime.getURL("/media/images/bot-image.png"), 58 | class: "bot-image", 59 | }); 60 | 61 | make_draggable(div, botImage); 62 | 63 | inputBox.appendChild(input); 64 | conversation.appendChild(inputBox); 65 | div.appendChild(conversation); 66 | div.appendChild(botImage); 67 | document.body.appendChild(div); 68 | getChats(); 69 | }); 70 | } 71 | } 72 | if (req.todo === "destroyBot") { 73 | var mydiv = document.getElementById("outer-box-bot"); 74 | if (mydiv) { 75 | mydiv.remove(); 76 | } 77 | } 78 | }); 79 | -------------------------------------------------------------------------------- /extension/scripts/front/std.js: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | * 3 | * Basic Utility Functions 4 | * 5 | ****************************************************************/ 6 | 7 | let url = "http://localhost:3000/"; 8 | let chatURL = url + "chat/"; 9 | let featureURL = url + "feature/"; 10 | 11 | function setAttributes(element, list) { 12 | for (var key in list) { 13 | element.setAttribute(key, list[key]); 14 | } 15 | } 16 | 17 | // use `await sleep(ms)` to stop process for ms milliseconds. 18 | function sleep(ms) { 19 | return new Promise((resolve) => setTimeout(resolve, ms)); 20 | } 21 | 22 | function debugEvent(xhr, type) { 23 | function handleEvent(e) { 24 | console.log(`${type}: ${e.type}: ${e.loaded} bytes transferred\n`); 25 | } 26 | 27 | xhr.addEventListener("loadstart", handleEvent); 28 | xhr.addEventListener("load", handleEvent); 29 | xhr.addEventListener("loadend", handleEvent); 30 | xhr.addEventListener("progress", handleEvent); 31 | xhr.addEventListener("error", handleEvent); 32 | xhr.addEventListener("abort", handleEvent); 33 | } 34 | 35 | function MsgPassing(featureName, type = "feature", target = "background") { 36 | class MsgPassingClass { 37 | constructor(type, target, featureName) { 38 | this.type = type; 39 | this.featureName = featureName; 40 | this.target = target; 41 | this.listeners = {}; 42 | } 43 | 44 | sendMessage(msg, params, response) { 45 | chrome.runtime.sendMessage( 46 | { 47 | type: this.type, 48 | featureName: this.featureName, 49 | target: this.target, 50 | msg: msg, 51 | params: params, 52 | }, 53 | response 54 | ); 55 | } 56 | 57 | addListener(msg, action) { 58 | this.listeners[msg] = action; 59 | } 60 | 61 | listen() { 62 | chrome.runtime.onMessage.addListener((req, sender, sendRes) => { 63 | if ( 64 | req.type === this.type && 65 | req.featureName === this.featureName && 66 | req.target === "front" 67 | ) { 68 | if (this.listeners[req.msg]) 69 | this.listeners[req.msg](req.params, sender, sendRes); 70 | else console.error(`unknown message "${req.msg}"`); 71 | } 72 | }); 73 | } 74 | } 75 | 76 | return new MsgPassingClass(type, target, featureName); 77 | } 78 | 79 | const debug = MsgPassing("debug"); 80 | 81 | debug.sendMessage("hello"); 82 | 83 | debug.addListener("hi", (req) => { 84 | console.log(req); 85 | }); 86 | 87 | debug.addListener("hello", (req) => { 88 | console.log("Oh god same reply!"); 89 | }); 90 | 91 | debug.listen(); 92 | -------------------------------------------------------------------------------- /extension/css/botBox.css: -------------------------------------------------------------------------------- 1 | .bot-outer-box { 2 | position: fixed; 3 | display: flex; 4 | flex-direction: row; 5 | align-items: center; 6 | 7 | min-height: 10vh; 8 | min-width: 16vw; 9 | z-index: 100000000; 10 | 11 | top: 60vh; 12 | right: 0vw; 13 | 14 | background-color: rgba(31, 31, 31, 0.171); 15 | color: antiquewhite; 16 | } 17 | 18 | .bot-chat-box { 19 | display: flex; 20 | flex-direction: column; 21 | align-items: flex-end; 22 | justify-content: start; 23 | min-width: 18vw; 24 | min-height: 12vh; 25 | } 26 | 27 | .bot-chat-bot, 28 | .bot-chat-user, 29 | .bot-input { 30 | justify-content: start; 31 | margin-top: 0.15em; 32 | 33 | width: fit-content; 34 | max-width: 400px; 35 | min-height: 2vh; 36 | 37 | font-size: 1.4em; 38 | font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif; 39 | overflow-wrap: break-word; 40 | 41 | border: solid; 42 | border-color: black; 43 | border-width: medium; 44 | } 45 | 46 | .bot-chat-bot { 47 | align-self: flex-end; 48 | padding-right: 0.5em; 49 | padding-left: 0.5em; 50 | margin-left: 2em; 51 | align-items: flex-end; 52 | 53 | border-top-left-radius: 1em; 54 | border-bottom-left-radius: 1em; 55 | 56 | background-color: rgb(0, 27, 7); 57 | color: rgb(123, 255, 0); 58 | } 59 | 60 | .bot-chat-user { 61 | align-self: flex-start; 62 | padding-left: 0.4em; 63 | padding-right: 0.6em; 64 | margin-right: 2em; 65 | align-items: flex-start; 66 | 67 | border-top-right-radius: 1em; 68 | border-bottom-right-radius: 1em; 69 | 70 | background-color: rgb(1, 4, 7); 71 | color: #08f7fe; 72 | } 73 | 74 | .bot-input { 75 | align-self: flex-end; 76 | padding-left: 0.4em; 77 | padding-right: 0.5em; 78 | margin-right: 2em; 79 | align-items: flex-start; 80 | 81 | border: thin solid white; 82 | border-top-right-radius: 1em; 83 | border-bottom-right-radius: 1em; 84 | 85 | background-color: rgb(1, 4, 7); 86 | color: #08f7fe; 87 | } 88 | 89 | .bot-input:hover, 90 | .bot-input:focus, 91 | .bot-input:active { 92 | outline: 0; 93 | } 94 | 95 | .bot-input-box { 96 | display: flex; 97 | flex-direction: row; 98 | flex-grow: 4; 99 | 100 | align-items: center; 101 | align-self: flex-start; 102 | justify-self: flex-end; 103 | justify-content: space-between; 104 | 105 | width: 100%; 106 | } 107 | 108 | .bot-image { 109 | height: 10em; 110 | width: 10em; 111 | } 112 | 113 | .bot-image:hover, 114 | .bot-image:active { 115 | animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; 116 | transform: translate3d(0, 0, 0); 117 | backface-visibility: hidden; 118 | perspective: 1000px; 119 | } 120 | 121 | @keyframes shake { 122 | 10%, 123 | 90% { 124 | transform: rotate(1deg); 125 | } 126 | 127 | 20%, 128 | 80% { 129 | transform: rotate(-2deg); 130 | } 131 | 132 | 30%, 133 | 50%, 134 | 70% { 135 | transform: rotate(4deg); 136 | } 137 | 138 | 40%, 139 | 60% { 140 | transform: rotate(-4deg); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /server/scripts/features/codeforces/index.js: -------------------------------------------------------------------------------- 1 | /*************************************** 2 | * AUTHOR : Yatharth Goswami * 3 | * Email : yatharthgoswami15@gmail.com * 4 | * Github Username : yatharth0610 * 5 | ****************************************/ 6 | 7 | const express = require("express"); 8 | const router = express.Router(); 9 | const axios = require("axios"); 10 | const cheerio = require("cheerio"); 11 | const fs = require("fs"); 12 | const execSync = require ("child_process").execSync; 13 | 14 | router.post("/cf-bot", async (req, res) => { 15 | const url = req.body.contestUrl; 16 | console.log("CF-Bot activated"); 17 | activateBot(url,res); 18 | }) 19 | 20 | function activateBot(url, res) { 21 | axios.get(url) 22 | .then(response => { 23 | getTotalProblemsFromContestHtml(response.data, url, res); 24 | }) 25 | } 26 | 27 | function getTotalProblemsFromContestHtml (html, url, res) { 28 | data = []; 29 | const $ = cheerio.load(html); 30 | let temp = JSON.parse(fs.readFileSync("./scripts/features/codeforces/test.json")); 31 | let path = temp[0].path; 32 | let contestNum = url.substring(url.lastIndexOf('/')+1); 33 | let dir = path + "/Codeforces_Round_" + contestNum; 34 | if (!fs.existsSync(dir)) { 35 | fs.mkdirSync(dir); 36 | } 37 | $('tr td.id a').each((i, elem) => { 38 | problemurl = 'https://codeforces.com/' + $(elem).attr('href') 39 | getTestCaseFromProblemUrl(problemurl, contestNum); 40 | }); 41 | setTimeout(function () { 42 | res.send("success"); 43 | openVscode (path, contestNum); 44 | }, 6000); 45 | } 46 | 47 | function getTestCaseFromProblemUrl(url, num) { 48 | let data = JSON.parse(fs.readFileSync("./scripts/features/codeforces/test.json")); 49 | let path = data[0].path; 50 | let dir = path + "/Codeforces_Round_" + num + `/task${url.substring(url.lastIndexOf('/')+1)}`; 51 | if (!fs.existsSync(dir)){ 52 | fs.mkdirSync(dir); 53 | } 54 | axios.get(url) 55 | .then(response => { 56 | getTestCaseFromProblemHtml(dir, response.data); 57 | }) 58 | .catch(err => console.log(err)); 59 | } 60 | 61 | function getTestCaseFromProblemHtml (dir, html) { 62 | fs.copyFileSync(`./scripts/features/codeforces/skeleton.cpp`, `${dir}/sol.cpp`); 63 | data = [] 64 | const $ = cheerio.load(html); 65 | $('div .input').each((i, element) => { 66 | data[i] = { 67 | ...data[i], 68 | input : $(element).find('pre').text(), 69 | }; 70 | }); 71 | $('div .output').each((i, element) => { 72 | data[i] = { 73 | ...data[i], 74 | output : $(element).find('pre').text(), 75 | }; 76 | }); 77 | let flag = 1; 78 | data.forEach((elem, i) => { 79 | fs.writeFile(`${dir}/in${i}.txt`, elem.input, function(err){ 80 | if (err) { 81 | console.log(err); 82 | flag = 0; 83 | } 84 | else console.log(`${dir}/in${i}.txt was successfully saved`) 85 | }); 86 | fs.writeFile(`${dir}/out${i}.txt`, elem.output, function(err){ 87 | if (err) { 88 | console.log(err); 89 | flag = 0; 90 | } 91 | else console.log(`${dir}/out${i}.txt was successfully saved`) 92 | }); 93 | }) 94 | } 95 | 96 | function openVscode(path, num) { 97 | let dir = path + "/Codeforces_Round_" + num; 98 | execSync('cd ' + dir + "; code .", (err, stdout, stderr) => { 99 | if (err) { 100 | console.log(err); 101 | } else { 102 | console.log("Success!!"); 103 | } 104 | }) 105 | } 106 | 107 | module.exports = router; 108 | --------------------------------------------------------------------------------