Allow file upload on Jarvis API

Delete SMS sent via Jarvis on Gmail's SentItems
Implement fall back for GPT with history mapping
Make recognizer settings as default
Move alarms and reminders to fileio
Fix inconsistent volume on RokuTV
Update documentation references to CNAME record
This commit is contained in:
thevickypedia
2023-09-10 23:24:42 -05:00
parent 932f8405f7
commit 7e8fce1a73
30 changed files with 149 additions and 122 deletions

View File

@@ -1,7 +1,7 @@
<p align="center" style="text-align: center">
<img src="https://vigneshrao.com/Jarvis/logo.png" width="371px" height="350px">
</p>
<h2 align="center">Fully Functional Voice Based Natural Language UI</h2>
<h2 align="center">Voice-Activated Natural Language UI</h2>
[![made-with-python](https://img.shields.io/badge/Made%20with-Python-blue?style=for-the-badge&logo=Python)](https://python.org)
@@ -189,7 +189,8 @@ Environment variables are loaded from a `.env` file and validated using `pydanti
Please use [recognizer.py](https://github.com/thevickypedia/Jarvis/blob/master/jarvis/modules/microphone/recognizer.py) to figure out the suitable values on a trial and error basis.
Sample settings (formatted as JSON object)
- `RECOGNIZER_SETTINGS`: `'{"energy_threshold": 1100, "dynamic_energy_threshold": false, "pause_threshold": 2, "phrase_threshold": 0.1, "non_speaking_duration": 2}'`
<br>
`RECOGNIZER_SETTINGS`: `'{"energy_threshold": 1100, "dynamic_energy_threshold": false, "pause_threshold": 2, "phrase_threshold": 0.1, "non_speaking_duration": 2}'`
**Description**
- `energy_threshold`: Minimum audio energy to consider for recording. Greater the value, louder the voice should be.
@@ -587,7 +588,7 @@ pre-commit run --all-files
## Runbook
[![made-with-sphinx-doc](https://img.shields.io/badge/Code%20Docs-Sphinx-1f425f.svg)](https://www.sphinx-doc.org/en/master/man/sphinx-autogen.html)
[https://thevickypedia.github.io/Jarvis/](https://thevickypedia.github.io/Jarvis/)
[https://jarvis-docs.vigneshrao.com/](https://jarvis-docs.vigneshrao.com/)
## License & copyright

View File

@@ -19,7 +19,7 @@
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="prev" title="Welcome to Jarviss documentation!" href="index.html" />
<link rel="prev" title="Jarvis - Voice-Activated Natural Language UI" href="index.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@@ -31,7 +31,7 @@
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="index.html" title="Welcome to Jarviss documentation!"
<a href="index.html" title="Jarvis - Voice-Activated Natural Language UI"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Jarvis documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Kick off</a></li>
@@ -46,7 +46,7 @@
<p align="center" style="text-align: center">
<img src="https://vigneshrao.com/Jarvis/logo.png" width="371px" height="350px">
</p>
<h2 align="center">Fully Functional Voice Based Natural Language UI</h2><p><a class="reference external" href="https://python.org"><img alt="made-with-python" src="https://img.shields.io/badge/Made%20with-Python-blue?style=for-the-badge&amp;logo=Python" /></a></p>
<h2 align="center">Voice-Activated Natural Language UI</h2><p><a class="reference external" href="https://python.org"><img alt="made-with-python" src="https://img.shields.io/badge/Made%20with-Python-blue?style=for-the-badge&amp;logo=Python" /></a></p>
<p><img alt="Python" src="https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11-orange" />
<a class="reference external" href="https://pypi.org/project/jarvis-ironman"><img alt="Pypi-downloads" src="https://img.shields.io/pypi/dm/jarvis-ironman" /></a></p>
<p><strong>Platform Supported</strong></p>
@@ -222,10 +222,9 @@
<details>
<summary><strong><i>Custom settings for speech recognition</i></strong></summary><p>These are customized according to the authors voice pitch.
Please use <a class="reference external" href="https://github.com/thevickypedia/Jarvis/blob/master/jarvis/modules/microphone/recognizer.py">recognizer.py</a> to figure out the suitable values on a trial and error basis.</p>
<p>Sample settings (formatted as JSON object)</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">RECOGNIZER_SETTINGS</span></code>: <code class="docutils literal notranslate"><span class="pre">'{&quot;energy_threshold&quot;:</span> <span class="pre">1100,</span> <span class="pre">&quot;dynamic_energy_threshold&quot;:</span> <span class="pre">false,</span> <span class="pre">&quot;pause_threshold&quot;:</span> <span class="pre">2,</span> <span class="pre">&quot;phrase_threshold&quot;:</span> <span class="pre">0.1,</span> <span class="pre">&quot;non_speaking_duration&quot;:</span> <span class="pre">2}'</span></code></p></li>
</ul>
<p>Sample settings (formatted as JSON object)
<br>
<code class="docutils literal notranslate"><span class="pre">RECOGNIZER_SETTINGS</span></code>: <code class="docutils literal notranslate"><span class="pre">'{&quot;energy_threshold&quot;:</span> <span class="pre">1100,</span> <span class="pre">&quot;dynamic_energy_threshold&quot;:</span> <span class="pre">false,</span> <span class="pre">&quot;pause_threshold&quot;:</span> <span class="pre">2,</span> <span class="pre">&quot;phrase_threshold&quot;:</span> <span class="pre">0.1,</span> <span class="pre">&quot;non_speaking_duration&quot;:</span> <span class="pre">2}'</span></code></p>
<p><strong>Description</strong></p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">energy_threshold</span></code>: Minimum audio energy to consider for recording. Greater the value, louder the voice should be.</p></li>
@@ -645,7 +644,7 @@ Clean code with pre-commit hooks: <a class="reference external" href="https://fl
<section id="runbook">
<h1>Runbook<a class="headerlink" href="#runbook" title="Permalink to this heading"></a></h1>
<p><a class="reference external" href="https://www.sphinx-doc.org/en/master/man/sphinx-autogen.html"><img alt="made-with-sphinx-doc" src="https://img.shields.io/badge/Code%20Docs-Sphinx-1f425f.svg" /></a></p>
<p><a class="reference external" href="https://thevickypedia.github.io/Jarvis/">https://thevickypedia.github.io/Jarvis/</a></p>
<p><a class="reference external" href="https://jarvis-docs.vigneshrao.com/">https://jarvis-docs.vigneshrao.com/</a></p>
</section>
<section id="license-copyright">
<h1>License &amp; copyright<a class="headerlink" href="#license-copyright" title="Permalink to this heading"></a></h1>
@@ -695,7 +694,7 @@ Clean code with pre-commit hooks: <a class="reference external" href="https://fl
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="index.html"
title="previous chapter">Welcome to Jarviss documentation!</a></p>
title="previous chapter">Jarvis - Voice-Activated Natural Language UI</a></p>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
@@ -728,7 +727,7 @@ Clean code with pre-commit hooks: <a class="reference external" href="https://fl
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="index.html" title="Welcome to Jarviss documentation!"
<a href="index.html" title="Jarvis - Voice-Activated Natural Language UI"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Jarvis documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Kick off</a></li>

View File

@@ -1,7 +1,7 @@
<p align="center" style="text-align: center">
<img src="https://vigneshrao.com/Jarvis/logo.png" width="371px" height="350px">
</p>
<h2 align="center">Fully Functional Voice Based Natural Language UI</h2>
<h2 align="center">Voice-Activated Natural Language UI</h2>
[![made-with-python](https://img.shields.io/badge/Made%20with-Python-blue?style=for-the-badge&logo=Python)](https://python.org)
@@ -189,7 +189,8 @@ Environment variables are loaded from a `.env` file and validated using `pydanti
Please use [recognizer.py](https://github.com/thevickypedia/Jarvis/blob/master/jarvis/modules/microphone/recognizer.py) to figure out the suitable values on a trial and error basis.
Sample settings (formatted as JSON object)
- `RECOGNIZER_SETTINGS`: `'{"energy_threshold": 1100, "dynamic_energy_threshold": false, "pause_threshold": 2, "phrase_threshold": 0.1, "non_speaking_duration": 2}'`
<br>
`RECOGNIZER_SETTINGS`: `'{"energy_threshold": 1100, "dynamic_energy_threshold": false, "pause_threshold": 2, "phrase_threshold": 0.1, "non_speaking_duration": 2}'`
**Description**
- `energy_threshold`: Minimum audio energy to consider for recording. Greater the value, louder the voice should be.
@@ -587,7 +588,7 @@ pre-commit run --all-files
## Runbook
[![made-with-sphinx-doc](https://img.shields.io/badge/Code%20Docs-Sphinx-1f425f.svg)](https://www.sphinx-doc.org/en/master/man/sphinx-autogen.html)
[https://thevickypedia.github.io/Jarvis/](https://thevickypedia.github.io/Jarvis/)
[https://jarvis-docs.vigneshrao.com/](https://jarvis-docs.vigneshrao.com/)
## License & copyright

View File

@@ -1,7 +1,7 @@
<p align="center" style="text-align: center">
<img src="https://vigneshrao.com/Jarvis/logo.png" width="371px" height="350px">
</p>
<h2 align="center">Fully Functional Voice Based Natural Language UI</h2>
<h2 align="center">Voice-Activated Natural Language UI</h2>
[![made-with-python](https://img.shields.io/badge/Made%20with-Python-blue?style=for-the-badge&logo=Python)](https://python.org)
@@ -189,7 +189,8 @@ Environment variables are loaded from a `.env` file and validated using `pydanti
Please use [recognizer.py](https://github.com/thevickypedia/Jarvis/blob/master/jarvis/modules/microphone/recognizer.py) to figure out the suitable values on a trial and error basis.
Sample settings (formatted as JSON object)
- `RECOGNIZER_SETTINGS`: `'{"energy_threshold": 1100, "dynamic_energy_threshold": false, "pause_threshold": 2, "phrase_threshold": 0.1, "non_speaking_duration": 2}'`
<br>
`RECOGNIZER_SETTINGS`: `'{"energy_threshold": 1100, "dynamic_energy_threshold": false, "pause_threshold": 2, "phrase_threshold": 0.1, "non_speaking_duration": 2}'`
**Description**
- `energy_threshold`: Minimum audio energy to consider for recording. Greater the value, louder the voice should be.
@@ -587,7 +588,7 @@ pre-commit run --all-files
## Runbook
[![made-with-sphinx-doc](https://img.shields.io/badge/Code%20Docs-Sphinx-1f425f.svg)](https://www.sphinx-doc.org/en/master/man/sphinx-autogen.html)
[https://thevickypedia.github.io/Jarvis/](https://thevickypedia.github.io/Jarvis/)
[https://jarvis-docs.vigneshrao.com/](https://jarvis-docs.vigneshrao.com/)
## License & copyright

View File

@@ -3,8 +3,8 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Jarvis's documentation!
==================================
Jarvis - Voice-Activated Natural Language UI
============================================
.. toctree::
:maxdepth: 2

View File

@@ -182,8 +182,6 @@
<li><a href="index.html#jarvis.executors.static_responses.age">age() (in module jarvis.executors.static_responses)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.Indicators.alarm">alarm (jarvis.modules.models.classes.Indicators attribute)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.FileIO.alarm_root">alarm_root (jarvis.modules.models.classes.FileIO attribute)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.FileIO.alarms">alarms (jarvis.modules.models.classes.FileIO attribute)</a>
</li>
@@ -201,10 +199,10 @@
</li>
<li><a href="index.html#jarvis.modules.exceptions.APIResponse">APIResponse</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#jarvis.modules.builtin_overrides.APIServer">APIServer (class in jarvis.modules.builtin_overrides)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#jarvis.modules.models.classes.FileIO.app_launcher">app_launcher (jarvis.modules.models.classes.FileIO attribute)</a>
</li>
<li><a href="index.html#jarvis.executors.others.apps">apps() (in module jarvis.executors.others)</a>
@@ -1928,15 +1926,17 @@
</li>
<li><a href="index.html#jarvis.modules.audio.listener.listen">listen() (in module jarvis.modules.audio.listener)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#jarvis.executors.listener_controls.listener_control">listener_control() (in module jarvis.executors.listener_controls)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#jarvis.modules.models.classes.EnvConfig.listener_phrase_limit">listener_phrase_limit (jarvis.modules.models.classes.EnvConfig attribute)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.EnvConfig.listener_timeout">listener_timeout (jarvis.modules.models.classes.EnvConfig attribute)</a>
</li>
<li><a href="index.html#jarvis.modules.facenet.face.FaceNet.load_dataset">load_dataset() (jarvis.modules.facenet.face.FaceNet method)</a>
</li>
<li><a href="index.html#jarvis._preexec.keywords_handler.load_ignores">load_ignores() (in module jarvis._preexec.keywords_handler)</a>
</li>
<li><a href="index.html#jarvis.executors.ios_functions.locate">locate() (in module jarvis.executors.ios_functions)</a>
@@ -2568,8 +2568,6 @@
<li><a href="index.html#jarvis.executors.vpn_server.regional_phrase">regional_phrase() (in module jarvis.executors.vpn_server)</a>
</li>
<li><a href="index.html#jarvis.executors.remind.reminder">reminder() (in module jarvis.executors.remind)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.FileIO.reminder_root">reminder_root (jarvis.modules.models.classes.FileIO attribute)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.FileIO.reminders">reminders (jarvis.modules.models.classes.FileIO attribute)</a>
</li>
@@ -2609,10 +2607,10 @@
</li>
<li><a href="index.html#jarvis.api.squire.timeout_otp.reset_robinhood">reset_robinhood() (in module jarvis.api.squire.timeout_otp)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#jarvis.api.squire.timeout_otp.reset_stock_monitor">reset_stock_monitor() (in module jarvis.api.squire.timeout_otp)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#jarvis.api.squire.timeout_otp.reset_surveillance">reset_surveillance() (in module jarvis.api.squire.timeout_otp)</a>
</li>
<li><a href="index.html#jarvis.executors.controls.restart">restart() (in module jarvis.executors.controls)</a>
@@ -3132,15 +3130,17 @@
</li>
<li><a href="index.html#jarvis.modules.exceptions.UnsupportedOS">UnsupportedOS</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#jarvis.modules.lights.smart_lights.MagicHomeApi.update_device">update_device() (jarvis.modules.lights.smart_lights.MagicHomeApi method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="index.html#jarvis.modules.microphone.graph_mic.update_plot">update_plot() (in module jarvis.modules.microphone.graph_mic)</a>
</li>
<li><a href="index.html#jarvis.executors.lights_squire.update_status">update_status() (in module jarvis.executors.lights_squire)</a>
</li>
<li><a href="index.html#jarvis.modules.car.connector.Connect.update_user_info">update_user_info() (jarvis.modules.car.connector.Connect method)</a>
</li>
<li><a href="index.html#jarvis.modules.models.classes.FileIO.uploads">uploads (jarvis.modules.models.classes.FileIO attribute)</a>
</li>
<li><a href="index.html#jarvis.api.models.settings.StockMonitor.user_info">user_info (jarvis.api.models.settings.StockMonitor attribute)</a>
</li>

View File

@@ -6,7 +6,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
<title>Welcome to Jarviss documentation! &#8212; Jarvis documentation</title>
<title>Jarvis - Voice-Activated Natural Language UI &#8212; Jarvis documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
<link rel="stylesheet" type="text/css" href="_static/static.css" />
@@ -34,7 +34,7 @@
<a href="README.html" title="Kick off"
accesskey="N">next</a> |</li>
<li class="nav-item nav-item-0"><a href="#">Jarvis documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Welcome to Jarviss documentation!</a></li>
<li class="nav-item nav-item-this"><a href="">Jarvis - Voice-Activated Natural Language UI</a></li>
</ul>
</div>
@@ -43,8 +43,8 @@
<div class="bodywrapper">
<div class="body" role="main">
<section id="welcome-to-jarvis-s-documentation">
<h1>Welcome to Jarviss documentation!<a class="headerlink" href="#welcome-to-jarvis-s-documentation" title="Permalink to this heading"></a></h1>
<section id="jarvis-voice-activated-natural-language-ui">
<h1>Jarvis - Voice-Activated Natural Language UI<a class="headerlink" href="#jarvis-voice-activated-natural-language-ui" title="Permalink to this heading"></a></h1>
<div class="toctree-wrapper compound">
<p class="caption" role="heading"><span class="caption-text">Read Me:</span></p>
<ul>
@@ -646,6 +646,12 @@
</section>
<section id="module-jarvis._preexec.keywords_handler">
<span id="keywords-classifier"></span><h1>Keywords Classifier<a class="headerlink" href="#module-jarvis._preexec.keywords_handler" title="Permalink to this heading"></a></h1>
<dl class="py function">
<dt class="sig sig-object py" id="jarvis._preexec.keywords_handler.load_ignores">
<span class="sig-prename descclassname"><span class="pre">jarvis._preexec.keywords_handler.</span></span><span class="sig-name descname"><span class="pre">load_ignores</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">data</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">dict</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="headerlink" href="#jarvis._preexec.keywords_handler.load_ignores" title="Permalink to this definition"></a></dt>
<dd><p>Loads <code class="docutils literal notranslate"><span class="pre">ignore_after</span></code> and <code class="docutils literal notranslate"><span class="pre">ignore_add</span></code> list to avoid iterations on the same phrase.</p>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="jarvis._preexec.keywords_handler.rewrite_keywords">
<span class="sig-prename descclassname"><span class="pre">jarvis._preexec.keywords_handler.</span></span><span class="sig-name descname"><span class="pre">rewrite_keywords</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="headerlink" href="#jarvis._preexec.keywords_handler.rewrite_keywords" title="Permalink to this definition"></a></dt>
@@ -2843,7 +2849,7 @@ Car Climate controls (Fahrenheit): 58 is LO, 84 is HOT</p>
<ul>
<li><div class="line-block">
<div class="line">Restarts the machine without approval when <code class="docutils literal notranslate"><span class="pre">uptime</span></code> is more than 2 days as the confirmation is requested</div>
<div class="line">in <a class="reference external" href="https://thevickypedia.github.io/Jarvis/#executors.system.system_vitals">system_vitals</a>.</div>
<div class="line">in <a class="reference external" href="https://jarvis-docs.vigneshrao.com/#executors.system.system_vitals">system_vitals</a>.</div>
</div>
</li>
<li><p>This is done ONLY when the system vitals are read, and the uptime is more than 2 days.</p></li>
@@ -4757,7 +4763,7 @@ Car Climate controls (Fahrenheit): 58 is LO, 84 is HOT</p>
<p class="admonition-title">See also</p>
<ul class="simple">
<li><p>Jarvis will suggest a reboot if the system uptime is more than 2 days.</p></li>
<li><p>If confirmed, invokes <a class="reference external" href="https://thevickypedia.github.io/Jarvis/#jarvis.restart">restart</a> function.</p></li>
<li><p>If confirmed, invokes <a class="reference external" href="https://jarvis-docs.vigneshrao.com/#jarvis.restart">restart</a> function.</p></li>
</ul>
</div>
</dd></dl>
@@ -5228,7 +5234,7 @@ Car Climate controls (Fahrenheit): 58 is LO, 84 is HOT</p>
</div>
<dl class="py function">
<dt class="sig sig-object py" id="jarvis.modules.audio.listener.listen">
<span class="sig-prename descclassname"><span class="pre">jarvis.modules.audio.listener.</span></span><span class="sig-name descname"><span class="pre">listen</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sound</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">PositiveInt</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">PositiveFloat</span><span class="p"><span class="pre">]</span></span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">3.0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">phrase_time_limit</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Optional</span><span class="p"><span class="pre">[</span></span><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">PositiveInt</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">PositiveFloat</span><span class="p"><span class="pre">]</span></span><span class="p"><span class="pre">]</span></span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">Optional</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span></span></span><a class="headerlink" href="#jarvis.modules.audio.listener.listen" title="Permalink to this definition"></a></dt>
<span class="sig-prename descclassname"><span class="pre">jarvis.modules.audio.listener.</span></span><span class="sig-name descname"><span class="pre">listen</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">sound</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">bool</span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">True</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">timeout</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">PositiveInt</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">PositiveFloat</span><span class="p"><span class="pre">]</span></span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">2.0</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">phrase_time_limit</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">PositiveInt</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">PositiveFloat</span><span class="p"><span class="pre">]</span></span></span><span class="w"> </span><span class="o"><span class="pre">=</span></span><span class="w"> </span><span class="default_value"><span class="pre">3.0</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">&#x2192;</span> <span class="sig-return-typehint"><span class="pre">Optional</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span></span></span><a class="headerlink" href="#jarvis.modules.audio.listener.listen" title="Permalink to this definition"></a></dt>
<dd><p>Function to activate listener, this function will be called by most upcoming functions to listen to user input.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
@@ -7619,16 +7625,6 @@ Pass 155 for LO and 285 for HI.</p>
<span class="sig-name descname"><span class="pre">root</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">DirectoryPath</span></em><a class="headerlink" href="#jarvis.modules.models.classes.FileIO.root" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="jarvis.modules.models.classes.FileIO.alarm_root">
<span class="sig-name descname"><span class="pre">alarm_root</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">DirectoryPath</span></em><a class="headerlink" href="#jarvis.modules.models.classes.FileIO.alarm_root" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="jarvis.modules.models.classes.FileIO.reminder_root">
<span class="sig-name descname"><span class="pre">reminder_root</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">DirectoryPath</span></em><a class="headerlink" href="#jarvis.modules.models.classes.FileIO.reminder_root" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="jarvis.modules.models.classes.FileIO.automation">
<span class="sig-name descname"><span class="pre">automation</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">FilePath</span></em><a class="headerlink" href="#jarvis.modules.models.classes.FileIO.automation" title="Permalink to this definition"></a></dt>
@@ -7774,6 +7770,11 @@ Pass 155 for LO and 285 for HI.</p>
<span class="sig-name descname"><span class="pre">secure_send</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">FilePath</span></em><a class="headerlink" href="#jarvis.modules.models.classes.FileIO.secure_send" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="jarvis.modules.models.classes.FileIO.uploads">
<span class="sig-name descname"><span class="pre">uploads</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="pre">DirectoryPath</span></em><a class="headerlink" href="#jarvis.modules.models.classes.FileIO.uploads" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
<hr class="docutils" />
@@ -11106,7 +11107,7 @@ response is mocked from the post request call.</p>
<div>
<h3><a href="#">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Welcome to Jarviss documentation!</a></li>
<li><a class="reference internal" href="#">Jarvis - Voice-Activated Natural Language UI</a></li>
<li><a class="reference internal" href="#preflight-tests">——Preflight Tests——</a></li>
<li><a class="reference internal" href="#module-jarvis.modules.camera.camera">Camera</a></li>
<li><a class="reference internal" href="#module-jarvis.modules.peripherals">Audio Devices</a></li>
@@ -11263,7 +11264,7 @@ response is mocked from the post request call.</p>
<a href="README.html" title="Kick off"
>next</a> |</li>
<li class="nav-item nav-item-0"><a href="#">Jarvis documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Welcome to Jarviss documentation!</a></li>
<li class="nav-item nav-item-this"><a href="">Jarvis - Voice-Activated Natural Language UI</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -3,8 +3,8 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Jarvis's documentation!
==================================
Jarvis - Voice-Activated Natural Language UI
============================================
.. toctree::
:maxdepth: 2

View File

@@ -2,7 +2,9 @@
# 'set -e' stops the execution of a script if a command or pipeline has an error.
# This is the opposite of the default shell behaviour, which is to ignore errors in scripts.
set -e
if [ -e "docs/CNAME" ]; then
mv "docs/CNAME" "CNAME"
fi
gitverse-release reverse -f release_notes.rst -t 'Release Notes' # Update release notes
rm -rf docs # Remove existing docs directory
mkdir docs # Create new docs directory
@@ -12,5 +14,8 @@ cd docs_gen && make clean html # cd into doc_gen and create the runbook
mv _build/html/* ../docs && mv README.md ../docs && rm -rf fileio logs # Move the runbook, readme and cleanup
# The existence of this file tells GitHub Pages not to run the published files through Jekyll.
# This is important since Jekyll will discard any files that begin with _
touch ../docs/.nojekyll
cp static.css ../docs/_static
cd ../ && touch docs/.nojekyll
if [ -e "CNAME" ]; then
mv "CNAME" "docs/CNAME"
fi

View File

@@ -10,6 +10,14 @@ from jarvis.modules.models import models
from jarvis.modules.utils import support
def load_ignores(data: dict) -> None:
"""Loads ``ignore_after`` and ``ignore_add`` list to avoid iterations on the same phrase."""
# Keywords for which the ' after ' split should not happen.
keywords.ignore_after = data['meetings'] + data['avoid']
# Keywords for which the ' and ' split should not happen.
keywords.ignore_and = data['send_notification'] + data['reminder'] + data['distance'] + data['avoid']
def rewrite_keywords() -> None:
"""Loads keywords.yaml file if available, else loads the base keywords module as an object."""
keywords_src = OrderedDict(**keywords.keyword_mapping(), **conversation.conversation_mapping())
@@ -32,6 +40,7 @@ def rewrite_keywords() -> None:
# compare as sorted, since this will allow changing the order of keywords in the yaml file
elif sorted(list(data.keys())) == sorted(list(keywords_src.keys())) and data.values() and all(data.values()):
keywords.keywords = data
load_ignores(data)
return
else: # Mismatch in keys
warnings.warn(
@@ -43,6 +52,7 @@ def rewrite_keywords() -> None:
with open(models.fileio.keywords, 'w') as dst_file:
ordered_dump(stream=dst_file, data=keywords_src, indent=4)
keywords.keywords = keywords_src
load_ignores(keywords_src)
rewrite_keywords()

View File

@@ -1,4 +1,5 @@
import os
from datetime import datetime
from http import HTTPStatus
from fastapi import APIRouter, UploadFile
@@ -22,7 +23,8 @@ async def list_files():
Dictionary of files that can be downloaded or uploaded.
"""
return {**{"logs": [file_ for __path, __directory, __file in os.walk('logs') for file_ in __file]},
**{"fileio": [f for f in os.listdir(models.fileio.root) if f.endswith('.yaml')]}}
**{"fileio": [f for f in os.listdir(models.fileio.root) if f.endswith('.yaml')]},
**{"uploads": [f for f in os.listdir(models.fileio.uploads) if not f.startswith('.')]}}
@router.get(path="/get-file", response_class=FileResponse, dependencies=authenticator.OFFLINE_PROTECTOR)
@@ -63,13 +65,16 @@ async def put_file(file: UploadFile):
file: Takes the UploadFile object as an argument.
"""
allowed_files = await list_files()
if file.filename not in allowed_files["fileio"]:
raise APIResponse(status_code=HTTPStatus.NOT_ACCEPTABLE.real,
detail=f"{file.filename!r} is not allowed for an update.\n"
f"Upload-able files:{allowed_files['fileio']}")
logger.info("Requested file: '%s' for upload.", file.filename)
content = await file.read()
allowed_files = await list_files()
if file.filename not in allowed_files["fileio"]:
with open(os.path.join(models.fileio.uploads,
f"{datetime.now().strftime('%d_%B_%Y-%I_%M_%p')}-{file.filename}"), "wb") as f_stream:
f_stream.write(content)
raise APIResponse(status_code=HTTPStatus.ACCEPTED.real,
detail=f"{file.filename!r} is not allowed for an update.\n"
"Hence storing as a standalone file.")
with open(os.path.join(models.fileio.root, file.filename), "wb") as f_stream:
f_stream.write(content)
raise APIResponse(status_code=HTTPStatus.OK.real, detail=f"{file.filename!r} was uploaded to {models.fileio.root}.")

View File

@@ -122,8 +122,10 @@ async def offline_communicator_api(request: Request, input_data: modals.OfflineC
if 'alarm' in command.lower() or 'remind' in command.lower():
command = command.lower()
if ' and ' in command and not word_match.word_match(phrase=command, match_list=keywords.ignore_and):
and_phrases = command.split(' and ')
logger.info("Looping through %s in iterations.", and_phrases)
and_response = ""
for each in command.split(' and '):
for each in and_phrases:
try:
and_response += f"{offline.offline_communicator(command=each)}\n"
except Exception as error:

View File

@@ -153,7 +153,8 @@ def set_alarm(phrase: str) -> None:
speaker.speak(text=f"An alarm at {hour}:{minute} {am_pm}? Are you an alien? "
"I don't think a time like that exists on Earth.")
else:
if word_match.word_match(phrase=phrase, match_list=('get', 'what', 'send', 'list', 'exist', 'existing')):
if word_match.word_match(phrase=phrase,
match_list=('get', 'what', 'send', 'list', 'exist', 'existing', 'do', 'have', 'i')):
if alarm_states := get_alarm_state():
if len(alarm_states) > 1:
speaker.speak(text=f"Your alarms are at, {util.comma_separator(alarm_states)}.")

View File

@@ -33,7 +33,9 @@ def split_phrase(phrase: str) -> 'conditions.conditions':
return False
if ' and ' in phrase and not word_match.word_match(phrase=phrase, match_list=keywords.ignore_and):
for each in phrase.split(' and '):
and_phrases = phrase.split(' and ')
logger.info("Looping through %s in iterations.", and_phrases)
for each in and_phrases:
exit_check = conditions.conditions(phrase=each.strip())
speaker.speak(run=True)
else:

View File

@@ -67,7 +67,8 @@ def send_sms(user: str, password: str, number: Union[str, int], body: str, subje
if not subject:
subject = "Message from Jarvis" if number == models.env.phone_number else f"Message from {models.env.name}"
sms_object = gmailconnector.SendSMS(gmail_user=user, gmail_pass=password)
response = sms_object.send_sms(phone=number or models.env.phone_number, subject=subject, message=body)
response = sms_object.send_sms(phone=number or models.env.phone_number,
subject=subject, message=body, delete_sent=True)
if response.ok:
logger.info('SMS notification has been sent.')
return True

View File

@@ -4,6 +4,7 @@ from threading import Thread
from jarvis.executors import (custom_conditions, functions, listener_controls,
others, restrictions, static_responses,
unconditional, word_match)
from jarvis.modules.audio import speaker
from jarvis.modules.conditions import keywords
from jarvis.modules.logger import logger
from jarvis.modules.models import models
@@ -92,5 +93,7 @@ def conditions(phrase: str) -> bool:
if not unconditional.google_maps(query=phrase):
if gpt.instance:
gpt.instance.query(phrase=phrase)
elif response := gpt.existing_response(request=phrase):
speaker.speak(text=response)
else:
static_responses.un_processable()

View File

@@ -32,7 +32,7 @@ def restart(ask: bool = True) -> None:
Warnings:
- | Restarts the machine without approval when ``uptime`` is more than 2 days as the confirmation is requested
| in `system_vitals <https://thevickypedia.github.io/Jarvis/#executors.system.system_vitals>`__.
| in `system_vitals <https://jarvis-docs.vigneshrao.com/#executors.system.system_vitals>`__.
- This is done ONLY when the system vitals are read, and the uptime is more than 2 days.
Args:

View File

@@ -101,7 +101,8 @@ def reminder(phrase: str) -> None:
re.search(' to (.*) in ', phrase) or re.search(' about (.*) in ', phrase) or \
re.search(' to (.*)', phrase) or re.search(' about (.*)', phrase)
if not message:
if word_match.word_match(phrase=phrase, match_list=('get', 'what', 'send', 'list', 'exist', 'existing')):
if word_match.word_match(phrase=phrase,
match_list=('get', 'what', 'send', 'list', 'exist', 'existing', 'do', 'have', 'i')):
if reminder_list := get_reminder_state():
speaker.speak(text=f"You have {len(reminder_list)} reminders {models.env.title}! "
f"{string.capwords(util.comma_separator(reminder_list))}")

View File

@@ -47,7 +47,7 @@ def system_vitals(*args) -> None:
See Also:
- Jarvis will suggest a reboot if the system uptime is more than 2 days.
- If confirmed, invokes `restart <https://thevickypedia.github.io/Jarvis/#jarvis.restart>`__ function.
- If confirmed, invokes `restart <https://jarvis-docs.vigneshrao.com/#jarvis.restart>`__ function.
"""
output = ""
if models.settings.os == models.supported_platforms.macOS:

View File

@@ -19,8 +19,7 @@ from jarvis.modules.utils import support
recognizer = Recognizer()
microphone = Microphone(device_index=models.env.microphone_index)
if models.env.recognizer_settings and models.settings.pname == "JARVIS":
logger.debug("Overriding recognizer settings: %s", models.env.recognizer_settings.__dict__)
if models.settings.pname == "JARVIS":
recognizer.energy_threshold = models.env.recognizer_settings.energy_threshold
recognizer.pause_threshold = models.env.recognizer_settings.pause_threshold
recognizer.phrase_threshold = models.env.recognizer_settings.phrase_threshold
@@ -44,8 +43,8 @@ def listen(sound: bool = True,
"""
with microphone as source:
try:
support.write_screen(text=f"Listener activated [{timeout}:{phrase_time_limit}]...")
playsound(sound=models.indicators.start, block=False) if sound else None
support.write_screen(text=f"Listener activated [{timeout}: {phrase_time_limit}]")
listened = recognizer.listen(source=source, timeout=timeout, phrase_time_limit=phrase_time_limit)
playsound(sound=models.indicators.end, block=False) if sound else None
support.flush_screen()

View File

@@ -112,11 +112,4 @@ def keyword_mapping() -> OrderedDict[str, List[str]]:
)
if keywords:
# Keywords for which the ' after ' split should not happen.
ignore_after = keywords['meetings'] + keywords['avoid']
# Keywords for which the ' and ' split should not happen.
ignore_and = keywords['send_notification'] + keywords['reminder'] + \
keywords['distance'] + keywords['avoid']
else:
ignore_after, ignore_and = [], []
ignore_after, ignore_and = [], []

View File

@@ -392,9 +392,9 @@ class EnvConfig(BaseSettings):
# Listener config
sensitivity: Union[Sensitivity, List[Sensitivity]] = Field(default=0.5, le=1, ge=0)
listener_timeout: Union[PositiveFloat, PositiveInt] = Field(default=3)
listener_phrase_limit: Union[PositiveFloat, PositiveInt] = Field(default=None)
recognizer_settings: RecognizerSettings = Field(default=None)
listener_timeout: Union[PositiveFloat, PositiveInt] = Field(default=2)
listener_phrase_limit: Union[PositiveFloat, PositiveInt] = Field(default=3)
recognizer_settings: RecognizerSettings = Field(default=RecognizerSettings())
# Telegram config
bot_token: str = Field(default=None)
@@ -496,8 +496,6 @@ class FileIO(BaseModel):
# Directories
root: DirectoryPath = os.path.realpath('fileio')
alarm_root: DirectoryPath = os.path.realpath('alarm')
reminder_root: DirectoryPath = os.path.realpath('reminder')
# Home automation
automation: FilePath = os.path.join(root, 'automation.yaml')
@@ -508,8 +506,8 @@ class FileIO(BaseModel):
contacts: FilePath = os.path.join(root, 'contacts.yaml')
# Alarms and Reminders
alarms: FilePath = os.path.join(alarm_root, 'alarms.yaml')
reminders: FilePath = os.path.join(reminder_root, 'reminders.yaml')
alarms: FilePath = os.path.join(root, 'alarms.yaml')
reminders: FilePath = os.path.join(root, 'reminders.yaml')
# Simulation
simulation: FilePath = os.path.join(root, 'simulation.yaml')
@@ -551,6 +549,9 @@ class FileIO(BaseModel):
# Secure Send
secure_send: FilePath = os.path.join(root, 'secure_send.yaml')
# On demand storage
uploads: DirectoryPath = os.path.join(root, "uploads")
fileio = FileIO()

View File

@@ -8,7 +8,6 @@
import os
import pathlib
import warnings
from typing import Union
import cv2
import pvporcupine
@@ -22,14 +21,13 @@ from jarvis.modules.exceptions import (CameraError, EgressErrors,
InvalidEnvVars, MissingEnvVars,
SegmentationError)
from jarvis.modules.models.classes import (DistanceUnits, Indicators,
RecognizerSettings,
TemperatureUnits, audio_driver, env,
fileio, settings,
supported_platforms)
from jarvis.modules.utils import util
# Shared across other modules
voices: Union[list, object] = audio_driver.getProperty("voices") if audio_driver else []
voices = audio_driver.getProperty("voices") if audio_driver else []
indicators = Indicators()
# TABLES to be created in `fileio.base_db`
TABLES = {
@@ -91,21 +89,15 @@ def _set_default_voice_name() -> None:
def _main_process_validations() -> None:
"""Validations that should happen only when the main process is triggered."""
if not env.recognizer_settings and not env.listener_phrase_limit:
env.recognizer_settings = RecognizerSettings() # Default override when phrase limit is not available
if settings.legacy:
pvporcupine.KEYWORD_PATHS = {}
pvporcupine.MODEL_PATH = os.path.join(os.path.dirname(pvporcupine.__file__),
'lib/common/porcupine_params.pv')
pvporcupine.LIBRARY_PATH = os.path.join(os.path.dirname(pvporcupine.__file__),
'lib/mac/x86_64/libpv_porcupine.dylib')
keyword_files = os.listdir(os.path.join(os.path.dirname(pvporcupine.__file__),
'resources/keyword_files/mac/'))
base_path = os.path.dirname(pvporcupine.__file__)
pvporcupine.MODEL_PATH = os.path.join(base_path, 'lib/common/porcupine_params.pv')
pvporcupine.LIBRARY_PATH = os.path.join(base_path, 'lib/mac/x86_64/libpv_porcupine.dylib')
for x in keyword_files: # Iterates over the available flash files, to override the class
pvporcupine.KEYWORD_PATHS[x.split('_')[0]] = os.path.join(os.path.dirname(pvporcupine.__file__),
f'resources/keyword_files/mac/{x}')
# Iterates over the available flash files, to override the object reference
for x in os.listdir(os.path.join(base_path, 'resources/keyword_files/mac/')):
pvporcupine.KEYWORD_PATHS[x.split('_')[0]] = os.path.join(base_path, f'resources/keyword_files/mac/{x}')
for keyword in env.wake_words:
if not pvporcupine.KEYWORD_PATHS.get(keyword) or not os.path.isfile(pvporcupine.KEYWORD_PATHS[keyword]):
@@ -122,16 +114,15 @@ def _main_process_validations() -> None:
db = database.Database(database=fileio.base_db)
for table, column in TABLES.items():
db.create_table(table_name=table, columns=column)
# Create required directory for alarms
if not os.path.isdir(fileio.alarm_root):
os.mkdir(fileio.alarm_root)
# Create required file for alarms
if not os.path.isfile(fileio.alarms):
pathlib.Path(fileio.alarms).touch()
# Create required directory for reminders
if not os.path.isdir(fileio.reminder_root):
os.mkdir(fileio.reminder_root)
# Create required file for reminders
if not os.path.isfile(fileio.reminders):
pathlib.Path(fileio.reminders).touch()
# Create required directory for uploads
if not os.path.isdir(fileio.uploads):
os.mkdir(fileio.uploads)
def _global_validations() -> None:

View File

@@ -307,7 +307,7 @@ class TelegramBot:
self.process_text(payload=message)
elif message.get('voice'):
self.process_voice(payload=message)
elif message.get('document'):
else: # consider everything else as document and try to store it in fileio/uploads
self.process_document(payload=message)
offset = result['update_id'] + 1
@@ -558,7 +558,9 @@ class TelegramBot:
return
if ' and ' in command and not word_match.word_match(phrase=command, match_list=keywords.ignore_and):
for each in command.split(' and '):
and_phrases = command.split(' and ')
logger.info("Looping through %s in iterations.", and_phrases)
for each in and_phrases:
self.executor(command=each, payload=payload)
return

View File

@@ -6,6 +6,7 @@
"""
import os
from datetime import datetime
from typing import Dict
from jarvis.modules.logger import logger
@@ -20,7 +21,8 @@ def _list_files() -> Dict[str, str]:
Dictionary of files that can be downloaded or uploaded.
"""
return {**{"logs": [file_ for __path, __directory, __file in os.walk('logs') for file_ in __file]},
**{"fileio": [f for f in os.listdir(models.fileio.root) if f.endswith('.yaml')]}}
**{"fileio": [f for f in os.listdir(models.fileio.root) if f.endswith('.yaml')]},
**{"uploads": [f for f in os.listdir(models.fileio.uploads) if not f.startswith('.')]}}
def list_files() -> str:
@@ -33,7 +35,8 @@ def list_files() -> str:
all_files = _list_files()
joined_logs = '\n'.join(all_files['logs'])
joined_fileio = '\n'.join(all_files['fileio'])
return f"{joined_logs}\n\n{joined_fileio}"
joined_uploads = '\n'.join(all_files['uploads'])
return f"{joined_logs}\n\n{joined_fileio}\n\n{joined_uploads}"
def get_file(filename: str) -> Dict:
@@ -78,10 +81,13 @@ def put_file(filename: str, file_content: bytes) -> str:
str:
Response to the user.
"""
logger.info("Requested file: '%s' for upload.", filename)
allowed_files = _list_files()
if filename not in allowed_files["fileio"]:
return f"{filename!r} is not allowed for an update."
logger.info("Requested file: '%s' for upload.", filename)
with open(os.path.join(models.fileio.uploads,
f"{datetime.now().strftime('%d_%B_%Y-%I_%M_%p')}-{filename}"), "wb") as f_stream:
f_stream.write(file_content)
return f"{filename!r} is not allowed for an update. Hence, storing as standalone file."
with open(os.path.join(models.fileio.root, filename), "wb") as f_stream:
f_stream.write(file_content)
return f"{filename!r} was uploaded to {os.path.basename(models.fileio.root)}."

View File

@@ -10,7 +10,7 @@ import openai
from openai.error import AuthenticationError, OpenAIError
from openai.openai_object import OpenAIObject
from jarvis.executors import files
from jarvis.executors import files, static_responses
from jarvis.modules.audio import speaker
from jarvis.modules.exceptions import MissingEnvVars
from jarvis.modules.logger import logger
@@ -151,7 +151,7 @@ class ChatGPT:
)
except OpenAIError as error:
logger.error(error)
speaker.speak(text=f"I'm sorry {models.env.title}! I wasn't able to process your request.")
static_responses.un_processable()
return
if chat.choices:
reply = chat.choices[0].message.content
@@ -160,7 +160,7 @@ class ChatGPT:
speaker.speak(text=reply)
else:
logger.error(chat)
speaker.speak(text=f"I'm sorry {models.env.title}! I wasn't able to process your request.")
static_responses.un_processable()
if models.settings.pname in ('JARVIS', 'telegram_api', 'fast_api'):

View File

@@ -99,7 +99,8 @@ class RokuECP:
Args:
limit: Number of iterations to increase the volume.
"""
for _ in range(limit + 1):
# RokuTVs perform in 2-step iterations for volume, so a single VolumeUp button increases the volume by 2%
for _ in range(int(limit / 2)):
self.make_call(path='/keypress/VolumeUp', method='POST')
def decrease_volume(self, limit: int = 10) -> None:
@@ -108,7 +109,8 @@ class RokuECP:
Args:
limit: Number of iterations to decrease the volume.
"""
for _ in range(limit + 1):
# RokuTVs perform in 2-step iterations for volume, so a single VolumeDown button decreases the volume by 2%
for _ in range(int(limit / 2)):
self.make_call(path='/keypress/VolumeDown', method='POST')
def mute(self) -> None:

View File

@@ -1,7 +1,7 @@
[project]
name = "jarvis-ironman"
dynamic = ["version", "dependencies"]
description = "Fully Functional Voice Based Natural Language UI"
description = "Voice-Activated Natural Language UI"
readme = "README.md"
authors = [{ name = "Vignesh Sivanandha Rao", email = "svignesh1793@gmail.com" }]
license = { file = "LICENSE" }
@@ -57,7 +57,7 @@ dev = ["sphinx==5.1.1", "pre-commit", "recommonmark", "pytest"]
API = "https://jarvis.vigneshrao.com"
Health = "https://health.jarvis.services"
Homepage = "https://github.com/thevickypedia/Jarvis"
Docs = "https://thevickypedia.github.io/Jarvis"
Docs = "https://jarvis-docs.vigneshrao.com"
Demo = "https://vigneshrao.com/Jarvis/Jarvis_Demo.mp4"
Source = "https://github.com/thevickypedia/Jarvis"
"Bug Tracker" = "https://github.com/thevickypedia/Jarvis/issues"