diff --git a/suricata/SuricataToIdea.py b/suricata/SuricataToIdea.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc7d53d57d213360423879d9b3d316f6a5203eb2
--- /dev/null
+++ b/suricata/SuricataToIdea.py
@@ -0,0 +1,426 @@
+import socket
+import json
+from uuid import uuid4
+import re
+import optparse
+import sys
+import os
+import signal
+import resource
+import os.path as pth
+import atexit
+import time
+from collections import OrderedDict
+import logging
+
+
+class FileWatcher(object):
+
+    def __init__(self, filename, tail=True):
+        self.filename = filename
+        self.open()
+        self.line_buffer = ""
+        if tail and self.f:
+            self.f.seek(0, os.SEEK_END)
+
+    def open(self):
+        '''
+        opens file, stored in self.filename and stores i-node and size of file to object
+        :return: nothing
+        '''
+        try:
+            self.f = open(self.filename, "r")
+            st = os.fstat(self.f.fileno())      # stores file stats get from filedescriptor
+            self.inode, self.size = st.st_ino, st.st_size
+        except IOError:
+            self.f = None
+            self.inode = -1
+            self.size = -1
+
+    def _check_reopen(self):
+        '''
+        if i-node or size of opened filed changed(someone renamed it, deleted it), then reopen file
+        :return: nothing
+        '''
+        try:
+            st = os.stat(self.filename)
+            cur_inode, cur_size = st.st_ino, st.st_size
+        except OSError as e:
+            cur_inode = -1
+            cur_size = -1
+        if cur_inode != self.inode or cur_size < self.size:
+            self.close()
+            self.open()
+
+    def readline(self):
+        '''
+        opens or reopens file and reads one line from it and appends it to self.line_buffer
+        :return: self.line_buffer
+        '''
+        if not self.f:
+            self.open()
+            if not self.f:
+                return self.line_buffer
+        res = self.f.readline()
+        if not res:
+            self._check_reopen()
+            if not self.f:
+                return self.line_buffer
+            res = self.f.readline()
+        if not res.endswith("\n"):
+            self.line_buffer += res
+        else:
+            res = self.line_buffer + res
+            self.line_buffer = ""
+            return res
+
+    def close(self):
+        try:
+            if self.f:
+                self.f.close()
+        except IOError:
+            pass
+        self.inode = -1
+        self.size = -1
+
+    def __repr__(self):
+        return '%s("%s")' % (type(self).__name__, self.filename)
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.close()
+        return False
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        return self.readline()
+
+
+class Filer(object):
+
+    def __init__(self, directory):
+        self.basedir = self._ensure_path(directory)
+        self.tmp = self._ensure_path(pth.join(self.basedir, "tmp"))
+        self.incoming = self._ensure_path(pth.join(self.basedir, "incoming"))
+        self.hostname = socket.gethostname()
+        self.pid = os.getpid()
+
+    def _ensure_path(self, p):
+        try:
+            os.mkdir(p)
+        except OSError:
+            if not pth.isdir(p):
+                raise
+        return p
+
+    def _get_new_name(self, fd=None):
+        (inode, device) = os.fstat(fd)[1:3] if fd else (0, 0)
+        return "%s.%d.%f.%d.%d" % (
+            self.hostname, self.pid, time.time(), device, inode)
+
+    def create_unique_file(self):
+        # First find and open name unique within tmp
+        tmpname = None
+        while not tmpname:
+            tmpname = self._get_new_name()
+            try:
+                fd = os.open(pth.join(self.tmp, tmpname), os.O_CREAT | os.O_RDWR | os.O_EXCL)
+            except OSError as e:
+                if e.errno != errno.EEXIST:
+                    raise   # other errors than duplicates should get noticed
+                tmpname = None
+        # Now we know the device/inode, rename to make unique within system
+        newname = self._get_new_name(fd)
+        os.rename(pth.join(self.tmp, tmpname), pth.join(self.tmp, newname))
+        nf = os.fdopen(fd, "w")
+        return nf, newname
+
+    def publish_file(self, short_name):
+        os.rename(pth.join(self.tmp, short_name), pth.join(self.incoming, short_name))
+
+
+class IdeaGen(object):
+
+    idea_categories = {'Intrusion.Botnet': re.compile("A Network Trojan was detected, signature: ET CNC"),
+                       'Malware.Trojan': re.compile("A Network Trojan was detected, signature: ET (?!CNC)"),
+                       'Recon.Scanning': re.compile("signature: (ET|GPL) (SCAN|DNS Query|CURRENT_EVENTS DNS Query)"),
+                       'Availability.DoS': re.compile("signature: ET DOS"),
+                       'Abusive.Spam': re.compile("signature:.*?Spam(?!cop.net)"),
+                       'Attempt.Exploit': re.compile("category: Web Application Attack")}
+    other_a_re = re.compile("signature: (GPL SNMP|GPL WEB_SERVER|ET DROP Dshield|ET WEB_CLIENT Hex Obfuscation|GPL TELNET)")
+    other_b_re = re.compile("Potential Corporate Privacy Violation, signature: ET (?!POLICY)")
+
+    def __init__(self, name, test):
+        self.name = name
+        self.test = test
+
+    def convert_category(self, category, signature):
+        if not (category and signature):
+            return None
+        suricata_category = "category: " + category + ", signature: " + signature
+        if IdeaGen.other_a_re.search(suricata_category) or IdeaGen.other_b_re.search(suricata_category):
+            return "Other"
+        for category, pattern in IdeaGen.idea_categories.items():
+            if pattern.search(suricata_category):
+               return category
+        return None
+
+    def gen_event_idea(self, timestamp, category, src_ip, src_port, proto, dest_ip, dest_port, orig_data,
+                       incident_desription):
+        event = {
+            'Format': "IDEA0",
+            'ID': str(uuid4()),
+            'DetectTime': timestamp,
+            'Category': [category] + (["Test"] if self.test else []),
+            'Note': incident_desription
+        }
+        source = {}
+        target = {}
+        if src_ip:
+            af = "IP4" if not ':' in src_ip else "IP6"
+            source[af] = [src_ip]
+        if src_port:
+            source['Port'] = [src_port]
+        if proto:
+            source['Proto'] = [proto]
+        if dest_ip:
+            af = "IP4" if not ':' in dest_ip else "IP6"
+            target[af] = [dest_ip]
+        if dest_port:
+            target['Port'] = [dest_port]
+        if source:
+            event['Source'] = [source]
+        if target:
+            event['Target'] = [target]
+        if orig_data:
+            attachment = {'Handle': "att1",
+                          'Note': "original data",
+                          'Content': orig_data}
+            event['Attach'] = attachment
+        event['Node'] = [{
+                            'Name': self.name,
+                            'Type': ["Connection", "Honeypot", "Recon"],
+                            'SW': ["HP Tipping Point"],
+                        }]
+        return event
+
+
+def daemonize(
+        work_dir=None, chroot_dir=None,
+        umask=None, uid=None, gid=None,
+        pidfile=None, files_preserve=[], signals={}):
+    # Dirs, limits, users
+    if chroot_dir is not None:
+        os.chdir(chroot_dir)
+        os.chroot(chroot_dir)
+    if umask is not None:
+        os.umask(umask)
+    if work_dir is not None:
+        os.chdir(work_dir)
+    if gid is not None:
+        os.setgid(gid)
+    if uid is not None:
+        os.setuid(uid)
+    # Doublefork, split session
+    if os.fork() > 0:
+        os._exit(0)
+    try:
+        os.setsid()
+    except OSError:
+        pass
+    if os.fork() > 0:
+        os._exit(0)
+    # Setup signal handlers
+    for (signum, handler) in signals.items():
+        signal.signal(signum, handler)
+    # Close descriptors
+    descr_preserve = set(f.fileno() for f in files_preserve)
+    maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
+    if maxfd == resource.RLIM_INFINITY:
+        maxfd = 65535
+    for fd in range(maxfd, 3, -1):  # 3 means omit stdin, stdout, stderr
+        if fd not in descr_preserve:
+            try:
+                os.close(fd)
+            except Exception:
+                pass
+    # Redirect stdin, stdout, stderr to /dev/null
+    devnull = os.open(os.devnull, os.O_RDWR)
+    for fd in range(3):
+        os.dup2(devnull, fd)
+    # PID file
+    if pidfile is not None:
+        pidd = os.open(pidfile, os.O_RDWR | os.O_CREAT | os.O_EXCL | os.O_TRUNC)
+        os.write(pidd, str(os.getpid())+"\n")
+        os.close(pidd)
+        # Define and setup atexit closure
+        @atexit.register
+        def unlink_pid():
+            try:
+                os.unlink(pidfile)
+            except Exception:
+                pass
+
+
+def get_args():
+    optp = optparse.OptionParser(
+        usage="usage: %prog [options] logfile ...",
+        description="Watch Suricata logfiles and generate Idea events into directory")
+    optp.add_option(
+        "-n", "--name",
+        default=None,
+        dest="name",
+        type="string",
+        action="store",
+        help="Warden client name")
+    optp.add_option(
+        "--test",
+        default=False,
+        dest="test",
+        action="store_true",
+        help="Add Test category")
+    optp.add_option(
+        "-o", "--oneshot",
+        default=False,
+        dest="oneshot",
+        action="store_true",
+        help="process files and quit (do not daemonize)")
+    optp.add_option(
+        "--poll",
+        default=1,
+        dest="poll",
+        type="int",
+        action="store",
+        help="log file polling interval")
+    optp.add_option(
+        "-d", "--dir",
+        default=None,
+        dest="dir",
+        type="string",
+        action="store",
+        help="Target directory (mandatory)")
+    optp.add_option(
+        "-p", "--pid",
+        default=pth.join("/var/run", pth.splitext(pth.basename(sys.argv[0]))[0] + ".pid"),
+        dest="pid",
+        type="string",
+        action="store",
+        help="create PID file with this name (default: %default)")
+    optp.add_option(
+        "-u", "--uid",
+        default=None,
+        dest="uid",
+        type="int",
+        action="store",
+        help="user id to run under")
+    optp.add_option(
+        "-g", "--gid",
+        default=None,
+        dest="gid",
+        type="int",
+        action="store",
+        help="group id to run under")
+    optp.add_option(
+        "--origdata",
+        default=False,
+        dest="origdata",
+        action="store_true",
+        help="Store original report to IDEA message")
+    return optp
+
+
+def save_events(event, filer):
+    f, name = filer.create_unique_file()
+    with f:
+        f.write(json.dumps(event, ensure_ascii=True))
+    filer.publish_file(name)
+
+running_flag = True
+reload_flag = False
+
+
+def terminate_me(signum, frame):
+    global running_flag
+    running_flag = False
+
+
+def reload_me(signum, frame):
+    global reload_flag
+    reload_flag = True
+
+
+def main():
+    global reload_flag
+    global running_flag
+    logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG, filename='suricataDaemonLog.log', filemode='w')
+    optp = get_args()
+    # win
+    '''opts, args = optp.parse_args(["--origdata", "-d", "C:\\Users\\Aisik\\PycharmProjects\\SuricataToIdea\\IdeaLogTest.txt", "-n",
+                                  "cz.cesnet.server.suricata", "C:\\Users\\Aisik\\PycharmProjects\\SuricataToIdea\\"
+                                                               "var\\log\\suricata\\suricataJsonLog.txt"])'''
+    # linux 
+    opts, args = optp.parse_args(["--origdata", "-d", "/root/Dokumenty/PycharmProjects/SuricataToIdea/IdeaLogTest", "-n",
+                                  "cz.cesnet.server.suricata", "/root/Dokumenty/PycharmProjects/SuricataToIdea/"
+                                                               "var/log/suricata/suricataJsonLog.txt"])
+    if not args or opts.name is None or opts.dir is None:
+        optp.print_help()
+        sys.exit()
+    if opts.oneshot:
+        signal.signal(signal.SIGINT, terminate_me)
+        signal.signal(signal.SIGTERM, terminate_me)
+        files = [open(arg) for arg in args]
+    else:
+        daemonize(
+            pidfile=opts.pid,
+            uid=opts.uid,
+            gid=opts.gid,
+            signals={
+                signal.SIGINT: terminate_me,
+                signal.SIGTERM: terminate_me,
+                signal.SIGHUP: reload_me
+            })
+        files = [FileWatcher(arg) for arg in args]
+    filer = Filer(opts.dir)
+    idea_gen = IdeaGen(opts.name, opts.test)
+    while running_flag:
+        for log_file in files:
+            while True:
+                try:
+                    line = log_file.readline()
+                    if line is None or not line.strip():
+                        logging.info("no line")
+                        break
+                    log = json.loads(line)
+                    logging.info("readline")
+                    category = idea_gen.convert_category(category=log.get('alert').get('category'),
+                                                         signature=log.get('alert').get('signature'))
+                    if category and log.get('timestamp'):
+                        idea_event = idea_gen.gen_event_idea(timestamp=log['timestamp'], category=category,
+                                                             src_ip=log.get('src_ip'),
+                                                             src_port=log.get('src_port'), proto=log.get('proto'),
+                                                             dest_ip=log.get('dest_ip'),
+                                                             dest_port=log.get('dest_port'),
+                                                             orig_data=str(log) if opts.origdata else False,
+                                                             incident_desription=log['alert']['signature'])
+                        save_events(idea_event, filer)
+                except Exception as e:
+                    logging.debug(e)
+            if not running_flag:
+                break
+            if reload_flag:
+                for f in files:
+                    f.close()
+                    f.open()
+                reload_flag = False
+        if opts.oneshot:
+            break
+        else:
+            time.sleep(opts.poll)
+
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file