User:Bohye Woo/Prototyping 02: Difference between revisions

From XPUB & Lens-Based wiki
No edit summary
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
=WORKSHOP – BLURRY BOUNDARY=
=Annotated Reader Website=
==TESSERACT — OCR/HOCR==
[[File:Annotation-Bot-by-Bohye-Woo.png|800px|center|Annotation Bot]]


<source lang="javascript">
<gallery mode="packed">
<script type="text/javascript">
File:Annotation-Bot-by-Bohye-Woo-2.png
File:Annotation-Bot-by-Bohye-Woo-3.png
File:Annotation-Bot-by-Bohye-Woo-4.png
File:Annotation-Bot-by-Bohye-Woo-5.png
File:Annotation-Bot-by-Bohye-Woo-6.png
File:Annotation-Bot-by-Bohye-Woo-7.png
File:Annotation-Bot-by-Bohye-Woo-8.png
File:Annotation-Bot-by-Bohye-Woo-9.png
File:Annotation-Bot-by-Bohye-Woo-10.png
File:Annotation-Bot-by-Bohye-Woo-11.png
</gallery>
 
==Annotation Bot Python script==
My annotation reader: https://git.xpub.nl/Bohye.Woo/si8-annotation-project <br>
Annotation Bot: https://git.xpub.nl/Bohye.Woo/Annotation-Bot
 
<source lang="python">
#!/usr/bin/env python3
 
import logging
from getpass import getpass
from argparse import ArgumentParser
import datetime
import pickle
import numpy as np
 
import slixmpp
import ssl, os, requests, urllib
from bs4 import BeautifulSoup
 
from urllib.parse import quote as urlquote, unquote as urlunquote
 
nickname_color = {}
 
# import the pickled object, serializing and de-serializing a Python object)
def save_obj(obj, name):
    with open(name + '.pkl', 'wb') as f:
        pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)
 
def load_obj(name):
    with open(name + '.pkl', 'rb') as f:
        return pickle.load(f)
 
# make a numbered text
def make_numbered_text(input_text, output_html):
    if not os.path.exists(output_html):  # if output_html path does not exist


    //store all class 'ocr_line' in 'lines'
        text = open(input_text, 'r')  # open the txt file
    var lines = document.querySelectorAll(".ocr_line");   
        lines = text.readlines()  # to divide the text into lines in the form {{"This is line 1"},{"This is line 2"},...}
        x = 1


    //loop through each element in 'lines'
        with open(output_html, 'w') as new_html:  # open the output_html with writing only as new_html
    for (var i = 0; i < lines.length; i++){
            new_html.write('<html><head><link rel="stylesheet" href="style.css" type="text/css"/><meta '
                          'charset="utf-8"/></head><body>')
            for line in lines:  # for each line in the list of lines
                new_html.write(
                    '<div class="linenum" id="linenum-{}"><div class="leftcolumn" id="leftcolumn-{}"><div class="linenumber">{}</div><div class="sentence">{}</div></div></div>'.format(
                        x, x, x, line))
                x = x + 1
            new_html.write('</body></html>')
            print('I wrote a file', output_html)


      var line = lines[i];
      console.log(line.title)


      //split the content of 'title' every space and store the list in 'parts'
# Get color from nickname_color dictionary. If it does not exist, create a color and save it
      var parts = line.title.split(" ");
def get_nickname_color(nickname):
      console.log(parts);
    if nickname not in nickname_color:  # If nickname is not in dict
        color = list(np.random.choice(range(256), size=3))  # Generate random new color
        nickname_color[nickname] = color  # Save new color in dict
        save_obj(nickname_color, 'nickname_color')
    return nickname_color[nickname]


      // width and height starts from the side
      var left = parseInt(parts[1], 10);
      var top = parseInt(parts[2], 10);
      var width = (parseInt(parts[3], 10) - left);
      var height = (parseInt(parts[4], 10) - top);


      // create a style element with the content selected from the list 'parts'
# (parameter variable,parameter variable,parameter variable)
      line.style = "position: absolute; left: " + parts[1] + "px; top: " + parts[2] + "px; width: " + width + "px; height: " + height + "px; border: 5px solid lightblue";
def insert_comment_at_line(output_html, comment, line_number, nickname):
    with open(output_html, 'r') as f:
        text = f.read()
        html = BeautifulSoup(text, 'html.parser')


      var words = line.querySelectorAll(".ocrx_word");
    div_id = 'linenum-{}'.format(line_number)  # out comes linenum-line_number
    line = html.find('div', {'id': div_id})  # find the div that has the id div_id (has the id linenum-line_number)


      for (var e = 0; e < words.length; e++){  
    if not html.find('div', {
        'id': 'rightcolumn-{}'.format(line_number)}):  # if there is no div with id rightcolumn-line_number
        # then make a new div with rightcolumn-line_number and class rightcolumn. Then, append it to the line variable.
        right_column = html.new_tag("div")
        right_column['id'] = 'rightcolumn-{}'.format(line_number)
        right_column['class'] = 'rightcolumn'
        line.append(right_column)
    else:
        right_column = html.find('div', {'id': 'rightcolumn-{}'.format(line_number)})


        var span = words[e];
    time = datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")
        console.log(span.title)  


        var parts = span.title.split(" ");
    color = get_nickname_color(nickname)
        console.log(parts);
    print(color)
    # new_comment = html.new_tag("comment")  # make <comment></comment>
    new_comment = html.new_tag("div")  # make <comment></comment>
    new_comment['id'] = 'comment-{}'.format(line_number)
    new_comment['class'] = 'comment'
    # new_comment['style'] = 'text-decoration: underline; -webkit-text-decoration-color: rgb(' + str(color[0]) + ',' + str(color[1]) + ',' + str(color[2])+');'
   
    comment_text = html.new_tag("span")
    comment_text['style'] = 'border-bottom: 2px solid rgb(' + str(color[0]) + ',' + str(color[1]) + ',' + str(color[2])+');'
   
    #remove #comment <number>
    comment = comment.split(' ',2)[2]


        var wleft = parseInt(parts[1], 10);
    comment_text.string = nickname + ': ' + comment + ' (' + time + ') ' # make <comment>comment (the parameter variable)</comment>
        var wtop = parseInt(parts[2], 10);
    comment_text['class'] = 'comment-text'
        var wwidth = (parseInt(parts[3], 10) - wleft);
    new_comment.append(comment_text)
        var wheight = (parseInt(parts[4], 10) - wtop);
    right_column.append(new_comment)


        span.style = "position: absolute; left: " + (wleft - left) + "px; top: " + (wtop - top) + "px; width: " + wwidth  + "px; height: " + wheight + "px; border: 2px solid purple";
    print(line, comment, '#' + str(line_number) + '#')
      }
     print(div_id)
     }


</source>
    if line:
        with open(output_html, 'w') as f:
            right_column.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 not html.find('div', {'id': 'rightcolumn-{}'.format(line_number)}):
        right_column = html.new_tag("div")
        right_column['id'] = 'rightcolumn-{}'.format(line_number)
        right_column['class'] = 'rightcolumn'
        line.append(right_column)
    else:
        right_column = html.find('div', {'id': 'rightcolumn-{}'.format(line_number)})
 
    print(line, mediafile, '#' + str(line_number) + '#')
    print(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)
            right_column.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', 'dependency-of-network.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
 
                # If we haven't set current line yet, prompt the user to do so
                if self.current_line < 0:
                    self.send_message(mto=msg['from'].bare,
                                      mbody="{}, before uploading an image, please use the following syntax: #image <line number>".format(
                                          msg['mucnick']),
                                      mtype='groupchat')


                # Add image to stream
                img = output_path
                insert_media_at_line('dependency-of-network.html', img, self.current_line)


<gallery mode="packed" heights="280px">
            else:
File:Ocring.png
                # TEXT MESSAGE
File:Proscan01.png
                words = msg['body'].split()
File:Screenshot1.png
                linenum = words[1]
File:Screenshot2.png
                if msg['body'].startswith("#image"):
File:Screenshot3.png
                    if (linenum.isdigit()):
