├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── pythonpublish.yml ├── .gitignore ├── .travis.yml ├── AUTHORS.md ├── CHANGELOG.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── Supported_Device_List.md ├── autopep8.bat ├── dev-requirements.txt ├── orangetool ├── __init__.py ├── __main__.py ├── orangetool_display.py ├── orangetool_ip.py ├── orangetool_params.py ├── orangetool_ram.py ├── orangetool_storage.py ├── orangetool_system.py ├── orangetool_test.py └── orangetool_utils.py ├── requirements.txt ├── setup.cfg ├── setup.py ├── test.sh └── version_check.py /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at info@orangetool.ir. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution 2 | 3 | Changes and improvements are more than welcome! ❤️ Feel free to fork and open a pull request. 4 | 5 | 6 | Please consider the following : 7 | 8 | 9 | 1. Fork it! 10 | 2. Create your feature branch (under `dev` branch) 11 | 3. Add your functions/methods to proper files 12 | 4. Add standard `docstring` to your functions/methods 13 | 5. Pass all CI tests 14 | 6. Update `CHANGELOG.md` 15 | - Describe changes under `[Unreleased]` section 16 | 7. Submit a pull request into `dev` (please complete the pull request template) -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | #### Description 2 | 3 | #### Steps/Code to Reproduce 4 | 5 | #### Expected Behavior 6 | 7 | #### Actual Behavior 8 | 9 | #### Operating System 10 | 11 | #### Python Version 12 | 13 | #### Orangetool Version 14 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | #### Reference Issues/PRs 2 | 3 | #### What does this implement/fix? Explain your changes. 4 | 5 | 6 | #### Any other comments? 7 | 8 | -------------------------------------------------------------------------------- /.github/workflows/pythonpublish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | name: Upload Python Package 5 | 6 | on: 7 | push: 8 | # Sequence of patterns matched against refs/tags 9 | tags: 10 | - '*' # Push events to matching v*, i.e. v1.0, v20.15.10 11 | 12 | jobs: 13 | deploy: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Set up Python 20 | uses: actions/setup-python@v1 21 | with: 22 | python-version: '3.x' 23 | - name: Install dependencies 24 | run: | 25 | python -m pip install --upgrade pip 26 | pip install setuptools wheel twine 27 | - name: Build and publish 28 | env: 29 | TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} 30 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 31 | run: | 32 | python setup.py sdist bdist_wheel 33 | twine upload dist/*.tar.gz 34 | twine upload dist/*.whl 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Python template 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *,cover 48 | .hypothesis/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | 58 | # Flask stuff: 59 | instance/ 60 | .webassets-cache 61 | 62 | # Scrapy stuff: 63 | .scrapy 64 | 65 | # Sphinx documentation 66 | docs/_build/ 67 | 68 | # PyBuilder 69 | target/ 70 | 71 | # Jupyter Notebook 72 | .ipynb_checkpoints 73 | 74 | # pyenv 75 | .python-version 76 | 77 | # celery beat schedule file 78 | celerybeat-schedule 79 | 80 | # dotenv 81 | .env 82 | 83 | # virtualenv 84 | .venv/ 85 | venv/ 86 | ENV/ 87 | 88 | # Spyder project settings 89 | .spyderproject 90 | 91 | # Rope project settings 92 | .ropeproject 93 | ### Example user template template 94 | ### Example user template 95 | 96 | # IntelliJ project files 97 | .idea 98 | *.iml 99 | out 100 | gen 101 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | matrix: 4 | include: 5 | - os: linux 6 | python: 3.7 7 | dist: xenial 8 | - os: linux 9 | python: 3.6 10 | - os: linux 11 | python: 3.5 12 | - os: linux 13 | python: 3.4 14 | - os: linux 15 | python: 2.7 16 | - os: linux 17 | python: 3.7-dev 18 | dist: xenial 19 | - os: linux 20 | python: 3.8-dev 21 | dist: xenial 22 | - os: linux 23 | python: nightly 24 | dist: xenial 25 | allow_failures: 26 | - os: linux 27 | python: 3.4 28 | - os: linux 29 | python: 2.7 30 | install: 31 | - pip install -r requirements.txt 32 | - python setup.py install 33 | - python -m orangetool 34 | before_script: 35 | - pip install --upgrade --upgrade-strategy=only-if-needed -r dev-requirements.txt 36 | - chmod +x test.sh 37 | script: 38 | - sh test.sh 39 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Core Developers # 2 | 3 | ---------- 4 | - Sepand Haghighi - Moduland Co - ([http://github.com/sepandhaghighi](http://github.com/sepandhaghighi)) ([sepand@qpage.ir](mailto:sepand@qpage.ir)) -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) 5 | and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | ## [0.50] - 2021-01-01 9 | ### Added 10 | - `network_control`, `network_enable` and `network_disable` functions 11 | ### Changed 12 | - `sync` parameter added to `wakeup` function 13 | - `debug` parameter added to `internet` function 14 | ## [0.45] - 2020-12-26 15 | ### Added 16 | - `__main__.py` 17 | - `__version__` variable 18 | - `hibernate` function 19 | - `usb_control`, `usb_on` and `usb_off` functions 20 | ### Changed 21 | - `dev-requirements.txt` modified 22 | - Test system modified 23 | - `DEBUG` parameter renamed to `debug` 24 | - All parameters moved to `orangetool_params.py` 25 | - Some functions moved to `orangetool_utils.py` 26 | - `ADDRESS` parameter renamed to `address` 27 | - `Zone` parameter renamed to `zone` 28 | - `uptime` and `idletime` functions updated 29 | - Docstrings updated 30 | - `README.md` modified 31 | ## [0.35] - 2019-06-01 32 | ### Added 33 | - `version_check.py` 34 | - `CODE_OF_CONDUCT.md` 35 | - `ISSUE_TEMPLATE.md` 36 | - `PULL_REQUEST_TEMPLATE.md` 37 | - `CONTRIBUTING.md` 38 | - `test.sh` 39 | - `autopep8.bat` 40 | - `dev-requirements.txt` 41 | - `CHANGELOG.md` 42 | - `MANIFEST.in` 43 | 44 | ### Changed 45 | - `README.md` modified 46 | - Test system modified 47 | - `restart`, `halt` and `sleep` functions modified 48 | - `hdmi_on` and `hdmi_off` functions modified 49 | - `version` function modified 50 | - `requirements.txt` modified 51 | - `DEVICE` parameter renamed to `device` in `set_ip` function 52 | - `restart` parameter added to `set_ip` function 53 | 54 | ## [0.25] - 2017-09-14 55 | ### Changed 56 | - Minor bug in PyPi dependencies fixed 57 | 58 | ## [0.24] - 2017-07-21 59 | ### Changed 60 | - Minor bugs fixed 61 | 62 | ## [0.23] - 2017-07-15 63 | ### Added 64 | - `Check_update` function 65 | 66 | 67 | ### Changed 68 | - Minor bugs fixed 69 | 70 | ## [0.22] - 2017-03-30 71 | ### Added 72 | - `Version` function 73 | - `Supported_Device_List.md` 74 | 75 | ### Changed 76 | - Minor bugs fixed 77 | 78 | ## [0.2] - 2017-03-06 79 | ### Added 80 | - `idletime` function 81 | - `mount`,`unmount` functions 82 | 83 | ### Changed 84 | - Some bugs fixed 85 | 86 | ## [0.1] - 2017-02-15 87 | ### Added 88 | - Some useful scripts for Orangepi/Raspberrypi boards 89 | 90 | [Unreleased]: https://github.com/Moduland/Orangetool/compare/v0.50...dev 91 | [0.50]: https://github.com/Moduland/Orangetool/compare/v0.45...v0.50 92 | [0.45]: https://github.com/Moduland/Orangetool/compare/v0.35...v0.45 93 | [0.35]: https://github.com/Moduland/Orangetool/compare/v0.25...v0.35 94 | [0.25]: https://github.com/Moduland/Orangetool/compare/v0.24...v0.25 95 | [0.24]: https://github.com/Moduland/Orangetool/compare/v0.23...v0.24 96 | [0.23]: https://github.com/Moduland/Orangetool/compare/v0.22...v0.23 97 | [0.22]: https://github.com/Moduland/Orangetool/compare/v0.2...v0.22 98 | [0.2]: https://github.com/Moduland/Orangetool/compare/v0.1...v0.2 99 | [0.1]: https://github.com/Moduland/Orangetool/compare/1e238cd...v0.1 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Moduland Co 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include *.md 3 | include *.spec 4 | include *.txt 5 | include *.yml 6 | include *.ini 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | DOI 6 | 7 | 8 | 9 | 10 |
11 | 12 | ---------- 13 | 14 | ## Table of contents 15 | * [Overview](https://github.com/Moduland/Orangetool#overview) 16 | * [Installation](https://github.com/Moduland/Orangetool#installation) 17 | * [Usage](https://github.com/Moduland/Orangetool#usage) 18 | * [IP Functions](https://github.com/Moduland/Orangetool#ip-functions) 19 | * [RAM Functions](https://github.com/Moduland/Orangetool#ram-functions) 20 | * [Storage Functions](https://github.com/Moduland/Orangetool#storage-functions) 21 | * [Display Functions](https://github.com/Moduland/Orangetool#display-functions) 22 | * [System Functions](https://github.com/Moduland/Orangetool#system-functions) 23 | * [Issues & Bug Reports](https://github.com/Moduland/Orangetool#issues--bug-reports) 24 | * [Supported Device List](https://github.com/Moduland/Orangetool/blob/master/Supported_Device_List.md) 25 | * [Dependencies](https://github.com/Moduland/Orangetool#dependencies) 26 | * [Contribution](https://github.com/Moduland/Orangetool/blob/master/.github/CONTRIBUTING.md) 27 | * [Cite](https://github.com/Moduland/Orangetool#cite) 28 | * [Authors](https://github.com/Moduland/Orangetool/blob/master/AUTHORS.md) 29 | * [License](https://github.com/Moduland/Orangetool/blob/master/LICENSE) 30 | * [Donate](https://github.com/Moduland/Orangetool#donate-to-our-project) 31 | * [Changelog](https://github.com/Moduland/Orangetool/blob/master/CHANGELOG.md) 32 | * [Code of Conduct](https://github.com/Moduland/Orangetool/blob/master/.github/CODE_OF_CONDUCT.md) 33 | 34 | ## Overview 35 | 36 | Control functions for Single-Board computers 37 | 38 | Tested on [Lubuntu](http://lubuntu.me/) 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
Open Hub
PyPI Counter
Github Stars
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
Branchmasterdev
Travis
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
Code Qualitycodebeat badgeCodeFactor
79 | 80 | ---------- 81 | 82 | By [Moduland Co](http://www.moduland.ir) 83 | 84 | 85 | ## Installation 86 | ### Source Code 87 | - Download [Version 0.50](https://github.com/moduland/Orangetool/archive/v0.50.zip) or [Latest Source ](https://github.com/Moduland/Orangetool/archive/dev.zip) 88 | - `pip3 install -r requirements.txt` or `pip install -r requirements.txt` (Need root access) 89 | - `python3 setup.py install` or `python setup.py install` 90 | ### PyPI 91 | 92 | - Check [Python Packaging User Guide](https://packaging.python.org/installing/) 93 | - `pip3 install orangetool==0.50` or `pip install orangetool==0.50` (Need root access) 94 |
95 | 96 |
97 | 98 | ### Conda 99 | 100 | - Check [Conda Managing Package](https://conda.io/docs/user-guide/tasks/manage-pkgs.html#installing-packages-from-anaconda-org) 101 | - `conda install -c sepandhaghighi orangetool` (Need root access) 102 | 103 | ### Easy install 104 | 105 | - Run `easy_install --upgrade orangetool` (Need root access) 106 | 107 | ## Usage 108 | 109 | ### IP Functions 110 | 111 | ```python 112 | import orangetool 113 | 114 | #1- local_ip 115 | 116 | local_ip=orangetool.local_ip() # this function return local ip of board as string 117 | 118 | #2- global_ip 119 | 120 | global_ip=orangetool.global_ip() # this function return global ip of board as string 121 | 122 | #3- internet 123 | 124 | status=orangetool.internet() #this function check internet connection and return True if internet connection is stable 125 | 126 | #4- ping 127 | 128 | ip_status=orangetool.ping(ip_address) #this function check ip and return True if this ip is available in network and False otherwise 129 | 130 | #5- set_ip 131 | 132 | orangetool.set_ip("192.168.1.46","eth0") #this function set static ip for system 133 | 134 | #6- mac 135 | 136 | mac_dic=orangetool.mac() # return dict of all system net devices mac addresses 137 | 138 | #7- network_enable 139 | 140 | status=network_enable("eth0") # enable network device 141 | 142 | #8- network_disable 143 | 144 | status=network_disable("eth0") # disable network device 145 | 146 | ``` 147 | 148 | ### RAM Functions 149 | 150 | ```python 151 | 152 | #1- total ram 153 | 154 | ram=orangetool.ram_total() #this function return total ram of the board 155 | 156 | #2- free ram 157 | 158 | ram=orangetool.ram_free() # this function return how much ram is available in the board 159 | 160 | #3- ram percentage 161 | 162 | ram=orangetool.ram_percent() # this function return used ram percentage 163 | 164 | #4- used percentage 165 | 166 | ram=orangetool.ram_used() # this function return used ram 167 | 168 | #5- freeup 169 | 170 | orangetool.freeup() # To free pagecache, dentries and inodes and return freeuped amount 171 | 172 | ``` 173 | 174 | ### Storage Functions 175 | 176 | ```python 177 | #1- mount_status 178 | 179 | mount_details=orangetool.mount_status("sda1") # This function return mount addresses of input device 180 | 181 | #2- storage_status 182 | 183 | mount_details=orangetool.storage_status() # This function return all of the inserted storage and their status 184 | 185 | #3- unmount 186 | 187 | orangetool.unmount("/mnt/usb1") # This function unmount input device 188 | 189 | #4- unmount_all 190 | 191 | 192 | orangetool.unmount_all() #This function unmount all of the mounted devices 193 | 194 | #5- mount 195 | 196 | orangetool.mount("sda1","/mnt/usb1") # This function mount input device in input addresses 197 | 198 | #6- usb_on 199 | 200 | orangetool.usb_on() # This function enable USB 201 | 202 | #7- usb_off 203 | 204 | orangetool.usb_off() # This function disable USB 205 | 206 | ``` 207 | 208 | ### Display Functions 209 | 210 | ```python 211 | #1- hdmi_on 212 | 213 | orangetool.hdmi_on() # turn on hdmi port 214 | 215 | #2- hdmi_off 216 | 217 | orangetool.hdmi_off() # turn off hdmi port 218 | 219 | #3- hdmi_size 220 | 221 | orangetool.hdmi_size(1280,720) # this function change hdmi display resolution 222 | 223 | ``` 224 | 225 | ### System Functions 226 | 227 | ```python 228 | #1- sleep 229 | 230 | orangetool.sleep() # put system in sleep mode 231 | 232 | #2- hibernate 233 | 234 | orangetool.hibernate() # put system in hibernate mode 235 | 236 | #3- halt 237 | 238 | orangetool.halt() # poweroff system 239 | 240 | #4- restart 241 | 242 | orangetool.restart() # restart system 243 | 244 | #5- wakeup 245 | 246 | orangetool.wakeup(day=1,hour=0,minute=1,sync=True) # set rtc wakeuptime 247 | 248 | #6- get_temp 249 | 250 | temp=orangetool.get_temp() # this function return cpu temperature as string 251 | 252 | #7- uptime 253 | 254 | time=orangetool.uptime() # this function return uptime of system 255 | 256 | #8- idletime 257 | 258 | time=orangetool.idletime() # this function return idle of system ( all cores) 259 | 260 | 261 | #9- version 262 | 263 | orangetool.version() # return orangetool version for test 264 | 265 | #10- check_update 266 | 267 | orangetool.check_update() # Return True if new version is available 268 | 269 | ``` 270 | 271 | 272 | 273 | - All of the functions in error state return `Error` String 274 | - `local_ip` and `global_ip` originally are available in ipz package [Link](http://github.com/sepandhaghighi/ipz) 275 | - RAM functions in this version need psutil package 276 | - Running `set_ip` function remotely will freeze your terminal so it's better to set `restart` parameter to True 277 | - Running `halt`,`restart`,`hibernate` & `sleep` functions remotely will freeze your terminal 278 | - Some of funtions need root access so it's better to run ```sudo -s``` before use this tool 279 | 280 | 281 | 282 | ## Issues & Bug Reports 283 | 284 | Just fill an issue and describe it. We'll check it ASAP! 285 | or send an email to [info@orangetool.ir](mailto:info@orangetool.ir "info@orangetool.ir"). 286 | 287 | ## Dependencies 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 |
masterdev
299 | 300 | 301 | ## Cite 302 | If you use orangetool in your research , please cite this ;-) 303 | 304 |
305 |

Sepand Haghighi. 2017. Moduland/Orangetool: Version 0.23. (July 2017). DOI:http://dx.doi.org/10.5281/zenodo.829797

306 |
307 | 308 | 309 | 310 | ## Donate to our project 311 | 312 | If you feel like our project is important can you please support us? 313 | Our project is not and is never going to be working for profit. We need the money just so we can continue doing what we do. 314 | 315 |

Bitcoin :

316 | 317 | ```1XGr9qbZjBpUQJJSB6WtgBQbDTgrhPLPA``` 318 | 319 | 320 |

Payping (For Iranian citizens) :

321 | 322 | 323 | 324 | ## License 325 |
326 | 327 |
328 | Moduland Website 329 | 330 |
331 | 332 | 333 | 334 | 335 | 336 | -------------------------------------------------------------------------------- /Supported_Device_List.md: -------------------------------------------------------------------------------- 1 | # Supported Device List # 2 | 3 | ---------- 4 | - Orange Pi Zero Plus2 H3 5 | - Orange Pi Zero Plus2 H5 6 | - Orange Pi Prime 7 | - Orange Pi PC 2 8 | - Orange Pi Zero 9 | - Orange Pi PC Plus 10 | - Orange Pi Plus2e 11 | - Orange Pi Lite 12 | - Orange Pi Plus2 and Plus 13 | - Orange Pi PC 14 | - Orange Pi One 15 | - Orange Pi2 16 | - Raspberry Pi 2 17 | - Raspberry Pi 3 -------------------------------------------------------------------------------- /autopep8.bat: -------------------------------------------------------------------------------- 1 | python -m autopep8 orangetool --recursive --aggressive --aggressive --in-place --pep8-passes 2000 --verbose 2 | python -m autopep8 setup.py --recursive --aggressive --aggressive --in-place --pep8-passes 2000 --verbose 3 | python -m autopep8 version_check.py --recursive --aggressive --aggressive --in-place --pep8-passes 2000 --verbose -------------------------------------------------------------------------------- /dev-requirements.txt: -------------------------------------------------------------------------------- 1 | psutil==5.8.0 2 | requests==2.25.1 3 | art==5.1 4 | setuptools>=40.8.0 5 | vulture>=1.0 6 | bandit>=1.5.1 7 | pydocstyle>=3.0.0 8 | 9 | 10 | -------------------------------------------------------------------------------- /orangetool/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool modules.""" 3 | 4 | from .orangetool_display import hdmi_on, hdmi_off, hdmi_size 5 | from .orangetool_ip import internet, local_ip, global_ip, set_ip, ping, mac, network_disable, network_enable 6 | from .orangetool_system import check_update, get_temp, uptime, idletime, wakeup, version, sleep, hibernate, halt, restart 7 | from .orangetool_ram import ram_total, ram_used, ram_free, ram_percent, freeup 8 | from .orangetool_storage import mount_status, storage_status, unmount, unmount_all, mount, usb_on, usb_off 9 | from .orangetool_params import ORANGETOOL_VERSION 10 | 11 | __version__ = ORANGETOOL_VERSION 12 | -------------------------------------------------------------------------------- /orangetool/__main__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool main.""" 3 | 4 | from .orangetool_system import version 5 | 6 | if __name__ == "__main__": 7 | version() 8 | -------------------------------------------------------------------------------- /orangetool/orangetool_display.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool display functions.""" 3 | from .orangetool_params import GENERAL_ERROR_MESSAGE 4 | 5 | 6 | def hdmi_controller(command, debug=False): 7 | """ 8 | Control hdmi port. 9 | 10 | :param command: input command 11 | :type command: bool 12 | :param debug: flag for using debug mode 13 | :type debug: bool 14 | :return: bool 15 | """ 16 | try: 17 | hdmi_control = open("/sys/class/graphics/fb0/blank", "w") 18 | if command: 19 | hdmi_control.write("0") 20 | else: 21 | hdmi_control.write("4") 22 | hdmi_control.close() 23 | return True 24 | except Exception as e: 25 | if debug: 26 | print(str(e)) 27 | return GENERAL_ERROR_MESSAGE 28 | 29 | 30 | def hdmi_on(debug=False): 31 | """ 32 | Turn on hdmi port (need sudo -s). 33 | 34 | :param debug: flag for using debug mode 35 | :type debug:bool 36 | :return: bool 37 | """ 38 | hdmi_controller(True, debug) 39 | 40 | 41 | def hdmi_off(debug=False): 42 | """ 43 | Turn off hdmi port (need sudo -s). 44 | 45 | :param debug: flag for using debug mode 46 | :type debug:bool 47 | :return: bool 48 | """ 49 | hdmi_controller(False, debug) 50 | 51 | 52 | def hdmi_size(v=None, h=None, debug=False): 53 | """ 54 | Change hdmi display resolution (need sudo -s) (if call without any argument return current resolution). 55 | 56 | :param v: vertical line 57 | :type v : int 58 | :param h: horizontal line 59 | :type h: int 60 | :param debug: flag for using debug mode 61 | :type debug:bool 62 | :return: bool 63 | """ 64 | try: 65 | if (not isinstance(v, int)) or (not isinstance(h, int)): 66 | hdmi_control = open("/sys/class/graphics/fb0/virtual_size", "r") 67 | resolution = hdmi_control.read()[:-1].replace(",", "x") 68 | hdmi_control.close() 69 | return resolution 70 | hdmi_control = open("/sys/class/graphics/fb0/virtual_size", "w") 71 | hdmi_control.write(str(v) + "," + str(h)) 72 | hdmi_control.close() 73 | return True 74 | except Exception as e: 75 | if debug: 76 | print(str(e)) 77 | return GENERAL_ERROR_MESSAGE 78 | -------------------------------------------------------------------------------- /orangetool/orangetool_ip.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool IP functions.""" 3 | from .orangetool_system import restart as restart_func 4 | from .orangetool_params import IP_PATTERN, GLOBAL_IP_API_1, GENERAL_ERROR_MESSAGE 5 | import subprocess as sub 6 | import socket 7 | import os 8 | import requests 9 | import re 10 | import platform 11 | 12 | 13 | def internet(host="8.8.8.8", port=53, timeout=3, debug=False): 14 | """ 15 | Check internet connections. 16 | 17 | :param host: the host that check connection to 18 | :type host:str 19 | :param port: port that check connection with 20 | :type port:int 21 | :param timeout: times that check the connection 22 | :type timeout:int 23 | :param debug:flag for using debug mode 24 | :type debug:bool 25 | :return bool: True if connection is stable 26 | >>> internet() # if there is stable internet connection 27 | True 28 | >>> internet() # if there is no stable internet connection 29 | False 30 | """ 31 | try: 32 | socket.setdefaulttimeout(timeout) 33 | socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port)) 34 | return True 35 | except Exception as e: 36 | if debug: 37 | print(str(e)) 38 | return False 39 | 40 | 41 | def local_ip(debug=False): 42 | """ 43 | Return local ip of computer in windows by socket module and in unix with hostname command in shell. 44 | 45 | :param debug:flag for using debug mode 46 | :type debug:bool 47 | :return: local ip as string 48 | """ 49 | try: 50 | ip = socket.gethostbyname(socket.gethostname()) 51 | if ip != "127.0.0.1": 52 | return ip 53 | if platform.system() != "Windows": 54 | command = sub.Popen(["hostname", 55 | "-I"], 56 | stdout=sub.PIPE, 57 | stderr=sub.PIPE, 58 | stdin=sub.PIPE, 59 | shell=False) 60 | response = list(command.communicate()) 61 | if len(response[0]) > 0: 62 | return str(response[0])[2:-4] 63 | return GENERAL_ERROR_MESSAGE 64 | return GENERAL_ERROR_MESSAGE 65 | 66 | except Exception as e: 67 | if debug: 68 | print(str(e)) 69 | return GENERAL_ERROR_MESSAGE 70 | 71 | 72 | def global_ip(debug=False): 73 | """ 74 | Return ip with by http://ipinfo.io/ip api. 75 | 76 | :param debug:flag for using debug mode 77 | :type debug:bool 78 | :return: global ip as string 79 | """ 80 | try: 81 | new_session = requests.session() 82 | response = new_session.get(GLOBAL_IP_API_1) 83 | ip_list = re.findall(IP_PATTERN, response.text) 84 | new_session.close() 85 | return ip_list[0] 86 | except Exception as e: 87 | if debug: 88 | print(str(e)) 89 | return GENERAL_ERROR_MESSAGE 90 | 91 | 92 | def set_ip(ip, restart=False, device="eth0", debug=False): 93 | """ 94 | Set static ip in interfaces file (need sudo). 95 | 96 | :param ip: static ip 97 | :type ip :str 98 | :param restart : restart flag 99 | :type restart : bool 100 | :param device: network device name 101 | :type device:str 102 | :param debug: flag for using debug mode 103 | :type debug:bool 104 | :return: True in successful 105 | """ 106 | static_string = ''' 107 | auto lo device 108 | iface lo inet loopback 109 | iface device inet static 110 | address ip 111 | netmask 255.255.255.0 112 | gateway 192.168.1.1 113 | dns-nameservers 8.8.8.8 8.8.4.4 114 | ''' 115 | try: 116 | if not bool(re.match(IP_PATTERN, ip)) or ip.find( 117 | "192.168.") == -1 or device not in mac().keys(): 118 | raise Exception("IP Formation Error") 119 | static_string = static_string.replace("ip", ip) 120 | static_string = static_string.replace("device", device) 121 | file = open("/etc/network/interfaces", "w") 122 | file.write(static_string) 123 | file.close() 124 | sub.Popen(["ifdown", device, "&&", "ifup", device], 125 | stderr=sub.PIPE, stdin=sub.PIPE, stdout=sub.PIPE) 126 | if restart: 127 | restart_func() 128 | return True 129 | except Exception as e: 130 | if debug: 131 | print(str(e)) 132 | return GENERAL_ERROR_MESSAGE 133 | 134 | 135 | def ping(ip, packet_number=3, debug=False): 136 | """ 137 | Ping ip and return True if this ip is available and False otherwise. 138 | 139 | :param ip: target ip 140 | :type ip :str 141 | :param packet_number: number of packet to size 142 | :type packet_number:int 143 | :param debug: flag for using debug mode 144 | :type debug:bool 145 | :return: a boolean value (True if ip is available and False otherwise) 146 | """ 147 | try: 148 | if not re.match(IP_PATTERN, ip): 149 | raise Exception("IP Formation Error") 150 | output = str(list(sub.Popen(["ping", 151 | ip, 152 | "-c", 153 | str(packet_number)], 154 | stdout=sub.PIPE, 155 | stderr=sub.PIPE).communicate())[0]) 156 | if output.find("Unreachable") == -1: 157 | return True 158 | return False 159 | except Exception as e: 160 | if debug: 161 | print(str(e)) 162 | return GENERAL_ERROR_MESSAGE 163 | 164 | 165 | def mac(debug=False): 166 | """ 167 | Return mac addresses of net devices. 168 | 169 | :param debug: flag for using debug mode 170 | :type debug:bool 171 | :return: return mac addresses as dict with name as keys and mac addresses as values 172 | """ 173 | try: 174 | net_dir = "/sys/class/net" 175 | mac_list = [] 176 | dir_list = os.listdir(net_dir) 177 | for item in dir_list: 178 | mac_addr = open(net_dir + "/" + item + "/address", "r") 179 | mac_list.append(mac_addr.read()[:-1]) 180 | mac_addr.close() 181 | return dict(zip(dir_list, mac_list)) 182 | except Exception as e: 183 | if debug: 184 | print(str(e)) 185 | return GENERAL_ERROR_MESSAGE 186 | 187 | 188 | def network_control(command, device="eth0", debug=False): 189 | """ 190 | Control network adaptor. 191 | 192 | :param command: input command 193 | :type command: str 194 | :param device: network device name 195 | :type device:str 196 | :param debug: flag for using debug mode 197 | :type debug:bool 198 | :return: True in successful and False otherwise 199 | """ 200 | try: 201 | cmd = "up" 202 | if command == "down": 203 | cmd = "down" 204 | cmd_out = sub.Popen(["ifconfig", device, cmd], 205 | stderr=sub.PIPE, stdin=sub.PIPE, stdout=sub.PIPE) 206 | output = list(cmd_out.communicate()) 207 | if len(output[0]) == 0 and len(output[1]) == 0: 208 | return True 209 | return False 210 | except Exception as e: 211 | if debug: 212 | print(str(e)) 213 | return GENERAL_ERROR_MESSAGE 214 | 215 | 216 | def network_enable(device="eth0", debug=False): 217 | """ 218 | Shortcut to enable network adaptor. 219 | 220 | :param device: network device name 221 | :type device:str 222 | :param debug: flag for using debug mode 223 | :type debug:bool 224 | :return: True in successful and False otherwise 225 | """ 226 | return network_control("up", device=device, debug=debug) 227 | 228 | 229 | def network_disable(device="eth0", debug=False): 230 | """ 231 | Shortcut to disable network adaptor. 232 | 233 | :param device: network device name 234 | :type device:str 235 | :param debug: flag for using debug mode 236 | :type debug:bool 237 | :return: True in successful and False otherwise 238 | """ 239 | return network_control("down", device=device, debug=debug) 240 | -------------------------------------------------------------------------------- /orangetool/orangetool_params.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool params.""" 3 | 4 | ORANGETOOL_VERSION = "0.50" 5 | UPDATE_URL = "http://www.orangetool.ir/version" 6 | IP_PATTERN = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}" 7 | GLOBAL_IP_API_1 = "http://ipinfo.io/ip" 8 | GENERAL_ERROR_MESSAGE = "Error" 9 | ROOT_ERROR_MESSAGE = "Root Error" 10 | -------------------------------------------------------------------------------- /orangetool/orangetool_ram.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool RAM functions.""" 3 | import psutil 4 | from .orangetool_params import GENERAL_ERROR_MESSAGE 5 | from .orangetool_utils import convert_bytes 6 | 7 | 8 | def ram_total(convert=True): 9 | """ 10 | Return total ram of board. 11 | 12 | :param convert: flag for convert mode (using of convert_byte function) 13 | :type convert:bool 14 | :return: total ram of board as string 15 | """ 16 | response = list(psutil.virtual_memory()) 17 | if convert: 18 | return convert_bytes(int(response[0])) 19 | return str(response[0]) 20 | 21 | 22 | def ram_used(convert=True): 23 | """ 24 | Return how much ram is using. 25 | 26 | :param convert: flag for convert mode (using of convert_byte function) 27 | :type convert:bool 28 | :return: how much ram is using as string 29 | """ 30 | response = list(psutil.virtual_memory()) 31 | if convert: 32 | return convert_bytes(int(response[3])) 33 | return str(response[3]) 34 | 35 | 36 | def ram_free(convert=True): 37 | """ 38 | Return how much ram is available. 39 | 40 | :param convert: flag for convert mode (using of convert_byte function) 41 | :type convert : bool 42 | :return: how much ram is available 43 | """ 44 | response = list(psutil.virtual_memory()) 45 | if convert: 46 | return convert_bytes(int(response[1])) 47 | return str(response[1]) 48 | 49 | 50 | def ram_percent(): 51 | """ 52 | Return available ram percentage. 53 | 54 | :return: available ram percentage as string with % 55 | """ 56 | response = list(psutil.virtual_memory()) 57 | return str(response[2]) + " %" 58 | 59 | 60 | def freeup(debug=False): 61 | """ 62 | To free pagecache, dentries and inodes. 63 | 64 | :param debug: flag for using debug mode 65 | :type debug:bool 66 | :return: amount of freeuped ram as string and converted by convert_bytes() 67 | """ 68 | try: 69 | RAM_before = int(ram_free(convert=False)) 70 | caches_control = open("/proc/sys/vm/drop_caches", "w") 71 | caches_control.write("3") 72 | caches_control.close() 73 | RAM_after = int(ram_free(convert=False)) 74 | freeuped_ram = RAM_after - RAM_before 75 | if freeuped_ram > 0: 76 | return convert_bytes(freeuped_ram) 77 | return convert_bytes(0) 78 | except Exception as e: 79 | if debug: 80 | print(str(e)) 81 | return GENERAL_ERROR_MESSAGE 82 | -------------------------------------------------------------------------------- /orangetool/orangetool_storage.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool storage functions.""" 3 | import subprocess as sub 4 | import os 5 | import string 6 | from .orangetool_params import GENERAL_ERROR_MESSAGE, ROOT_ERROR_MESSAGE 7 | from .orangetool_utils import random_generator 8 | 9 | 10 | def mount_status(device_name, debug=False): 11 | """ 12 | Return addresses of mounted memory devices in dev by device name. 13 | 14 | :param device_name: name of device 15 | :type device_name: str 16 | :param debug: flag for using debug mode 17 | :type debug:bool 18 | :return: list of memory devices 19 | """ 20 | try: 21 | file = open("/proc/mounts") 22 | output = file.readlines() 23 | memory_list = [] 24 | for item in output: 25 | temp = item.split(" ") 26 | if temp[0].find(device_name) != -1: 27 | memory_list.append(temp[1]) 28 | if len(memory_list) == 0: 29 | return "u" 30 | return memory_list 31 | except Exception as e: 32 | if debug: 33 | print(str(e)) 34 | return GENERAL_ERROR_MESSAGE 35 | 36 | 37 | def storage_status(debug=False): 38 | """ 39 | Return all of the inserted memory and their status. 40 | 41 | :param debug: flag for using debug mode 42 | :type debug:bool 43 | :return: all of the inserted memory and their status as dictionary ( device name as keys and mount status (mounted_addresses as list and u --> unmounted) as values 44 | """ 45 | try: 46 | folder_items = os.listdir("/dev/") 47 | memory_items = [] 48 | memory_status = [] 49 | for i in string.ascii_lowercase: 50 | if "sd" + i + "1" in folder_items: 51 | memory_items.append("sd" + i + "1") 52 | for item in memory_items: 53 | memory_status.append(mount_status(item)) 54 | return dict(zip(memory_items, memory_status)) 55 | except Exception as e: 56 | if debug: 57 | print(str(e)) 58 | return GENERAL_ERROR_MESSAGE 59 | 60 | 61 | def unmount(address, debug=False): 62 | """ 63 | Unmount memory devices by addresses. 64 | 65 | :param address: address of that device mount on 66 | :type address:str 67 | :param debug: flag for using debug mode 68 | :type debug:bool 69 | :return: True if device unmount correctly and False other wise 70 | """ 71 | try: 72 | command = sub.Popen(["umount", address], 73 | stdout=sub.PIPE, stderr=sub.PIPE) 74 | output = list(command.communicate()) 75 | if len(output[0]) == 0 and len(output[1]) == 0: 76 | return True 77 | return False 78 | except Exception as e: 79 | if debug: 80 | print(str(e)) 81 | return GENERAL_ERROR_MESSAGE 82 | 83 | 84 | def unmount_all(debug=False): 85 | """ 86 | Unmount all of the mounted devices. 87 | 88 | :param debug: flag for using debug mode 89 | :type debug:bool 90 | :return: return True if all of the mounted devices unmount correctly 91 | """ 92 | try: 93 | storage_output = storage_status() 94 | storage_keys = list(storage_output.keys()) 95 | storage_values = list(storage_output.values()) 96 | for i, item in enumerate(storage_values): 97 | if storage_values[i] != "u": 98 | print(item) 99 | for j in item: 100 | unmount(j) 101 | return True 102 | except Exception as e: 103 | if debug: 104 | print(str(e)) 105 | return GENERAL_ERROR_MESSAGE 106 | 107 | 108 | def mount(device_name, mount_address=None, debug=False): 109 | """ 110 | Mount memory devices by addresses. 111 | 112 | :param device_name: name of device for mounted example = sda1 113 | :type device_name:str 114 | :param mount_address: address for mounting device example = /mnt/usb , default value is None in this case function generate random number for mount folder name 115 | :type mount_address:str 116 | :param debug: flag for using debug mode 117 | :type debug:bool 118 | :return: True if device mount correctly and False other wise 119 | """ 120 | try: 121 | if mount_status(device_name) != "u": 122 | raise Exception("Device already mount") 123 | if mount_address is None: 124 | mount_address = "/mnt/" + random_generator(5) 125 | command = sub.Popen(["mkdir", mount_address], 126 | stdout=sub.PIPE, stderr=sub.PIPE) 127 | command = sub.Popen(["mount", 128 | "/dev/" + device_name, 129 | mount_address], 130 | stdout=sub.PIPE, 131 | stderr=sub.PIPE) 132 | output = list(command.communicate()) 133 | if len(output[0]) == 0 and len(output[1]) == 0: 134 | return True 135 | return False 136 | except Exception as e: 137 | if debug: 138 | print(str(e)) 139 | return GENERAL_ERROR_MESSAGE 140 | 141 | 142 | def usb_control(code, debug=False): 143 | """ 144 | Control different usb options. 145 | 146 | :param code: permission code 147 | :type code: str 148 | :param debug: flag for using debug mode 149 | :type debug: bool 150 | :return: None 151 | """ 152 | try: 153 | command = sub.Popen( 154 | ["chmod", "-R", code, "/media/"], 155 | stderr=sub.PIPE, 156 | stdout=sub.PIPE, 157 | stdin=sub.PIPE) 158 | response = list(command.communicate()) 159 | if len(response[1]) > 0: 160 | raise Exception(ROOT_ERROR_MESSAGE) 161 | except Exception as e: 162 | if debug: 163 | print(str(e)) 164 | return GENERAL_ERROR_MESSAGE 165 | 166 | 167 | def usb_on(debug=False): 168 | """ 169 | Shortcut for enable usb (need sudo). 170 | 171 | :param debug: flag for using debug mode 172 | :type debug:bool 173 | :return: None 174 | """ 175 | usb_control("777", debug) 176 | 177 | 178 | def usb_off(debug=False): 179 | """ 180 | Shortcut for disable usb (need sudo). 181 | 182 | :param debug: flag for using debug mode 183 | :type debug:bool 184 | :return: None 185 | """ 186 | usb_control("000", debug) 187 | -------------------------------------------------------------------------------- /orangetool/orangetool_system.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool system functions.""" 3 | import subprocess as sub 4 | from .orangetool_params import ORANGETOOL_VERSION, UPDATE_URL, GENERAL_ERROR_MESSAGE, ROOT_ERROR_MESSAGE 5 | from .orangetool_utils import time_convert 6 | import time 7 | import requests 8 | from art import tprint 9 | 10 | 11 | def check_update(debug=False): 12 | """ 13 | Check orangetool site for new version. 14 | 15 | :param debug: flag for using debug mode 16 | :type debug:bool 17 | :return: True if new version is available 18 | """ 19 | try: 20 | new_version = requests.get(UPDATE_URL).text 21 | if float(new_version) > float(ORANGETOOL_VERSION): 22 | print("New Version (" + new_version + ") Of Orangetool Is Available") 23 | return True 24 | print("Update!") 25 | return False 26 | except Exception as e: 27 | if debug: 28 | print(str(e)) 29 | return GENERAL_ERROR_MESSAGE 30 | 31 | 32 | def get_temp(zone=0, debug=False): 33 | """ 34 | Read cpu temperature. 35 | 36 | :param zone : thermal zone index 37 | :type zone:int 38 | :param debug : flag for using debug mode 39 | :type debug:bool 40 | :return: board temp as string in celsius 41 | """ 42 | try: 43 | command = open("/sys/class/thermal/thermal_zone" + str(zone) + "/temp") 44 | # command=sub.Popen(["cat","/sys/class/thermal/thermal_zone"+str(zone)+"/temp"],stderr=sub.PIPE,stdin=sub.PIPE,stdout=sub.PIPE) 45 | # response=list(command.communicate()) 46 | response = command.read() 47 | return response[:-1] 48 | # if len(response[0])!=0: 49 | # return str(response[0])[2:-3] 50 | # else: 51 | # return GENERAL_ERROR_MESSAGE 52 | except Exception as e: 53 | if debug: 54 | print(str(e)) 55 | return GENERAL_ERROR_MESSAGE 56 | 57 | 58 | def time_control(mode="uptime", debug=False): 59 | """ 60 | Return system time. 61 | 62 | :param mode: time mode (uptime / idle) 63 | :type mode: str 64 | :param debug: flag for using debug mode 65 | :type debug:bool 66 | :return: system time as string 67 | """ 68 | index = 0 69 | if mode in ["idle", "idletime"]: 70 | index = 1 71 | try: 72 | command = open("/proc/uptime") 73 | response = command.read() 74 | return time_convert(response[:-1].split(" ")[index]) 75 | except Exception as e: 76 | if debug: 77 | print(str(e)) 78 | return GENERAL_ERROR_MESSAGE 79 | 80 | 81 | def uptime(debug=False): 82 | """ 83 | Return system uptime. 84 | 85 | :param debug: flag for using debug mode 86 | :type debug:bool 87 | :return: system uptime as string 88 | """ 89 | return time_control(mode="uptime", debug=debug) 90 | 91 | 92 | def idletime(debug=False): 93 | """ 94 | Return system idletime. 95 | 96 | :param debug: flag for using debug mode 97 | :type debug:bool 98 | :return: system idle as string 99 | """ 100 | return time_control(mode="idle", debug=debug) 101 | 102 | 103 | def version(): 104 | """ 105 | Return orangetool version. 106 | 107 | :return: return orangetool-version number as string 108 | """ 109 | tprint("orangetool", font="bulbhead") 110 | tprint("v" + ORANGETOOL_VERSION, font="bulbhead") 111 | 112 | 113 | def wakeup(day=0, hour=0, minute=0, sync=True, debug=False): 114 | """ 115 | Set wakeup time for kernel RTC (need sudo). 116 | 117 | :param day: days for wakeup 118 | :type day:int 119 | :param hour: hour for wakeup 120 | :type hour:int 121 | :param minute: minute for wakeup 122 | :type minute:int 123 | :param sync: RTC sync flag 124 | :type sync: bool 125 | :param debug: flag for using debug mode 126 | :type debug:bool 127 | :return: bool 128 | """ 129 | try: 130 | if sync: 131 | _ = sub.Popen( 132 | ["hwclock", "-w"], 133 | stderr=sub.PIPE, 134 | stdout=sub.PIPE, 135 | stdin=sub.PIPE) 136 | total_time = day * 24 * 60 + hour * 60 + minute 137 | epoch = time.time() + total_time * 60 138 | file = open("/sys/class/rtc/rtc0/wakealarm", "w") 139 | file.write("0") 140 | file.close() 141 | file = open("/sys/class/rtc/rtc0/wakealarm", "w") 142 | file.write(str(epoch)) 143 | file.close() 144 | return True 145 | except Exception as e: 146 | if debug: 147 | print(str(e)) 148 | return GENERAL_ERROR_MESSAGE 149 | 150 | 151 | def power_control(command, debug=False): 152 | """ 153 | Control different power options. 154 | 155 | :param command: input command 156 | :type command: str 157 | :param debug: flag for using debug mode 158 | :type debug: bool 159 | :return: None 160 | """ 161 | try: 162 | command = sub.Popen( 163 | command, 164 | stderr=sub.PIPE, 165 | stdout=sub.PIPE, 166 | stdin=sub.PIPE) 167 | response = list(command.communicate()) 168 | if len(response[1]) > 0: 169 | raise Exception(ROOT_ERROR_MESSAGE) 170 | except Exception as e: 171 | if debug: 172 | print(str(e)) 173 | return GENERAL_ERROR_MESSAGE 174 | 175 | 176 | def sleep(debug=False): 177 | """ 178 | Shortcut for sleep command (need sudo). 179 | 180 | :param debug: flag for using debug mode 181 | :type debug:bool 182 | :return: None 183 | """ 184 | power_control("pm-suspend", debug) 185 | 186 | 187 | def hibernate(debug=False): 188 | """ 189 | Shortcut for hibernate command (need sudo). 190 | 191 | :param debug: flag for using debug mode 192 | :type debug:bool 193 | :return: None 194 | """ 195 | power_control("pm-hibernate", debug) 196 | 197 | 198 | def halt(debug=False): 199 | """ 200 | Shortcut for poweroff (need sudo). 201 | 202 | :param debug: flag for using debug mode 203 | :type debug:bool 204 | :return: None 205 | """ 206 | power_control("poweroff", debug) 207 | 208 | 209 | def restart(debug=False): 210 | """ 211 | Shortcut for reboot (need sudo). 212 | 213 | :param debug: flag for using debug mode 214 | :type debug:bool 215 | :return: None 216 | """ 217 | power_control("reboot", debug) 218 | -------------------------------------------------------------------------------- /orangetool/orangetool_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool test.""" 3 | from orangetool import version, check_update 4 | 5 | if __name__ == "__main__": 6 | version() 7 | check_update() 8 | -------------------------------------------------------------------------------- /orangetool/orangetool_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Orangetool utils.""" 3 | import random 4 | 5 | 6 | def zero_insert(input_string): 7 | """ 8 | Get a string as input if input is one digit add a zero. 9 | 10 | :param input_string: input digit az string 11 | :type input_string:str 12 | :return: modified output as str 13 | """ 14 | if len(input_string) == 1: 15 | return "0" + input_string 16 | return input_string 17 | 18 | 19 | def time_convert(input_string): 20 | """ 21 | Convert input_string from sec to DD,HH,MM,SS Format. 22 | 23 | :param input_string: input time string in sec 24 | :type input_string:str 25 | :return: converted time as string 26 | """ 27 | input_sec = float(input_string) 28 | input_minute = input_sec // 60 29 | input_sec = int(input_sec - input_minute * 60) 30 | input_hour = input_minute // 60 31 | input_minute = int(input_minute - input_hour * 60) 32 | input_day = int(input_hour // 24) 33 | input_hour = int(input_hour - input_day * 24) 34 | return zero_insert(str(input_day)) + " days, " + zero_insert(str(input_hour)) + " hour, " + \ 35 | zero_insert(str(input_minute)) + " minutes, " + zero_insert(str(input_sec)) + " seconds" 36 | 37 | 38 | def random_generator(number): 39 | """ 40 | Generate random number. 41 | 42 | :param number: random number digits 43 | :type number: int 44 | :return: random number as str 45 | """ 46 | response = "" 47 | i = 0 48 | while(i < number): 49 | i += 1 50 | response += str(random.randint(0, 9)) 51 | return response 52 | 53 | 54 | def convert_bytes(num): 55 | """ 56 | Convert num to idiomatic byte unit. 57 | 58 | :param num: the input number. 59 | :type num:int 60 | :return: str 61 | >>> convert_bytes(200) 62 | '200.0 bytes' 63 | >>> convert_bytes(6000) 64 | '5.9 KB' 65 | >>> convert_bytes(80000) 66 | '78.1 KB' 67 | """ 68 | for x in ['bytes', 'KB', 'MB', 'GB', 'TB']: 69 | if num < 1024.0: 70 | return "%3.1f %s" % (num, x) 71 | num /= 1024.0 72 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | psutil>=5.2.1 2 | requests>=2.14.0 3 | art>=0.9 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal = 1 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Setup module.""" 3 | try: 4 | from setuptools import setup 5 | except ImportError: 6 | from distutils.core import setup 7 | 8 | 9 | def get_requires(): 10 | """Read requirements.txt.""" 11 | requirements = open("requirements.txt", "r").read() 12 | return list(filter(lambda x: x != "", requirements.split())) 13 | 14 | 15 | def read_description(): 16 | """Read README.md and CHANGELOG.md.""" 17 | try: 18 | with open("README.md") as r: 19 | description = "\n" 20 | description += r.read() 21 | with open("CHANGELOG.md") as c: 22 | description += "\n" 23 | description += c.read() 24 | return description 25 | except Exception: 26 | return "Some useful script for Orangepi/Raspberrypi boards" 27 | 28 | 29 | setup( 30 | name='orangetool', 31 | packages=['orangetool'], 32 | version='0.50', 33 | description='Some useful script for Orangepi/Raspberrypi boards', 34 | long_description=read_description(), 35 | long_description_content_type='text/markdown', 36 | author='Moduland Co', 37 | author_email='info@orangetool.ir', 38 | url='https://github.com/Moduland/Orangetool', 39 | download_url='https://github.com/Moduland/Orangetool/tarball/v0.50', 40 | keywords="orangepi raspberrypi embedded-systems python", 41 | classifiers=[ 42 | 'Development Status :: 4 - Beta', 43 | 'Intended Audience :: Developers', 44 | 'Natural Language :: English', 45 | 'License :: OSI Approved :: MIT License', 46 | 'Operating System :: Unix', 47 | 'Intended Audience :: Developers', 48 | 'Programming Language :: Python :: 3.5', 49 | 'Programming Language :: Python :: 3.6', 50 | 'Programming Language :: Python :: 3.7', 51 | 'Programming Language :: Python :: 3.8', 52 | 'Programming Language :: Python :: 3.9', 53 | 'Topic :: Scientific/Engineering', 54 | ], 55 | install_requires=get_requires(), 56 | license='MIT', 57 | ) 58 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | set -x 3 | python version_check.py 4 | python orangetool/orangetool_test.py 5 | python -m orangetool 6 | if [ "$TRAVIS_PYTHON_VERSION" = '3.6' ] 7 | then 8 | python -m vulture orangetool/ setup.py version_check.py --min-confidence 65 --sort-by-size 9 | python -m bandit -r orangetool -s B607,B603,B404,B311 10 | python -m pydocstyle -v --match-dir=orangetool 11 | fi -------------------------------------------------------------------------------- /version_check.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """Version-check script.""" 3 | import os 4 | import sys 5 | import codecs 6 | Failed = 0 7 | VERSION = "0.50" 8 | 9 | 10 | SETUP_ITEMS = [ 11 | "version='{0}'", 12 | 'https://github.com/Moduland/Orangetool/tarball/v{0}'] 13 | README_ITEMS = [ 14 | "[Version {0}](https://github.com/moduland/Orangetool/archive/v{0}.zip)", 15 | "pip install orangetool=={0}", 16 | "pip3 install orangetool=={0}"] 17 | CHANGELOG_ITEMS = [ 18 | "## [{0}]", 19 | "https://github.com/Moduland/Orangetool/compare/v{0}...dev", 20 | "[{0}]:"] 21 | PARAMS_ITEMS = ['ORANGETOOL_VERSION = "{0}"'] 22 | FILES = { 23 | "setup.py": SETUP_ITEMS, 24 | "README.md": README_ITEMS, 25 | "CHANGELOG.md": CHANGELOG_ITEMS, 26 | os.path.join( 27 | "orangetool", 28 | "orangetool_params.py"): PARAMS_ITEMS} 29 | 30 | TEST_NUMBER = len(FILES.keys()) 31 | 32 | 33 | def print_result(failed=False): 34 | """ 35 | Print final result. 36 | 37 | :param failed: failed flag 38 | :type failed: bool 39 | :return: None 40 | """ 41 | message = "Version tag tests " 42 | if not failed: 43 | print("\n" + message + "passed!") 44 | else: 45 | print("\n" + message + "failed!") 46 | print("Passed : " + str(TEST_NUMBER - Failed) + "/" + str(TEST_NUMBER)) 47 | 48 | 49 | if __name__ == "__main__": 50 | for file_name in FILES.keys(): 51 | try: 52 | file_content = codecs.open( 53 | file_name, "r", "utf-8", 'ignore').read() 54 | for test_item in FILES[file_name]: 55 | if file_content.find(test_item.format(VERSION)) == -1: 56 | print("Incorrect version tag in " + file_name) 57 | Failed += 1 58 | break 59 | except Exception as e: 60 | Failed += 1 61 | print("Error in " + file_name + "\n" + "Message : " + str(e)) 62 | 63 | if Failed == 0: 64 | print_result(False) 65 | sys.exit(0) 66 | else: 67 | print_result(True) 68 | sys.exit(1) 69 | --------------------------------------------------------------------------------