Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
9
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Open sidebar
weechat
scripts
Commits
4588eaa9
Commit
4588eaa9
authored
Dec 30, 2020
by
KittyKatt
Committed by
Sébastien Helleu
Dec 30, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New script weejoin.py: push notifications of highlights and private messages to Join
parent
5818c8b7
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
299 additions
and
0 deletions
+299
-0
python/weejoin.py
python/weejoin.py
+299
-0
No files found.
python/weejoin.py
0 → 100644
View file @
4588eaa9
# weejoin
# KittyKatt (kittykatt@teknik.io)
# Released under the BSD license.
# vim: set fileencoding=utf8 ts=4 sw=4 expandtab :
import
json
import
re
import
urllib.parse
import
urllib.request
import
time
import
weechat
as
w
# Constant used to check if configs are required
REQUIRED
=
'_required'
w
.
register
(
'weejoin'
,
'KittyKatt (Lefty for weebullet)'
,
'1.0'
,
'BSD'
,
'weejoin pushes notifications from IRC to Join.'
,
''
,
''
)
w
.
hook_print
(
""
,
"irc_privmsg"
,
""
,
1
,
"priv_msg_cb"
,
""
)
w
.
hook_command
(
"send_push_note"
,
# command
"send a push note"
,
# description
"[message]"
# arguments description,
""
,
# argument
""
,
""
,
"cmd_send_push_note"
,
""
)
w
.
hook_command
(
"weejoin"
,
"pushes notifications from IRC to Join"
,
"[command]"
,
"Available commands are:
\n
"
" help : prints config options and defaults
\n
"
" listdevices : prints a list of all devices associated"
" with your Join API key
\n
"
" listignores : prints a list of channels that highlights "
" won't be pushed for
\n
"
" ignore : adds a channel to the blacklist
\n
"
" unignore : removes a channel from the blacklist"
,
""
,
"cmd_help"
,
""
)
configs
=
{
"api_key"
:
REQUIRED
,
"away_only"
:
"1"
,
# only send when away
"inactive_only"
:
"1"
,
# only send if buffer inactive
"device_iden"
:
"all"
,
# send to all devices
"ignored_channels"
:
""
,
# no ignored channels
"min_notify_interval"
:
"0"
,
# seconds, don't notify
# more often than this
"debug"
:
"0"
,
# enable debugging
"ignore_on_relay"
:
"0"
,
# if relay connected,
# don't send push notification
}
last_notification
=
0
# 0 seconds from the epoch
# Icon used by Join for notification icon
notification_icon
=
'https://upload.wikimedia.org/wikipedia/commons/thumb/a/a3/Weechat_logo.png/64px-Weechat_logo.png'
for
option
,
default_value
in
configs
.
items
():
if
w
.
config_get_plugin
(
option
)
==
""
:
if
configs
[
option
]
==
REQUIRED
:
w
.
prnt
(
""
,
w
.
prefix
(
"error"
)
+
"join: Please set option: %s"
%
option
)
if
type
(
default_value
)
==
"str"
:
w
.
prnt
(
""
,
"join: /set plugins.var.python.weejoin.%s STRING"
%
option
)
elif
type
(
default_value
)
==
"int"
:
w
.
prnt
(
""
,
"join: /set plugins.var.python.weejoin.%s INT"
%
option
)
else
:
w
.
prnt
(
""
,
"join: /set plugins.var.python.weejoin.%s VALUE"
%
option
)
else
:
w
.
config_set_plugin
(
option
,
configs
[
option
])
def
debug
(
msg
):
if
str
(
w
.
config_get_plugin
(
"debug"
))
is
not
"0"
:
w
.
prnt
(
""
,
"[weejoin] DEBUG: %s"
%
str
(
msg
))
def
process_devicelist_cb
(
data
,
url
,
status
,
response
,
err
):
try
:
devices
=
json
.
loads
(
response
)[
"records"
]
w
.
prnt
(
""
,
"Device List:"
)
for
device
in
devices
:
if
"deviceName"
in
device
:
w
.
prnt
(
""
,
"---
\n
%s"
%
device
[
"deviceName"
])
else
:
w
.
prnt
(
""
,
"---
\n
Unnamed"
)
w
.
prnt
(
""
,
"%s"
%
device
[
"id"
])
except
KeyError
:
w
.
prnt
(
""
,
"[weejoin] Error accessing device list: %s"
%
response
)
return
w
.
WEECHAT_RC_ERROR
return
w
.
WEECHAT_RC_OK
def
get_ignored_channels
():
ignored_channels
=
w
.
config_get_plugin
(
"ignored_channels"
)
if
ignored_channels
==
""
:
return
[]
else
:
return
[
channel
.
strip
()
for
channel
in
ignored_channels
.
split
(
','
)]
def
cmd_help
(
data
,
buffer
,
args
):
# Get current list of ignored channels in list form
ignored_channels
=
get_ignored_channels
()
# Used for checking for ignore/unignore commands and getting the arguments
ignore_command
=
re
.
match
(
"^ignore\s+(.+)"
,
args
)
unignore_command
=
re
.
match
(
"^unignore\s+(.+)"
,
args
)
if
(
ignore_command
is
not
None
):
channels_to_ignore
=
ignore_command
.
group
(
1
).
split
(
' '
)
for
channel
in
channels_to_ignore
:
if
channel
not
in
ignored_channels
:
ignored_channels
.
append
(
channel
)
w
.
config_set_plugin
(
"ignored_channels"
,
','
.
join
(
ignored_channels
))
w
.
prnt
(
""
,
"Updated. Ignored channels: %s"
%
w
.
config_get_plugin
(
"ignored_channels"
))
elif
(
unignore_command
is
not
None
):
channels_to_unignore
=
unignore_command
.
group
(
1
).
split
(
' '
)
for
channel
in
channels_to_unignore
:
if
channel
in
ignored_channels
:
ignored_channels
.
remove
(
channel
)
w
.
config_set_plugin
(
"ignored_channels"
,
','
.
join
(
ignored_channels
))
w
.
prnt
(
""
,
"Updated. Ignored channels: %s"
%
w
.
config_get_plugin
(
"ignored_channels"
))
elif
(
args
==
"listignores"
):
w
.
prnt
(
""
,
"Ignored channels: %s"
%
w
.
config_get_plugin
(
"ignored_channels"
))
elif
(
args
==
"listdevices"
):
apikey
=
w
.
string_eval_expression
(
w
.
config_get_plugin
(
"api_key"
),
{},
{},
{})
apiurl
=
"https://joinjoaomgcd.appspot.com/_ah/api/registration/v1/listDevices?apikey=%s"
%
(
apikey
)
w
.
hook_process
(
"url:"
+
apiurl
,
20000
,
"process_devicelist_cb"
,
""
)
else
:
w
.
prnt
(
""
,
"""
WeeJoin requires an API key from your Join account to work. Set your API key with (evaluated):
/set plugins.var.python.weejoin.api_key <KEY>
WeeJoin will by default only send notifications when you are marked away on IRC. You can change this with:
/set plugins.var.python.weejoin.away_only [0|1]
WeeJoin will by default send to all devices associated with your Join account. You can change this with:
/set plugins.var.python.weejoin.device_iden <ID>
WeeJoin can ignore repeated notifications if they arrive too often. You can set this with (0 or blank to disable):
/set plugins.var.python.weejoin.min_notify_interval <NUMBER>
You can get a list of your devices from the Join website, or by using
/weejoin listdevices
"""
)
return
w
.
WEECHAT_RC_OK
def
process_join_cb
(
data
,
url
,
status
,
response
,
err
):
body
=
None
headers
=
{}
lines
=
response
.
rstrip
().
splitlines
()
status_code
=
int
(
lines
.
pop
(
0
).
split
()[
1
])
for
line
in
lines
:
if
body
==
""
:
body
+=
line
continue
header_line
=
line
.
split
(
":"
,
2
)
if
len
(
header_line
)
!=
2
:
body
=
""
continue
headers
[
header_line
[
0
].
strip
()]
=
header_line
[
1
].
strip
()
# response is the string of http body
if
status
==
w
.
WEECHAT_HOOK_PROCESS_ERROR
:
w
.
prnt
(
""
,
"[weejoin] Error sending to join: %s - %s"
%
(
status
,
url
))
return
w
.
WEECHAT_RC_ERROR
if
status_code
is
401
or
status_code
is
403
:
w
.
prnt
(
""
,
"[weejoin] Invalid API Token: %s"
%
(
w
.
string_eval_expression
(
w
.
config_get_plugin
(
"api_key"
),
{},
{},
{})))
return
w
.
WEECHAT_RC_ERROR
if
status_code
is
not
200
:
w
.
prnt
(
""
,
"[weejoin] Error sending to join: %s - %s - %s"
%
(
url
,
status_code
,
body
))
return
w
.
WEECHAT_RC_ERROR
return
w
.
WEECHAT_RC_OK
def
send_push
(
title
,
body
):
global
last_notification
interval
=
w
.
config_get_plugin
(
"min_notify_interval"
)
if
interval
is
not
None
and
interval
!=
""
and
int
(
interval
)
!=
0
:
interval
=
int
(
interval
)
earliest_notification
=
last_notification
+
int
(
interval
)
if
last_notification
is
not
None
and
time
.
time
()
<=
earliest_notification
:
debug
(
"Too soon since last notification, skipping"
)
return
w
.
WEECHAT_RC_OK
last_notification
=
time
.
time
()
# check to see if the relay is connected, ignore if so
check_relays
=
w
.
config_string_to_boolean
(
w
.
config_get_plugin
(
'ignore_on_relay'
))
CONNECTED_RELAY
=
False
if
check_relays
:
infolist
=
w
.
infolist_get
(
'relay'
,
''
,
''
)
if
infolist
:
while
w
.
infolist_next
(
infolist
):
status
=
w
.
infolist_string
(
infolist
,
'status_string'
)
if
status
==
'connected'
:
CONNECTED_RELAY
=
True
break
w
.
infolist_free
(
infolist
)
if
CONNECTED_RELAY
is
True
:
# we have a relay conected, don't notify
debug
(
"Relay is connected, not sending push."
)
return
w
.
WEECHAT_RC_OK
debug
(
"Sending push. Title: [%s], body: [%s]"
%
(
title
,
body
))
apikey
=
w
.
string_eval_expression
(
w
.
config_get_plugin
(
"api_key"
),
{},
{},
{})
apiurl
=
"https://joinjoaomgcd.appspot.com/_ah/api/messaging/v1/sendPush?apikey=%s"
%
(
apikey
)
timeout
=
20000
# FIXME - actually use config
if
len
(
title
)
is
not
0
or
len
(
body
)
is
not
0
:
deviceiden
=
w
.
config_get_plugin
(
"device_iden"
)
if
deviceiden
==
"all"
:
payload
=
urllib
.
parse
.
urlencode
({
'title'
:
title
,
'text'
:
body
,
'deviceId'
:
'group.all'
,
'icon'
:
notification_icon
})
debug
(
"Full Payload: %s%s"
%
(
apiurl
,
payload
))
else
:
payload
=
urllib
.
parse
.
urlencode
({
'title'
:
title
,
'text'
:
body
,
'deviceId'
:
deviceiden
,
'icon'
:
notification_icon
})
debug
(
"Full Payload: %s%s"
%
(
apiurl
,
payload
))
w
.
hook_process_hashtable
(
"url:"
+
apiurl
,
{
"postfields"
:
payload
,
"header"
:
"1"
},
timeout
,
"process_join_cb"
,
""
)
def
cmd_send_push_note
(
data
,
buffer
,
args
):
send_push
(
title
=
"Manual Notification from weechat"
,
body
=
args
)
return
w
.
WEECHAT_RC_OK
def
priv_msg_cb
(
data
,
bufferp
,
uber_empty
,
tagsn
,
isdisplayed
,
ishilight
,
prefix
,
message
):
"""Sends highlighted message to be printed on notification"""
if
w
.
config_get_plugin
(
"away_only"
)
==
"1"
:
am_away
=
w
.
buffer_get_string
(
bufferp
,
'localvar_away'
)
else
:
am_away
=
True
if
not
am_away
:
# TODO: make debug a configurable
debug
(
"Not away, skipping notification"
)
return
w
.
WEECHAT_RC_OK
# If 'inactive_only' is enabled, we need to check if the notification is
# coming from the active buffer.
if
w
.
config_get_plugin
(
"inactive_only"
)
==
"1"
:
if
w
.
current_buffer
()
==
bufferp
:
# The notification came from the current buffer - don't notify
debug
(
"Notification came from the active buffer, "
"skipping notification"
)
return
w
.
WEECHAT_RC_OK
notif_body
=
u
"<%s> %s"
%
(
prefix
,
message
)
# Check that it's in a "/q" buffer and that I'm not the one writing the msg
is_pm
=
w
.
buffer_get_string
(
bufferp
,
"localvar_type"
)
==
"private"
is_notify_private
=
re
.
search
(
r
'(^|,)notify_private(,|$)'
,
tagsn
)
is
not
None
# PM (query)
if
(
is_pm
and
is_notify_private
):
send_push
(
title
=
"Privmsg from %s"
%
prefix
,
body
=
notif_body
)
# Highlight (your nick is quoted)
elif
(
str
(
ishilight
)
==
"1"
):
bufname
=
(
w
.
buffer_get_string
(
bufferp
,
"short_name"
)
or
w
.
buffer_get_string
(
bufferp
,
"name"
))
ignored_channels
=
get_ignored_channels
()
if
bufname
not
in
ignored_channels
:
send_push
(
title
=
"Highlight in %s"
%
bufname
,
body
=
notif_body
)
else
:
debug
(
"[weejoin] Ignored channel, skipping notification in %s"
%
bufname
)
return
w
.
WEECHAT_RC_OK
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