In [ ]:
import random
import datetime
import pytz
import struct
import string

In [ ]:
import tornado.ioloop
import tornado.web
import tornado.template

import tornado.httpserver

import os

##loader = template.Loader('templates/')

settings = {
    'static_path': os.path.join(os.getcwd(), 'static'),
    'template_path': os.path.join(os.getcwd(), 'templates'),
    'cookie_secret': '__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__',
    'login_url': '/login',
    'xsrf_cookies': True,
}

def make_web(sql_session): 
    
    return tornado.web.Application([
        (r'/', IndexHandler, dict(database=sql_session)),
        (r'/login', LoginHandler, dict(database=sql_session)),
        (r'/logout', LogoutHandler, dict(database=sql_session)),
        (r'/main', MainHandler, dict(database=sql_session)),
        (r'/show_cards', SteeringCardShowHandler, dict(database=sql_session)),
        (r'/edit_card', SteeringCardEditHandler, dict(database=sql_session))
    ], **settings)

def make_ssl(app):
    http_server = tornado.httpserver.HTTPServer(app, ssl_options={
        'certfile': 'keys/ca.csr',
        'keyfile': 'keys/ca.key',
    })
    http_server.listen(443)
    return http_server

In [ ]:
class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self): # Sets current_user in every template       
        name = self.get_secure_cookie('user') 
        print('GetCurrentUser ' + str(name))
        if not name: 
            return None
        
        data =  tornado.escape.json_decode(name)
        usr = session['session'].query(User).filter(User.username==str(data[0])).first()
        
        if usr is None:
            return None
        if usr.session_id is None:
            return None
        
        time = (datetime.datetime.now(pytz.utc).replace(tzinfo=None) - usr.session_date).total_seconds()
        if usr.session_id == data[1] and time < 3600:            
            return usr            
        
        return None

    def initialize(self, database):
        self.database = database


class IndexHandler(BaseHandler):
    @tornado.web.asynchronous
    def get(self):  
        if self.current_user is None:
            self.render('index.html')
        else:
            self.redirect(u'/main')
        
        
        
        
class LoginHandler(BaseHandler):              
    @tornado.web.asynchronous
    def get(self):    
        error_msg = ''        
        for itr in self.get_arguments('error'):
            if itr == '1':
                error_msg = error_msg + 'Invalide password!\n'
            if itr == '2':
                 error_msg = error_msg + 'Username does not exist!\n'
        
        self.render('login.html', error=error_msg, next=self.get_argument('next','/'))
    
        
    def post(self):
        username = self.get_argument('username', '')
        password = self.get_argument('password', '')             
        
        usr = session['session'].query(User).filter(User.username==str(username)).first()
        if usr is None:
            error_msg = u'?error=' + tornado.escape.url_escape('2')
            self.redirect(u'/login' + error_msg) 
        elif usr.password == password: 
            print('Login ' + usr.username)
            cookie = usr.login( random.getrandbits(32) )
            self.set_secure_cookie('user', tornado.escape.json_encode(cookie))            
            self.redirect(self.get_argument('next', u'/main'))  
        else:
            error_msg = u'?error=' + tornado.escape.url_escape('1')
            self.redirect(u'/login' + error_msg) 
            
            
class LogoutHandler(BaseHandler):
    @tornado.web.authenticated 
    def get(self):   
        if self.current_user is None:
            self.redirect(u'/')          
        else:
            self.current_user.logout()
            self.clear_cookie('user') 
            self.current_user = None
            self.redirect(u'/')

        
class MainHandler(BaseHandler):           
    @tornado.web.authenticated  
    def get(self):            
        sim = session['session'].query(Simulation).order_by(Simulation.startTime.desc()).all()
        self.render('main.html', simulation=sim)
        
class SteeringCardShowHandler(BaseHandler):
    @tornado.web.authenticated  
    def get(self):  
        card = []
        if self.get_arguments('id'):
            for itr in self.get_arguments('id'):
                card = card + session['session'].query(Steering_Card).filter(Steering_Card.id==itr). \
                                                                      filter(Steering_Card.privat==False).all()
                card = card + session['session'].query(Steering_Card).filter(Steering_Card.id==itr). \
                                                                      filter(Steering_Card.privat==True). \
                                                                      filter(Steering_Card.user_id==self.current_user.id).all()
        else:
            card = session['session'].query(Steering_Card).filter(Steering_Card.user_id==self.current_user.id).order_by(Steering_Card.create_date.desc()).all()
       
    
        
            
        self.render('show_steeringcard.html', steering=card)
        
