├── home ├── README.md └── midiplayer.py ├── addons ├── text │ ├── requirements2.txt │ ├── help.txt │ ├── port_names.txt │ └── cats.txt ├── tkinter-calc.py ├── panno.py └── Notepad.py ├── .vscode └── settings.json ├── config.ini ├── python ├── soundfonts.py ├── setup.py ├── registry.py ├── file.py ├── fileloop.py ├── loginscreen.py ├── shell.py ├── towii.py ├── main.py ├── bluescreen.py ├── time.py └── PythonicOS.py ├── README.md ├── .github └── workflows │ ├── python-app.yml │ └── snyk-security.yml ├── whatshappened.md ├── controbuting.md ├── requirements.txt └── LICENSE /home/README.md: -------------------------------------------------------------------------------- 1 | # turbo-potato 2 | test builds 3 | -------------------------------------------------------------------------------- /addons/text/requirements2.txt: -------------------------------------------------------------------------------- 1 | main.py == sf.py, PythonicOS -------------------------------------------------------------------------------- /addons/text/help.txt: -------------------------------------------------------------------------------- 1 | welcome to the help section of PythonicOS -------------------------------------------------------------------------------- /addons/text/port_names.txt: -------------------------------------------------------------------------------- 1 | pydata1 2 | pydata2 3 | pydata3 4 | pydata4 5 | pydata5 6 | pydata6 -------------------------------------------------------------------------------- /addons/text/cats.txt: -------------------------------------------------------------------------------- 1 | i like dumb catz 2 | they are fun 3 | 4 | because if they wernt dumb then we would throw them out the window 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.testing.pytestArgs": [ 3 | "python" 4 | ], 5 | "python.testing.unittestEnabled": false, 6 | "python.testing.pytestEnabled": true 7 | } -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | [Section1] 2 | option1 = Value1 3 | option2 = Value2 4 | 5 | [Section2] 6 | option3 = Value3 7 | option4 = Value4 8 | 9 | # If you want a good way to configure, use .conf, yaml, json or toml. Thx -h4rl -------------------------------------------------------------------------------- /python/soundfonts.py: -------------------------------------------------------------------------------- 1 | import playsound 2 | from playsound import playsound 3 | def start(): 4 | playsound('start1.mp3') 5 | def warning(): 6 | playsound('warning.mp3') 7 | def stop(): 8 | playsound('stop.mp3') 9 | def fearofdark1(): 10 | playsound('mp3/fearofdark1.mp3') 11 | 12 | # like huh? isn't playsound broken? -------------------------------------------------------------------------------- /python/setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | DIRS = [ 4 | 'home', 5 | 'bin', 6 | 'scripts', 7 | 'addons', 8 | 'documents', 9 | 'home/user', 10 | 'home/user/documents', 11 | 'home/user/documents/projects', 12 | 'system', 13 | 'system/scripts', 14 | 'system/logs' 15 | 'mount' 16 | ] 17 | # Why are there different files that create directories? 18 | def main(): 19 | for i in DIRS: 20 | if not os.path.exists(i): 21 | os.makedirs(i) 22 | -------------------------------------------------------------------------------- /python/registry.py: -------------------------------------------------------------------------------- 1 | import configparser 2 | 3 | config = configparser.ConfigParser() 4 | 5 | config.add_section('Section1') 6 | config.set('Section1', 'Option1', 'Value1') 7 | config.set('Section1', 'Option2', 'Value2') 8 | 9 | config.add_section('Section2') 10 | config.set('Section2', 'Option3', 'Value3') 11 | config.set('Section2', 'Option4', 'Value4') 12 | 13 | # INI is not really recommended for configuration 14 | with open('config.ini', 'w') as configfile: 15 | config.write(configfile) 16 | print('File created') -------------------------------------------------------------------------------- /python/file.py: -------------------------------------------------------------------------------- 1 | import os 2 | config_file = os.path.join(os.path.dirname(__file__), 'config.ini') 3 | usrpass = os.path.join(os.path.dirname(__file__), 'pass.ini') 4 | config_login = os.path.join(os.path.dirname(__file__), 'config_login.ini') 5 | home_dir = os.path.join(os.path.dirname(__file__), 'home') 6 | pythonOS = os.path.join(os.path.dirname(__file__), 'home') 7 | 8 | # You should really structure this better and using python for this type of project isn't wise 9 | 10 | panno = 'addons/panno.py' 11 | pyle = 'addons/pyle.py' 12 | addons = 'addons' 13 | shell = 'PythonOS/shell.py' 14 | 15 | -------------------------------------------------------------------------------- /python/fileloop.py: -------------------------------------------------------------------------------- 1 | import curses 2 | # ?? 3 | def draw_desktop(stdscr): 4 | stdscr.clear() 5 | stdscr.addstr(0, 0, "Desktop") 6 | stdscr.addstr(2, 1, "[File1] Document.txt") 7 | stdscr.addstr(3, 1, "[File2] Picture.jpg") 8 | stdscr.addstr(4, 1, "[File3] Music.mp3") 9 | stdscr.addstr(5, 1, "[File4] Video.mp4") 10 | stdscr.addstr(7, 0, "Press 'q' to quit.") 11 | 12 | stdscr.refresh() 13 | 14 | def main(): 15 | stdscr = curses.initscr() 16 | curses.noecho() 17 | curses.cbreak() 18 | 19 | try: 20 | draw_desktop(stdscr) 21 | while True: 22 | key = stdscr.getch() 23 | if key == ord('q'): 24 | break 25 | 26 | finally: 27 | curses.echo() 28 | curses.nocbreak() 29 | curses.endwin() 30 | 31 | if __name__ == '__main__': 32 | main() 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PythonicOS 2 | 3 | # this repo has been left to die for sad reasons. 4 | ## there is a new one that actualy tries to work and be something. 5 | 6 | PythonicOS is a Open Source Desktop/Display manager for linux 7 | # Contributing 8 | 9 | We welcome contributions from the community to enhance PythonicOS. To contribute, please follow these steps: 10 | 11 | Fork the PythonicOS repository. 12 | 13 | Create a new branch for your feature or bug fix: 14 | 15 | git checkout -b feature/your-feature-name 16 | 17 | Make the necessary changes and commit them: 18 | 19 | git commit -m "Add your commit message here" 20 | 21 | Push your changes to your forked repository: 22 | 23 | git push origin feature/your-feature-name 24 | 25 | Open a pull request in the original PythonicOS repository, describing your changes and their purpose. 26 | ------------------------------------------------------------------------------------------------------ 27 | License 28 | PythonicOS is released under the Apache 2.0License. 29 | 30 | Contact 31 | For any questions, suggestions, or feedback, please reach out to us at our discord, 32 | -------------------------------------------------------------------------------- /home/midiplayer.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | # Won't this show the annoying pygame prompt though? 3 | def play_music(music_file): 4 | """ 5 | stream music with mixer.music module in blocking manner 6 | this will stream the sound from disk while playing 7 | """ 8 | clock = pygame.time.Clock() 9 | try: 10 | pygame.mixer.music.load(music_file) 11 | print ("Music file %s loaded!" % music_file) 12 | except pygame.error: 13 | print ("File %s not found! (%s)" % (music_file, pygame.get_error())) 14 | return 15 | pygame.mixer.music.play() 16 | while pygame.mixer.music.get_busy(): 17 | # check if playback has finished 18 | clock.tick(30) 19 | # pick a midi music file you have ... 20 | # (if not in working folder use full path) 21 | 22 | midi_file = 'home/town.mid' 23 | freq = 44100 # audio CD quality 24 | bitsize = -16 # unsigned 16 bit 25 | channels = 2 # 1 is mono, 2 is stereo 26 | buffer = 1024 # number of samples 27 | pygame.mixer.init(freq, bitsize, channels, buffer) 28 | 29 | # optional volume 0 to 1.0 30 | pygame.mixer.music.set_volume(0.8) 31 | try: 32 | play_music(midi_file) 33 | except KeyboardInterrupt: 34 | # if user hits Ctrl/C then exit 35 | # (works only in console mode) 36 | pygame.mixer.music.fadeout(1000) 37 | pygame.mixer.music.stop() 38 | raise SystemExit 39 | -------------------------------------------------------------------------------- /.github/workflows/python-app.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a single version of Python 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python 3 | 4 | name: Python application 5 | 6 | on: 7 | push: 8 | branches: [ "main" ] 9 | pull_request: 10 | branches: [ "main" ] 11 | 12 | permissions: 13 | contents: read 14 | 15 | jobs: 16 | build: 17 | 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | - name: Set up Python 3.10 23 | uses: actions/setup-python@v3 24 | with: 25 | python-version: "3.10" 26 | - name: Install dependencies 27 | run: | 28 | python -m pip install --upgrade pip 29 | pip install flake8 pytest 30 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 31 | - name: Lint with flake8 32 | run: | 33 | # stop the build if there are Python syntax errors or undefined names 34 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 35 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 36 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 37 | - name: Test with pytest 38 | run: | 39 | pytest 40 | -------------------------------------------------------------------------------- /python/loginscreen.py: -------------------------------------------------------------------------------- 1 | # loginscreen.py 2 | # seems unsafe - h4rl 3 | import subprocess 4 | import tkinter as tk 5 | import configparser 6 | import os 7 | import argparse 8 | import configparser 9 | from file import usrpass,config_login,shell 10 | root = tk.Tk() 11 | 12 | config = configparser.ConfigParser() 13 | config.read(config_login) 14 | 15 | def login(): 16 | username = username_entry.get() 17 | password = password_entry.get() 18 | 19 | # Read passwords from configuration file 20 | config_file = os.path.join(os.path.dirname(__file__), 'pass.ini') 21 | config = configparser.ConfigParser() 22 | config.read(config_file) 23 | 24 | # Check if entered username and password match the ones in the configuration file 25 | if username in config['login'] and config['login'][username] == password: 26 | print("Login successful!") 27 | 28 | subprocess.Popen(["python3", 'PythonOS/shell.py']) 29 | print('cat') 30 | root.destroy() # Close the login window 31 | else: 32 | print("Incorrect username or password.") 33 | 34 | 35 | # Create login form 36 | root.geometry('140x140') 37 | username_label = tk.Label(root, text='Username') 38 | username_entry = tk.Entry(root) 39 | password_label = tk.Label(root, text='Password') 40 | password_entry = tk.Entry(root, show='*') 41 | login_button = tk.Button(root, text='Login', command=login) 42 | # Add widgets to the window 43 | username_label.pack() 44 | username_entry.pack() 45 | password_label.pack() 46 | password_entry.pack() 47 | login_button.pack() 48 | 49 | # Create root window 50 | 51 | 52 | # Call login() after the root window has been created 53 | login() 54 | 55 | # Start the event loop 56 | root.mainloop() -------------------------------------------------------------------------------- /whatshappened.md: -------------------------------------------------------------------------------- 1 | # whats happened 2 | ### Overview 3 | 4 | The repositories PythonicOS-beta and PythonicOS-DEV/DEVV has been archived due to an accidental duplication of forks and subsequent realization that branches could be used instead. As a result, both forks were archived to avoid confusion and consolidate development efforts into a single repository. 5 | Background 6 | 7 | The duplication occurred when the repository owner accidentally forked the original repository multiple times, unaware that branches within a single fork could achieve the desired functionality. Recognizing the redundancy and potential confusion caused by maintaining multiple forks, the decision was made to archive both repositories and focus efforts on the primary fork. 8 | Actions Taken 9 | 10 | The original repository was forked unintentionally, resulting in two separate copies. 11 | After realizing the duplication, it was decided to use branches within a single repository to manage different development efforts. 12 | Both forks were archived to streamline development and avoid unnecessary duplication. 13 | The primary fork is now the active repository, where further development and collaboration will take place. 14 | 15 | # Next Steps 16 | 17 | Moving forward, the primary Repo OpenStudio/PythonicOS will be the central repository for development efforts. Here's what you can do: 18 | 19 | If you have previously cloned or forked one of the archived repositories, it is recommended to update your remote URLs to point to the primary repo. 20 | Ensure you are working with the latest version of the primary fork by pulling the latest changes. 21 | If you were contributing to one of the archived forks, please redirect your efforts to the primary fork and submit any future pull requests there. 22 | Be mindful of the branching structure within the primary repository to organize and manage different features or development streams. 23 | 24 | Contact 25 | 26 | If you have any questions or concerns regarding the repository status or the archiving process, please feel free to reach out to the repository owner via the available communication channels. 27 | 28 | We apologize for any confusion caused by the accidental duplication of forks, and appreciate your understanding as we consolidate our development efforts into a single repository. 29 | -------------------------------------------------------------------------------- /addons/tkinter-calc.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | #-----------------------------------------# 3 | # 4 | # 5 | # Who made this? - H4rl 6 | # 7 | # 8 | # 9 | #-----------------------------------------# 10 | 11 | 12 | 13 | 14 | calc = tk.Tk() 15 | calc.title("CrappyCalc") 16 | 17 | buttons = [ 18 | '7', '8', '9', '*', 'C', 19 | '4', '5', '6', '/', 'Neg', 20 | '1', '2', '3', '-', '$', 21 | '0', '.', '=', '+', '@' ] 22 | 23 | # set up GUI 24 | row = 1 25 | col = 0 26 | for i in buttons: 27 | button_style = 'raised' 28 | action = lambda x = i: click_event(x) 29 | tk.Button(calc, text = i, width = 7, height = 7, relief = button_style, command = action) \ 30 | .grid(row = row, column = col, sticky = 'nesw', ) 31 | col += 1 32 | if col > 4: 33 | col = 0 34 | row += 1 35 | 36 | display = tk.Entry(calc, width = 40, bg = "white") 37 | display.grid(row = 0, column = 0, columnspan = 5) 38 | 39 | def click_event(key): 40 | 41 | # = -> calculate results 42 | if key == '=': 43 | # safeguard against integer division 44 | if '/' in display.get() and '.' not in display.get(): 45 | display.insert(tk.END, ".0") 46 | 47 | # attempt to evaluate results 48 | try: 49 | result = eval(display.get()) 50 | display.insert(tk.END, " = " + str(result)) 51 | except: 52 | display.insert(tk.END, " Error, use only valid chars") 53 | 54 | # C -> clear display 55 | elif key == 'C': 56 | display.delete(0, tk.END) 57 | 58 | 59 | # $ -> clear display 60 | elif key == '$': 61 | display.delete(0, tk.END) 62 | display.insert(tk.END, "$$$$C.$R.$E.$A.$M.$$$$") 63 | 64 | 65 | # @ -> clear display 66 | elif key == '@': 67 | display.delete(0, tk.END) 68 | display.insert(tk.END, "wwwwwwwwwwwwwwwwebsite") 69 | 70 | 71 | # neg -> negate term 72 | elif key == 'neg': 73 | if '=' in display.get(): 74 | display.delete(0, tk.END) 75 | try: 76 | if display.get()[0] == '-': 77 | display.delete(0) 78 | else: 79 | display.insert(0, '-') 80 | except IndexError: 81 | pass 82 | 83 | # clear display and start new input 84 | else: 85 | if '=' in display.get(): 86 | display.delete(0, tk.END) 87 | display.insert(tk.END, key) 88 | 89 | # RUNTIME 90 | calc.mainloop() -------------------------------------------------------------------------------- /python/shell.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | import tkinter 4 | from tkinter import messagebox 5 | from towii import pydata1, pydata2 6 | 7 | 8 | def print_greetings(): 9 | ''' 10 | Print a welcome message to the user. 11 | ''' 12 | print("Thanks for using PythonicShell!") 13 | print("Version 1.0") 14 | 15 | 16 | def print_help(): 17 | print("Here are the available commands:") 18 | print("cd : Change current working directory to ") 19 | print("help: Display this help message") 20 | print("exit: Exit MyShell") 21 | 22 | 23 | def mkdir(): 24 | ''' 25 | Create a new directory in the current working directory. 26 | ''' 27 | directory_name = input("Enter the name of the directory to be created: ") 28 | path = os.path.join(os.getcwd(), directory_name) 29 | 30 | try: 31 | os.mkdir(path) 32 | print(f"Directory '{directory_name}' created successfully.") 33 | except OSError as error: 34 | print(f"Error creating directory '{directory_name}': {error}") 35 | 36 | 37 | def editfile(): 38 | # If you're just gonna use nano anyway, why even bother having this? 39 | ''' 40 | Edit a file in the current working directory. 41 | ''' 42 | filename = input("Enter the name of the file to edit: ") 43 | path = os.path.join(os.getcwd(), filename) 44 | if not os.path.exists(path): 45 | open(filename, 'w') 46 | 47 | try: 48 | subprocess.run(["nano", path]) 49 | print("Editing file:", filename) 50 | except OSError as error: 51 | print(f"Error editing file '{filename}': {error}") 52 | 53 | 54 | def senddata(): 55 | message = input("Enter the message to send: ") 56 | pydata1.send(message.encode('utf-8')) 57 | 58 | 59 | def StartOS(): 60 | subprocess.Popen('PythonicOS.exe') 61 | 62 | 63 | def my_shell(): 64 | print_greetings() 65 | 66 | while True: 67 | command = input(f"{os.getcwd()} $ ") 68 | tokens = command.split() 69 | 70 | if len(tokens) == 0: 71 | continue 72 | 73 | if tokens[0] == "cd": 74 | if len(tokens) > 1: 75 | os.chdir(tokens[1]) 76 | else: 77 | print("cd: missing operand") 78 | elif tokens[0] == "help": 79 | print_help() 80 | elif tokens[0] == "sd": 81 | senddata() 82 | elif tokens[0] == "exit": 83 | break 84 | elif tokens[0] == "help": 85 | print_greetings() 86 | elif tokens[0] == "edit": 87 | editfile() 88 | elif tokens[0] == "start": 89 | StartOS() 90 | elif tokens[0] == "time": 91 | subprocess.call(['python', 'python/time.py']) 92 | else: 93 | print(f"{tokens[0]}: command not found") 94 | 95 | 96 | if __name__ == "__main__": 97 | my_shell() 98 | input("Press Enter to exit...") 99 | -------------------------------------------------------------------------------- /.github/workflows/snyk-security.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | # A sample workflow which sets up Snyk to analyze the full Snyk platform (Snyk Open Source, Snyk Code, 7 | # Snyk Container and Snyk Infrastructure as Code) 8 | # The setup installs the Snyk CLI - for more details on the possible commands 9 | # check https://docs.snyk.io/snyk-cli/cli-reference 10 | # The results of Snyk Code are then uploaded to GitHub Security Code Scanning 11 | # 12 | # In order to use the Snyk Action you will need to have a Snyk API token. 13 | # More details in https://github.com/snyk/actions#getting-your-snyk-token 14 | # or you can signup for free at https://snyk.io/login 15 | # 16 | # For more examples, including how to limit scans to only high-severity issues 17 | # and fail PR checks, see https://github.com/snyk/actions/ 18 | 19 | name: Snyk Security 20 | 21 | on: 22 | push: 23 | branches: ["main" ] 24 | pull_request: 25 | branches: ["main"] 26 | 27 | permissions: 28 | contents: read 29 | 30 | jobs: 31 | snyk: 32 | permissions: 33 | contents: read # for actions/checkout to fetch code 34 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results 35 | actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status 36 | runs-on: ubuntu-latest 37 | steps: 38 | - uses: actions/checkout@v3 39 | - name: Set up Snyk CLI to check for security issues 40 | # Snyk can be used to break the build when it detects security issues. 41 | # In this case we want to upload the SAST issues to GitHub Code Scanning 42 | uses: snyk/actions/setup@806182742461562b67788a64410098c9d9b96adb 43 | 44 | # For Snyk Open Source you must first set up the development environment for your application's dependencies 45 | # For example for Node 46 | #- uses: actions/setup-node@v3 47 | # with: 48 | # node-version: 16 49 | 50 | env: 51 | # This is where you will need to introduce the Snyk API token created with your Snyk account 52 | SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} 53 | 54 | # Runs Snyk Code (SAST) analysis and uploads result into GitHub. 55 | # Use || true to not fail the pipeline 56 | - name: Snyk Code test 57 | run: snyk code test --sarif > snyk-code.sarif # || true 58 | 59 | # Runs Snyk Open Source (SCA) analysis and uploads result to Snyk. 60 | - name: Snyk Open Source monitor 61 | run: snyk monitor --all-projects 62 | 63 | # Runs Snyk Infrastructure as Code (IaC) analysis and uploads result to Snyk. 64 | # Use || true to not fail the pipeline. 65 | - name: Snyk IaC test and report 66 | run: snyk iac test --report # || true 67 | 68 | # Build the docker image for testing 69 | - name: Build a Docker image 70 | run: docker build -t your/image-to-test . 71 | # Runs Snyk Container (Container and SCA) analysis and uploads result to Snyk. 72 | - name: Snyk Container monitor 73 | run: snyk container monitor your/image-to-test --file=Dockerfile 74 | 75 | # Push the Snyk Code results into GitHub Code Scanning tab 76 | - name: Upload result to GitHub Code Scanning 77 | uses: github/codeql-action/upload-sarif@v2 78 | with: 79 | sarif_file: snyk-code.sarif 80 | -------------------------------------------------------------------------------- /python/towii.py: -------------------------------------------------------------------------------- 1 | import socket 2 | # welcome to that one wifi 3 | # this is the wifi driveer for PythonicOS 4 | # it is more of a wifi esc type of driver 5 | # the whole just of this file is to allow people to make sockets to connect to the main desktop 6 | # eather too ask it whats on the desktop, or the location of the home directory, if the user has clicked on a file ECT. 7 | # if you want to make your own sockets for the desktop or have a literal standard for data transfer 8 | # import socket thenn call socket.socketpair() with the names of the socket like pydata1, pydata2 = socket.socketpair() 9 | # 10 | # do note that pydata1 is the socket that is used to recive data from the desktop and should allways be left open 11 | # pydata2 is the socket that is used to send data to the desktop and should allways be left open 12 | # if you want to send data to the desktop use pydata2.send(data.encode()) 13 | # 14 | # if you want to recive data from the desktop use data = pydata2.recv(1024).decode() 15 | # you can only recive from pydata1, and only send from pydata2 16 | # 17 | # 18 | # does this even work? - h4rl 19 | # 20 | # 21 | # 22 | # 23 | # 24 | # 25 | 26 | pydata1 , pydata2 = socket.socketpair() 27 | pydata3 , pydata4 = socket.socketpair() 28 | pydata5 , pydata6 = socket.socketpair() 29 | pydata7 , pydata8 = socket.socketpair() 30 | pydata9 , pydata10 = socket.socketpair() 31 | pydata11, pydata12 = socket.socketpair() 32 | pydata13, pydata14 = socket.socketpair() 33 | pydata15, pydata16 = socket.socketpair() 34 | pydata17, pydata18 = socket.socketpair() 35 | pydata19, pydata20 = socket.socketpair() 36 | pydata21, pydata22 = socket.socketpair() 37 | pydata23, pydata24 = socket.socketpair() 38 | pydata25, pydata26 = socket.socketpair() 39 | pydata27, pydata28 = socket.socketpair() 40 | pydata29, pydata30 = socket.socketpair() 41 | pydata31, pydata32 = socket.socketpair() 42 | pydata33, pydata34 = socket.socketpair() 43 | pydata35, pydata36 = socket.socketpair() 44 | pydata37, pydata38 = socket.socketpair() 45 | pydata39, pydata40 = socket.socketpair() 46 | pydata41, pydata42 = socket.socketpair() 47 | pydata43, pydata44 = socket.socketpair() 48 | pydata45, pydata46 = socket.socketpair() 49 | pydata47, pydata48 = socket.socketpair() 50 | pydata49, pydata50 = socket.socketpair() 51 | pydata51, pydata52 = socket.socketpair() 52 | pydata53, pydata54 = socket.socketpair() 53 | pydata55, pydata56 = socket.socketpair() 54 | pydata57, pydata58 = socket.socketpair() 55 | pydata59, pydata60 = socket.socketpair() 56 | pydata61, pydata62 = socket.socketpair() 57 | pydata63, pydata64 = socket.socketpair() 58 | pydata65, pydata66 = socket.socketpair() 59 | pydata67, pydata68 = socket.socketpair() 60 | pydata69, pydata70 = socket.socketpair() 61 | pydata71, pydata72 = socket.socketpair() 62 | pydata73, pydata74 = socket.socketpair() 63 | pydata75, pydata76 = socket.socketpair() 64 | pydata77, pydata78 = socket.socketpair() 65 | pydata79, pydata80 = socket.socketpair() 66 | pydata81, pydata82 = socket.socketpair() 67 | pydata83, pydata84 = socket.socketpair() 68 | pydata85, pydata86 = socket.socketpair() 69 | pydata87, pydata88 = socket.socketpair() 70 | pydata89, pydata90 = socket.socketpair() 71 | pydata91, pydata92 = socket.socketpair() 72 | pydata93, pydata94 = socket.socketpair() 73 | pydata95, pydata96 = socket.socketpair() 74 | pydata97, pydata98 = socket.socketpair() 75 | pydata99, pydata100 = socket.socketpair() 76 | wait1, wait2 = socket.socketpair() 77 | time1, time2 = socket.socketpair() 78 | start1, start2 = socket.socketpair() 79 | stop1, stop2 = socket.socketpair() 80 | cont1,cont2 = socket.socketpair() 81 | halt1, halt2 = socket.socketpair() 82 | -------------------------------------------------------------------------------- /python/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | import subprocess 5 | import platform 6 | from towii import pydata1, pydata2,time1 7 | 8 | def startcmd(): 9 | subprocess.call('shell.exe',) 10 | 11 | def timeis(): 12 | secconds = time.time() 13 | time1.sendall(secconds) 14 | 15 | def print_slow(str): 16 | for letter in str: 17 | sys.stdout.write(letter) 18 | sys.stdout.flush() 19 | time.sleep(0.005) 20 | sys.stdout.write('\n') 21 | 22 | def startSH(): 23 | pydata1.sendall(b"Hello! just letting you know that PythonicOS is starting!") 24 | data = pydata2.recv(1024) 25 | print("Received:", data.decode()) 26 | print_slow('######## ## ## ######## ## ## ####### ## ## #### ###### ####### ###### ') 27 | print_slow('## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ') 28 | print_slow('## ## #### ## ## ## ## ## #### ## ## ## -#-#-#-#-#- ## ## ## ') 29 | print_slow('######## ## ## ######### ## ## ## ## ## ## ## #-#-#-#-#-# ## ## ###### ') 30 | print_slow('## ## ## ## ## ## ## ## #### ## ## -#-#-#-#-#- ## ## ## ') 31 | print_slow('## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ') 32 | print_slow('## ## ## ## ## ####### ## ## #### ###### ####### ###### ') 33 | print_slow('*******************************************************************************************************') 34 | print_slow('-------------------------------------------PythonicOS--------------------------------------------------') 35 | print_slow('---------------------------------------------v 0.1-----------------------------------------------------') 36 | print_slow('------------------Copyright 2023 OpenStudio and our github supporters and collaborators----------------') 37 | print_slow('------------------Welcome to the interactive start wizard for Windows, MacOS and Linux.----------------') 38 | print_slow('-------------------------------------------------------------------------------------------------------') 39 | print_slow('-------------------This wizard will allow you to navagate PythonicOS and its features!-----------------') 40 | print_slow('----------------using the helpful commands listed below you can navigate around the shell!-------------') 41 | print_slow('-------------------------------------------------------------------------------------------------------') 42 | print_slow('-------------------------------------------------------------------------------------------------------') 43 | print_slow('-------------------------------------------------------------------------------------------------------') 44 | print_slow('-----------------------------------CD : changes directory-----------------------------------') 45 | print_slow('-------------------MKDIR followed by on a new line: makes a directory------------------') 46 | print_slow('------------------------------------------Help: displays Help------------------------------------------') 47 | print_slow('-------------------------------------------------------------------------------------------------------') 48 | print_slow('-------------------------------------------------------------------------------------------------------') 49 | print_slow('-------------------------------------------------------------------------------------------------------') 50 | print_slow('*******************************************************************************************************') 51 | startcmd() 52 | if __name__ == ('__main__'): 53 | startSH() 54 | -------------------------------------------------------------------------------- /python/bluescreen.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | import tkinter.font as tkFont 3 | error = "" 4 | 5 | # How is this supposed to work? 6 | class App: 7 | def __init__(self, root): 8 | #setting title 9 | root.title("undefined") 10 | #setting window size 11 | width=600 12 | height=500 13 | screenwidth = root.winfo_screenwidth() 14 | screenheight = root.winfo_screenheight() 15 | alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) 16 | root.geometry(alignstr) 17 | root.resizable(width=False, height=False) 18 | 19 | GButton_145=tk.Button(root) 20 | GButton_145["bg"] = "#f0f0f0" 21 | ft = tkFont.Font(family='Times',size=10) 22 | GButton_145["font"] = ft 23 | GButton_145["fg"] = "#000000" 24 | GButton_145["justify"] = "center" 25 | GButton_145["text"] = "restart" 26 | GButton_145.place(x=0,y=470,width=596,height=30) 27 | GButton_145["command"] = self.GButton_145_command 28 | 29 | GLabel_688=tk.Label(root) 30 | ft = tkFont.Font(family='Times',size=10) 31 | GLabel_688["font"] = ft 32 | GLabel_688["fg"] = "#333333" 33 | GLabel_688["justify"] = "center" 34 | GLabel_688["text"] = "well that doesnt seem too great!" 35 | GLabel_688["relief"] = "raised" 36 | GLabel_688.place(x=160,y=0,width=246,height=30) 37 | 38 | GLabel_735=tk.Label(root) 39 | ft = tkFont.Font(family='Times',size=10) 40 | GLabel_735["font"] = ft 41 | GLabel_735["fg"] = "#333333" 42 | GLabel_735["justify"] = "center" 43 | GLabel_735["text"] = "so it seems like pythonicOS has crashed? or it just wanted to do this because it could?" 44 | GLabel_735.place(x=0,y=50,width=612,height=30) 45 | 46 | GLabel_544=tk.Label(root) 47 | ft = tkFont.Font(family='Times',size=10) 48 | GLabel_544["font"] = ft 49 | GLabel_544["fg"] = "#333333" 50 | GLabel_544["justify"] = "center" 51 | GLabel_544["text"] = "here is the error message that you got, well if you got any?" 52 | GLabel_544.place(x=130,y=100,width=353,height=30) 53 | 54 | GLabel_42=tk.Label(root) 55 | ft = tkFont.Font(family='Times',size=10) 56 | GLabel_42["font"] = ft 57 | GLabel_42["fg"] = "#333333" 58 | GLabel_42["justify"] = "center" 59 | GLabel_42["text"] = error 60 | GLabel_42.place(x=190,y=150,width=192,height=30) 61 | 62 | GLabel_508=tk.Label(root) 63 | ft = tkFont.Font(family='Times',size=10) 64 | GLabel_508["font"] = ft 65 | GLabel_508["fg"] = "#333333" 66 | GLabel_508["justify"] = "center" 67 | GLabel_508["text"] = "if you could be so great and hit that button on the bottom for me, ill take care of the rest!" 68 | GLabel_508.place(x=110,y=240,width=373,height=30) 69 | 70 | GLabel_164=tk.Label(root) 71 | ft = tkFont.Font(family='Times',size=10) 72 | GLabel_164["font"] = ft 73 | GLabel_164["fg"] = "#333333" 74 | GLabel_164["justify"] = "center" 75 | GLabel_164["text"] = "if you could before you go, could you please open a issue on github.com/OpenStudioCorp/PythonicOS with your error code please? that will help out alot!" 76 | GLabel_164.place(x=100,y=340,width=395,height=33) 77 | 78 | GLabel_844=tk.Label(root) 79 | ft = tkFont.Font(family='Times',size=10) 80 | GLabel_844["font"] = ft 81 | GLabel_844["fg"] = "#333333" 82 | GLabel_844["justify"] = "center" 83 | GLabel_844["text"] = "cheers!" 84 | GLabel_844.place(x=250,y=410,width=70,height=25) 85 | 86 | def GButton_145_command(self): 87 | print("command") 88 | 89 | if __name__ == "__main__": 90 | root = tk.Tk() 91 | app = App(root) 92 | root.mainloop() 93 | -------------------------------------------------------------------------------- /controbuting.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Contributing to PythonicOS 4 | 5 | Thank you for your interest in contributing to PythonicOS! We appreciate your support and welcome any contributions to our project. 6 | 7 | ## How to contribute 8 | 9 | There are many ways you can contribute to PythonicOS, such as: 10 | 11 | - Reporting issues 12 | - Submitting pull requests 13 | - Suggesting features 14 | - Testing the project 15 | - Writing documentation 16 | 17 | Please read the following guidelines before you start contributing. 18 | 19 | ## Reporting issues 20 | 21 | If you encounter any bugs, errors, or crashes while using PythonicOS, please report them as issues on our GitHub repo. To report an issue, follow these steps: 22 | 23 | - Check if the issue has already been reported by searching the existing issues. 24 | - If the issue is not reported yet, create a new issue and fill out the issue template with the required information. 25 | - Provide as much detail as possible, such as the steps to reproduce the issue, the expected and actual behavior, the error messages, the screenshots, etc. 26 | - Be respectful and polite to other users and developers. 27 | 28 | ## Submitting pull requests 29 | 30 | If you want to fix an issue or add a feature to PythonicOS, you can submit a pull request with your code changes. To submit a pull request, follow these steps: 31 | 32 | - Fork the PythonicOS repo and clone it to your local machine. 33 | - Create a new branch for your changes and switch to it. 34 | - Make your changes and commit them with a clear and descriptive message. 35 | - Push your branch to your forked repo and create a pull request from it to the main repo. 36 | - Fill out the pull request template with the required information and link it to the related issue if any. 37 | - Wait for the code review and feedback from the maintainers. 38 | - Address any comments or requests for changes and update your pull request accordingly. 39 | - Be respectful and polite to other users and developers. 40 | 41 | ## Suggesting features 42 | 43 | If you have an idea for a new feature or an improvement for PythonicOS, you can suggest it as an issue on our GitHub repo. To suggest a feature, follow these steps: 44 | 45 | - Check if the feature has already been suggested by searching the existing issues. 46 | - If the feature is not suggested yet, create a new issue and fill out the feature request template with the required information. 47 | - Provide as much detail as possible, such as the motivation, use cases, benefits, drawbacks, alternatives, etc. 48 | - Be respectful and polite to other users and developers. 49 | 50 | ## Testing the project 51 | 52 | If you want to help us test PythonicOS and ensure its quality and stability, you can run it on your machine and report any issues or feedback. To test the project, follow these steps: 53 | 54 | - Download or clone the latest version of PythonicOS from our GitHub repo. 55 | - Follow the installation instructions in the README.md file. 56 | - Run PythonicOS on your machine and try out its features and functionalities. 57 | - Report any issues or feedback as described in the reporting issues section. 58 | 59 | ## Writing documentation 60 | 61 | If you want to help us improve the documentation of PythonicOS and make it more clear and comprehensive, you can write or edit the existing documentation files. To write documentation, follow these steps: 62 | 63 | - Fork the PythonicOS repo and clone it to your local machine. 64 | - Find the documentation file that you want to write or edit in the docs directory. 65 | - Write or edit the documentation using GitHub Flavored Markdown syntax. 66 | - Commit your changes with a clear and descriptive message. 67 | - Push your branch to your forked repo and create a pull request from it to the main repo. 68 | - Fill out the pull request template with the required information and link it to the related issue if any. 69 | - Wait for the code review and feedback from the maintainers. 70 | - Address any comments or requests for changes and update your pull request accordingly. 71 | - Be respectful and polite to other users and developers. 72 | 73 | ## Code of conduct 74 | 75 | Please note that this project is released with a [Code of Conduct](CODE_OF_CONDUCT.md). By contributing to this project, you agree to abide by its terms. 76 | -------------------------------------------------------------------------------- /python/time.py: -------------------------------------------------------------------------------- 1 | import time 2 | import os 3 | import time 4 | import os 5 | import sys 6 | 7 | def clear_screen(): 8 | # Clear the console screen 9 | os.system('cls' if os.name == 'nt' else 'clear') 10 | 11 | def kbhit(): 12 | # Check if a key is pressed 13 | if os.name == 'nt': 14 | import msvcrt 15 | return msvcrt.kbhit() 16 | else: 17 | import termios 18 | import fcntl 19 | import select 20 | # Set stdin file descriptor to non-blocking mode 21 | fd = sys.stdin.fileno() 22 | old_attr = termios.tcgetattr(fd) 23 | new_attr = old_attr[:] 24 | new_attr[3] = new_attr[3] & ~termios.ICANON & ~termios.ECHO 25 | termios.tcsetattr(fd, termios.TCSANOW, new_attr) 26 | old_flags = fcntl.fcntl(fd, fcntl.F_GETFL) 27 | fcntl.fcntl(fd, fcntl.F_SETFL, old_flags | os.O_NONBLOCK) 28 | 29 | try: 30 | # Check if there is any input available 31 | _, _, _ = select.select([sys.stdin], [], [], 0) 32 | return True 33 | except: 34 | return False 35 | finally: 36 | # Restore stdin back to blocking mode 37 | termios.tcsetattr(fd, termios.TCSAFLUSH, old_attr) 38 | fcntl.fcntl(fd, fcntl.F_SETFL, old_flags) 39 | 40 | def display_clock(): 41 | while True: 42 | # Clear the screen before displaying the time 43 | clear_screen() 44 | # Get the current time 45 | current_time = time.strftime("%H:%M:%S") 46 | 47 | # ASCII art digits for each number 48 | digits = { 49 | "0": [" 8888 ", 50 | "88 88", 51 | "88 88", 52 | "88 88", 53 | " 8888 "], 54 | "1": [" 88 ", 55 | " 888 ", 56 | " 88 ", 57 | " 88 ", 58 | "888888"], 59 | "2": [" 8888 ", 60 | " 88", 61 | " 8888 ", 62 | "88 ", 63 | "888888"], 64 | "3": [" 8888 ", 65 | " 88", 66 | " 8888 ", 67 | " 88", 68 | " 8888 "], 69 | "4": ["88 88", 70 | "88 88", 71 | "888888", 72 | " 88", 73 | " 88"], 74 | "5": ["888888", 75 | "88 ", 76 | "8888 ", 77 | " 88", 78 | "8888 "], 79 | "6": [" 8888 ", 80 | "88 ", 81 | "8888 ", 82 | "88 88", 83 | " 8888 "], 84 | "7": ["888888", 85 | " 88", 86 | " 88 ", 87 | " 88 ", 88 | " 88 "], 89 | "8": [" 8888 ", 90 | "88 88", 91 | " 8888 ", 92 | "88 88", 93 | " 8888 "], 94 | "9": [" 8888 ", 95 | "88 88", 96 | " 88888", 97 | " 88", 98 | " 8888 "], 99 | ":": [" ", 100 | " ++ ", 101 | " ", 102 | " ++ ", 103 | " "], 104 | " ": [" ", 105 | " ", 106 | " ", 107 | " ", 108 | " "], 109 | "AM": [" ", 110 | " 8888 ", 111 | "88 88", 112 | "88 88", 113 | " "], 114 | "PM": [" ", 115 | "88 88", 116 | "88 88", 117 | " 8888 ", 118 | " "] 119 | } 120 | 121 | 122 | # Display the time 123 | lines = ["", "", "", "", ""] 124 | for digit in current_time: 125 | if digit in digits: 126 | for i, line in enumerate(digits[digit]): 127 | lines[i] += line + " " 128 | else: 129 | for i in range(5): 130 | lines[i] += " " 131 | 132 | # Print the time in the center of the screen 133 | print("\n" + "-" * 30) 134 | for line in lines: 135 | print(line) 136 | print("-" * 30) 137 | 138 | 139 | 140 | # Check if the user pressed the 'Q' key 141 | if kbhit(): 142 | key = sys.stdin.read(1).upper() 143 | if key == 'Q': 144 | break 145 | 146 | # Wait for 1 second 147 | time.sleep(1) 148 | 149 | # Run the clock 150 | display_clock() -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | abstract_singleton==1.0.1 2 | aiofiles==23.1.0 3 | aiohttp==3.9.0 4 | aiosignal==1.3.1 5 | altair==5.0.1 6 | altgraph==0.17.3 7 | anyio==3.7.0 8 | async-generator==1.10 9 | async-timeout==4.0.2 10 | asynctest==0.13.0 11 | attrs==23.1.0 12 | auto_gpt_plugin_template==0.0.3 13 | autoflake==2.1.1 14 | beautifulsoup4==4.12.2 15 | black==23.3.0 16 | blis==0.7.9 17 | buildozer==1.5.0 18 | cachetools==5.3.1 19 | catalogue==2.0.8 20 | certifi==2023.7.22 21 | cffi==1.15.1 22 | cfgv==3.3.1 23 | chardet==5.1.0 24 | charset-normalizer==3.1.0 25 | click==8.1.3 26 | colorama==0.4.6 27 | confection==0.0.4 28 | contourpy==1.0.7 29 | coverage==7.2.6 30 | cryptography==42.0.4 31 | cssselect==1.2.0 32 | cycler==0.11.0 33 | cymem==2.0.7 34 | dataclasses==0.6 35 | dateutils==0.6.12 36 | distlib==0.3.6 37 | distro==1.8.0 38 | dnspython==2.3.0 39 | docker==6.1.2 40 | docutils==0.20.1 41 | duckduckgo-search==3.6.0 42 | en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.5.0/en_core_web_sm-3.5.0-py3-none-any.whl 43 | exceptiongroup==1.1.1 44 | execnet==1.9.0 45 | fastapi==0.95.2 46 | ffmpy==0.3.0 47 | filelock==3.12.0 48 | flake8==6.0.0 49 | fluidsynth==0.2 50 | fonttools==4.39.4 51 | frozenlist==1.3.3 52 | fsspec==2023.5.0 53 | future==0.18.3 54 | ghp-import==2.1.0 55 | gitdb==4.0.10 56 | GitPython==3.1.34 57 | google-api-core==2.11.0 58 | google-api-python-client==2.87.0 59 | google-auth==2.19.0 60 | google-auth-httplib2==0.1.0 61 | googleapis-common-protos==1.59.0 62 | gradio==3.34.0 63 | gradio_client==0.2.5 64 | gTTS==2.3.1 65 | h11==0.14.0 66 | h2==4.1.0 67 | hpack==4.0.0 68 | httpcore==0.17.2 69 | httplib2==0.22.0 70 | httpx==0.24.1 71 | huggingface-hub==0.14.1 72 | hyperframe==6.0.1 73 | identify==2.5.24 74 | idna==3.4 75 | iniconfig==2.0.0 76 | iso8601==1.1.0 77 | isort==5.12.0 78 | Jinja2==3.1.2 79 | jsonschema==4.17.3 80 | Kivy==2.2.0 81 | kivy-deps.angle==0.3.3 82 | kivy-deps.glew==0.3.1 83 | kivy-deps.sdl2==0.6.0 84 | Kivy-Garden==0.1.5 85 | kiwisolver==1.4.4 86 | langcodes==3.3.0 87 | linkify-it-py==2.0.2 88 | loguru==0.7.0 89 | lxml==4.9.2 90 | Markdown==3.3.7 91 | markdown-it-py==2.2.0 92 | MarkupSafe==2.1.2 93 | matplotlib==3.7.1 94 | mccabe==0.7.0 95 | mdit-py-plugins==0.3.3 96 | mdurl==0.1.2 97 | mergedeep==1.3.4 98 | mido==1.2.10 99 | mido-fix==1.2.12 100 | mkdocs==1.4.3 101 | mpmath==1.3.0 102 | multidict==6.0.4 103 | murmurhash==1.0.9 104 | musicpy==6.73 105 | mypy-extensions==1.0.0 106 | networkx==3.1 107 | nodeenv==1.8.0 108 | nsetools==1.0.11 109 | numpy==1.24.3 110 | oauthlib==3.2.2 111 | openai==0.27.2 112 | openapi-python-client==0.13.4 113 | orjson==3.9.15 114 | outcome==1.2.0 115 | packaging==23.1 116 | pandas==2.0.1 117 | pathspec==0.11.1 118 | pathy==0.10.1 119 | pefile==2023.2.7 120 | pexpect==4.8.0 121 | Pillow==10.0.1 122 | pinecone-client==2.2.1 123 | platformdirs==3.5.1 124 | playsound==1.2.2 125 | pluggy==1.0.0 126 | pre-commit==3.3.2 127 | preshed==3.0.8 128 | protobuf==4.23.2 129 | ptyprocess==0.7.0 130 | py==1.11.0 131 | py-cpuinfo==9.0.0 132 | pyasn1==0.5.0 133 | pyasn1-modules==0.3.0 134 | pycodestyle==2.10.0 135 | pycparser==2.21 136 | pydantic==1.10.8 137 | pydub==0.25.1 138 | pyflakes==3.0.1 139 | pyFluidSynth==1.3.2 140 | pygame==2.4.0 141 | Pygments==2.15.1 142 | pyinstaller==5.13.1 143 | pyinstaller-hooks-contrib==2023.3 144 | pymdown-extensions==10.0.1 145 | pyOpenSSL==23.1.1 146 | pyparsing==3.0.9 147 | pypiwin32==223 148 | PyQt5==5.15.9 149 | pyqt5-plugins==5.15.9.2.3 150 | PyQt5-Qt5==5.15.2 151 | PyQt5-sip==12.12.1 152 | pyqt5-tools==5.15.9.3.3 153 | pyrsistent==0.19.3 154 | pyserial==3.5 155 | PySocks==1.7.1 156 | pytest==7.3.1 157 | pytest-asyncio==0.21.0 158 | pytest-benchmark==4.0.0 159 | pytest-cov==4.1.0 160 | pytest-integration==0.2.3 161 | pytest-mock==3.10.0 162 | pytest-recording==0.12.2 163 | pytest-xdist==3.3.1 164 | python-dateutil==2.8.2 165 | python-dotenv==1.0.0 166 | python-multipart==0.0.6 167 | python-rtmidi==1.5.0 168 | pytz==2023.3 169 | PyVirtualSerialPorts==1.0.1 170 | pywin32==306 171 | pywin32-ctypes==0.2.0 172 | PyYAML==6.0 173 | pyyaml_env_tag==0.1 174 | qt5-applications==5.15.2.2.3 175 | qt5-tools==5.15.2.1.3 176 | readability-lxml==0.8.1 177 | redis==4.5.5 178 | regex==2023.5.5 179 | requests==2.31.0 180 | requests-oauthlib==1.3.1 181 | rsa==4.9 182 | SCons==4.5.2 183 | selenium==4.1.4 184 | semantic-version==2.10.0 185 | serial==0.0.97 186 | sf2-loader==1.24 187 | sh==2.0.4 188 | shellingham==1.5.0.post1 189 | six==1.16.0 190 | smart-open==6.3.0 191 | smmap==5.0.0 192 | sniffio==1.3.0 193 | sortedcontainers==2.4.0 194 | soupsieve==2.4.1 195 | spacy==3.5.3 196 | spacy-legacy==3.0.12 197 | spacy-loggers==1.0.4 198 | srsly==2.4.6 199 | starlette==0.27.0 200 | sympy==1.12 201 | text-generation==0.4.1 202 | thinc==8.1.10 203 | tiktoken==0.3.3 204 | tokenizers==0.13.3 205 | toolz==0.12.0 206 | torch==2.0.1 207 | tqdm==4.65.0 208 | transformers==4.29.2 209 | trio==0.22.0 210 | trio-websocket==0.10.2 211 | tweepy==4.14.0 212 | typer==0.7.0 213 | typing_extensions==4.6.2 214 | tzdata==2023.3 215 | uc-micro-py==1.0.2 216 | uritemplate==4.1.1 217 | urllib3==1.26.18 218 | urllib3-secure-extra==0.1.0 219 | uvicorn==0.22.0 220 | vcrpy==4.3.1 221 | virtualenv==20.23.0 222 | wasabi==1.1.1 223 | watchdog==3.0.0 224 | webdriver-manager==3.8.6 225 | websocket-client==1.5.2 226 | websockets==11.0.3 227 | win32-setctime==1.1.0 228 | wrapt==1.15.0 229 | wsproto==1.2.0 230 | yarl==1.9.2 -------------------------------------------------------------------------------- /addons/panno.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from tkinter import filedialog 3 | from tkinter import messagebox 4 | from tkinter import simpledialog 5 | import sys 6 | 7 | class TextEditorApp: 8 | def __init__(self, root): 9 | self.root = root 10 | self.root.title("PANNO!") 11 | self.text = tk.Text(root) 12 | self.text.pack(fill=tk.BOTH, expand=True) 13 | self.undo_stack = [] 14 | self.redo_stack = [] 15 | self.bind_keyboard_shortcuts() 16 | self.current_file = None # Variable to store the current file name 17 | self.file_dialog_open = False # Flag to track if file dialog is open 18 | 19 | # Create the menu bar 20 | menu_bar = tk.Menu(root) 21 | file_menu = tk.Menu(menu_bar, tearoff=0) 22 | file_menu.add_command(label="Open", command=self.load_file) 23 | file_menu.add_command(label="Save", command=self.save_file) 24 | menu_bar.add_cascade(label="File", menu=file_menu) 25 | root.config(menu=menu_bar) 26 | 27 | # Create the toolbar 28 | toolbar = tk.Frame(root) 29 | toolbar.pack(side=tk.TOP, fill=tk.X) 30 | 31 | load_button = tk.Button(toolbar, text="Load", command=self.load_file) 32 | load_button.pack(side=tk.LEFT) 33 | 34 | save_button = tk.Button(toolbar, text="Save", command=self.save_file) 35 | save_button.pack(side=tk.LEFT) 36 | 37 | redo_button = tk.Button(toolbar, text="Redo", command=self.redo) 38 | redo_button.pack(side=tk.LEFT) 39 | 40 | # Bind the right-click event for the text widget 41 | self.text.bind("", self.show_text_context_menu) 42 | 43 | # Check if file path is passed as an argument 44 | if len(sys.argv) > 1: 45 | file_path = sys.argv[1] 46 | self.load_file(file_path) 47 | 48 | def bind_keyboard_shortcuts(self): 49 | self.root.bind("", self.save_file) 50 | self.root.bind("", self.undo) 51 | self.root.bind("", self.redo) 52 | 53 | def load_file(self, file_path=None): 54 | if not file_path: 55 | file_path = filedialog.askopenfilename() 56 | 57 | if file_path: 58 | try: 59 | with open(file_path, "r") as file: 60 | self.text.delete("1.0", tk.END) 61 | self.text.insert(tk.END, file.read()) 62 | self.current_file = file_path # Update the current file name 63 | self.update_title() # Update the title 64 | except FileNotFoundError: 65 | messagebox.showerror("Error", "File not found.") 66 | except Exception as e: 67 | messagebox.showerror("Error", f"An error occurred: {str(e)}") 68 | 69 | def save_file(self, event=None): 70 | if self.current_file: 71 | try: 72 | with open(self.current_file, "w") as file: 73 | file.write(self.text.get("1.0", tk.END)) 74 | messagebox.showinfo("Save", "File saved successfully.") 75 | except Exception as e: 76 | messagebox.showerror("Error", f"An error occurred: {str(e)}") 77 | else: 78 | file_path = filedialog.asksaveasfilename(defaultextension=".txt") 79 | if file_path: 80 | try: 81 | with open(file_path, "w") as file: 82 | file.write(self.text.get("1.0", tk.END)) 83 | self.current_file = file_path # Update the current file name 84 | self.update_title() # Update the title 85 | messagebox.showinfo("Save", "File saved successfully.") 86 | except Exception as e: 87 | messagebox.showerror("Error", f"An error occurred: {str(e)}") 88 | 89 | def undo(self, event=None): 90 | if self.undo_stack: 91 | text = self.undo_stack.pop() 92 | self.redo_stack.append(self.text.get("1.0", tk.END)) 93 | self.text.delete("1.0", tk.END) 94 | self.text.insert(tk.END, text) 95 | 96 | def redo(self, event=None): 97 | if self.redo_stack: 98 | text = self.redo_stack.pop() 99 | self.undo_stack.append(self.text.get("1.0", tk.END)) 100 | self.text.delete("1.0", tk.END) 101 | self.text.insert(tk.END, text) 102 | 103 | def update_title(self): 104 | if self.current_file: 105 | self.root.title(f"Text Editor - {self.current_file}") 106 | else: 107 | self.root.title("Text Editor") 108 | 109 | def show_text_context_menu(self, event): 110 | text_context_menu = tk.Menu(self.root, tearoff=0) 111 | text_context_menu.add_command(label="Cut", command=lambda: self.text.event_generate("<>")) 112 | text_context_menu.add_command(label="Copy", command=lambda: self.text.event_generate("<>")) 113 | text_context_menu.add_command(label="Paste", command=lambda: self.text.event_generate("<>")) 114 | text_context_menu.add_separator() 115 | text_context_menu.add_command(label="Select All", command=lambda: self.text.tag_add("sel", "1.0", tk.END)) 116 | text_context_menu.post(event.x_root, event.y_root) 117 | 118 | if __name__ == "__main__": 119 | root = tk.Tk() 120 | app = TextEditorApp(root) 121 | root.mainloop() 122 | -------------------------------------------------------------------------------- /addons/Notepad.py: -------------------------------------------------------------------------------- 1 | import tkinter 2 | import os 3 | from tkinter import * 4 | from tkinter.messagebox import * 5 | from tkinter.filedialog import * 6 | #-----------------------------------------# 7 | #this notepad applacation was made by six519 8 | # https://github.com/six519/Python-Notepad 9 | # This program plugin change applies the original creators repos license.md file 10 | # Any addons added to PythonicOS shall make PythonicOS free and open source 11 | # Great that you actually credited the original creator on this one :) -h4rl 12 | # 13 | #-----------------------------------------# 14 | 15 | class Notepad: 16 | 17 | #variables 18 | __root = Tk() 19 | 20 | #default window width and height 21 | __thisWidth = 300 22 | __thisHeight = 300 23 | __thisTextArea = Text(__root) 24 | __thisMenuBar = Menu(__root) 25 | __thisFileMenu = Menu(__thisMenuBar,tearoff=0) 26 | __thisEditMenu = Menu(__thisMenuBar,tearoff=0) 27 | __thisHelpMenu = Menu(__thisMenuBar,tearoff=0) 28 | __thisScrollBar = Scrollbar(__thisTextArea) 29 | __file = None 30 | 31 | def __init__(self,**kwargs): 32 | #initialization 33 | 34 | #set icon 35 | try: 36 | self.__root.wm_iconbitmap("Notepad.ico") #GOT TO FIX THIS ERROR (ICON) 37 | except: 38 | pass 39 | 40 | #set window size (the default is 300x300) 41 | 42 | try: 43 | self.__thisWidth = kwargs['width'] 44 | except KeyError: 45 | pass 46 | 47 | try: 48 | self.__thisHeight = kwargs['height'] 49 | except KeyError: 50 | pass 51 | 52 | #set the window text 53 | self.__root.title("Untitled - Notepad") 54 | 55 | #center the window 56 | screenWidth = self.__root.winfo_screenwidth() 57 | screenHeight = self.__root.winfo_screenheight() 58 | 59 | left = (screenWidth / 2) - (self.__thisWidth / 2) 60 | top = (screenHeight / 2) - (self.__thisHeight /2) 61 | 62 | self.__root.geometry('%dx%d+%d+%d' % (self.__thisWidth, self.__thisHeight, left, top)) 63 | 64 | #to make the textarea auto resizable 65 | self.__root.grid_rowconfigure(0,weight=1) 66 | self.__root.grid_columnconfigure(0,weight=1) 67 | 68 | #add controls (widget) 69 | 70 | self.__thisTextArea.grid(sticky=N+E+S+W) 71 | 72 | self.__thisFileMenu.add_command(label="New",command=self.__newFile) 73 | self.__thisFileMenu.add_command(label="Open",command=self.__openFile) 74 | self.__thisFileMenu.add_command(label="Save",command=self.__saveFile) 75 | self.__thisFileMenu.add_separator() 76 | self.__thisFileMenu.add_command(label="Exit",command=self.__quitApplication) 77 | self.__thisMenuBar.add_cascade(label="File",menu=self.__thisFileMenu) 78 | 79 | self.__thisEditMenu.add_command(label="Cut",command=self.__cut) 80 | self.__thisEditMenu.add_command(label="Copy",command=self.__copy) 81 | self.__thisEditMenu.add_command(label="Paste",command=self.__paste) 82 | self.__thisMenuBar.add_cascade(label="Edit",menu=self.__thisEditMenu) 83 | 84 | self.__thisHelpMenu.add_command(label="About Notepad",command=self.__showAbout) 85 | self.__thisMenuBar.add_cascade(label="Help",menu=self.__thisHelpMenu) 86 | 87 | self.__root.config(menu=self.__thisMenuBar) 88 | 89 | self.__thisScrollBar.pack(side=RIGHT,fill=Y) 90 | self.__thisScrollBar.config(command=self.__thisTextArea.yview) 91 | self.__thisTextArea.config(yscrollcommand=self.__thisScrollBar.set) 92 | 93 | 94 | def __quitApplication(self): 95 | self.__root.destroy() 96 | #exit() 97 | 98 | def __showAbout(self): 99 | showinfo("Notepad","Created by: Ferdinand Silva (http://ferdinandsilva.com) and used within PythonicOS by the repo's licence.MD file") 100 | 101 | def __openFile(self): 102 | 103 | self.__file = askopenfilename(defaultextension=".txt",filetypes=[("All Files","*.*"),("Text Documents","*.txt")]) 104 | 105 | if self.__file == "": 106 | #no file to open 107 | self.__file = None 108 | else: 109 | #try to open the file 110 | #set the window title 111 | self.__root.title(os.path.basename(self.__file) + " - Notepad") 112 | self.__thisTextArea.delete(1.0,END) 113 | 114 | file = open(self.__file,"r") 115 | 116 | self.__thisTextArea.insert(1.0,file.read()) 117 | 118 | file.close() 119 | 120 | 121 | def __newFile(self): 122 | self.__root.title("Untitled - Notepad") 123 | self.__file = None 124 | self.__thisTextArea.delete(1.0,END) 125 | 126 | def __saveFile(self): 127 | 128 | if self.__file == None: 129 | #save as new file 130 | self.__file = asksaveasfilename(initialfile='Untitled.txt',defaultextension=".txt",filetypes=[("All Files","*.*"),("Text Documents","*.txt")]) 131 | 132 | if self.__file == "": 133 | self.__file = None 134 | else: 135 | #try to save the file 136 | file = open(self.__file,"w") 137 | file.write(self.__thisTextArea.get(1.0,END)) 138 | file.close() 139 | #change the window title 140 | self.__root.title(os.path.basename(self.__file) + " - Notepad") 141 | 142 | 143 | else: 144 | file = open(self.__file,"w") 145 | file.write(self.__thisTextArea.get(1.0,END)) 146 | file.close() 147 | 148 | def __cut(self): 149 | self.__thisTextArea.event_generate("<>") 150 | 151 | def __copy(self): 152 | self.__thisTextArea.event_generate("<>") 153 | 154 | def __paste(self): 155 | self.__thisTextArea.event_generate("<>") 156 | 157 | def run(self): 158 | 159 | #run main application 160 | self.__root.mainloop() 161 | 162 | 163 | 164 | 165 | #run main application 166 | notepad = Notepad(width=600,height=400) 167 | notepad.run() 168 | 169 | 170 | -------------------------------------------------------------------------------- /python/PythonicOS.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | import subprocess 3 | from tkinter import messagebox 4 | import sys 5 | import time 6 | import os 7 | subprocess.call('setup.exe') 8 | 9 | home_dir = 'python/home' 10 | 11 | def start_rename(home_dir, label): 12 | entry = tk.Entry(label, relief=tk.FLAT) 13 | entry.insert(0, label.cget("text")) 14 | entry.bind("", lambda event, path=home_dir, entry=entry: finish_rename(path, entry)) 15 | entry.bind("", lambda event, entry=entry: entry.destroy()) 16 | entry.pack() 17 | entry.select_range(0, tk.END) 18 | entry.focus() 19 | 20 | def finish_rename(home_dir, entry): 21 | new_filename = entry.get().strip() 22 | new_home_dir = os.path.join(os.path.dirname(home_dir), new_filename) 23 | 24 | # Close any open file handles 25 | entry.destroy() 26 | 27 | # Rename the file 28 | try: 29 | os.rename(home_dir, new_home_dir) 30 | load_files(home_dir) 31 | except PermissionError as e: 32 | messagebox.showerror("Error", str(e)) 33 | return 34 | load_files(home_dir) 35 | if is_pinned(home_dir): 36 | unpin_from_taskbar(home_dir) 37 | pin_to_taskbar(new_home_dir) 38 | load_files(new_home_dir) 39 | 40 | def delete_file(home_dir): 41 | if os.path.isfile(home_dir): 42 | os.remove(home_dir) 43 | load_files(home_dir) 44 | print(f'{home_dir} has been deleted.') 45 | load_files(home_dir) 46 | def pin_to_taskbar(home_dir): 47 | if not is_pinned(home_dir): 48 | taskbar_label = tk.Label(taskbar, text=os.path.basename(home_dir), padx=10) 49 | taskbar_label.pack(side=tk.LEFT) 50 | 51 | def open_pinned_file(path=home_dir): 52 | open_file(path) 53 | 54 | taskbar_label.bind("", lambda event: open_pinned_file()) 55 | taskbar_label.bind("", lambda event: show_files_context_menu(event)) 56 | load_files(home_dir) 57 | def open_file(home_dir): 58 | if home_dir: 59 | subprocess.Popen(['python', 'addons/panno.py', home_dir]) 60 | print(home_dir) 61 | else: 62 | print("No file path provided.") 63 | 64 | def unpin_from_taskbar(home_dir): 65 | for widget in taskbar.winfo_children(): 66 | if isinstance(widget, tk.Label) and widget.cget("text") == os.path.basename(home_dir): 67 | widget.destroy() 68 | 69 | def find_label(home_dir): 70 | for widget in desktop.winfo_children(): 71 | if isinstance(widget, tk.Label) and widget.cget("text") == os.path.basename(home_dir): 72 | return widget 73 | 74 | def is_pinned(home_dir): 75 | for widget in taskbar.winfo_children(): 76 | if isinstance(widget, tk.Label) and widget.cget("text") == os.path.basename(home_dir): 77 | return True 78 | return False 79 | 80 | def create_file(home_dir): 81 | if not os.path.exists(home_dir): 82 | os.mkdir(home_dir) 83 | 84 | filename = 'file{}.py'.format(len(os.listdir(home_dir))) 85 | 86 | with open(os.path.join(home_dir, filename), 'w') as file: 87 | file.write('This is the content of {}'.format(filename)) 88 | print("print com1") 89 | load_files(home_dir) 90 | 91 | def show_popup(message): 92 | popup = tk.Tk() 93 | popup.wm_title("Popup") 94 | label = tk.Label(popup, text=message) 95 | label.pack() 96 | popup.after(3000, lambda: popup.destroy()) # Close the popup after 3000 milliseconds (3 seconds) 97 | popup.mainloop() 98 | 99 | def show_files_context_menu(event): 100 | context_menu = tk.Menu(desktop, tearoff=0) 101 | 102 | label = event.widget 103 | home_dir = os.path.join(os.path.dirname(__file__), 'home', label.cget("text")) 104 | 105 | if not is_pinned(home_dir): 106 | context_menu.add_command(label='Pin to Taskbar', command=lambda: pin_to_taskbar(home_dir)) 107 | if is_pinned(home_dir): 108 | context_menu.add_command(label='Unpin from Taskbar', command=lambda: unpin_from_taskbar(home_dir)) 109 | context_menu.add_command(label='Rename', command=lambda: start_rename(home_dir, label)) 110 | context_menu.add_command(label='Refresh', command=lambda: refresh_code()) 111 | context_menu.add_command(label='Delete', command=lambda: (delete_file(home_dir), load_files(home_dir))) 112 | context_menu.post(event.x_root, event.y_root) 113 | 114 | def load_files(home_dir): 115 | for widget in desktop.winfo_children(): 116 | widget.destroy() 117 | 118 | if not os.path.exists(home_dir): 119 | os.makedirs(home_dir) 120 | 121 | files = sorted(os.listdir(home_dir)) # Sort files alphabetically 122 | grid_columns = 9 123 | grid_row = 0 124 | grid_column = 0 125 | 126 | for file in files: 127 | file_path = os.path.join(home_dir, file) 128 | label = tk.Label(desktop, text=file, pady=10) 129 | 130 | # Get the file extension 131 | _, extension = os.path.splitext(file_path) 132 | 133 | # Set the background color based on the file extension 134 | if extension == '.cs': 135 | label.configure(background='darkblue') 136 | elif extension == '.html': 137 | label.configure(background='red') 138 | elif extension == '.py': 139 | label.configure(background='yellow') 140 | elif extension == '.css': 141 | label.configure(background='blue') 142 | elif extension == '.js': 143 | label.configure(background='orange') 144 | elif extension == '.txt': 145 | label.configure(background='white') 146 | 147 | grid_column += 1 148 | if grid_column == grid_columns: 149 | grid_column = 0 150 | grid_row += 1 151 | 152 | label.bind("", lambda event, path=file_path: open_file(path)) 153 | label.bind("", lambda event, path=file_path: show_files_context_menu(event)) 154 | label.grid(row=grid_row, column=grid_column, padx=10, pady=10, sticky='w') 155 | 156 | def refresh_code(): 157 | load_files(home_dir) 158 | 159 | root = tk.Tk() 160 | root.title('PythonicOS') 161 | root.geometry('640x480') 162 | 163 | taskbar_height = '50' 164 | taskbar_color = 'blue' 165 | 166 | taskbar = tk.Frame(root, height=taskbar_height, bg=taskbar_color) 167 | taskbar.pack(side=tk.TOP, fill=tk.X) 168 | 169 | desktop = tk.Frame(root, bg='lightblue') 170 | desktop.pack(expand=True, fill=tk.BOTH) 171 | load_files(home_dir) 172 | 173 | def show_desktop_context_menu(event): 174 | global file_context_menu 175 | file_context_menu = tk.Menu(desktop, tearoff=False) 176 | home_dir = os.path.join(os.path.dirname(__file__), 'home') 177 | 178 | if not is_pinned(home_dir): 179 | file_context_menu.add_command(label='Pin to Taskbar', command=lambda: pin_to_taskbar(home_dir)) 180 | if is_pinned(home_dir): 181 | file_context_menu.add_command(label='Unpin from Taskbar', command=lambda: unpin_from_taskbar(home_dir)) 182 | 183 | file_context_menu.add_command(label='New File', command=lambda: create_file(home_dir)) 184 | file_context_menu.add_command(label='Load Files', command=lambda: load_files(home_dir)) 185 | file_context_menu.add_command(label='Refresh', command=lambda: refresh_code()) 186 | file_context_menu.add_command(label='Delete', command=lambda: (delete_file(home_dir), load_files(home_dir))) 187 | file_context_menu.post(event.x_root, event.y_root) 188 | 189 | desktop.bind("", show_desktop_context_menu) 190 | load_files(home_dir) 191 | load_files(home_dir) 192 | 193 | root.mainloop() 194 | 195 | if __name__ =='__main__': 196 | load_files(home_dir) 197 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------