</gallery>
                        self.current_line = int(words[1])
                        self.send_message(mto=msg['from'].bare,
                                          mbody="Please now upload the image to be inserted on line {}.".format(
                                              self.current_line),
                                          mtype='groupchat')
                    else:
                        self.current_line = -1
                        self.send_message(mto=msg['from'].bare,
                                          mbody="{}, please use the following syntax: #image <line number>".format(
                                              msg['mucnick']),
                                          mtype='groupchat')
                if msg['body'].startswith("#comment"):
                    print(linenum)
                    if (linenum.isdigit()):
                        self.send_message(mto=msg['from'].bare,
                                          mbody="Really? Oke. I'll add your comment that for you, {}.".format(
                                              msg['mucnick']),
                                          mtype='groupchat')
                        # output_html,comment,line_number,username
                        insert_comment_at_line('dependency-of-network.html', msg['body'], linenum, msg['mucnick'])
                    else:
                        self.send_message(mto=msg['from'].bare,
                                          mbody="{}, please use the following syntax: #comment <line number> <message>...".format(
                                              msg['mucnick']),
                                          mtype='groupchat')


==DIGITAL WATERMAKING==
According to the Digital Watermarking Alliance:  http://digitalwatermarkingalliance.org/about/quick-facts/
    Digital watermarking is the process by which identifying data is woven into media content such as images, printed materials, movies, music or TV programming, giving those objects a unique, digital identity that can be used for a variety of valuable applications.
    ...
    Digital watermarking can enable content identification, forensic tracking and copyright communication on a broad scale and can provide a range of solutions for identifying, securing, managing and tracking digital images, audio, video, and printed materials.


===* Verso Books===
if __name__ == '__main__':
** Create an account in https://www.versobooks.com/
    # Setup the command line arguments.
** Download book as epub, a free one will do, for instance https://www.versobooks.com/books/2772-verso-2017-mixtape
    parser = ArgumentParser()  # making your own command line - ArgumentParser.
** search for watermarks on the EPUB
** Look at the Institute for Biblio-Immunology -- First Communique: https://pastebin.com/raw/E1xgCUmb for more leads. https://www.booxtream.com/


    # 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)


====Notes====
    # JID and password options.
*we found our names and emails on cover of the books, and our names on each of the file. (e.g. 02_Copyrightbohye5416yournamegmailcom.xhtml: This eBook is licensed to your-name, id@gmail.com on 05/13/2019)
    parser.add_argument("-j", "--jid", dest="jid",  # jid = user
*we need to target these texts and remove them (how?)  
                        help="JID to use")
*they were appended to file while we download the item. BooXtream video explained how it works:
    parser.add_argument("-p", "--password", dest="password",
industry standard epub file + customer data
                        help="password to use")
BooXtream API
    parser.add_argument("-r", "--room", dest="room",
download link to BooXtream watermarked file
                        help="MUC room to join")
multiple invisible watermarks encoded with personal information data (kindle files) Exlibris
    parser.add_argument("-n", "--nick", dest="nick",
*
                        help="MUC nickname") # MUC = multi user chat


===Watermarks===
    # output folder for images
====[WM0] -- Ex Libris Image Watermark====
    parser.add_argument("-o", "--output", dest="output",
Ex Libris Image Watermark is a small personalised bookplate. (visible)
                        help="output folder, this is where the files are stored",
                        default="./output/", type=str)


====[WM1] -- Disclaimer Page Watermark: (visible)====
    args = parser.parse_args()
(e.g.    This ebook was sold to bohye woo, bohyeklaire@gmail.com on 13/05/2019.
Verso ebooks are free of Digital Rights Management (DRM-free) but are subject to the terms of this license. You own this file once you’ve downloaded it, and you can use it on any of your devices. It has visible and invisible watermarks, applied by Booxtream, which contain your name and email address. You are prohibited from uploading Verso ebooks to any website or file-sharing network, or in any other way making them available for distribution, sharing, copying, downloading, or reselling. Royalties from every sale will be paid to the author: if you’re reading someone else’s copy, then please buy your own license from Verso Books.)


====[WM2] -- Footer Watermarks: (visible)====
    # Setup logging.
It's on every at the end of the chapter on the bottom:
    logging.basicConfig(level=args.loglevel,
(e.g. This eBook is licensed to bohye woo, bohyeklaire@gmail.com on 05/13/2019)
                        format='%(levelname)-8s %(message)s')


====[WM3] -- Filename Watermarks (invisible)====
    if args.jid is None:
https://sigil-ebook.com/
        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: ")


====[WM4] -- Timestamp Fingerprinting====
    # Setup the MUCBot and register plugins. Note that while plugins may
====[WM5] -- CSS Watermark====
    # have interdependencies, the order in which you register them does
remove boekstaaf class in css stylesheet
    # not matter.
====[WM6] -- Image Metadata Watermarks====
    xmpp = MUCBot(args.jid, args.password, args.room, args.nick, args.output)
how to use Exiftool http://xahlee.info/img/metadata_in_image_files.html
    xmpp.register_plugin('xep_0030')  # Service Discovery
https://www.sno.phy.queensu.ca/~phil/exiftool/
    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)


====Steganograhy tool====
    # Connect to the XMPP server and start processing XMPP stanzas.
Steganography with  https://www.blackmoreops.com/2017/01/11/steganography-in-kali-linux-hiding-data-in-image/
    xmpp.connect()
    xmpp.process()
apt-get install steghide


==FINAL==
    # Load color data
    if os.path.exists("nickname_color.pkl"):
        nickname_color = load_obj("nickname_color")  # Load dictionary from file into variable (nickname_color)
</source>

Latest revision as of 00:16, 19 June 2019

Annotated Reader Website

Annotation Bot

Annotation Bot Python script

My annotation reader: https://git.xpub.nl/Bohye.Woo/si8-annotation-project
Annotation Bot: https://git.xpub.nl/Bohye.Woo/Annotation-Bot

#!/usr/bin/env python3

import logging
from getpass import getpass
from argparse import ArgumentParser
import datetime
import pickle
import numpy as np

import slixmpp
import ssl, os, requests, urllib
from bs4 import BeautifulSoup

from urllib.parse import quote as urlquote, unquote as urlunquote

nickname_color = {}

# import the pickled object, serializing and de-serializing a Python object)
def save_obj(obj, name):
    with open(name + '.pkl', 'wb') as f:
        pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)

def load_obj(name):
    with open(name + '.pkl', 'rb') as f:
        return pickle.load(f)

# make a numbered text
def make_numbered_text(input_text, output_html):
    if not os.path.exists(output_html):  # if output_html path does not exist

        text = open(input_text, 'r')  # open the txt file
        lines = text.readlines()  # to divide the text into lines in the form {{"This is line 1"},{"This is line 2"},...}
        x = 1

        with open(output_html, 'w') as new_html:  # open the output_html with writing only as new_html
            new_html.write('<html><head><link rel="stylesheet" href="style.css" type="text/css"/><meta '
                           'charset="utf-8"/></head><body>')
            for line in lines:  # for each line in the list of lines
                new_html.write(
                    '<div class="linenum" id="linenum-{}"><div class="leftcolumn" id="leftcolumn-{}"><div class="linenumber">{}</div><div class="sentence">{}</div></div></div>'.format(
                        x, x, x, line))
                x = x + 1
            new_html.write('</body></html>')
            print('I wrote a file', output_html)


# Get color from nickname_color dictionary. If it does not exist, create a color and save it
def get_nickname_color(nickname):
    if nickname not in nickname_color:  # If nickname is not in dict
        color = list(np.random.choice(range(256), size=3))  # Generate random new color
        nickname_color[nickname] = color  # Save new color in dict
        save_obj(nickname_color, 'nickname_color')
    return nickname_color[nickname]