class SteeringCardEditHandler(BaseHandler):
    @tornado.web.authenticated  
    def get(self):  
        if self.get_arguments('id'):
            tmp = session['session'].query(Steering_Card).filter(Steering_Card.id==self.get_arguments('id')). \
                                    filter( _or(Steering_Card.privat==False), _and(Steering_Card.privat==True, Steering_Card.user_id==self.current_user.id)).all()
        self.render('edit_steeringcard.html', steering=tmp)
        
    def post(self):
        return

In [ ]:
from tornado.tcpserver import TCPServer

class CorsikaManager(TCPServer):
    
    @tornado.gen.coroutine
    def handle_stream(self, stream, address):
        
        connection = CorsikaClient(stream)
        yield connection.on_connect()
        
        #print('TCP: ' + str(stream) + ' | ' + str(address))
        #print('Message: ' + str(stream.read_bytes(5).result()) )
        
   

class CorsikaClient(object):
    client_id = 0

    def __init__(self, stream):
        super().__init__()
        CorsikaClient.client_id += 1
        self.id = CorsikaClient.client_id
        self.stream = stream

        #self.stream.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) # Deactivates packet collection to bigger ones
        #self.stream.socket.setsockopt(socket.IPPROTO_TCP, socket.SO_KEEPALIVE, 1) # activates keep_alive message
        self.stream.set_close_callback(self.on_disconnect)


    @tornado.gen.coroutine
    def on_disconnect(self):
        self.log("disconnected")
        yield []

    @tornado.gen.coroutine
    def dispatch_client(self):
        try:
            while True:               
                length_byte = yield self.stream.read_bytes(4)
                length = struct.unpack("<I", length_byte)[0]
                data = yield self.stream.read_bytes(length)
                self.log('got |%s|' % data.decode('utf-8').strip())
                #yield self.stream.write(line)
        except tornado.iostream.StreamClosedError:
            pass

    @tornado.gen.coroutine
    def on_connect(self):
        raddr = 'closed'
        try:
            raddr = '%s:%d' % self.stream.socket.getpeername()
        except Exception:
            pass
        self.log('new, %s' % raddr)

        yield self.dispatch_client()

    def log(self, msg, *args, **kwargs):
        print('[connection %d] %s' % (self.id, msg.format(*args, **kwargs)))

In [ ]:
if __name__ == '__main__':
    app = make_app()
    app.listen(10003)
    
    corsika_server = CorsikaManager()
    corsika_server.listen(10004)
    #corsika_server.start(0)  # Forks multiple sub-processes
    #tornado.ioloop.IOLoop.current().start()

In [ ]:


In [ ]:
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

In [ ]:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker



#engine://user:password@host:port/database
def createSession(url):
    engine = create_engine(url, pool_recycle=3600) 
    engine.echo = False  #Output

    Session = sessionmaker(bind=engine)
    session = Session()

    Base.metadata.create_all(engine)

    return {'session':session, 'engine':engine}

In [ ]:
from sqlalchemy import Column, Integer, String, Float, ForeignKey, Text, BigInteger, DateTime, Enum, Boolean

from sqlalchemy.orm import relationship

from sqlalchemy import types

from sqlalchemy.sql import func

from sqlalchemy import update


class User(Base):
    __tablename__ = 'User'
        
    id = Column('id', Integer, primary_key=True)
    username = Column('username', String(32), nullable=False, unique=True)
    fullname = Column('fullname', String(64), default='')
        
    password = Column('password',  String(32), nullable=False)
    salt = Column('salt',  String(32))
        
    email = Column('email', String(128), default='')
    permission = Column('permission', Integer(), default=10000)
        
    session_id = Column('session_id', BigInteger())
    session_date = Column('lastLogin', DateTime())
                    
    steering_cards = relationship('Steering_Card', backref='user')    
    simulations = relationship('Simulation', backref='user') 

    def __repr__(self):
        return '<Username(%s, %s, %s, %s)>' % (self.id, self.username, self.fullname, self.email)
             
    def login(self, sessionID):
        self.session_id = sessionID
        self.session_date = func.utc_timestamp()
        session['session'].commit()        
        return (self.username, sessionID)
    
    def logout(self):
        self.session_id = 0
        session['session'].commit()  
            
