#!/usr/bin/env python3 import logging from getpass import getpass from argparse import ArgumentParser import slixmpp import ssl, os, requests, urllib from bs4 import BeautifulSoup from urllib.parse import quote as urlquote, unquote as urlunquote def make_numbered_text(input_text,output_html): if not os.path.exists(output_html): text = open(input_text, 'r') # open the txt file lines = text.readlines() # to divide the text into lines x = 1 with open(output_html, 'w') as new_html: # open the output_html with writing only as new_html new_html.write('') new_html.write('
') for line in lines: new_html.write('

{} {}

'.format(x, x, x, x, x, line)) x = x + 1 new_html.write('
') print('I wrote a new file!', output_html) def insert_comment_at_line(output_html,comment,line_number): with open (output_html,'r') as f: text = f.read() html = BeautifulSoup(text,'html.parser') div_id = 'linenum-{}'.format(line_number) line = html.find('div',{'id' : div_id}) print(line,comment,'#'+str(line_number)+'#') print(div_id) if line: with open (output_html,'w') as f: new_comment = html.new_tag("comment") new_comment.string = comment line.append(new_comment) f.write(html.decode()) def insert_media_at_line(output_html,mediafile,line_number): with open (output_html,'r') as f: text = f.read() html = BeautifulSoup(text,'html.parser') div_id = 'linenum-{}'.format(line_number) line = html.find('div',{'id' : div_id}) if line: #notes to self write function to the detect media type with open (output_html,'w') as f: new_image = html.new_tag("img", src = mediafile) line.append(new_image) f.write(html.decode()) class MUCBot(slixmpp.ClientXMPP): def __init__(self, jid, password, room, nick, output): slixmpp.ClientXMPP.__init__(self, jid, password) self.room = room self.nick = nick self.output = output self.current_line = 0 self.add_event_handler("session_start", self.start) # moment that it logs on self.add_event_handler("groupchat_message", self.muc_message) # moment that someone start speaking someone output = self.output if not os.path.exists(output): os.mkdir(output) make_numbered_text('text.txt','annotated-reader.html') def start(self, event): self.get_roster() self.send_presence() # https://xmpp.org/extensions/xep-0045.html self.plugin['xep_0045'].join_muc(self.room, self.nick, # If a room password is needed, use: # password=the_room_password, wait=True) def muc_message(self, msg): # Always check that a message is not the bot itself, otherwise you will create an infinite loop responding to your own messages. if msg['mucnick'] != self.nick: # Check if an OOB URL is included in the stanza (which is how an image is sent) # (OOB object - https://xmpp.org/extensions/xep-0066.html#x-oob) if len(msg['oob']['url']) > 0: # UPLOADED IMAGE # Send a reply self.send_message(mto=msg['from'].bare, mbody="Really? Oke. I'll add your photo for you, {}.".format(msg['mucnick']), mtype='groupchat') # Save the image to the output folder url = msg['oob']['url'] # grep the url in the message # urlunquote is like url to filename filename = os.path.basename(urlunquote(url)) # grep the filename in the url output = self.output # if not os.path.exists(output): # os.mkdir(output) output_path = os.path.join(output, filename) u = urllib.request.urlopen(url) # read the image data new_html = open(output_path, 'wb') # open the output file new_html.write(u.read()) # write image to file new_html.close() # close the output file # Add image to stream img = output_path insert_media_at_line('annotated-reader.html',img,self.current_line) else: # TEXT MESSAGE for word in msg['body'].split(): if word.startswith("#line"): self.current_line = int(word[5:]) self.send_message(mto=msg['from'].bare, mbody="I've set the current line number to {}.".format(self.current_line), mtype='groupchat') elif word == "#comment": self.send_message(mto=msg['from'].bare, mbody="Really? Oke. I'll add your comment that for you, {}.".format(msg['mucnick']), mtype='groupchat') insert_comment_at_line('annotated-reader.html',msg['body'], self.current_line) if __name__ == '__main__': # Setup the command line arguments. parser = ArgumentParser() # making your own command line - ArgumentParser. # output verbosity options. parser.add_argument("-q", "--quiet", help="set logging to ERROR", action="store_const", dest="loglevel", const=logging.ERROR, default=logging.INFO) parser.add_argument("-d", "--debug", help="set logging to DEBUG", action="store_const", dest="loglevel", const=logging.DEBUG, default=logging.INFO) # JID and password options. parser.add_argument("-j", "--jid", dest="jid", # jid = user help="JID to use") parser.add_argument("-p", "--password", dest="password", help="password to use") parser.add_argument("-r", "--room", dest="room", help="MUC room to join") parser.add_argument("-n", "--nick", dest="nick", help="MUC nickname") # MUC = multi user chat # output folder for images parser.add_argument("-o", "--output", dest="output", help="output folder, this is where the files are stored", default="./output/", type=str) args = parser.parse_args() # Setup logging. logging.basicConfig(level=args.loglevel, format='%(levelname)-8s %(message)s') if args.jid is None: args.jid = input("User: ") if args.password is None: args.password = getpass("Password: ") if args.room is None: args.room = input("MUC room: ") if args.nick is None: args.nick = input("MUC nickname: ") if args.output is None: args.output = input("Output folder: ") # Setup the MUCBot and register plugins. Note that while plugins may # have interdependencies, the order in which you register them does # not matter. xmpp = MUCBot(args.jid, args.password, args.room, args.nick, args.output) xmpp.register_plugin('xep_0030') # Service Discovery xmpp.register_plugin('xep_0045') # Multi-User Chat xmpp.register_plugin('xep_0199') # XMPP Ping xmpp.register_plugin('xep_0066') # Process URI's (files, images) # Connect to the XMPP server and start processing XMPP stanzas. xmpp.connect() xmpp.process()