# (parameter variable,parameter variable,parameter variable)
def insert_comment_at_line(output_html, comment, line_number, nickname):
    with open(output_html, 'r') as f:
        text = f.read()
        html = BeautifulSoup(text, 'html.parser')

    div_id = 'linenum-{}'.format(line_number)  # out comes linenum-line_number
    line = html.find('div', {'id': div_id})  # find the div that has the id div_id (has the id linenum-line_number)

    if not html.find('div', {
        'id': 'rightcolumn-{}'.format(line_number)}):  # if there is no div with id rightcolumn-line_number
        # then make a new div with rightcolumn-line_number and class rightcolumn. Then, append it to the line variable.
        right_column = html.new_tag("div")
        right_column['id'] = 'rightcolumn-{}'.format(line_number)
        right_column['class'] = 'rightcolumn'
        line.append(right_column)
    else:
        right_column = html.find('div', {'id': 'rightcolumn-{}'.format(line_number)})

    time = datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")

    color = get_nickname_color(nickname)
    print(color)
    # new_comment = html.new_tag("comment")  # make <comment></comment>
    new_comment = html.new_tag("div")  # make <comment></comment>
    new_comment['id'] = 'comment-{}'.format(line_number)
    new_comment['class'] = 'comment'
    # new_comment['style'] = 'text-decoration: underline; -webkit-text-decoration-color: rgb(' + str(color[0]) + ',' + str(color[1]) + ',' + str(color[2])+');'
    
    comment_text = html.new_tag("span")
    comment_text['style'] = 'border-bottom: 2px solid rgb(' + str(color[0]) + ',' + str(color[1]) + ',' + str(color[2])+');'
    
    #remove #comment <number>
    comment = comment.split(' ',2)[2] 

    comment_text.string = nickname + ': ' + comment + ' (' + time + ') ' # make <comment>comment (the parameter variable)</comment>
    comment_text['class'] = 'comment-text'
    new_comment.append(comment_text)
    right_column.append(new_comment)

    print(line, comment, '#' + str(line_number) + '#')
    print(div_id)

    if line:
        with open(output_html, 'w') as f:
            right_column.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 not html.find('div', {'id': 'rightcolumn-{}'.format(line_number)}):
        right_column = html.new_tag("div")
        right_column['id'] = 'rightcolumn-{}'.format(line_number)
        right_column['class'] = 'rightcolumn'
        line.append(right_column)
    else:
        right_column = html.find('div', {'id': 'rightcolumn-{}'.format(line_number)})

    print(line, mediafile, '#' + str(line_number) + '#')
    print(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)
            right_column.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', 'dependency-of-network.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

                # If we haven't set current line yet, prompt the user to do so
                if self.current_line < 0:
                    self.send_message(mto=msg['from'].bare,
                                      mbody="{}, before uploading an image, please use the following syntax: #image <line number>".format(
                                          msg['mucnick']),
                                      mtype='groupchat')

                # Add image to stream
                img = output_path
                insert_media_at_line('dependency-of-network.html', img, self.current_line)

            else:
                # TEXT MESSAGE
                words = msg['body'].split()
                linenum = words[1]
                if msg['body'].startswith("#image"):
                    if (linenum.isdigit()):
                        self.current_line = int(words[1])
                        self.send_message(mto=msg['from'].bare,
                                          mbody="Please now upload the image to be inserted on line {}.".format(
                                              self.current_line),
                                          mtype='groupchat')
                    else:
                        self.current_line = -1
                        self.send_message(mto=msg['from'].bare,
                                          mbody="{}, please use the following syntax: #image <line number>".format(
                                              msg['mucnick']),
                                          mtype='groupchat')
                if msg['body'].startswith("#comment"):
                    print(linenum)
                    if (linenum.isdigit()):
                        self.send_message(mto=msg['from'].bare,
                                          mbody="Really? Oke. I'll add your comment that for you, {}.".format(
                                              msg['mucnick']),
                                          mtype='groupchat')
                        # output_html,comment,line_number,username
                        insert_comment_at_line('dependency-of-network.html', msg['body'], linenum, msg['mucnick'])
                    else:
                        self.send_message(mto=msg['from'].bare,
                                          mbody="{}, please use the following syntax: #comment <line number> <message>...".format(
                                              msg['mucnick']),
                                          mtype='groupchat')


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()

    # Load color data
    if os.path.exists("nickname_color.pkl"):
        nickname_color = load_obj("nickname_color")  # Load dictionary from file into variable (nickname_color)