├── .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 |

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 | Open Hub |
43 |  |
44 |
45 |
46 | PyPI Counter |
47 |  |
48 |
49 |
50 | Github Stars |
51 |  |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Branch |
60 | master |
61 | dev |
62 |
63 |
64 | Travis |
65 |  |
66 |  |
67 |
68 |
69 |
70 |
71 |
72 |
73 | Code Quality |
74 |  |
75 |  |
76 |  |
77 |
78 |
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 | master |
292 | dev |
293 |
294 |
295 |  |
296 |  |
297 |
298 |
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 |

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 |
--------------------------------------------------------------------------------