Skip to content
This repository was archived by the owner on Dec 30, 2024. It is now read-only.

Replace imaplib by imap_tools for accents & tips for cloud running #10

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
worker: python siricontrol.py
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# SiriControl

This is an updated version of SiriControl, which allow to use it in French. Here is a complete tutorial to build your own SiriController and running it on the cloud for free: https://pydathon.medium.com/how-to-build-your-own-virtual-assistant-with-siricontrol-e9d531f05772

![SiriControl Demo](https://images.ctfassets.net/tvfg2m04ppj4/1PZVE9xziMv8DlKNKJONts/7264a51ae7c8b59ba2b39b49fb86f0cf/SiriControl.jpg)

SiriControl is an open source framework designed with developers in mind. It provides a simple way of using Siri commands by dynamically loading modules created by the user. This means that you can add voice controlled capability to any project, with Siri.
Expand All @@ -15,3 +17,5 @@ Convinced that SiriControl is awesome?
Well, here is the link on how to get started: https://medium.com/@thesanjeetc/bae98aceb586




13 changes: 13 additions & 0 deletions modules/lightoff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This module aim is to trigger a smart plug or bubble to turn it on.

#You can import any required modules here
import requests

#This can be anything you want
moduleName = "lightoff"

#All of the words must be heard in order for this module to be executed
commandWords = ["off", "lights"]

def execute(command):
requests.get("https://sequematic.com/trigger-custom-webhook/........")
12 changes: 12 additions & 0 deletions modules/lighton.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#You can import any required modules here
import requests


#This can be anything you want
moduleName = "lighton"

#All of the words must be heard in order for this module to be executed
commandWords = ["on", "lights"]

def execute(command):
requests.get("https://sequematic.com/trigger-custom-webhook/........")
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
requests==2.25.1
Flask==1.1.1
Unidecode==1.2.0
imap-tools==0.37.0
50 changes: 27 additions & 23 deletions siricontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
import email
import os
import pkgutil

import sys
import subprocess
import unidecode
import requests
from imap_tools import MailBox, AND
##########################################

# Add your gmail username and password here
Expand All @@ -23,23 +27,22 @@ def __init__(self, username, password):
print("------------------------------------------------------")
print("- SIRI CONTROL -")
print("- Created by Sanjeet Chatterjee -")
print("- Adapted by Pydathon -")
print("- Website: https://medium.com/@thesanjeetc -")
print("------------------------------------------------------")

try:
self.last_checked = -1
self.mail = imaplib.IMAP4_SSL("imap.gmail.com", 993)
self.mail.login(username, password)
self.mail.list()
self.mail.select("Notes")

self.mail = MailBox('imap.gmail.com')
self.mail.login(username, password, initial_folder='Notes')

# Gets last Note id to stop last command from executing
result, uidlist = self.mail.search(None, "ALL")
uidlist = [msg.uid for msg in self.mail.fetch(AND(all=True))]
subjects = [msg.subject for msg in self.mail.fetch(AND(all=True))]
try:
self.last_checked = uidlist[0].split()[-1]
self.last_checked = uidlist[-1].split()[-1]
except IndexError:
pass

self.load()
self.handle()
except imaplib.IMAP4.error:
Expand Down Expand Up @@ -72,46 +75,46 @@ def load(self):

def fetch_command(self):
"""Retrieve the last Note created if new id found"""
self.mail.list()
self.mail.select("Notes")

result, uidlist = self.mail.search(None, "ALL")
uidlist = [msg.uid for msg in self.mail.fetch(AND(all=True))]
subjects = [msg.subject for msg in self.mail.fetch(AND(all=True))]
try:
latest_email_id = uidlist[0].split()[-1]
latest_email_id = uidlist[-1].split()[-1]
except IndexError:
return

if latest_email_id == self.last_checked:
return

self.last_checked = latest_email_id
result, data = self.mail.fetch(latest_email_id, "(RFC822)")
voice_command = email.message_from_string(data[0][1].decode('utf-8'))
return str(voice_command.get_payload()).lower().strip()
data = subjects[-1]
return data.lower().strip()

def handle(self):
"""Handle new commands

Poll continuously every second and check for new commands.
"""
print("Fetching commands...")
print("\n")

while True:
folder_status = self.mail.folder.status('Notes')
nb_messages = folder_status["MESSAGES"] # permet d'actualiser la mailbox
try:
command = self.fetch_command()
if not command:
raise ControlException("No command found.")

print("The word(s) '" + command + "' have been said")
print("The word(s) '" + unidecode.unidecode(str(command).lower()) + "' have been said")
for module in self.modules:
foundWords = []
for word in module.commandWords:
if str(word) in command:
foundWords.append(str(word))
#print("command=",unidecode.unidecode(str(command).lower()))
#print("word=", unidecode.unidecode(str(word).lower()))
#print(unidecode.unidecode(str(word).lower()) in unidecode.unidecode(str(command).lower()))
if unidecode.unidecode(str(word).lower()) in unidecode.unidecode(str(command).lower()):
foundWords.append(unidecode.unidecode(str(word).lower()))
if len(foundWords) == len(module.commandWords):
try:
module.execute(command)
module.execute(unidecode.unidecode(str(command).lower()))
print("The module {0} has been executed "
"successfully.".format(module.moduleName))
except:
Expand All @@ -120,6 +123,7 @@ def handle(self):
module.moduleName))
else:
print("\n")
self.mail.move(self.mail.fetch(), 'notes_old')
except (TypeError, ControlException):
pass
except Exception as exc:
Expand Down