-
Notifications
You must be signed in to change notification settings - Fork 0
/
keep.py
167 lines (145 loc) · 5.5 KB
/
keep.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/env python2.7
# keep.py is used for xmpp communication between digitalocean server and laptop/mobile xmpp chat client for myfitnesspal project
# starting code from http://off-the-stack.moorman.nu/2012-10-10-keep-in-touch-with-your-servers-using-xmpp.html
# code modified by Aleksandar Josifoski 2018 May
"""
Prototype client for simple monitoring purposes.
"""
import os
import time
import traceback
import xmpp
import codecs
import glob
import sys
reload(sys)
sys.setdefaultencoding('utf8')
# dir_in is directory where project files will be placed, assuming that on server
# username is mfp and directory is also called mfp
dir_in = '/home/mfp/mfp/'
# In CLIENT_JID you set server xmpp account
# Example: CLIENT_JID = "[email protected]"
CLIENT_JID = ""
CLIENT_PASSWORD = ""
# In AUTHORIZED_JIDS list you set personal xmpp accounts
# Example AUTHORIZED_JIDS = ["[email protected]", "[email protected]"]
AUTHORIZED_JIDS = []
mysender = ''
mymessage_type = None
def writetocommandtxt(command):
''' this function will append command to line_commands.txt '''
with codecs.open(dir_in + 'command.txt'.strip(), 'w', 'utf-8') as fout:
fout.write(str(command))
def handle_responses(client):
''' function to handle responses '''
lr = glob.glob(dir_in + 'responses/' + '*.txt')
lr.sort()
for resp in lr:
fresp = codecs.open(resp, 'r', 'utf-8')
line = fresp.read()
line = line.strip()
fresp.close()
message = line
client.send(xmpp.Message(mysender, message, typ=mymessage_type))
os.remove(resp)
def handle_messages(jids, commands):
"""
Returns a stanza handler function which executes given commands
from the provided jids.
"""
def handler(client, stanza):
"""
Handler which executes given commands from authorized jids.
"""
global mysender
global mymessage_type
sender = stanza.getFrom()
mysender = sender
#print(str(sender) + '*' * 100)
message_type = stanza.getType()
mymessage_type = message_type
if any([sender.bareMatch(x) for x in jids]):
command = stanza.getBody()
#print(str(command) + '*' * 100)
if str(command) != 'None':
writetocommandtxt(command)
return handler
def handle_presences(jids):
"""
Returns a stanza handler function which automatically authorizes
incoming presence requests from the provided jids.
"""
def handler(client, stanza):
"""
Handler which automatically authorizes subscription requests
from authorized jids.
"""
sender = stanza.getFrom()
presence_type = stanza.getType()
if presence_type == "subscribe":
if any([sender.bareMatch(x) for x in jids]):
client.send(xmpp.Presence(to=sender, typ="subscribed"))
return handler
def run_client(client_jid, client_password, authorized_jids):
"""
Initializes and runs a fresh xmpp client (blocking).
"""
high_load = 5
commands = {
"stats": lambda *args: os.popen("uptime").read().strip(),
}
# Initialize and connect the client.
jid = xmpp.JID(client_jid)
client = xmpp.Client(jid.domain)
if not client.connect():
return
# Authenticate.
if not client.auth(jid.node, client_password, jid.resource):
return
# Register the message handler which is used to respond
# to messages from the authorized contacts.
message_callback = handle_messages(authorized_jids, commands)
client.RegisterHandler("message", message_callback)
# Register the presence handler which is used to automatically
# authorize presence-subscription requests from authorized contacts.
presence_callback = handle_presences(authorized_jids)
client.RegisterHandler("presence", presence_callback)
# Go "online".
client.sendInitPresence()
client.Process()
# Finally, loop, update the presence according to the load and
# "sleep" for a while.
previous_load_maximum = 0
while client.isConnected():
# Determine the load averages and the maximum of the 1, 10 and 15 minute
# averages.
# In case the maximum is above the "high_load" value, the status will be
# set to "do not disturb" with the load averages as status message.
# The status will be updated continuously once we reached high load.
# When the load decreases and the maximum is below the "high_load" value
# again, the status is reset to "available".
load = os.getloadavg()
load_string = "load: %s %s %s" % load
load_maximum = max(list(load))
if load_maximum >= high_load:
client.send(xmpp.Presence(show="dnd", status=load_string))
elif load_maximum < high_load and previous_load_maximum >= high_load:
client.send(xmpp.Presence())
previous_load_maximum = load_maximum
# Handle stanzas and sleep.
client.Process()
handle_responses(client)
time.sleep(1)
if __name__ == "__main__":
# Loop until the program is terminated.
# In case of connection problems and/or exceptions, the client is
# run again after a delay.
while True:
print "Trying to connect ..."
try:
run_client(CLIENT_JID, CLIENT_PASSWORD, AUTHORIZED_JIDS)
except Exception, e:
print "Caught exception!"
traceback.print_exc()
print "Not connected - attempting reconnect in a moment."
time.sleep(10)