Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
D
domotikad
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
domotika
domotikad
Commits
68da1e55
Commit
68da1e55
authored
8 years ago
by
Franco (nextime) Lanza
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Better code organization
parent
f4087849
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
229 additions
and
135 deletions
+229
-135
dmdb.py
domotika/db/dmdb.py
+1
-1
domotika.py
domotika/domotika.py
+7
-4
bot.py
domotika/web/bot.py
+221
-130
No files found.
domotika/db/dmdb.py
View file @
68da1e55
...
...
@@ -941,7 +941,7 @@ def getVoiceCommandList():
def
getScreenshotUri
(
target
):
qstring
=
"select screenshot from mediasources where button_name LIKE '"
+
target
+
"
%
'
limit 1
"
qstring
=
"select screenshot from mediasources where button_name LIKE '"
+
target
+
"
%
'"
return
runQuery
(
qstring
)
def
getClimaUniques
():
...
...
This diff is collapsed.
Click to expand it.
domotika/domotika.py
View file @
68da1e55
...
...
@@ -2455,13 +2455,16 @@ class domotikaService(service.Service):
def
web_on_getScreenshotList
(
self
,
screenshot
=
True
):
return
dmdb
.
getScreenshotList
(
screenshot
=
screenshot
)
def
web_on_getScreenshot
(
self
,
target
):
def
web_on_getScreenshot
(
self
,
target
,
callback
=
None
):
def
imageReturn
(
img
):
return
img
def
prepareScreenshot
(
res
):
if
callback
==
None
:
if
res
:
return
wu
.
getPage
(
res
[
0
][
0
])
.
addCallback
(
imageReturn
)
return
False
for
r
in
res
:
wu
.
getPage
(
r
[
0
])
.
addCallback
(
callback
)
return
dmdb
.
getScreenshotUri
(
target
)
.
addCallback
(
prepareScreenshot
)
def
web_on_getClimaUniques
(
self
):
...
...
This diff is collapsed.
Click to expand it.
domotika/web/bot.py
View file @
68da1e55
from
zope.interface
import
Interface
,
implements
from
twisted.python
import
components
from
nevow
import
rend
,
inevow
from
corepost
import
Response
,
NotFoundException
,
AlreadyExistsException
...
...
@@ -16,6 +17,8 @@ from Queue import Queue
import
uuid
from
domotika.singleton
import
messengerlinks
from
StringIO
import
StringIO
import
imghdr
_MESSENGER_LINKS
=
messengerlinks
.
MessengerLinkRegistry
()
_MESSENGER_PSID
=
messengerlinks
.
MessengerPSIDRegistry
()
...
...
@@ -33,6 +36,114 @@ log = logging.getLogger( 'Webgui' )
BOTResource
=
RESTResource
class
IBotProtoInterface
(
Interface
):
def
getUsername
(
self
,
uid
):
""" get a username from uid """
def
isLogged
(
self
,
uid
):
""" return True if it's a know user """
def
sendAPI
(
self
,
payload
,
req_uri
):
""" Send request to the API """
def
receivedAuthentication
(
self
,
msg
):
""" receive auth message """
def
receivedTextMessage
(
self
,
msg
):
""" receive text message """
def
receivedDeliveryConfirmation
(
self
,
msg
):
""" receive delivery confirmation """
def
receivedPostback
(
self
,
msg
):
""" receive a postback message """
def
receivedAccountLink
(
self
,
msg
):
""" receive account linking message """
def
sendCommandList
(
self
,
recipient_id
):
""" send command list to the user """
def
sendScreenshotList
(
self
,
recipient_id
):
""" send a list of screenshots available """
def
sendScreenshot
(
self
,
recipient_id
,
target
):
""" send one or more screenshots """
def
sendClima
(
self
,
recipient_id
):
""" send Clima status """
def
sendMessage
(
self
,
recipient_id
,
message
):
""" send a text message """
def
sendImageMessage
(
self
,
recipient_id
,
imguri
):
""" send an image link """
def
sendImageMessageData
(
self
,
recipient_id
,
imagedata
,
mtype
):
""" send an image by data """
def
sendAuthRequest
(
self
,
recipient_id
):
""" send login request """
class
BotProto
(
object
):
def
__init__
(
self
,
core
):
self
.
core
=
core
def
botCommandParser
(
self
,
uid
,
txt
):
def
voiceResult
(
res
):
log
.
info
(
'VoiceResult: '
+
str
(
res
))
if
len
(
res
)
>
0
:
if
res
[
0
]
==
'Ok'
and
len
(
res
)
>
1
:
try
:
result
=
'ho eseguito "'
+
" "
.
join
(
res
[
1
][
'clean'
])
+
'"'
except
:
pass
else
:
result
=
'Spiacente, non ho trovato un comando corrispondente'
self
.
sendMessage
(
uid
,
result
)
txt
=
unicode
(
txt
.
lower
())
if
not
self
.
isLogged
(
uid
):
if
txt
==
u'hello'
or
txt
==
u'ciao'
:
self
.
sendMessage
(
uid
,
'Hello, how can i help you?'
)
elif
txt
==
u'?'
or
txt
==
u'help'
:
self
.
sendMessage
(
uid
,
'you can
\'
t do that.'
)
elif
txt
==
u'login'
:
self
.
sendAuthRequest
(
uid
)
else
:
self
.
sendMessage
(
uid
,
txt
+
u" come se fosse antani"
)
else
:
if
txt
==
u'hello'
or
txt
==
u'ciao'
:
self
.
sendMessage
(
uid
,
'Hello
%
s, how can i help you?'
%
(
self
.
getUsername
(
uid
)))
elif
txt
==
u'?'
or
txt
==
u'help'
:
self
.
sendMessage
(
uid
,
'Ok, devo ancora implementare l
\'
aiuto! Sorry for that!'
)
self
.
sendMessage
(
uid
,
'Anyway, i comandi che hai sono: "command list", "screenshot list", "screenshot" e "clima".'
)
self
.
sendMessage
(
uid
,
'Qualsiasi altro comando viene interpretato come un potenziale comando vocale.'
)
elif
txt
==
u'logout'
:
self
.
sendMessage
(
uid
,
'Ok, devo ancora implementare anche il logout'
)
elif
txt
==
u'login'
:
self
.
sendMessage
(
uid
,
'Sei gia
\'
loggato,
%
s!'
%
(
self
.
getUsername
(
uid
)))
elif
txt
==
u'command list'
or
txt
==
'cmd list'
:
self
.
sendCommandList
(
uid
)
elif
txt
==
u'screenshot list'
or
txt
==
u'ss list'
:
self
.
sendScreenshotList
(
uid
)
elif
txt
.
startswith
(
'screenshot '
)
or
txt
.
startswith
(
'ss '
):
self
.
sendScreenshot
(
uid
,
" "
.
join
(
txt
.
split
()[
1
:]))
elif
txt
==
u'clima'
:
self
.
sendClima
(
uid
)
else
:
self
.
core
.
voiceReceived
(
txt
,
confidence
=
1.0
,
lang
=
"it"
)
.
addCallback
(
voiceResult
)
class
BotCore
(
object
):
path
=
""
...
...
@@ -76,19 +187,23 @@ class MessengerMessage(object):
self
.
payload
=
payload
self
.
uri
=
uri
class
MessengerCo
re
(
object
):
class
MessengerCo
nf
(
object
):
def
_cfgGet
(
self
,
keyword
):
return
self
.
core
.
configGet
(
'messenger'
,
keyword
)
class
MessengerBot
(
BotCore
,
MessengerCore
):
class
MessengerBotAdapter
(
MessengerConf
):
implements
(
IBotProtoInterface
)
path
=
"messenger"
graphuri
=
'https://graph.facebook.com/v2.6'
sendQueue
=
Queue
()
sendlock
=
False
#graphuri = 'http://192.168.4.2/v2.6'
def
__init__
(
self
,
orig
):
self
.
orig
=
orig
self
.
core
=
orig
.
core
@
property
def
auth_args
(
self
):
...
...
@@ -109,6 +224,7 @@ class MessengerBot(BotCore, MessengerCore):
hmac_object
=
hmac
.
new
(
bytearray
(
self
.
_cfgGet
(
'app_secret'
),
'utf8'
),
str
(
self
.
_cfgGet
(
'page_token'
))
.
encode
(
'utf8'
),
hashlib
.
sha256
)
return
hmac_object
.
hexdigest
()
def
_dataSent
(
self
,
res
):
log
.
debug
(
'Messenger BOT Datasent OK'
)
log
.
debug
(
res
)
...
...
@@ -128,8 +244,6 @@ class MessengerBot(BotCore, MessengerCore):
return
wu
.
getPage
(
message
.
uri
,
method
=
'POST'
,
headers
=
message
.
headers
,
postdata
=
message
.
payload
)
.
addCallbacks
(
self
.
_dataSent
,
self
.
_dataError
)
def
sendAPI
(
self
,
payload
,
req_uri
=
'/me/messages'
):
request_endpoint
=
self
.
graphuri
+
req_uri
request_uri
=
request_endpoint
+
'?'
+
urlencode
(
self
.
auth_args
)
...
...
@@ -137,112 +251,23 @@ class MessengerBot(BotCore, MessengerCore):
ctype
=
{
"Content-Type"
:
"application/json"
}
return
wu
.
getPage
(
request_uri
,
method
=
'POST'
,
headers
=
ctype
,
postdata
=
convertToJson
(
payload
))
.
addCallbacks
(
self
.
_dataSent
,
self
.
_dataError
)
def
getUsername
(
self
,
uid
):
return
_MESSENGER_PSID
.
get_link
(
uid
)
@
route
(
"/"
,
Http
.
GET
)
def
rootGet
(
self
,
request
,
*
a
,
**
kw
):
if
'hub.mode'
in
kw
.
keys
()
and
kw
[
'hub.mode'
]
==
'subscribe'
and
'hub.challenge'
in
kw
.
keys
():
if
'hub.verify_token'
in
kw
.
keys
()
and
kw
[
'hub.verify_token'
]
==
self
.
_cfgGet
(
'verify_token'
):
log
.
info
(
"New verification request for Messenger BOT: "
+
str
(
kw
))
return
kw
[
'hub.challenge'
]
return
Response
(
403
,
"Failed validation."
)
@
route
(
"/"
,
Http
.
POST
)
@
messengerValidator
()
def
rootPost
(
self
,
request
,
*
a
,
**
kw
):
log
.
debug
(
"New messenger bot request: "
+
str
(
kw
))
if
'object'
in
kw
.
keys
()
and
kw
[
'object'
]
==
'page'
and
'entry'
in
kw
.
keys
():
for
entry
in
kw
[
'entry'
]:
try
:
#if True:
pageID
=
entry
[
'id'
]
timestamp
=
entry
[
'time'
]
messaging
=
entry
[
'messaging'
]
for
message
in
messaging
:
msgkeys
=
message
.
keys
()
if
'optin'
in
msgkeys
:
self
.
receivedAuthentication
(
message
)
elif
'message'
in
msgkeys
:
self
.
receivedMessage
(
message
)
elif
'delivery'
in
msgkeys
:
self
.
receivedDeliveryConfirmation
(
message
)
elif
'postback'
in
msgkeys
:
self
.
receivedPostback
(
message
)
elif
'read'
in
msgkeys
:
self
.
receivedMessageRead
(
message
)
elif
'account_linking'
in
msgkeys
:
self
.
receivedAccountLink
(
message
)
else
:
log
.
info
(
"Received unknow messaging webhook for messenger BOT: "
+
str
(
kw
))
except
:
pass
return
Response
(
200
,
'OK'
)
@
route
(
"/loginfailed"
)
def
loginFailed
(
self
,
request
,
*
a
,
**
kw
):
k
=
kw
.
keys
()
if
'account_linking_token'
in
k
and
'redirect_uri'
in
k
:
log
.
info
(
"Passed linking uri "
+
kw
[
'redirect_uri'
])
luri
=
kw
[
'redirect_uri'
]
log
.
info
(
"Authorization failed: redirecting to "
+
luri
)
return
Response
(
302
,
'Authorization failed'
,
headers
=
{
'Location'
:
luri
})
return
Response
(
200
,
"Authorization failed."
)
def
isLogged
(
self
,
uid
):
return
_MESSENGER_PSID
.
linkid_exists
(
uid
)
def
receivedAuthentication
(
self
,
msg
):
log
.
info
(
"Messenger bot received authentication: "
+
str
(
msg
))
def
receivedMessage
(
self
,
msg
):
def
voiceResult
(
res
):
log
.
info
(
'VoiceResult: '
+
str
(
res
))
if
len
(
res
)
>
0
:
if
res
[
0
]
==
'Ok'
and
len
(
res
)
>
1
:
try
:
result
=
'ho eseguito "'
+
" "
.
join
(
res
[
1
][
'clean'
])
+
'"'
except
:
pass
else
:
result
=
'Spiacente, non ho trovato un comando corrispondente'
self
.
sendMessage
(
msg
[
'sender'
][
'id'
],
result
)
def
receivedTextMessage
(
self
,
msg
):
log
.
info
(
"Messenger bot received message: "
+
str
(
msg
))
message
=
u'Received: '
+
unicode
(
msg
[
'message'
][
'text'
])
txt
=
unicode
(
msg
[
'message'
][
'text'
])
senderid
=
msg
[
'sender'
][
'id'
]
if
not
'is_echo'
in
msg
[
'message'
]
.
keys
()
or
not
msg
[
'message'
][
'is_echo'
]:
if
not
_MESSENGER_PSID
.
linkid_exists
(
senderid
):
log
.
info
(
_MESSENGER_PSID
.
links
)
if
txt
==
u'hello'
or
txt
==
u'ciao'
:
self
.
sendMessage
(
senderid
,
'Hello, how can i help you?'
)
elif
txt
==
u'?'
or
txt
==
u'help'
:
self
.
sendMessage
(
senderid
,
'you can
\'
t do that.'
)
elif
txt
==
u'login'
:
self
.
sendAuthRequest
(
senderid
)
else
:
self
.
sendMessage
(
senderid
,
txt
+
" come se fosse antani"
)
else
:
if
txt
==
u'hello'
or
txt
==
u'ciao'
:
self
.
sendMessage
(
senderid
,
'Hello
%
s, how can i help you?'
%
(
_MESSENGER_PSID
.
get_link
(
senderid
)))
elif
txt
==
u'?'
or
txt
==
u'help'
:
self
.
sendMessage
(
senderid
,
'Ok, devo ancora implementare l
\'
aiuto! Sorry for that!'
)
self
.
sendMessage
(
senderid
,
'Anyway, i comandi che hai sono: "command list", "screenshot list", "screenshot" e "clima".'
)
self
.
sendMessage
(
senderid
,
'Qualsiasi altro comando viene interpretato come un potenziale comando vocale.'
)
elif
txt
==
u'logout'
:
self
.
sendMessage
(
senderid
,
'Ok, devo ancora implementare anche il logout'
)
elif
txt
==
u'command list'
or
txt
==
'cmd list'
:
self
.
sendCommandList
(
senderid
)
elif
txt
==
u'screenshot list'
or
txt
==
u'ss list'
:
self
.
sendScreenshotList
(
senderid
)
elif
txt
.
startswith
(
'screenshot '
)
or
txt
.
startswith
(
'ss '
):
self
.
sendScreenshot
(
senderid
,
" "
.
join
(
txt
.
split
()[
1
:]))
elif
txt
==
u'clima'
:
self
.
sendClima
(
senderid
)
else
:
self
.
core
.
voiceReceived
(
txt
,
confidence
=
1.0
,
lang
=
"it"
)
.
addCallback
(
voiceResult
)
message
=
u'Received: '
+
unicode
(
msg
[
'message'
][
'text'
])
txt
=
unicode
(
msg
[
'message'
][
'text'
])
.
lower
()
botCommandParser
(
self
,
senderid
,
txt
)
def
receivedDeliveryConfirmation
(
self
,
msg
):
log
.
info
(
"Messenger bot received delivery confirmation: "
+
str
(
msg
))
...
...
@@ -286,7 +311,7 @@ class MessengerBot(BotCore, MessengerCore):
if
target
.
endswith
(
'
%
'
):
target
=
target
[:
-
1
]
if
len
(
target
)
>
0
:
self
.
core
.
getScreenshot
(
target
)
.
addCallback
(
pushImage
)
self
.
core
.
getScreenshot
(
target
,
pushImage
)
def
sendClima
(
self
,
recipient_id
):
def
pushClima
(
res
):
...
...
@@ -330,19 +355,22 @@ class MessengerBot(BotCore, MessengerCore):
}
return
self
.
sendAPI
(
payload
)
def
sendImageMessageData
(
self
,
recipient_id
,
imagedata
):
payload
=
{
'recipient'
:
{
'id'
:
recipient_id
},
'message'
:
{
'attachment'
:
{
'type'
:
'image'
,
'payload'
:
{}
}
}
}
fname
=
str
(
uuid
.
uuid4
()
.
get_hex
())
+
'.jpg'
def
sendImageMessageData
(
self
,
recipient_id
,
imagedata
,
mtype
=
None
):
if
not
imagedata
:
return
if
mtype
==
None
:
ft
=
imghdr
.
what
(
None
,
imagedata
)
log
.
info
(
"FILE TYPE: "
+
str
(
ft
))
if
ft
in
[
'jpeg'
,
'gif'
,
'png'
]:
mtype
=
ft
else
:
log
.
warning
(
"Image mimetype doesn't seems to be valid: "
+
str
(
ft
))
log
.
warning
(
"Assuming it's a jpeg."
)
mtype
=
'jpeg'
fname
=
str
(
uuid
.
uuid4
()
.
get_hex
())
+
mtype
bond
=
"------------------------"
+
str
(
uuid
.
uuid4
()
.
get_hex
())[:
16
]
data
=
"--"
+
bond
+
"
\r\n
"
data
+=
"Content-Disposition: form-data; name=
\"
recipient
\"\r\n\r\n
"
...
...
@@ -352,7 +380,7 @@ class MessengerBot(BotCore, MessengerCore):
data
+=
'{"attachment":{"type":"image", "payload":{}}}'
+
"
\r\n
"
data
+=
"--"
+
bond
+
"
\r\n
"
data
+=
'Content-Disposition: form-data; name="filedata"; filename="'
+
fname
+
'"'
+
"
\r\n
"
data
+=
'Content-Type: image/
jpeg'
+
"
\r\n\r\n
"
data
+=
'Content-Type: image/
'
+
mtype
+
"
\r\n\r\n
"
data
+=
str
(
imagedata
)
data
+=
"
\r\n
--"
+
bond
+
"--
\r\n
"
headers
=
{
...
...
@@ -365,7 +393,6 @@ class MessengerBot(BotCore, MessengerCore):
return
wu
.
getPage
(
request_uri
,
agent
=
"curl/7.50.1"
,
method
=
'POST'
,
headers
=
headers
,
postdata
=
data
,
expect100
=
True
)
.
addCallbacks
(
self
.
_dataSent
,
self
.
_dataError
)
def
sendAuthRequest
(
self
,
recipient_id
):
payload
=
{
'recipient'
:
{
...
...
@@ -390,8 +417,72 @@ class MessengerBot(BotCore, MessengerCore):
}
return
self
.
sendAPI
(
payload
)
components
.
registerAdapter
(
MessengerBotAdapter
,
BotProto
,
IBotProtoInterface
)
class
MessengerBot
(
BotCore
,
MessengerConf
):
path
=
"messenger"
@
route
(
"/"
,
Http
.
GET
)
def
rootGet
(
self
,
request
,
*
a
,
**
kw
):
if
'hub.mode'
in
kw
.
keys
()
and
kw
[
'hub.mode'
]
==
'subscribe'
and
'hub.challenge'
in
kw
.
keys
():
if
'hub.verify_token'
in
kw
.
keys
()
and
kw
[
'hub.verify_token'
]
==
self
.
_cfgGet
(
'verify_token'
):
log
.
info
(
"New verification request for Messenger BOT: "
+
str
(
kw
))
return
kw
[
'hub.challenge'
]
return
Response
(
403
,
"Failed validation."
)
@
route
(
"/"
,
Http
.
POST
)
@
messengerValidator
()
def
rootPost
(
self
,
request
,
*
a
,
**
kw
):
log
.
debug
(
"New messenger bot request: "
+
str
(
kw
))
botproto
=
BotProto
(
self
.
core
)
botiface
=
IBotProtoInterface
(
botproto
)
if
'object'
in
kw
.
keys
()
and
kw
[
'object'
]
==
'page'
and
'entry'
in
kw
.
keys
():
for
entry
in
kw
[
'entry'
]:
#try:
if
True
:
pageID
=
entry
[
'id'
]
timestamp
=
entry
[
'time'
]
messaging
=
entry
[
'messaging'
]
for
message
in
messaging
:
msgkeys
=
message
.
keys
()
if
'optin'
in
msgkeys
:
botiface
.
receivedAuthentication
(
message
)
elif
'message'
in
msgkeys
:
botiface
.
receivedTextMessage
(
message
)
elif
'delivery'
in
msgkeys
:
botiface
.
receivedDeliveryConfirmation
(
message
)
elif
'postback'
in
msgkeys
:
botiface
.
receivedPostback
(
message
)
elif
'read'
in
msgkeys
:
botiface
.
receivedMessageRead
(
message
)
elif
'account_linking'
in
msgkeys
:
botiface
.
receivedAccountLink
(
message
)
else
:
log
.
info
(
"Received unknow messaging webhook for messenger BOT: "
+
str
(
kw
))
#except:
# pass
return
Response
(
200
,
'OK'
)
@
route
(
"/loginfailed"
)
def
loginFailed
(
self
,
request
,
*
a
,
**
kw
):
k
=
kw
.
keys
()
if
'account_linking_token'
in
k
and
'redirect_uri'
in
k
:
log
.
info
(
"Passed linking uri "
+
kw
[
'redirect_uri'
])
luri
=
kw
[
'redirect_uri'
]
log
.
info
(
"Authorization failed: redirecting to "
+
luri
)
return
Response
(
302
,
'Authorization failed'
,
headers
=
{
'Location'
:
luri
})
return
Response
(
200
,
"Authorization failed."
)
class
MessengerBotAuth
(
BotCore
,
MessengerCo
re
):
class
MessengerBotAuth
(
BotCore
,
MessengerCo
nf
):
path
=
"messenger"
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment