diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..d98d252d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,6 @@ +{ + "name": "PythonBuddy", + "image": "mcr.microsoft.com/vscode/devcontainers/python:3.7", + "features": { + } +} diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..3a3efaa2 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: ethanchewy diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..dd84ea78 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..bbcbbe7d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index 5639973b..b390b4ba 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -9,7 +9,7 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Set up Python 3.7 + - name: Test requirements uses: actions/setup-python@v1 with: python-version: 3.7 @@ -17,14 +17,3 @@ jobs: run: | python -m pip install --upgrade pip pip install -r requirements.txt - - name: Lint with flake8 - run: | - pip install flake8 - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest - run: | - pip install pytest - pytest diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index fa4d8cb0..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: python -python: - - "3.6" -# command to install dependencies -install: - - "pip install -r requirements.txt" - - pip install coverage - - pip install coveralls -# command to run tests -script: - - pytest - - coverage run --source=PythonBuddy -m unittest tests/test_linter.py - - coverage report -m - - coveralls diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..185d3072 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at 17chiue@gmail.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/LICENSE.md b/LICENSE.md index 0017cc46..164c8c89 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2019, Ethan Chiu. All rights reserved. +Copyright (c) 2022, Ethan Chiu. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/PythonBuddy/app.py b/PythonBuddy/app.py index 5ab0f7c2..430d4655 100644 --- a/PythonBuddy/app.py +++ b/PythonBuddy/app.py @@ -71,8 +71,6 @@ def check_code(): return jsonify(output) # Run python in secure system - - @app.route('/run_code', methods=['POST']) def run_code(): """Run python 3 code @@ -87,6 +85,9 @@ def run_code(): session["time_now"] = datetime.now() output = None + if not "file_name" in session: + with tempfile.NamedTemporaryFile(delete=False) as temp: + session["file_name"] = temp.name cmd = 'python ' + session["file_name"] p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) @@ -120,13 +121,12 @@ def evaluate_pylint(text): """ # Open temp file for specific session. # IF it doesn't exist (aka the key doesn't exist), create one - try: - session["file_name"] + if "file_name" in session: f = open(session["file_name"], "w") for t in text: f.write(t) f.flush() - except KeyError as e: + else: with tempfile.NamedTemporaryFile(delete=False) as temp: session["file_name"] = temp.name for t in text: diff --git a/PythonBuddy/static/js/cm-validator-remote.js b/PythonBuddy/static/js/cm-validator-remote.js index c1c1b680..f491774e 100644 --- a/PythonBuddy/static/js/cm-validator-remote.js +++ b/PythonBuddy/static/js/cm-validator-remote.js @@ -17,7 +17,7 @@ CodeMirror.remoteValidator = function(cm, updateLinting, options) { { var error = error_list[i]; - // Null check to make sure eror message is not empty + // Null check to make sure error message is not empty if (error.line_no != null && error.message != null && error.severity != null) { var start_line = error.line_no; diff --git a/README.md b/README.md index c90d655e..8f9365d8 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,33 @@ # PythonBuddy 🖊️ 🐍 -[![Travis branch](https://img.shields.io/travis/rust-lang/rust/master.svg)](https://travis-ci.org/ethanchewy/OnlinePythonLinterSyntaxChecker) -[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](http://paypal.me/Ethan302)
-Online Python 3.6 Programming with Live Pylint Syntax Checking! -
- - Demo: http://pythonbuddy.com - +Online Python 3 Programming with Live Pylint Syntax Checking!
+ ![](gifs/demo.gif) ### Usage + +**GitHub Codespaces** + +The quickest way to use PythonBuddy is to launch your own GitHub Codespace! + +1) From the GitHub repo, click the green "Code" button and select "Codespaces". +2) Create a new Codespace or select a previous one you've already created. +3) Navigate to the new tab created for your Codespace. +4) In terminal, run `bash ./setup.sh` +5) Click "Open in Browser" in the bottom right corner after the setup is complete. + * The website may take a while to load or error at first while GitHub sets up the preview environment. In this case, reload the website. +6) Remember to **stop your workspace** after you're done using it. + +**Local Use** + +Due to Codespace's monthly limits, it's recommended to run PythonBuddy locally if used often. + 1) Fetch from repo: ``` git clone https://github.com/ethanchewy/PythonBuddy.git ``` -2) Change to directory +2) Change to PythonBuddy directory ``` cd PythonBuddy ``` @@ -23,23 +35,29 @@ Online Python 3.6 Programming with Live Pylint Syntax Checking! ``` python3 -m venv venv ``` -3) Activate vitrual environment: +3) Activate virtual environment: ``` source venv/bin/activate ``` -4) Pipe requirements to venv folder: +4) Enusre that your virtualenv uses Python 3.7.6 via this command: ``` - pip install -r requirements.txt + python --version ``` -5) Set FLASK_APP variable: + If you don't use Python Python 3.7.6, some Python libraries that PythonBuddy relies on **may not work**. Please refer to this documentation for figuring out how to create a specific version of Python via virtualenv via this StackOverflow [post](https://stackoverflow.com/a/39713544). + +5) Pipe requirements to venv folder: ``` - export FLASK_APP=app.py + pip install -r requirements.txt ``` -6) Change to app folder +6) Change to the PythonBuddy application folder. You should now be in `PythonBuddy/PythonBuddy/`. ``` cd PythonBuddy ``` -7) Run flask app: +7) Set FLASK_APP variable: + ``` + export FLASK_APP=app.py + ``` +8) Run flask app: ``` flask run ``` @@ -110,7 +128,7 @@ pytest --cov-report html --cov=PythonBuddy tests/ ### FAQ: Why did you make this?
-In 2014, I was a Community TA at MIT edX 6.00.1x course where I helped teach over 1000 students. The year after I started researching under Prof. Eni Mustafaraj. She had a data set from that course and we saw a high attrition rate of students within the first 2 weeks. After digging through the curriculumn and data, I realized that the students left because of difficulties setting up their Python environment and complex error messages that they couldn't solve when running their code (ex: some students had path issues). +In 2014, I was a Community TA at MIT edX 6.00.1x course where I helped teach over 1000 students. The year after I started researching under Prof. Eni Mustafaraj. She had a data set from that course and we saw a high attrition rate of students within the first 2 weeks. After digging through the curriculum and data, I realized that the students left because of difficulties setting up their Python environment and complex error messages that they couldn't solve when running their code (ex: some students had path issues).
So, I created PythonBuddy to address this issue so that students wouldn't have to go through the frustrations of setting up a Python environment and running into seemingly "random" bugs. PythonBuddy allows users to jump right into Python programming with the support of live syntax checking & highlighting. Also, professors and teachers could easily set up a server and allow students to quickly test out their code with PythonBuddy online. @@ -137,37 +155,10 @@ Regular: https://github.com/ethanchewy/OnlinePythonLinterSyntaxChecker/wiki Sandboxed: https://github.com/ethanchewy/PythonBuddy/wiki/Running-Sandboxed-PythonBuddy ### Press: -Featured on Python Weekly, CSS Author, and the Talk Python Podcast +Featured on FlaskCon 2020, Python Weekly, CSS Author, and the Talk Python Podcast ### Credits: This was made by Ethan Chiu as a research project under the guidance of Wellesley College professor Eni Mustafaraj. -### Donations: -Github Sponsors: https://github.com/sponsors/ethanchewy -Github will match all donations for the first year! -
-Direct PayPal: [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](http://paypal.me/Ethan302) - -I started working on this in 2016 after seeing no one had addressed the issue of reducing the high attrition rate of beginning Python programmers due to the difficulties of setting up their programming environment. - -So, ever since then, I've always been trying to improve PythonBuddy such as security and scalabitliy. Thus, I have dedicated as much as my free time into this project. - -Since 2016, it's cost more than $250 per year to run and deploy the demo site excluding development costs. - -Before college, I've been able to save money from various jobs. Now that I am in college, I have to pay a hefty tuition, housing, food, etc so it's much harder to sustain PythonBuddy even with a part-time job. - -My goal is to keep the demo site PythonBuddy running since more than 4,000 users use it daily. All donations will go towards PythonBuddy and any excess will be used to increase the specs of the PythonBuddy demo server. - -Any donation would be greatly appreciated. - - No donation is too small. A dollar goes a long way :) - -### Sponsorships: - - - - - - - -If you are interested in sponsoring this project and getting you or your company featured in the README or demo site, feel free to contact me at 17chiue@gmail.com. PythonBuddy gets over 4000 visits every day. +### Other: +As of October 2020, PythonBuddy.com will no longer be a demo server for this open-source project due to the increasing costs of hosting it for 80,000+ people monthly. Instead, this URL will redirect back to this GitHub repo. diff --git a/requirements.txt b/requirements.txt index 4e5ed667..47a4ae7a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,24 +1,21 @@ -astroid==2.0.4 -click==6.7 -dnspython==1.15.0 -eventlet==0.24.1 -Flask==1.0.2 -Flask-SocketIO==3.0.2 -greenlet==0.4.15 -isort==4.3.4 -itsdangerous==0.24 -Jinja2==2.10.1 -lazy-object-proxy==1.3.1 -MarkupSafe==1.0 +astroid==2.4.2 +click==7.1.2 +dnspython==1.16.0 +eventlet==0.31.0 +Flask==1.1.2 +Flask-SocketIO==4.3.1 +greenlet==0.4.17 +isort==5.6.4 +itsdangerous==1.1.0 +Jinja2==2.11.3 +lazy-object-proxy==1.4.3 +MarkupSafe==1.1.1 mccabe==0.6.1 -monotonic==1.5 -pylint==2.1.1 -python-engineio==3.8.2.post1 -python-socketio==2.0.0 -six==1.11.0 -typed-ast==1.1.0 -Werkzeug==0.15.3 -wrapt==1.10.11 -pytest==5.2.1 -pytest-cov==2.8.1 -pytest-html==2.0.0 +pylint==2.6.0 +python-engineio==3.13.2 +python-socketio==4.6.0 +six==1.15.0 +toml==0.10.1 +typed-ast==1.4.1 +Werkzeug==1.0.1 +wrapt==1.12.1 diff --git a/setup.sh b/setup.sh new file mode 100644 index 00000000..1a98ed3b --- /dev/null +++ b/setup.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +FLASK_APP=app.py + +pip install -r requirements.txt + +cd PythonBuddy +flask run \ No newline at end of file