import enum
class SimulationStatus(enum.Enum):
    unknown = 0
    running = 1
    stopped = 2
    crashed = 3
   
            
class Simulation(Base):
        __tablename__ = 'Simulation'
        
        id = Column('id', Integer, primary_key=True)
        ip = Column('IP', String(39)) #IPv6 compatible
        
        startTime = Column('Start', DateTime(), default=datetime.datetime.now(pytz.utc).replace(tzinfo=None))
        
        endTime = Column('End', DateTime())
        status = Column('Status', Integer, default=SimulationStatus.unknown.value)
        
        profile = Column ('profile', String(32), default='')     
        
        steering_card_id = Column('steering_card_id', Integer, default=1)        
        
        hostname = Column('hostname', String(32), default='')
        
        user_id = Column('user_id', Integer, ForeignKey('User.id'), default=1)       
        
        events = Column('events', Integer, default=0)
        
        ## CPU: /proc/cpuinfo
        ## MEM: /proc/meminfo
        
        #def __init__(self, data): 

        def __repr__(self):
                return "<Simulation(%s, %s, %s)>" % (self.id, self.ip, self.profile)         
            
class Steering_Card(Base):
        __tablename__ = 'Steering_Card'
        
        id = Column('id', Integer, primary_key=True)   
        
        privat = Column('privat', Boolean(), default=False)
        
        name = Column('name', String(32)) 
        
        card = Column('card', String(512)) 
        
        create_date = Column('create_date', DateTime(), default=datetime.datetime.now(pytz.utc).replace(tzinfo=None))
        update_date = Column('update_date', DateTime(), onupdate=datetime.datetime.now(pytz.utc).replace(tzinfo=None))
        
        user_id = Column('user_id', Integer, ForeignKey('User.id'), default=1) 
                
        ## CPU: /proc/cpuinfo
        ## MEM: /proc/meminfo
        
        #def __init__(self, data): 

        def __repr__(self):
                return "<Steering_Card(%s, %s, %s)>" % (self.id, self.name, self.user_id)

In [ ]:
session = createSession('mysql+pymysql://dbaack:1245@vollmond.app.tu-dortmund.de:10001/Corsika')

In [ ]:
admin = User(username='dbaack', fullname='Dominik Baack', password='abcd', email='dominik.baack@udo.edu', permission='0')   
dummy = User(username='', password=''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(32)))
try:
    session['session'].add(dummy)
    session['session'].add(admin)    
    session['session'].commit()
except:
    session['session'].rollback()
    pass

In [ ]:
try:
    testSim1 = Simulation(ip='127.0.0.1', profile='test')
    testSim2 = Simulation(ip='127.0.0.1', profile='test')
    session['session'].add(testSim1)
    session['session'].add(testSim2)
    session['session'].commit()
except:
    session['session'].rollback()
    pass

In [ ]:
try:
    testCard1 = Steering_Card(card='', name='dummy', user=dummy)
    testCard2 = Steering_Card(card='Test2')
    session['session'].add(testCard1)
    session['session'].add(testCard2)
    session['session'].commit()
except:
    session['session'].rollback()
    pass

import socket import threading import time

def socketTest(sock): time.sleep(5)
for i in range(10): rndmID = random.randint(0,49) s = sock[rndmID]

    len = struct.pack('<I',5)
    print('Index: ' + str(rndmID + 1))
    s.send(len + b'Debu')
    s.send(b'g')

time.sleep(5)

for s in sock:
    s.close()


time.sleep(5)
sock = [] for i in range(50): s = socket.socket( socket.AF_INET, socket.SOCK_STREAM)

s.connect(('127.0.0.1', 18889))

sock.append(s)   

for i in range(10):

t = threading.Thread(target=socketTest, args=(sock,))
t.start()

In [ ]: