├── .python-version ├── Procfile ├── requirements.txt ├── .gitignore ├── run.py ├── package.json ├── views ├── index.html └── layout.html ├── index.js ├── README.md └── controllers └── default.js /.python-version: -------------------------------------------------------------------------------- 1 | 3.12.2 -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node index.js -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Your requirements go here -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | core.Microsoft* 2 | core.mongo* 3 | core.python* 4 | env.py 5 | __pycache__/ 6 | *.py[cod] 7 | node_modules/ 8 | .github/ 9 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | # Your code goes here. 2 | # You can delete these comments, but do not change the name of this file 3 | # Write your code to expect a terminal of 80 characters wide and 24 rows high 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "terminal", 3 | "version": "1.0.0", 4 | "main": "server.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/lechien73/terminal.git" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "bugs": { 15 | "url": "https://github.com/lechien73/terminal/issues" 16 | }, 17 | "homepage": "https://github.com/lechien73/terminal#readme", 18 | "dependencies": { 19 | "node-static": "^0.7.11", 20 | "node-pty": "^0.10.1", 21 | "total4": "^0.0.45" 22 | } 23 | } -------------------------------------------------------------------------------- /views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 27 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // =================================================== 2 | // Total.js start script 3 | // https://www.totaljs.com 4 | // =================================================== 5 | 6 | const options = {}; 7 | 8 | // options.ip = '127.0.0.1'; 9 | options.port = parseInt(process.env.PORT); 10 | // options.unixsocket = require('path').join(require('os').tmpdir(), 'app_name'); 11 | // options.config = { name: 'Total.js' }; 12 | // options.sleep = 3000; 13 | // options.inspector = 9229; 14 | // options.watch = ['private']; 15 | // options.livereload = 'https://yourhostname'; 16 | 17 | // Enables cluster: 18 | // options.cluster = 'auto'; 19 | // options.cluster_limit = 10; // max 10. threads (works only with "auto" scaling) 20 | 21 | // Enables threads: 22 | // options.cluster = 'auto'; 23 | // options.cluster_limit = 10; // max 10. threads (works only with "auto" scaling) 24 | // options.timeout = 5000; 25 | // options.threads = '/api/'; 26 | // options.logs = 'isolated'; 27 | 28 | var type = process.argv.indexOf('--release', 1) !== -1 || process.argv.indexOf('release', 1) !== -1 ? 'release' : 'debug'; 29 | // require('total4/' + type)(options); 30 | require('total4').http('release', options); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![CI logo](https://codeinstitute.s3.amazonaws.com/fullstack/ci_logo_small.png) 2 | 3 | Welcome, 4 | 5 | This is the Code Institute student template for deploying your third portfolio project, the Python command-line project. The last update to this file was: **May 26, 2025** 6 | 7 | ## Reminders 8 | 9 | - Your code must be placed in the `run.py` file 10 | - Your dependencies must be placed in the `requirements.txt` file 11 | - Do not edit any of the other files or your code may not deploy properly 12 | 13 | ## Creating the Heroku app 14 | 15 | When you create the app, you will need to add two buildpacks from the _Settings_ tab. The ordering is as follows: 16 | 17 | 1. `heroku/python` 18 | 2. `heroku/nodejs` 19 | 20 | You must then create a _Config Var_ called `PORT`. Set this to `8000` 21 | 22 | If you have credentials, such as in the Love Sandwiches project, you must create another _Config Var_ called `CREDS` and paste the JSON into the value field. 23 | 24 | Connect your GitHub repository and deploy as normal. 25 | 26 | ## Constraints 27 | 28 | The deployment terminal is set to 80 columns by 24 rows. That means that each line of text needs to be 80 characters or less otherwise it will be wrapped onto a second line. 29 | 30 | --- 31 | 32 | Happy coding! 33 | -------------------------------------------------------------------------------- /controllers/default.js: -------------------------------------------------------------------------------- 1 | const Pty = require('node-pty'); 2 | const fs = require('fs'); 3 | 4 | exports.install = function () { 5 | 6 | ROUTE('/'); 7 | WEBSOCKET('/', socket, ['raw']); 8 | 9 | }; 10 | 11 | function socket() { 12 | 13 | this.encodedecode = false; 14 | this.autodestroy(); 15 | 16 | this.on('open', function (client) { 17 | 18 | // Spawn terminal 19 | client.tty = Pty.spawn('python3', ['run.py'], { 20 | name: 'xterm-color', 21 | cols: 80, 22 | rows: 24, 23 | cwd: process.env.PWD, 24 | env: process.env 25 | }); 26 | 27 | client.tty.on('exit', function (code, signal) { 28 | client.tty = null; 29 | client.close(); 30 | console.log("Process killed"); 31 | }); 32 | 33 | client.tty.on('data', function (data) { 34 | client.send(data); 35 | }); 36 | 37 | }); 38 | 39 | this.on('close', function (client) { 40 | if (client.tty) { 41 | client.tty.kill(9); 42 | client.tty = null; 43 | console.log("Process killed and terminal unloaded"); 44 | } 45 | }); 46 | 47 | this.on('message', function (client, msg) { 48 | client.tty && client.tty.write(msg); 49 | }); 50 | } 51 | 52 | if (process.env.CREDS != null) { 53 | console.log("Creating creds.json file."); 54 | fs.writeFile('creds.json', process.env.CREDS, 'utf8', function (err) { 55 | if (err) { 56 | console.log('Error writing file: ', err); 57 | socket.emit("console_output", "Error saving credentials: " + err); 58 | } 59 | }); 60 | } -------------------------------------------------------------------------------- /views/layout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Python Terminal by Code Institute 12 | 169 | 170 | 171 | @{body} 172 | 173 | --------------------------------------------------------------------------------