From bab2deb0685c07267bec6f9f4bfd1bd58fd662d5 Mon Sep 17 00:00:00 2001 From: Emidio Valeretto <53981181+emidiovaleretto@users.noreply.github.com> Date: Thu, 28 Oct 2021 23:59:53 +0100 Subject: [PATCH] Initial commit --- .gitignore | 8 ++ .gitpod.dockerfile | 74 +++++++++++++++++ .gitpod.yml | 13 +++ .vscode/client.cnf | 10 +++ .vscode/font_fix.py | 22 +++++ .vscode/heroku_config.sh | 26 ++++++ .vscode/init_tasks.sh | 26 ++++++ .vscode/launch.json | 14 ++++ .vscode/mysql.cnf | 25 ++++++ .vscode/settings.json | 26 ++++++ .vscode/start_mysql.sh | 17 ++++ .vscode/uptime.sh | 23 ++++++ Procfile | 1 + README.md | 31 +++++++ controllers/default.js | 60 ++++++++++++++ index.js | 30 +++++++ package.json | 23 ++++++ requirements.txt | 1 + run.py | 3 + views/index.html | 27 ++++++ views/layout.html | 173 +++++++++++++++++++++++++++++++++++++++ 21 files changed, 633 insertions(+) create mode 100644 .gitignore create mode 100644 .gitpod.dockerfile create mode 100644 .gitpod.yml create mode 100644 .vscode/client.cnf create mode 100644 .vscode/font_fix.py create mode 100644 .vscode/heroku_config.sh create mode 100644 .vscode/init_tasks.sh create mode 100644 .vscode/launch.json create mode 100644 .vscode/mysql.cnf create mode 100644 .vscode/settings.json create mode 100644 .vscode/start_mysql.sh create mode 100644 .vscode/uptime.sh create mode 100644 Procfile create mode 100644 README.md create mode 100644 controllers/default.js create mode 100644 index.js create mode 100644 package.json create mode 100644 requirements.txt create mode 100644 run.py create mode 100644 views/index.html create mode 100644 views/layout.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f7c47fb --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +core.Microsoft* +core.mongo* +core.python* +env.py +__pycache__/ +*.py[cod] +node_modules/ +.github/ diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile new file mode 100644 index 0000000..f30115f --- /dev/null +++ b/.gitpod.dockerfile @@ -0,0 +1,74 @@ +FROM gitpod/workspace-full + +# Setup Heroku CLI +RUN curl https://cli-assets.heroku.com/install.sh | sh + +# Setup Python linters + +RUN pip3 install flake8 flake8-flask flake8-django + +# Setup MongoDB and MySQL +RUN sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 20691eec35216c63caf66ce1656408e390cfb1f5 && \ + sudo sh -c 'echo "deb http://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-4.4.list' && \ + sudo apt-get update -y && \ + sudo touch /etc/init.d/mongod && \ + sudo apt-get install -y mongodb-org-shell && \ + sudo apt-get install -y links && \ + sudo apt-get install -y mysql-server && \ + sudo apt-get clean -y && \ + sudo rm -rf /var/cache/apt/* /var/lib/apt/lists/* /tmp/* && \ + sudo mkdir /var/run/mysqld && \ + sudo chown -R gitpod:gitpod /etc/mysql /var/run/mysqld /var/log/mysql /var/lib/mysql /var/lib/mysql-files /var/lib/mysql-keyring /var/lib/mysql-upgrade /home/gitpod/.cache/heroku/ + +# Setup PostgreSQL + +RUN sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list' && \ + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8 && \ + sudo apt-get update -y && \ + sudo apt-get install -y postgresql-12 + +ENV PGDATA="/workspace/.pgsql/data" + +RUN mkdir -p ~/.pg_ctl/bin ~/.pg_ctl/sockets \ + && echo '#!/bin/bash\n[ ! -d $PGDATA ] && mkdir -p $PGDATA && initdb --auth=trust -D $PGDATA\npg_ctl -D $PGDATA -l ~/.pg_ctl/log -o "-k ~/.pg_ctl/sockets" start\n' > ~/.pg_ctl/bin/pg_start \ + && echo '#!/bin/bash\npg_ctl -D $PGDATA -l ~/.pg_ctl/log -o "-k ~/.pg_ctl/sockets" stop\n' > ~/.pg_ctl/bin/pg_stop \ + && chmod +x ~/.pg_ctl/bin/* + +# ENV DATABASE_URL="postgresql://gitpod@localhost" +ENV PGHOSTADDR="127.0.0.1" +ENV PGDATABASE="postgres" + +# Upgrade Node + +ENV NODE_VERSION=14.15.4 +RUN bash -c ". .nvm/nvm.sh && \ + nvm install ${NODE_VERSION} && \ + nvm alias default ${NODE_VERSION} && \ + npm install -g yarn" + +ENV PATH="/usr/lib/postgresql/12/bin:/home/gitpod/.nvm/versions/node/v${NODE_VERSION}/bin:$HOME/.pg_ctl/bin:$PATH" + +# Create our own config files + +COPY .vscode/mysql.cnf /etc/mysql/mysql.conf.d/mysqld.cnf + +COPY .vscode/client.cnf /etc/mysql/mysql.conf.d/client.cnf + +COPY .vscode/start_mysql.sh /etc/mysql/mysql-bashrc-launch.sh + +# Start MySQL when we log in +# Add aliases + +RUN echo 'alias run="python3 $GITPOD_REPO_ROOT/manage.py runserver 0.0.0.0:8000"' >> ~/.bashrc && \ + echo 'alias heroku_config=". $GITPOD_REPO_ROOT/.vscode/heroku_config.sh"' >> ~/.bashrc && \ + echo 'alias python=python3' >> ~/.bashrc && \ + echo 'alias pip=pip3' >> ~/.bashrc && \ + echo 'alias font_fix="python3 $GITPOD_REPO_ROOT/.vscode/font_fix.py"' >> ~/.bashrc && \ + echo ". /etc/mysql/mysql-bashrc-launch.sh" >> ~/.bashrc + +# Local environment variables +# C9USER is temporary to allow the MySQL Gist to run +ENV C9_USER="root" +ENV PORT="8080" +ENV IP="0.0.0.0" +ENV C9_HOSTNAME="localhost" diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..7632030 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,13 @@ +image: + file: .gitpod.dockerfile +tasks: + - init: . ${GITPOD_REPO_ROOT}/.vscode/init_tasks.sh + command: /home/gitpod/.pg_ctl/bin/pg_start > /dev/null + - command: . ${GITPOD_REPO_ROOT}/.vscode/uptime.sh & +vscode: + extensions: + - ms-python.python + - formulahendry.auto-close-tag + - eventyret.bootstrap-4-cdn-snippet + - hookyqr.beautify + - matt-rudge.auto-open-preview-panel diff --git a/.vscode/client.cnf b/.vscode/client.cnf new file mode 100644 index 0000000..12dcd7a --- /dev/null +++ b/.vscode/client.cnf @@ -0,0 +1,10 @@ +[client] +host = localhost +user = root +password = +socket = /var/run/mysqld/mysqld.sock +[mysql_upgrade] +host = localhost +user = root +password = +socket = /var/run/mysqld/mysqld.sock diff --git a/.vscode/font_fix.py b/.vscode/font_fix.py new file mode 100644 index 0000000..81e8816 --- /dev/null +++ b/.vscode/font_fix.py @@ -0,0 +1,22 @@ +# Fixes the font issue on Brave browser +# Matt Rudge +# August 2021 + +import json +import os + +BASE_PATH = os.environ.get("GITPOD_REPO_ROOT") + +with open(f"{BASE_PATH}/.vscode/settings.json", "r+") as f: + content = json.loads(f.read()) + + if "terminal.integrated.fontFamily" not in content: + print("Adding wider and higher font settings") + content["terminal.integrated.lineHeight"] = 1.2 + content["terminal.integrated.letterSpacing"] = 2 + else: + print("Wider and higher font settings already added!") + + f.seek(0, os.SEEK_SET) + f.write(json.dumps(content)) + f.truncate() diff --git a/.vscode/heroku_config.sh b/.vscode/heroku_config.sh new file mode 100644 index 0000000..f842c96 --- /dev/null +++ b/.vscode/heroku_config.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Script to allow Heroku API key to be pasted +# exported as an environment variable +# +# Matt Rudge, May 2021 + +echo Heroku authentication configuration script +echo Code Institute, 2021 +echo +echo Get your Heroku API key by going to https://dashboard.heroku.com +echo Go to Account Settings and click on Reveal to view your Heroku API key +echo + +if [[ -z "${HEROKU_API_KEY}" ]]; then + echo Paste your Heroku API key here or press Enter to quit: + read apikey + if [[ -z "${apikey}" ]]; then + return 0 + fi + echo export HEROKU_API_KEY=${apikey} >> ~/.bashrc + echo Added the export. Refreshing the terminal. + . ~/.bashrc > /dev/null + echo Done! +else + echo API key is already set. Exiting +fi diff --git a/.vscode/init_tasks.sh b/.vscode/init_tasks.sh new file mode 100644 index 0000000..933bf6b --- /dev/null +++ b/.vscode/init_tasks.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Creates a user record for the current Cloud9 user +# Gives a personalised greeting +# Adds configuration options for SQLite +# Creates run aliases +# Author: Matt Rudge + +echo "Setting the greeting" +sed -i "s/USER_NAME/$GITPOD_GIT_USER_NAME/g" ${GITPOD_REPO_ROOT}/README.md +echo "Creating the gitpod user in MySQL" +RESULT="$(mysql -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'gitpod')")" +if [ "$RESULT" = 1 ]; then + echo "gitpod already exists" +else + mysql -e "CREATE USER 'gitpod'@'%' IDENTIFIED BY '';" -u root + echo "Granting privileges" + mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'gitpod'@'%' WITH GRANT OPTION;" -u root +fi +echo "Creating .sqliterc file" +echo ".headers on" > ~/.sqliterc +echo ".mode column" >> ~/.sqliterc +echo "Your workspace is ready to use. Happy coding!" + +# Open README.md file +code README.md diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..d9e387c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Current File (Integrated Terminal)", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "internalConsole" + } + ] +} diff --git a/.vscode/mysql.cnf b/.vscode/mysql.cnf new file mode 100644 index 0000000..1fd3264 --- /dev/null +++ b/.vscode/mysql.cnf @@ -0,0 +1,25 @@ +[mysqld_safe] +socket = /var/run/mysqld/mysqld.sock +nice = 0 + +[mysqld] +user = gitpod +pid-file = /var/run/mysqld/mysqld.pid +socket = /var/run/mysqld/mysqld.sock +port = 3306 +basedir = /usr +datadir = /workspace/mysql +tmpdir = /tmp +lc-messages-dir = /usr/share/mysql +skip-external-locking + +key_buffer_size = 16M +max_allowed_packet = 16M +thread_stack = 192K +thread_cache_size = 8 + +myisam-recover-options = BACKUP + +general_log_file = /var/log/mysql/mysql.log +general_log = 1 +log_error = /var/log/mysql/error.log diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..890f2f9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,26 @@ +{ + "python.linting.pylintEnabled": true, + "python.linting.enabled": true, + "python.linting.pycodestyleEnabled": false, + "python.linting.flake8Enabled": true, + "python.terminal.activateEnvironment": false, + "python.formatting.autopep8Path": "/home/gitpod/.pyenv/shims/autopep8", + "python.linting.flake8Path": "/home/gitpod/.pyenv/shims/flake8", + "cornflakes.linter.executablePath": "/home/gitpod/.pyenv/shims/flake8", + "files.exclude": { + "**/.DS_Store": true, + "**/.git": true, + "**/.github": true, + "**/.gitp*": true, + "**/.hg": true, + "**/.svn": true, + "**/.vscode": true, + "**/core.Microsoft*": true, + "**/core.mongo*": true, + "**/core.python*": true, + "**/CVS": true + }, + "files.autoSave": "off", + "workbench.colorTheme": "Visual Studio Dark", + "editor.defaultFormatter": "HookyQR.beautify" +} diff --git a/.vscode/start_mysql.sh b/.vscode/start_mysql.sh new file mode 100644 index 0000000..1872562 --- /dev/null +++ b/.vscode/start_mysql.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# this script is intended to be called from .bashrc +# This is a workaround for not having something like supervisord + +if [ ! -e /var/run/mysqld/gitpod-init.lock ] +then + touch /var/run/mysqld/gitpod-init.lock + + # initialize database structures on disk, if needed + [ ! -d /workspace/mysql ] && mysqld --initialize-insecure + + # launch database, if not running + [ ! -e /var/run/mysqld/mysqld.pid ] && mysqld --daemonize + + rm /var/run/mysqld/gitpod-init.lock +fi diff --git a/.vscode/uptime.sh b/.vscode/uptime.sh new file mode 100644 index 0000000..25a37f8 --- /dev/null +++ b/.vscode/uptime.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Pings the webhook so that we can gather +# basic usage stats. No personally identifiable +# data is captured here, and it is impossible to +# identify an individual user from the captured data. +# Matt Rudge, April 2021 + +UUID=$(cat /proc/sys/kernel/random/uuid) +URL=https://1xthkmzwg3.execute-api.eu-west-1.amazonaws.com/prod/lrsapi/ +API_KEY=jceBCdeGZP9RDeUNCfM4jIQ39Cx0jtG51QgcwDwc +VERB="started" + +clear + +while true; do + + DATA="{\"activity_time\":\"$(date +%Y-%m-%dT%H:%M:%S).000Z\",\"actor\":\"${UUID}\",\"verb\":\"${VERB}\",\"activity_object\":\"Gitpod Workspace\",\"extra_data\":\"{}\"}" + curl -s -X POST -H "x-api-key: ${API_KEY}" -d "${DATA}" ${URL} 1> /dev/null + VERB="running" + sleep 300 + +done diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..5ec9cc2 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: node index.js \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fb3339e --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +![CI logo](https://codeinstitute.s3.amazonaws.com/fullstack/ci_logo_small.png) + +Welcome USER_NAME, + +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: **August 17, 2021** + +## Reminders + +* Your code must be placed in the `run.py` file +* Your dependencies must be placed in the `requirements.txt` file +* Do not edit any of the other files or your code may not deploy properly + +## Creating the Heroku app + +When you create the app, you will need to add two buildpacks from the _Settings_ tab. The ordering is as follows: + +1. `heroku/python` +2. `heroku/nodejs` + +You must then create a _Config Var_ called `PORT`. Set this to `8000` + +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. + +Connect your GitHub repository and deploy as normal. + +## Constraints + +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. + +----- +Happy coding! \ No newline at end of file diff --git a/controllers/default.js b/controllers/default.js new file mode 100644 index 0000000..96ffdd4 --- /dev/null +++ b/controllers/default.js @@ -0,0 +1,60 @@ +const Pty = require('node-pty'); +const fs = require('fs'); + +exports.install = function () { + + ROUTE('/'); + WEBSOCKET('/', socket, ['raw']); + +}; + +function socket() { + + this.encodedecode = false; + this.autodestroy(); + + this.on('open', function (client) { + + // Spawn terminal + client.tty = Pty.spawn('python3', ['run.py'], { + name: 'xterm-color', + cols: 80, + rows: 24, + cwd: process.env.PWD, + env: process.env + }); + + client.tty.on('exit', function (code, signal) { + client.tty = null; + client.close(); + console.log("Process killed"); + }); + + client.tty.on('data', function (data) { + client.send(data); + }); + + }); + + this.on('close', function (client) { + if (client.tty) { + client.tty.kill(9); + client.tty = null; + console.log("Process killed and terminal unloaded"); + } + }); + + this.on('message', function (client, msg) { + client.tty && client.tty.write(msg); + }); +} + +if (process.env.CREDS != null) { + console.log("Creating creds.json file."); + fs.writeFile('creds.json', process.env.CREDS, 'utf8', function (err) { + if (err) { + console.log('Error writing file: ', err); + socket.emit("console_output", "Error saving credentials: " + err); + } + }); +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..2598955 --- /dev/null +++ b/index.js @@ -0,0 +1,30 @@ +// =================================================== +// Total.js start script +// https://www.totaljs.com +// =================================================== + +const options = {}; + +// options.ip = '127.0.0.1'; +options.port = parseInt(process.env.PORT); +// options.unixsocket = require('path').join(require('os').tmpdir(), 'app_name'); +// options.config = { name: 'Total.js' }; +// options.sleep = 3000; +// options.inspector = 9229; +// options.watch = ['private']; +// options.livereload = 'https://yourhostname'; + +// Enables cluster: +// options.cluster = 'auto'; +// options.cluster_limit = 10; // max 10. threads (works only with "auto" scaling) + +// Enables threads: +// options.cluster = 'auto'; +// options.cluster_limit = 10; // max 10. threads (works only with "auto" scaling) +// options.timeout = 5000; +// options.threads = '/api/'; +// options.logs = 'isolated'; + +var type = process.argv.indexOf('--release', 1) !== -1 || process.argv.indexOf('release', 1) !== -1 ? 'release' : 'debug'; +// require('total4/' + type)(options); +require('total4').http('release', options); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..56ca191 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "terminal", + "version": "1.0.0", + "main": "server.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/lechien73/terminal.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/lechien73/terminal/issues" + }, + "homepage": "https://github.com/lechien73/terminal#readme", + "dependencies": { + "node-static": "^0.7.11", + "node-pty": "^0.10.1", + "total4": "^0.0.45" + } +} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8596436 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +# Your requirements go here \ No newline at end of file diff --git a/run.py b/run.py new file mode 100644 index 0000000..72b2970 --- /dev/null +++ b/run.py @@ -0,0 +1,3 @@ +# Your code goes here. +# You can delete these comments, but do not change the name of this file +# Write your code to expect a terminal of 80 characters wide and 24 rows high diff --git a/views/index.html b/views/index.html new file mode 100644 index 0000000..6e6c1ac --- /dev/null +++ b/views/index.html @@ -0,0 +1,27 @@ + + +
+ + + \ No newline at end of file diff --git a/views/layout.html b/views/layout.html new file mode 100644 index 0000000..aaec1c9 --- /dev/null +++ b/views/layout.html @@ -0,0 +1,173 @@ + + + + + + + + + + + Python Terminal by Code Institute + + + +@{body} + + \ No newline at end of file