Пример #1
0
    def __init__(self, serverId, addr, peers, dataDir):
        super()

        if not os.path.exists(dataDir):
            os.makedirs(dataDir)

        self.serverId = serverId
        self.addr = addr
        self.database = DBEngine(dataDir)
        self.miner = MinerThreading()
        self.daemonTimer = RepeatedTimer(0.5, self.daemon)

        self.peers = peers
        self.stubs = []
        for peer in self.peers:
            logging.info('added peer {}'.format(peer))
            channel = grpc.insecure_channel(peer)
            self.stubs.append(db_pb2_grpc.BlockChainMinerStub(channel))
            self.stubs[-1].addr = peer

        self.miner.daemon = True
        self.miner.start()
        self.daemonTimer.start()
Пример #2
0
def delete_user(user_id):
    DBEngine().delete_user(user_id)
    return '', 200
Пример #3
0
def delete_post(post_id):
    DBEngine().delete_post(post_id)
    return '', 200
Пример #4
0
def get_users():
    return jsonify({'users': DBEngine().get_users()}), 200
Пример #5
0
import sys
import os
from db import DBEngine

if __name__ == "__main__":
    argv = sys.argv

    if len(argv) != 4:
        print("Usage: %s <path_to_db> <user_name> <password>" % argv[0])
        sys.exit(1)

    path_to_db = os.path.abspath(argv[1])
    engine = DBEngine(path_to_db)
    engine.add_user_to_db(argv[2], argv[3])
Пример #6
0
class Logic(object):
    def __init__(self):

        self.onlineUsers = UserModel()
        self.dbEngine = DBEngine()

    def reset(self):

        self.onlineUsers.reset()

    def findBadInput(self, inputstring):
        """
        输入是否合法,防止sql注入
        """
        if '\'' in inputstring:
            return True
        elif '\"' in inputstring:
            return True
        elif '`' in inputstring:
            return True
        elif ' ' in inputstring:
            return True

    ####################################################################################
    #协议处理部分
    ####################################################################################
    def handlePackage(self, connection, package):
        """
        逻辑处理部分
        """
        if isinstance(package, PackageRegister):
            self.handleUserRegister(connection, package)

        elif isinstance(package, PackageLogin):
            self.handleUserLogin(connection, package)

        elif isinstance(package, PackageGetNotFriendsByCodeAndDate):
            self.handleGetNotFriendsWithCodeAndDate(connection, package)

        elif isinstance(package, PackageAddFriendRequest):
            self.handleAddFriendRequest(connection, package)

        elif isinstance(package, PackageAddFriendStatus):
            self.handleAddFriendRequestStatus(connection, package)

        elif isinstance(package, PackageGetFriends):
            self.handleGetFriends(connection, package)

        elif isinstance(package, PackageDeleteFriend):
            self.handleDeleteFriend(connection, package)

        elif isinstance(package, PackageGetFriendDetail):
            self.handleGetFriendDetail(connection, package)

        elif isinstance(package, PackageSendChatMessage):
            self.handleSendChatMessage(connection, package)

    def closeConnection(self, connection):

        user = self.onlineUsers.getUserByConnection(connection)
        self.onlineUsers.deleteUserByUser(user)

        friends = user.getAllFriends()
        if len(friends) > 0:
            self.broadcastOnlineStatusToAllFriend(user, 0)

    ####################################################################################
    #逻辑处理
    ####################################################################################
    def handleUserRegister(self, connection, package):
        """
        用户注册处理
        """
        retPackage = SendToClientPackage('register')

        #step 1,检查参数合法性
        if self.findBadInput(package.username) or self.findBadInput(
                package.password):
            #帐号异常
            retPackage.errcode = PACKAGE_ERRCODE_INPUTWRONG

        #step 2,检查参数长度
        elif len(package.username) < 6 or len(package.password) < 6:
            #长度太小
            retPackage.errcode = PACKAGE_ERRCODE_LENGTHTOSHORT

        else:
            #step 3,检查用户是否存在
            db_user = self.dbEngine.isUserExist(package.username,
                                                package.password)

            #不存在用户,插入数据库
            if not db_user:
                #插入数据库
                self.dbEngine.register_new_user(package.username,
                                                package.password)
                retPackage.status = 1
                print("user register is ok!")

            else:
                #已经存在用户,返回从新注册
                retPackage.errcode = PACKAGE_ERRCODE_USERISEXIST

        connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    def handleUserLogin(self, connection, package):
        """
        用户登录处理
        """
        retPackage = SendToClientPackage('login')
        #step 1,检查参数合法性
        if self.findBadInput(package.username) or self.findBadInput(
                package.password):

            retPackage.errcode = PACKAGE_ERRCODE_INPUTWRONG

        else:

            #step 2. 查询数据库
            db_user = self.dbEngine.isUserExist(package.username,
                                                package.password)

            if db_user:

                #step 1. 枚举在线好友,如果在线,退掉
                online_user = self.onlineUsers.getUserExistByUsername(
                    package.username)
                if online_user:
                    #step 1.发送异地登录消息
                    another = SendToClientPackage('anotherlogin')
                    another.status = 1

                    online_user.connection.send_message(
                        json.dumps(another, cls=ComplexEncoder))

                    #step 2.关闭联接
                    online_user.connection.close()

                #从新加入到在线用户
                user = UserObject(connection, db_user)
                self.onlineUsers.addNewOnlineUser(user)

                retPackage.status = 1
                retPackage.obj = SendToClientPackageUser(
                    user.DBUser.uid, user.DBUser.username, user.DBUser.sex,
                    user.DBUser.description)

                #加载好友列表
                self.getUserFriendsWithDBAndOnLineUsers(user)

                #检查离线消息,是否有人希望添加我为好友
                self.getAllAddFriendRequestFromDBAndSendToClient(user)

                #是否有人给我发离线消息
                self.getOfflineChatMessageAndSendWithUser(user)

                #广播好友列表,通知本人上线
                self.broadcastOnlineStatusToAllFriend(user, 1)

                #修改在线列表,本人上线
                self.setUserOnlineInOnlineUsersFriends(user)

            else:
                #用户不存在,提醒注册
                retPackage.errcode = 10010

        connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    def handleGetNotFriendsWithCodeAndDate(self, connection, package):
        """
        根据code和date获取好友信息
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('getfriendlistbytrainandtime')

        #step 1 检查是否为自己
        if user.DBUser.uid == int(package.uid):

            retPackage.status = 1

            ret_friends = self.getNotFriendsWithCodeAndDateAndPage(
                user, package.traincode, package.date, package.page)

            if ret_friends and len(ret_friends) > 0:
                retPackage.obj = ret_friends

        else:
            #用户ID错误
            retPackage.errcode = PACKAGE_ERRCODE_USERID

        connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    def handleAddFriendRequest(self, connection, package):
        """
        有人想添加好友
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('addfriend')

        bFriendship = False
        #检查是否是自己
        #并且不是自己想要添加自己为好友
        if user.DBUser.uid == int(
                package.uid) and user.DBUser.uid != package.fid:

            friend = user.getFriendWithId(package.fid)
            if friend:
                bFriendship = True

            if not bFriendship:
                retPackage.status = 1
                user.connection.send_message(
                    json.dumps(retPackage, cls=ComplexEncoder))

                #step2 在线,发送添加
                online_user = self.onlineUsers.getUserExistByUserid(
                    package.fid)

                if online_user:

                    addreq = SendToClientPackageRecvAddFriendRequest(
                        package.uid, package.fid, user.DBUser.username,
                        user.DBUser.sex, user.DBUser.description, package.msg,
                        datetime.datetime.now())
                    retPackage.obj = addreq

                    online_user.connection.send_message(
                        json.dumps(retPackage, cls=ComplexEncoder))
                else:
                    #插入数据库,等待上线时候通知
                    self.dbEngine.setOfflineAddFriendReuqest(
                        package.uid, package.fid, package.msg,
                        datetime.datetime.now())

            else:
                #已经是好友,返回错误信息
                retPackage.errcode = PACKAGE_ERRCODE_FRIENDSHIPEXIST
                user.connection.send_message(
                    json.dumps(retPackage, cls=ComplexEncoder))

        else:
            #用户ID错误,或者用户ID等于好友ID
            retPackage.errcode = PACKAGE_ERRCODE_USERFRIENDID
            user.connection.send_message(
                json.dumps(retPackage, cls=ComplexEncoder))

    def handleAddFriendRequestStatus(self, connection, package):
        """
        应答是否同意添加好友请求
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('addfriendstatus')
        #自己的id
        if user.DBUser.uid == int(
                package.uid) and user.DBUser.uid != int(package.fid):

            #如果同意
            if package.agree:
                #step 1. 检查是否是自己的好友

                if not self.dbEngine.getFriendshipWithUserFriendId(
                        package.uid, package.fid):

                    db_friend = self.dbEngine.getUserInfoWithUserId(
                        package.fid)

                    #存在数据库中
                    if db_friend:
                        retPackage.status = 1
                        #保存关系到数据库
                        self.dbEngine.setFriendshipWithUserIds(
                            package.uid, package.fid)

                        user.connection.send_message(
                            json.dumps(retPackage, cls=ComplexEncoder))
                        #检查是否在线,在线发送上线通知
                        online_friend = self.onlineUsers.getUserExistByUserid(
                            package.fid)

                        if online_friend:
                            #当前在线
                            online_status = SendToClientAddFriendStatusReuest(
                                package.uid, package.fid, user.DBUser.username,
                                user.DBUser.sex, user.DBUser.description,
                                package.agree)
                            retPackage.obj = online_status
                            #发送有人添加好友申请
                            online_friend.connection.send_message(
                                json.dumps(retPackage, cls=ComplexEncoder))

                            #添加到我的好友列表
                            user.addFriend(online_friend)

                    else:
                        #数据库中不存在此用户
                        retPackage.errcode = PACKAGE_ERRCODE_NOTHISUSER

                        #返回添加好友状态
                        user.connection.send_message(
                            json.dumps(retPackage, cls=ComplexEncoder))

                else:
                    #已经是好友提示
                    retPackage.errcode = PACKAGE_ERRCODE_FRIENDSHIPEXIST

                    user.connection.send_message(
                        json.dumps(retPackage, cls=ComplexEncoder))

            else:
                #返回状态
                retPackage.status = 1
                #返回添加好友状态
                user.connection.send_message(
                    json.dumps(retPackage, cls=ComplexEncoder))

                #TODO:拒绝不提示
                pass

        else:
            #用户ID异常
            retPackage.errcode = PACKAGE_ERRCODE_USERFRIENDID
            user.connection.send_message(
                json.dumps(retPackage, cls=ComplexEncoder))

    def handleGetFriends(self, connection, package):
        """
        获取好友列表
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('getfriends')
        #自己的id
        if user.DBUser.uid == int(package.uid):

            retFriend = self.getUserFriendsWithUserAndPage(
                user, int(package.page))

            if len(retFriend) > 0:
                retPackage.obj = retFriend

            retPackage.status = 1

        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID

        user.connection.send_message(json.dumps(retPackage,
                                                cls=ComplexEncoder))

    def handleDeleteFriend(self, connection, package):
        """
        删除好友
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('delfriend')
        #自己的id
        if user.DBUser.uid == int(
                package.uid) and user.DBUser.uid != int(package.fid):

            retPackage.status = 1
            #从数据库中删除
            self.dbEngine.deleteFriendshipByUserAndFriendId(
                package.uid, package.fid)

            user.connection.send_message(
                json.dumps(retPackage, cls=ComplexEncoder))

            #给在线好友发送通知,删除
            online_friend = self.onlineUsers.getUserExistByUserid(package.fid)
            if online_friend:
                sendObj = SendToClientPackageUser(user.DBUser.uid,
                                                  user.DBUser.username,
                                                  user.DBUser.sex,
                                                  user.DBUser.description)
                retPackage.obj = sendObj
                online_friend.connection.send_message(
                    json.dumps(retPackage, cls=ComplexEncoder))

                #从维护的好友列表中删除
                user.deleteFriend(online_friend)

        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
            user.connection.send_message(
                json.dumps(retPackage, cls=ComplexEncoder))

    def handleGetFriendDetail(self, connection, package):
        """
        获得用户相信信息
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('delfriend')
        #自己的id
        if user.DBUser.uid == int(
                package.uid) and user.DBUser.uid != int(package.fid):

            retPackage.status = 1

            #TODO:获取用户详细资料返回

        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
            user.connection.send_message(
                json.dumps(retPackage, cls=ComplexEncoder))

    def handleSendChatMessage(self, connection, package):
        """
        发送聊天消息
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('sendchatmsg')
        #自己的id
        if user.DBUser.uid == int(
                package.uid) and user.DBUser.uid != int(package.fid):

            #寻找好友ID
            for friend in user.getAllFriends():
                if friend.DBUser.uid == int(package.fid):
                    #发送消息给好友
                    retPackage.status = 1

                    user.connection.send_message(
                        json.dumps(retPackage, cls=ComplexEncoder))

                    chat = SendToClientPackageChatMessage(
                        user.DBUser.uid, package.fid, package.chatmsg)
                    retPackage.obj = chat
                    if friend.connection:
                        friend.connection.send_message(
                            json.dumps(retPackage, cls=ComplexEncoder))
                    else:
                        #当前不在线,数据库插入离线消息
                        self.dbEngine.addOfflineChatMessageWithUserId(
                            user.DBUser.uid, package.fid, package.chatmsg,
                            datetime.datetime.now())

                    return

        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
            user.connection.send_message(
                json.dumps(retPackage, cls=ComplexEncoder))

    ####################################################################################
    #逻辑中的部分细节处理
    ####################################################################################

    def getUserFriendsWithDBAndOnLineUsers(self, user):
        """
        获取用户的所有好友信息
        """
        #step 1.从数据库加载
        (user1Friends,
         user2Friends) = self.dbEngine.getUserFriendshipWithUserId(
             user.DBUser.uid)

        for friend in user1Friends:
            db_user = self.dbEngine.getUserInfoWithUserId(friend.user2id)
            friend = UserObject(None, db_user)
            user.addFriend(friend)
            online_friend = self.onlineUsers.getUserExistByUsername(
                db_user.username)
            if online_friend:
                friend.connection = online_friend.connection
                friend.online = True

        for friend in user2Friends:
            db_user = self.dbEngine.getUserInfoWithUserId(friend.user1id)
            friend = UserObject(None, db_user)
            user.addFriend(friend)
            online_friend = self.onlineUsers.getUserExistByUsername(
                db_user.username)
            if online_friend:
                friend.connection = online_friend.connection
                friend.online = True

    def broadcastOnlineStatusToAllFriend(self, user, online):
        """
        广播用户的上线下线消息
        """
        retPackage = SendToClientPackage('useronoffline')

        for friend in user.getAllFriends():
            #通知所有好友下线
            retPackage.status = 1
            obj = SendToClientUserOnOffStatus(user.DBUser.uid,
                                              user.DBUser.username,
                                              user.DBUser.sex,
                                              user.DBUser.description, online)
            retPackage.obj = obj

            if friend.connection:
                friend.connection.send_message(
                    json.dumps(retPackage, cls=ComplexEncoder))

            if not online:
                #清空联接
                online_friend = self.onlineUsers.getUserExistByUsername(
                    friend.DBUser.username)
                if online_friend:
                    #从好友列表里面将自己的connection 清0
                    myself = online_friend.getFriendWithUsername(
                        user.DBUser.username)
                    myself.connection = None

    def setUserOnlineInOnlineUsersFriends(self, user):
        """
        将在线用户列表里面的所有状态修改为本人在线
        """

        for friend in user.getAllFriends():
            online_friend = self.onlineUsers.getUserExistByUsername(
                friend.DBUser.username)
            if online_friend:
                myself = online_friend.getFriendWithUsername(
                    user.DBUser.username)
                myself.connection = user.connection

    def getAllAddFriendRequestFromDBAndSendToClient(self, user):
        """
        从数据库获取所有申请添加好友的用户并发送给用户
        """
        add_requests = []
        offline_add_friend_requests = self.dbEngine.getOfflineAddFriendRequests(
            user.DBUser.uid)
        for off_add_req in offline_add_friend_requests:
            db_user = self.dbEngine.getUserInfoWithUserId(off_add_req.fromid)
            send_request = SendToClientPackageRecvAddFriendRequest(
                off_add_req.fromid, db_user.username, off_add_req.toid,
                db_user.sex, db_user.description, off_add_req.msg,
                off_add_req.lastdate)
            add_requests.append(send_request)

        if len(add_requests) > 0:
            #发送
            retRequest = SendToClientPackage('addfriend')
            retRequest.status = 1
            retRequest.obj = add_requests

            user.connection.send_message(
                json.dumps(retRequest, cls=ComplexEncoder))

            #删除离线好友请求
            self.dbEngine.deleteOfflineAddFriendRequestWithUserId(
                user.DBUser.uid)

    def getOfflineChatMessageAndSendWithUser(self, user):
        """
        获取所有离线消息并发送
        """
        db_offline_chat_messages = self.dbEngine.getAllOfflineChatMessageWithUserId(
            user.DBUser.uid)

        ret_off_chat_messages = []
        if db_offline_chat_messages:
            for off_chat_msg in db_offline_chat_messages:
                off_msg = SendToClientPackageOfflineChatMessage(
                    off_chat_msg.fromuserid, off_chat_msg.touserid,
                    off_chat_msg.msg, off_chat_msg.last_date)

                ret_off_chat_messages.append(off_msg)

        if ret_off_chat_messages:
            #发送离线消息
            retPackage = SendToClientPackage('sendchatmsg')
            retPackage.status = 1
            retPackage.obj = ret_off_chat_messages

            user.connection.send_message(
                json.dumps(retPackage, cls=ComplexEncoder))

            #从数据库中删除
            self.dbEngine.deleteAllOfflineChatMessageWithUserId(
                user.DBUser.uid)

    def getNotFriendsWithCodeAndDateAndPage(self, user, traincode, date, page):
        """
        根据列车或者航班+日期获取的好友
        """
        friends = self.dbEngine.getNotfriendsWithCodeAndDate(traincode, date)
        ret_friends = []
        nCount = 0
        if friends:
            for friend in friends:
                #不是自己
                if friend.userid != user.DBUser.uid:
                    #计算页码
                    if (nCount / 20 == page):
                        db_friend = self.dbEngine.getUserInfoWithUserId(
                            friend.userid)
                        ret_friend = SendToClientPackageUser(
                            db_friend.uid, db_friend.username, db_friend.sex,
                            db_friend.description)
                        ret_friends.append(ret_friend)

                    nCount += 1

        return ret_friends

    def getUserFriendsWithUserAndPage(self, user, page):
        """
        获取用户好友
        """
        retFriends = []
        friends = user.getAllFriends()
        friendCount = len(friends)
        if friends and friendCount > 0:
            nStart = 0
            nEnd = 0

            #计算页码是否在范围内
            if USERS_PAGES_SIZE * page < friendCount:

                #计算结束页码
                if USERS_PAGES_SIZE * (page + 1) > friendCount:
                    nEnd = friendCount - USERS_PAGES_SIZE * page
                else:
                    nEnd = USERS_PAGES_SIZE * page

                #在页码范围内的好友
                friends = friends[nStart * USERS_PAGES_SIZE:nEnd]
                for friend in friends:
                    online = False
                    if friend.connection:
                        online = True
                    retUser = SendToClientPackageUser(
                        friend.DBUser.uid, friend.DBUser.username,
                        friend.DBUser.sex, friend.DBUser.description, online)
                    retFriends.append(retUser)

        return retFriends
Пример #7
0
def get_posts():
    return jsonify({'post': DBEngine().get_posts()}), 200
Пример #8
0
def create_post():
    author = request.form['author']
    title = request.form['title']
    content = request.form['content']
    return jsonify({'post': DBEngine().create_post(author, title,
                                                   content)}), 201
Пример #9
0
class WinApp(QMainWindow, Ui_MainWindow):
    stmt_signal = pyqtSignal(str)

    def __init__(self):
        super(QMainWindow, self).__init__()

        self.setupUi(self)
        self.connButtonBox.button(QDialogButtonBox.Ok).setText("Connect")
        self.runButtonBox.button(QDialogButtonBox.Ok).setText("Run")
        self.tunnelButton.clicked[bool].connect(self.toggle_tunnel)
        self.tunnelWidget.hide()
        self.keyFileButton.clicked.connect(self.choose_keyfile)
        self.clearButton.clicked.connect(self.clear_tunnel)
        self.keyComboBox.activated[str].connect(self.set_key_type)

        self.db_engine = DBEngine()
        self.db_engine.result_signal.connect(self.show_results)
        self.db_engine.progress_signal.connect(self.set_progress)
        self.db_engine.error_signal.connect(self.show_error)
        self.db_engine.msg_signal.connect(self.show_msg)
        self.stmt_signal.connect(self.db_engine.receive_stmt)

        self.db_lite = DBLite()
        self.tunnel = Tunnel()
        self.tunnel_keyfile = ""
        self.data_schema = []
        self.settings = QSettings()
        self.restore_settings()

        history = self.db_lite.history()
        self.historyMenuBar = QMenuBar(self.sqlWidget)
        self.historyMenuBar.setNativeMenuBar(False)
        self.historyMenu = self.historyMenuBar.addMenu('     &History   ⇲    ')
        actions = [
            QAction(sql.replace('\n', ' '), self.historyMenu)
            for sql in history
        ]
        for i in range(len(actions)):
            actions[i].triggered.connect(partial(self.use_history, history[i]))
        self.historyMenu.addActions(actions)

        self.history_cache = pylru.lrucache(history_limit, self.remove_action)
        for i in reversed(range(len(history))):
            self.history_cache[history[i]] = {
                KEY_ACTION: actions[i],
                KEY_RESULTS: [],
                KEY_COLUMNS: []
            }

        self.historyMenu.setStyleSheet("""
        QMenu {
            max-width: 1000px;
            font-size: 12px;
        }
        """)
        self.historyMenuBar.setStyleSheet("""
        QMenuBar {
            border: None;
        }
        QMenuBar::item {
            background: #404040;
            color: #ffffff;
            border-radius: 4px;
        }
        QMenuBar::item:selected {
            background: rgba(1, 1, 1, 0.2);;
            color: #404040;
            border-radius: 4px;
        }
        """)
        self.sqlWidgetLayout.insertWidget(0, self.historyMenuBar)

        self.connButtonBox.accepted.connect(self.connect)
        self.connButtonBox.rejected.connect(self.disconnect)
        self.runButtonBox.accepted.connect(self.run)
        self.runButtonBox.rejected.connect(self.cancel)
        self.tablesWidget.itemDoubleClicked.connect(self.get_meta)
        self.tablesWidget.itemExpanded.connect(self.get_meta)

        self.progressBar = QProgressBar()
        self.statusbar.addPermanentWidget(self.progressBar)
        self.progressBar.setValue(100)
        QApplication.processEvents()

        self.highlight = syntax.PrestoHighlighter(self.sqlEdit)

        self.dataWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.dataWidget.customContextMenuRequested.connect(
            self.show_table_context_menu)
        self.dataWidget.horizontalHeader().setStretchLastSection(False)
        self.dataWidget.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)

        self.schemaView.header().setStretchLastSection(False)
        self.schemaView.header().setSectionResizeMode(
            QHeaderView.ResizeToContents)

        self.runButtonBox.button(
            QDialogButtonBox.Ok).setShortcut("Ctrl+Return")

        self.completer = SQLCompleter(self)
        self.sqlEdit.setCompleter(self.completer)

        self.set_key_type(self.keyComboBox.currentText())
        self.sqlEdit.setFocus()

    def connect(self):
        self.tablesWidget.clear()
        self.schemaView.clear()
        try:
            if self.serverEdit.text().strip() and self.gatewayEdit.text(
            ).strip() and self.tunnelUserEdit.text().strip():
                self.statusbar.showMessage('Starting tunnel')
                QApplication.processEvents()
                self.tunnel.start_tunnel(
                    self.serverEdit.text().strip(),
                    self.gatewayEdit.text().strip(),
                    self.tunnelUserEdit.text().strip(),
                    self.keyComboBox.currentText() == 'KeyFile',
                    self.tunnel_keyfile, self.pwdLineEdit.text(),
                    self.urlEdit.text().strip())

            self.statusbar.showMessage('Connecting')
            QApplication.processEvents()
            self.db_engine.connect(self.urlEdit.text().strip(),
                                   self.userEdit.text().strip())
            self.statusbar.showMessage('Fetching db info')
            QApplication.processEvents()

            dbs = self.db_engine.dbs()
            for db in dbs:
                db_item = QTreeWidgetItem([db])
                db_item.setChildIndicatorPolicy(QTreeWidgetItem.ShowIndicator)
                self.tablesWidget.addTopLevelItem(db_item)
            self.completer.addItems(dbs)
            self.statusbar.showMessage('Connected')

        except Exception as err:
            QMessageBox.critical(self, "Error", str(err))
            self.db_engine.close()
            self.statusbar.showMessage('Disconnected')

    def disconnect(self):
        self.db_engine.close()
        self.tunnel.stop_tunnel()
        self.schemaView.clear()
        self.tablesWidget.clear()
        self.statusbar.showMessage('Disconnected')

    def get_meta(self, item):
        try:
            if item.parent():
                columns = self.db_engine.columns(item.parent().text(0),
                                                 item.text(0))
                self.set_columns(columns)
                self.completer.addItems([column[0] for column in columns])
            else:
                if item.childCount() <= 0:
                    tables = self.db_engine.tables(item.text(0))
                    item.addChildren(
                        [QTreeWidgetItem([table]) for table in tables])
                    self.completer.addTreeItem(item)
        except Exception as err:
            QMessageBox.critical(self, "Error", str(err))

    def set_columns(self, columns):
        try:
            self.schemaView.clear()
            for column in columns:
                column_item = self.type_tree(column[0],
                                             type_parser.parse(column[1]))
                self.schemaView.addTopLevelItem(column_item)
            self.schemaView.expandToDepth(2)
            for j in range(self.schemaView.columnCount()):
                self.schemaView.resizeColumnToContents(j)
        except Exception as err:
            QMessageBox.critical(self, "Error", str(err))

    def run(self):
        self.dataWidget.setRowCount(0)
        self.dataWidget.setColumnCount(0)
        try:
            self.stmt_signal.emit(self.sqlEdit.toPlainText().strip().replace(
                ';', ''))
            self.db_engine.start()
        except Exception as err:
            QMessageBox.critical(self, "Error", str(err))

    def show_results(self, results, columns, sql, save=True):
        try:
            num_cols = len(columns)
            num_rows = len(results)
            self.dataWidget.setRowCount(num_rows)
            self.dataWidget.setColumnCount(num_cols)
            for i in range(num_rows):
                for j in range(num_cols):
                    self.dataWidget.setItem(
                        i, j, QTableWidgetItem(str(results[i][j])))
            self.dataWidget.resizeColumnsToContents()
            for j in range(num_cols):
                header_label = columns[j][0]
                # header_width = self.fm.width(header_label)
                # if header_width > self.dataWidget.columnWidth(j):
                #     self.dataWidget.setColumnWidth(j, header_width)
                self.dataWidget.setHorizontalHeaderItem(
                    j, QTableWidgetItem(header_label))
            self.data_schema = [column[1] for column in columns]
            if not columns and not results:
                self.dataWidget.setColumnCount(1)
                self.dataWidget.setHorizontalHeaderItem(
                    0, QTableWidgetItem("Empty Result"))
            if save:
                self.save_history(sql, results, columns)
        except Exception as err:
            QMessageBox.critical(self, "Error", str(err))
        finally:
            self.statusbar.showMessage('Finished')

    def cancel(self):
        self.db_engine.cancel()

    def set_progress(self, progress):
        self.progressBar.setValue(progress)
        QApplication.processEvents()

    def save_history(self, sql, results, columns):
        if sql not in self.history_cache:
            action = QAction(sql.replace('\n', ' '), self.historyMenu)
            action.triggered.connect(partial(self.use_history, sql))
            self.history_cache[sql] = {
                KEY_ACTION: action,
                KEY_RESULTS: results,
                KEY_COLUMNS: columns
            }
        else:
            action = self.history_cache[sql][KEY_ACTION]
            self.historyMenu.removeAction(action)
            if len(results) * len(columns) <= CACHE_LIMIT:
                self.history_cache[sql][KEY_RESULTS] = results
                self.history_cache[sql][KEY_COLUMNS] = columns
            else:
                self.history_cache[sql][KEY_RESULTS] = []
                self.history_cache[sql][KEY_COLUMNS] = [
                    ("results too large to cache", "varchar")
                ]
        self.historyMenu.insertAction(
            self.historyMenu.actions()[0] if
            (self.historyMenu.actions()) else None, action)
        self.db_lite.upsert(sql)

    def use_history(self, sql):
        self.sqlEdit.setText(sql)
        QApplication.processEvents()
        cached = self.history_cache[sql]
        self.db_engine.result_signal.emit(cached[KEY_RESULTS],
                                          cached[KEY_COLUMNS], sql, False)
        self.statusbar.showMessage("Loaded cached history")

    def remove_action(self, sql, cached):
        self.historyMenu.removeAction(cached[KEY_ACTION])

    def show_table_context_menu(self, position):
        col = self.dataWidget.columnAt(position.x())
        dialog = QDialog(self, Qt.Popup)
        schema_view = QTreeWidget(dialog)
        schema_view.headerItem().setText(0, "Field")
        schema_view.headerItem().setText(1, "Type")
        root = type_parser.parse(self.data_schema[col])
        schema_tree = self.type_tree(
            self.dataWidget.horizontalHeaderItem(col).text(), root)
        schema_view.addTopLevelItem(schema_tree)
        schema_view.expandToDepth(2)
        schema_view.header().setStretchLastSection(False)
        schema_view.setSizeAdjustPolicy(
            QAbstractScrollArea.AdjustToContentsOnFirstShow)
        schema_view.header().setSectionResizeMode(QHeaderView.ResizeToContents)
        schema_view.setMinimumHeight(30)
        schema_view.setMaximumHeight(400)
        schema_view.adjustSize()
        schema_view.setHeaderHidden(True)

        dialog.move(
            self.dataWidget.mapToGlobal(position) +
            QPoint(dialog.width() / 5 * 2,
                   dialog.height() + 5))
        dialog.adjustSize()
        dialog.show()

    def type_tree(self, name, root):
        if root.children[0].data == 'primitive_type':
            return QTreeWidgetItem([name, root.children[0].children[0].value])
        elif root.children[0].data == 'row_type':
            root_widget = QTreeWidgetItem([name, 'row'])
            for i in range(len(root.children[0].children) // 2):
                name = root.children[0].children[i * 2].value
                child_type = root.children[0].children[i * 2 + 1]
                root_widget.addChild(self.type_tree(name, child_type))
            return root_widget
        elif root.children[0].data == 'array_type':
            if root.children[0].children[0].children[
                    0].data == 'primitive_type':
                return QTreeWidgetItem([
                    name, 'array(' +
                    root.children[0].children[0].children[0].children[0].value
                    + ')'
                ])
            else:
                root_widget = QTreeWidgetItem([name, 'array(row)'])
                for i in range(
                        len(root.children[0].children[0].children[0].children)
                        // 2):
                    name = root.children[0].children[0].children[0].children[
                        i * 2].value
                    child_type = root.children[0].children[0].children[
                        0].children[i * 2 + 1]
                    root_widget.addChild(self.type_tree(name, child_type))
                return root_widget

        elif root.children[0].data == 'map_type':
            root_widget = QTreeWidgetItem([name, 'map'])
            key = self.type_tree('_key', root.children[0].children[0])
            value = self.type_tree('_value', root.children[0].children[1])
            root_widget.addChildren([key, value])
            return root_widget
        else:
            pass

    def toggle_tunnel(self, pressed):
        if pressed:
            self.tunnelWidget.show()
            self.repaint()
        else:
            self.tunnelWidget.hide()

    def choose_keyfile(self):
        file_name, _ = QFileDialog.getOpenFileName(self, "Choose Key File",
                                                   QDir.homePath() + "/.ssh",
                                                   "All Files (*)")
        if file_name:
            self.tunnel_keyfile = file_name
            self.keyFileButton.setText(file_name.split('/')[-1])

    def clear_tunnel(self):
        self.tunnel_keyfile = None
        self.keyFileButton.setText("Choose Key File...")
        self.serverEdit.clear()
        self.gatewayEdit.clear()
        self.tunnelUserEdit.clear()
        self.pwdLineEdit.clear()

    def close_all(self):
        self.save_settings()
        self.db_engine.close()
        self.tunnel.stop_tunnel()

    def restore_settings(self):
        self.urlEdit.setText(self.settings.value(URL, ""))
        self.userEdit.setText(self.settings.value(USER, ""))
        self.serverEdit.setText(self.settings.value(SERVER, ""))
        self.gatewayEdit.setText(self.settings.value(GATEWAY, ""))
        self.tunnelUserEdit.setText(self.settings.value(TUNNEL_USER, ""))
        self.tunnel_keyfile = self.settings.value(KEYFILE, "")
        if self.tunnel_keyfile:
            self.keyFileButton.setText(self.tunnel_keyfile.split('/')[-1])
        self.pwdLineEdit.setText(self.settings.value(TUNNEL_PWD, ""))
        self.keyComboBox.setCurrentText(self.settings.value(
            KEYTYPE, "KeyFile"))

    def save_settings(self):
        self.settings.setValue(URL, self.urlEdit.text().strip())
        self.settings.setValue(USER, self.userEdit.text().strip())
        self.settings.setValue(SERVER, self.serverEdit.text().strip())
        self.settings.setValue(GATEWAY, self.gatewayEdit.text().strip())
        self.settings.setValue(TUNNEL_USER, self.tunnelUserEdit.text().strip())
        self.settings.setValue(KEYFILE, self.tunnel_keyfile)
        self.settings.setValue(KEYTYPE, self.keyComboBox.currentText())
        self.settings.setValue(TUNNEL_PWD, self.pwdLineEdit.text())
        self.settings.sync()

    def show_error(self, error):
        QMessageBox.critical(self, "Error", error)

    def show_msg(self, msg):
        self.statusbar.showMessage(msg)

    def set_key_type(self, key_type):
        if key_type == 'KeyFile':
            self.pwdLineEdit.hide()
            self.keyFileButton.show()
        else:
            self.keyFileButton.hide()
            self.pwdLineEdit.show()
Пример #10
0
    # noinspection PyBroadException
    try:
        spider_html = spider_response.read().decode('utf-8')
    except socket.timeout as e:
        return 'error, socket.timeout'
    except UnicodeDecodeError as e:
        return 'error, UnicodeDecodeError'
    except Exception as e:
        return 'error, Exception: %s' % e

    return spider_html


if __name__ == '__main__':
    urlbase = 'https://www.exploit-db.com/exploits/'
    start = 30
    db = DBEngine()
    for i in range(3000):
        if db.is_eid_exist(start + i):
            pass
        else:
            url = urlbase + str(start + i) + '/'
            print(url)
            html = spider(url)
            table = bs4html(html)
            poc = DBPoc(table.eid, table.cve, table.title, table.author,
                        table.published_time, table.verified, table.platform,
                        table.exploit_type, table.exploit_url,
                        table.exploit_app)
            db.add_poc(poc)
Пример #11
0
    def __init__(self):

        self.onlineUsers = UserModel()
        self.dbEngine = DBEngine()
Пример #12
0
class Logic(object):

    def __init__(self):

        self.onlineUsers = UserModel()
        self.dbEngine = DBEngine()


    def reset(self):

        self.onlineUsers.reset()


    def findBadInput(self, inputstring):
        """
        输入是否合法,防止sql注入
        """
        if '\'' in inputstring:
            return True
        elif '\"' in inputstring:
            return True
        elif '`' in inputstring:
            return True
        elif ' ' in inputstring:
            return True

    ####################################################################################
    #协议处理部分
    ####################################################################################
    def handlePackage(self, connection , package):
        """
        逻辑处理部分
        """
        if isinstance(package, PackageRegister):
            self.handleUserRegister(connection , package)

        elif isinstance(package, PackageLogin):
            self.handleUserLogin(connection , package)

        elif isinstance(package, PackageGetNotFriendsByCodeAndDate):
            self.handleGetNotFriendsWithCodeAndDate( connection , package )

        elif isinstance( package , PackageAddFriendRequest ):
            self.handleAddFriendRequest( connection, package )

        elif isinstance( package , PackageAddFriendStatus ):
            self.handleAddFriendRequestStatus( connection , package )

        elif isinstance( package , PackageGetFriends ):
            self.handleGetFriends( connection, package )

        elif isinstance( package , PackageDeleteFriend ):
            self.handleDeleteFriend( connection , package )

        elif isinstance( package , PackageGetFriendDetail ):
            self.handleGetFriendDetail( connection , package )

        elif isinstance( package , PackageSendChatMessage ):
            self.handleSendChatMessage( connection , package )



    def closeConnection(self, connection):

        user = self.onlineUsers.getUserByConnection(connection)
        self.onlineUsers.deleteUserByUser(user)

        friends = user.getAllFriends()
        if len(friends) > 0:
            self.broadcastOnlineStatusToAllFriend( user , 0 )


    ####################################################################################
    #逻辑处理
    ####################################################################################
    def handleUserRegister(self, connection , package):
        """
        用户注册处理
        """
        retPackage = SendToClientPackage('register')

        #step 1,检查参数合法性
        if self.findBadInput(package.username) or self.findBadInput(package.password):
            #帐号异常
            retPackage.errcode = PACKAGE_ERRCODE_INPUTWRONG

        #step 2,检查参数长度
        elif len(package.username) < 6 or len(package.password) < 6:
            #长度太小
            retPackage.errcode = PACKAGE_ERRCODE_LENGTHTOSHORT

        else:
            #step 3,检查用户是否存在
            db_user = self.dbEngine.isUserExist(package.username, package.password)

            #不存在用户,插入数据库
            if not db_user:
                #插入数据库
                self.dbEngine.register_new_user(package.username, package.password)
                retPackage.status = 1

            else:
                #已经存在用户,返回从新注册
                retPackage.errcode = PACKAGE_ERRCODE_USERISEXIST

        connection.send_message( json.dumps(retPackage, cls=ComplexEncoder) )



    def handleUserLogin(self, connection , package):
        """
        用户登录处理
        """
        retPackage = SendToClientPackage('login')
        #step 1,检查参数合法性
        if self.findBadInput(package.username) or self.findBadInput(package.password):

            retPackage.errcode = PACKAGE_ERRCODE_INPUTWRONG

        else:

            #step 2. 查询数据库
            db_user = self.dbEngine.isUserExist(package.username, package.password)

            if db_user:

                #step 1. 枚举在线好友,如果在线,退掉
                online_user = self.onlineUsers.getUserExistByUsername(package.username)
                if online_user:
                    #step 1.发送异地登录消息
                    another = SendToClientPackage('anotherlogin')
                    another.status = 1

                    online_user.connection.send_message( json.dumps( another , cls= ComplexEncoder ) )

                    #step 2.关闭联接
                    online_user.connection.close()

                #从新加入到在线用户
                user = UserObject(connection, db_user)
                self.onlineUsers.addNewOnlineUser(user)

                retPackage.status = 1
                retPackage.obj = SendToClientPackageUser( user.DBUser.uid,
                                                          user.DBUser.username,
                                                          user.DBUser.sex,
                                                          user.DBUser.description)


                #加载好友列表
                self.getUserFriendsWithDBAndOnLineUsers( user )

                #检查离线消息,是否有人希望添加我为好友
                self.getAllAddFriendRequestFromDBAndSendToClient( user )

                #是否有人给我发离线消息
                self.getOfflineChatMessageAndSendWithUser( user )

                #广播好友列表,通知本人上线
                self.broadcastOnlineStatusToAllFriend( user , 1 )

                #修改在线列表,本人上线
                self.setUserOnlineInOnlineUsersFriends( user )

            else:
                #用户不存在,提醒注册
                retPackage.errcode = 10010

        connection.send_message( json.dumps(retPackage, cls=ComplexEncoder) )



    def handleGetNotFriendsWithCodeAndDate(self, connection, package):
        """
        根据code和date获取好友信息
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('getfriendlistbytrainandtime')

        #step 1 检查是否为自己
        if user.DBUser.uid == int (package.uid):

            retPackage.status = 1

            ret_friends = self.getNotFriendsWithCodeAndDateAndPage(user ,
                                                                   package.traincode,
                                                                   package.date,
                                                                   package.page)


            if ret_friends and len(ret_friends) > 0:
                retPackage.obj = ret_friends

        else:
            #用户ID错误
            retPackage.errcode = PACKAGE_ERRCODE_USERID

        connection.send_message( json.dumps(retPackage, cls= ComplexEncoder) )



    def handleAddFriendRequest(self, connection , package):
        """
        有人想添加好友
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('addfriend')

        bFriendship = False
        #检查是否是自己
        #并且不是自己想要添加自己为好友
        if user.DBUser.uid == int(package.uid) and user.DBUser.uid != package.fid:

            friend = user.getFriendWithId(package.fid)
            if friend:
                bFriendship = True

            if not bFriendship:
                retPackage.status = 1
                user.connection.send_message( json.dumps(retPackage , cls= ComplexEncoder) )

                #step2 在线,发送添加
                online_user = self.onlineUsers.getUserExistByUserid(package.fid)

                if online_user:

                    addreq = SendToClientPackageRecvAddFriendRequest(package.uid,
                                                                     package.fid ,
                                                                     user.DBUser.username,
                                                                     user.DBUser.sex,
                                                                     user.DBUser.description,
                                                                     package.msg, datetime.datetime.now())
                    retPackage.obj = addreq

                    online_user.connection.send_message( json.dumps(retPackage, cls= ComplexEncoder) )
                else:
                    #插入数据库,等待上线时候通知
                    self.dbEngine.setOfflineAddFriendReuqest(package.uid, package.fid, package.msg, datetime.datetime.now())

            else:
                #已经是好友,返回错误信息
                retPackage.errcode = PACKAGE_ERRCODE_FRIENDSHIPEXIST
                user.connection.send_message( json.dumps(retPackage , cls= ComplexEncoder) )


        else:
            #用户ID错误,或者用户ID等于好友ID
            retPackage.errcode = PACKAGE_ERRCODE_USERFRIENDID
            user.connection.send_message( json.dumps(retPackage , cls= ComplexEncoder) )



    def handleAddFriendRequestStatus(self, connection ,package):
        """
        应答是否同意添加好友请求
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('addfriendstatus')
        #自己的id
        if user.DBUser.uid == int(package.uid) and user.DBUser.uid != int(package.fid):

            #如果同意
            if package.agree:
                #step 1. 检查是否是自己的好友

                if not self.dbEngine.getFriendshipWithUserFriendId(package.uid, package.fid):

                    db_friend = self.dbEngine.getUserInfoWithUserId(package.fid)

                    #存在数据库中
                    if db_friend:
                        retPackage.status = 1
                        #保存关系到数据库
                        self.dbEngine.setFriendshipWithUserIds(package.uid, package.fid)

                        user.connection.send_message( json.dumps(retPackage, cls= ComplexEncoder) )
                        #检查是否在线,在线发送上线通知
                        online_friend = self.onlineUsers.getUserExistByUserid(package.fid)

                        if online_friend:
                            #当前在线
                            online_status = SendToClientAddFriendStatusReuest(package.uid,
                                                                              package.fid,
                                                                              user.DBUser.username,
                                                                              user.DBUser.sex,
                                                                              user.DBUser.description,
                                                                              package.agree)
                            retPackage.obj = online_status
                            #发送有人添加好友申请
                            online_friend.connection.send_message( json.dumps( retPackage, cls=ComplexEncoder ) )

                            #添加到我的好友列表
                            user.addFriend(online_friend)

                    else:
                        #数据库中不存在此用户
                        retPackage.errcode = PACKAGE_ERRCODE_NOTHISUSER

                        #返回添加好友状态
                        user.connection.send_message( json.dumps(retPackage, cls= ComplexEncoder) )


                else:
                    #已经是好友提示
                    retPackage.errcode = PACKAGE_ERRCODE_FRIENDSHIPEXIST

                    user.connection.send_message( json.dumps( retPackage , cls= ComplexEncoder ) )

            else:
                #返回状态
                retPackage.status = 1
                #返回添加好友状态
                user.connection.send_message( json.dumps(retPackage, cls= ComplexEncoder) )

                #TODO:拒绝不提示
                pass

        else:
            #用户ID异常
            retPackage.errcode = PACKAGE_ERRCODE_USERFRIENDID
            user.connection.send_message( json.dumps( retPackage , cls= ComplexEncoder ) )



    def handleGetFriends(self , connection , package ):
        """
        获取好友列表
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('getfriends')
        #自己的id
        if user.DBUser.uid == int(package.uid):

            retFriend = self.getUserFriendsWithUserAndPage( user, int(package.page) )

            if len(retFriend) > 0:
                retPackage.obj = retFriend

            retPackage.status = 1

        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID

        user.connection.send_message( json.dumps( retPackage , cls= ComplexEncoder ) )


    def handleDeleteFriend(self , connection , package):
        """
        删除好友
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('delfriend')
        #自己的id
        if user.DBUser.uid == int(package.uid) and user.DBUser.uid != int(package.fid):

            retPackage.status = 1
            #从数据库中删除
            self.dbEngine.deleteFriendshipByUserAndFriendId( package.uid, package.fid )

            user.connection.send_message( json.dumps( retPackage , cls=ComplexEncoder ) )

            #给在线好友发送通知,删除
            online_friend = self.onlineUsers.getUserExistByUserid( package.fid )
            if online_friend:
                sendObj = SendToClientPackageUser(user.DBUser.uid,
                                                  user.DBUser.username,
                                                  user.DBUser.sex,
                                                  user.DBUser.description)
                retPackage.obj = sendObj
                online_friend.connection.send_message( json.dumps( retPackage , cls=ComplexEncoder ) )

                #从维护的好友列表中删除
                user.deleteFriend(online_friend)


        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
            user.connection.send_message( json.dumps( retPackage , cls= ComplexEncoder ) )



    def handleGetFriendDetail(self, connection , package):
        """
        获得用户相信信息
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('delfriend')
        #自己的id
        if user.DBUser.uid == int(package.uid) and user.DBUser.uid != int(package.fid):

            retPackage.status = 1

            #TODO:获取用户详细资料返回

        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
            user.connection.send_message( json.dumps( retPackage , cls= ComplexEncoder ) )


    def handleSendChatMessage(self, connection , package):
        """
        发送聊天消息
        """
        user = self.onlineUsers.getUserByConnection(connection)

        retPackage = SendToClientPackage('sendchatmsg')
        #自己的id
        if user.DBUser.uid == int(package.uid) and user.DBUser.uid != int(package.fid):

            #寻找好友ID
            for friend in user.getAllFriends():
                if friend.DBUser.uid == int(package.fid):
                    #发送消息给好友
                    retPackage.status = 1

                    user.connection.send_message( json.dumps( retPackage, cls= ComplexEncoder ) )

                    chat = SendToClientPackageChatMessage(user.DBUser.uid ,package.fid, package.chatmsg)
                    retPackage.obj = chat
                    if friend.connection:
                        friend.connection.send_message( json.dumps(retPackage, cls= ComplexEncoder) )
                    else:
                        #当前不在线,数据库插入离线消息
                        self.dbEngine.addOfflineChatMessageWithUserId(user.DBUser.uid ,
                                                                      package.fid,
                                                                      package.chatmsg,
                                                                      datetime.datetime.now())

                    return



        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
            user.connection.send_message( json.dumps( retPackage , cls= ComplexEncoder ) )



    ####################################################################################
    #逻辑中的部分细节处理
    ####################################################################################

    def getUserFriendsWithDBAndOnLineUsers(self , user):
        """
        获取用户的所有好友信息
        """
        #step 1.从数据库加载
        (user1Friends, user2Friends) = self.dbEngine.getUserFriendshipWithUserId( user.DBUser.uid )

        for friend in user1Friends:
            db_user = self.dbEngine.getUserInfoWithUserId(friend.user2id)
            friend = UserObject(None , db_user )
            user.addFriend( friend )
            online_friend = self.onlineUsers.getUserExistByUsername(db_user.username)
            if online_friend:
                friend.connection = online_friend.connection
                friend.online = True

        for friend in user2Friends:
            db_user = self.dbEngine.getUserInfoWithUserId(friend.user1id)
            friend = UserObject(None , db_user )
            user.addFriend( friend )
            online_friend = self.onlineUsers.getUserExistByUsername(db_user.username)
            if online_friend:
                friend.connection = online_friend.connection
                friend.online = True



    def broadcastOnlineStatusToAllFriend(self, user, online):
        """
        广播用户的上线下线消息
        """
        retPackage = SendToClientPackage('useronoffline')

        for friend in user.getAllFriends():
            #通知所有好友下线
            retPackage.status = 1
            obj = SendToClientUserOnOffStatus(user.DBUser.uid ,
                                                  user.DBUser.username,
                                                  user.DBUser.sex,
                                                  user.DBUser.description,
                                                  online)
            retPackage.obj = obj

            if friend.connection:
                friend.connection.send_message( json.dumps( retPackage , cls=ComplexEncoder ) )

            if not online:
                #清空联接
                online_friend = self.onlineUsers.getUserExistByUsername(friend.DBUser.username)
                if online_friend:
                    #从好友列表里面将自己的connection 清0
                    myself = online_friend.getFriendWithUsername( user.DBUser.username )
                    myself.connection = None

    def setUserOnlineInOnlineUsersFriends(self, user):
        """
        将在线用户列表里面的所有状态修改为本人在线
        """

        for friend in user.getAllFriends():
            online_friend =  self.onlineUsers.getUserExistByUsername( friend.DBUser.username )
            if online_friend:
                myself = online_friend.getFriendWithUsername( user.DBUser.username )
                myself.connection = user.connection



    def getAllAddFriendRequestFromDBAndSendToClient(self, user):
        """
        从数据库获取所有申请添加好友的用户并发送给用户
        """
        add_requests = []
        offline_add_friend_requests = self.dbEngine.getOfflineAddFriendRequests( user.DBUser.uid )
        for off_add_req in offline_add_friend_requests:
            db_user = self.dbEngine.getUserInfoWithUserId( off_add_req.fromid )
            send_request = SendToClientPackageRecvAddFriendRequest(off_add_req.fromid ,
                                                                   db_user.username ,
                                                                   off_add_req.toid ,
                                                                   db_user.sex,
                                                                   db_user.description,
                                                                   off_add_req.msg,
                                                                   off_add_req.lastdate)
            add_requests.append(send_request)

        if len(add_requests) > 0:
            #发送
            retRequest = SendToClientPackage('addfriend')
            retRequest.status = 1
            retRequest.obj = add_requests

            user.connection.send_message( json.dumps( retRequest , cls=ComplexEncoder ) )

            #删除离线好友请求
            self.dbEngine.deleteOfflineAddFriendRequestWithUserId( user.DBUser.uid )



    def getOfflineChatMessageAndSendWithUser(self , user):
        """
        获取所有离线消息并发送
        """
        db_offline_chat_messages = self.dbEngine.getAllOfflineChatMessageWithUserId( user.DBUser.uid )


        ret_off_chat_messages = []
        if db_offline_chat_messages:
            for off_chat_msg in db_offline_chat_messages:
                off_msg = SendToClientPackageOfflineChatMessage(off_chat_msg.fromuserid,
                                                                off_chat_msg.touserid,
                                                                off_chat_msg.msg,
                                                                off_chat_msg.last_date )

                ret_off_chat_messages.append(off_msg)

        if ret_off_chat_messages:
            #发送离线消息
            retPackage = SendToClientPackage('sendchatmsg')
            retPackage.status = 1
            retPackage.obj = ret_off_chat_messages

            user.connection.send_message( json.dumps( retPackage , cls=ComplexEncoder ) )

            #从数据库中删除
            self.dbEngine.deleteAllOfflineChatMessageWithUserId( user.DBUser.uid )



    def getNotFriendsWithCodeAndDateAndPage(self , user , traincode, date , page):
        """
        根据列车或者航班+日期获取的好友
        """
        friends = self.dbEngine.getNotfriendsWithCodeAndDate(traincode, date)
        ret_friends = []
        nCount = 0
        if friends:
            for friend in friends:
                #不是自己
                if friend.userid != user.DBUser.uid:
                    #计算页码
                    if (nCount / 20 == page):
                        db_friend = self.dbEngine.getUserInfoWithUserId(friend.userid)
                        ret_friend = SendToClientPackageUser(db_friend.uid, db_friend.username, db_friend.sex, db_friend.description)
                        ret_friends.append(ret_friend)

                    nCount += 1

        return ret_friends



    def getUserFriendsWithUserAndPage(self, user , page):
        """
        获取用户好友
        """
        retFriends = []
        friends = user.getAllFriends()
        friendCount = len(friends)
        if friends and friendCount > 0:
            nStart = 0
            nEnd = 0

            #计算页码是否在范围内
            if USERS_PAGES_SIZE * page < friendCount:

                #计算结束页码
                if USERS_PAGES_SIZE * (page + 1) > friendCount:
                    nEnd = friendCount - USERS_PAGES_SIZE * page
                else:
                    nEnd = USERS_PAGES_SIZE * page

                #在页码范围内的好友
                friends = friends[nStart * USERS_PAGES_SIZE : nEnd]
                for friend in friends:
                    online = False
                    if friend.connection:
                        online = True
                    retUser = SendToClientPackageUser(friend.DBUser.uid,
                                                      friend.DBUser.username,
                                                      friend.DBUser.sex,
                                                      friend.DBUser.description,
                                                      online)
                    retFriends.append( retUser )


        return retFriends
Пример #13
0
 def __init__(self):
     self.serverList = ServeList()
     self.dbEngine = DBEngine()
     self.groupInit()
Пример #14
0
class Logic(object):

    #0.初始化
    def __init__(self):
        self.serverList = ServeList()
        self.dbEngine = DBEngine()
        self.groupInit()

    #1.输入是否合法,防止sql注入
    def findBadInput(self, inputstring):

        if '\'' in inputstring:
            return True
        elif '\"' in inputstring:
            return True
        elif '`' in inputstring:
            return True
        elif ' ' in inputstring:
            return True

    #2.初始化群组
    def groupInit(self):
        db_groups = self.dbEngine.get_all_group()
        for db_group in db_groups:
            group = GroupObject(db_group)
            self.serverList.addNewGroup(group)
            self.getGroupMemberWithDB(group)

    #3.重置服务器
    def reset(self):
        self.serverList.reset()

    ####################################################################################
    # 一.协议处理部分
    ####################################################################################

    #0.逻辑处理部分
    def handlePackage(self, connection , package):
        if isinstance(package, PackageRegister):                        #请求邮箱认证码状态返回
            print('package register')
            self.handleUserRegister(connection, package)
        elif isinstance(package, PackageRegisterAuth):                  #注册状态返回
            print('package registerauth')
            self.handleUserRegisterAuth(connection, package)
        elif isinstance(package, PackageLogin):                         #登陆状态返回
            print('package login')
            self.handleUserLogin(connection, package)
        elif isinstance(package, PackageDg):                            #获取DG证书
            print('package dg')
            self.handleDG(connection, package)
        elif isinstance(package, PackagePublicDg):                      #获取DG公钥证书
            print('package publicdg')
            self.handlePublicDg(connection, package)
        elif isinstance(package, PackageAddFriendRequest):              #转发添加好友申请
            print('package addfriend')
            self.handleAddFriendRequest(connection, package)
        elif isinstance(package, PackageAddFriendStatus):               #返回好友添加结果
            print('package addfriendstatus')
            self.handleAddFriendRequestStatus(connection, package)
        elif isinstance(package, PackageDeleteFriend):                  #删除好友通知
            print('package delfriend')
            self.handleDeleteFriend(connection, package)
        elif isinstance(package, PackageGetFriends):                    #好友列表返回
            print('package getfriends')
            self.handleGetFriends(connection, package)
        elif isinstance(package, PackageGetFriendDetail):               #获取好友信息
            print('package getfrienddetail')
            self.handleGetFriendDetail(connection, package)
        elif isinstance(package, PackageJoinGroup):                     #好友加群提醒
            print('package joingroup')
            self.handleJoinGroup(package)
        elif isinstance(package, PackageGetGroupList):                  #获取群列表
            print('package getgrouplist')
            self.handleGetGroupList(connection, package)
        elif isinstance(package, PackageGetGroupMember):                #获取群成员
            print('package getgroupmember')
            self.handleGetGroupMember(connection, package)
        elif isinstance(package, PackageExitGroup):                     #好友退群提醒
            print('package exitgroup')
            self.handleExitGroup(package)
        elif isinstance(package, PackageSendChatMessage):               #发送聊天信息
            print('package sendchatmsg')
            self.handleSendChatMessage(connection, package)

    #1.根据connection断开连接
    def closeConnection(self, connection):
        print("Connection closed")
        user = self.serverList.getUserByConnection(connection)
        if user:
            self.serverList.deleteUserByUser(user)
            friends = user.getAllFriends()
            if len(friends) > 0:
                self.broadcastOnlineStatusToAllFriend(user, 0)

    ####################################################################################
    # 二.逻辑处理
    ####################################################################################


    #----0.请求邮箱认证码状态返回----#
    def handleUserRegister(self, connection, package):

        retPackage = SendToClientPackage('register')

        #step 1,检查参数合法性
        if self.findBadInput(package.username):
            #帐号异常#
            retPackage.errcode = PACKAGE_ERRCODE_INPUTWRONG

        #step 2,检查参数长度
        elif len(package.username) < 5 or len(package.username) > 13:
            #长度太小#
            retPackage.errcode = PACKAGE_ERRCODE_LENGTHTOSHORT

        else:
            #step 3,检查用户是否存在
            db_user = self.dbEngine.isUserExist(package.username, package.password)

            #已经存在用户,返回重新注册
            if db_user:
                retPackage.errcode = PACKAGE_ERRCODE_USERISEXIST

            #不存在,插入数据库
            else:
                #检查邮箱是否已经被注册
                db_mail = self.dbEngine.isMailExist(package.mail)
                if db_mail:
                    retPackage.errcode = PACKAGE_ERRCODE_USEDMAIL
                else:
                    #发送验证码至邮箱
                    print('authcode')
                    authcode = self.getauthcode()
                    self.dbEngine.wirte_mail_auth(package.mail, authcode)
                    self.sendmailauth(package.mail, authcode)
                    self.createDGPairs(package.username)
                    #将该验证码存至数据库
                    self.dbEngine.register_new_user(package.username, package.password, package.mail, package.sex)
                    retPackage.status = 1

        connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----1.注册状态返回----#
    def handleUserRegisterAuth(self,connection, package):

        retPackage = SendToClientPackage('registerauth')
        #step 1 #
        correctcode = self.dbEngine.getauthbymail(package.mail)
        print(correctcode.authword)
        print(package.auth)
        if correctcode.authword == package.auth:
            retPackage.status = 1
            #修改数据库
            self.dbEngine.finish_new_user(package.mail)
            print('change')
        else:
            retPackage.errcode = PACKAGE_ERRCODE_AUTHFAILED
        #step 2
        connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----2.登陆状态返回----#
    def handleUserLogin(self, connection, package):

        retPackage = SendToClientPackage('login')

        #step 1,检查参数合法性
        if self.findBadInput(package.username):
            retPackage.errcode = PACKAGE_ERRCODE_INPUTWRONG

        else:
            #step 2. 查询数据库
            
            db_user = self.dbEngine.isUserExist(package.username, package.password)
            if not db_user:
                #用户不存在,提醒注册
                retPackage.errcode = PACKAGE_ERRCODE_USERUNEXIST

            elif db_user.authsuccess == 0:
                retPackage.errcode = PACKAGE_ERRCODE_MAILNOTCONFIRM

            else:
                #step 1. 枚举在线用户,如果在线,退掉
                online_user = self.serverList.getUserExistByUsername(package.username)
                if online_user:
                    #step 1.发送异地登录消息
                    another = SendToClientPackage('anotherlogin')
                    another.errcode = PACKAGE_ERRCODE_ANOTHERLOGIN
                    another.obj = SendToClientPackageAnotherLogin(self.serverList.users[package.username].connection._address[0])

                    online_user.connection.send_message(json.dumps(another, cls=ComplexEncoder))

                    #step 2.关闭联接
                    online_user.connection.close()

                #重新加入到在线用户
                user = UserObject(connection, db_user)
                self.serverList.addNewOnlineUser(user)

                #XMLCertificate = self.createXMLCertificate() 生成XML证书

                retPackage.status = 1
                retPackage.obj = SendToClientPackageUser(user.username,
                                                         user.DBUser.sex,
                                                         user.DBUser.mail)
                #加载好友列表
                print ('getUserFriendsWithDBAndOnLineUsers')
                self.getUserFriendsWithDBAndOnLineUsers(user)

                #广播好友列表,通知本人上线
                print ('broadcastOnlineStatusToAllFriend')
                self.broadcastOnlineStatusToAllFriend(user, 1)

                #修改在线列表,本人上线
                print ('setUserOnlineInOnlineUsersFriends')
                self.setUserOnlineInOnlineUsersFriends(user)

        connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
        if retPackage.status == 1:
            my_user = self.serverList.getUserByConnection(connection)
            #检查离线消息,是否有人希望添加我为好友
            print ('getAllAddFriendRequestFromDBAndSendToClient')
            self.getAllAddFriendRequestFromDBAndSendToClient(my_user)
            #是否有发给我的离线消息
            print ('getOfflineChatMessageAndSendWithUser')
            self.getOfflineChatMessageAndSendWithUser(my_user)
    
    #----3.获取公钥数字证书----#
    def handleDG(self, connection, package):
        user = self.serverList.getUserByConnection(connection)
        retPackage = SendToClientPackage('applymydg')
        #自己的name
        if user.DBUser.username == package.username:
            retPackage.status = 1
            return_obj = SendToClientPackageDG(user.DBUser.username,self.getDGPublicKey(user.DBUser.username))
            retPackage.obj = return_obj
        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
        user.connection.send_message(json.dumps(retPackage,cls=ComplexEncoder))

    #----4.获取私钥证书----#
    def handlePublicDg(self, connection, package):
        user = self.serverList.getUserByConnection(connection)
        retPackage = SendToClientPackage('applyfrienddg')
        #自己的name
        if user.DBUser.username == package.username:
            retPackage.status = 1
            return_obj = SendToClientPackageDG(package.friendname,self.getDGPrivateKey(package.friendname))
            retPackage.obj = return_obj
        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
        user.connection.send_message(json.dumps(retPackage,cls=ComplexEncoder))

    #----5.转发添加好友申请----#
    def handleAddFriendRequest(self, connection, package):

        user = self.serverList.getUserByConnection(connection)
        retPackage = SendToClientPackage('returnaddfriend')
        bFriendship = False

        #检查是否是自己并且自己不是自己想要添加自己为好友
        if user.DBUser.username == package.fromname and user.DBUser.username != package.toname:
            isexist = self.dbEngine.getUserInfoWithUserName(package.toname)
            #检查用户是否存在
            if isexist:
                friend = user.getFriendWithUsername(package.toname)
                if friend:
                    bFriendship = True

                if not bFriendship:
                    retPackage.status = 1
                    user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

                    #step2 在线,发送添加
                    online_user = self.serverList.getUserExistByUsername(package.toname)

                    if online_user:
                        add_obj = []
                        addreq = SendToClientPackageRecvAddFriendRequest(package.fromname,
                                                                         package.toname,
                                                                         user.DBUser.sex,
                                                                         package.msg,
                                                                         datetime.datetime.now())
                        add_obj.append(addreq)
                        retPackagetofriend = SendToClientPackage('addfriend')
                        retPackagetofriend.status = 1
                        retPackagetofriend.obj = add_obj

                        online_user.connection.send_message(json.dumps(retPackagetofriend, cls=ComplexEncoder))
                    else:
                        #插入数据库,等待上线时候通知
                        print('Insert datebase')
                        self.dbEngine.setOfflineAddFriendReuqest(package.toname, package.fromname, package.msg, datetime.datetime.now())
                else:
                    #已经是好友,返回错误信息
                    retPackage.errcode = PACKAGE_ERRCODE_FRIENDSHIPEXIST
                    user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
            else:
                retPackage.errcode = PACKAGE_ERRCODE_NOTHISUSER
                user.connection.send_message(json.dumps(retPackage,cls=ComplexEncoder))
        else:
            #用户ID错误,或者用户ID等于好友ID
            retPackage.errcode = PACKAGE_ERRCODE_USERFRIENDID
            user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----6.返回好友添加结果----#
    def handleAddFriendRequestStatus(self, connection, package):

        user = self.serverList.getUserByConnection(connection)
        retPackage = SendToClientPackage('returnaddfriendstatus')

        #自己的ID是目标ID && 自己不能添加自己为好友
        if user.DBUser.username == package.toname and user.DBUser.username != package.fromname:

            #如果同意
            if package.agree:

                #step 1. 检查是否是自己的好友
                if not self.dbEngine.getFriendshipWithUserFriendName(package.fromname, package.toname):
                    db_friend = self.dbEngine.getUserInfoWithUserName(package.fromname)
                    #在线列表中
                    usob = self.serverList.getUserByUsername(package.fromname)
                    #存在数据库中
                    if db_friend:#判断用户是否存在
                        retPackage.status = 1
                        #保存关系到数据库
                        self.dbEngine.setFriendshipWithUserNames(package.toname, package.fromname)
                        return_obj=[]
                        if usob:#用户在在线列表中

                            return_tem = SendToClientPackageFriendsList(package.fromname,
                                                                        db_friend.sex,
                                                                        db_friend.mail,
                                                                        usob.connection._address[0],
                                                                        package.agree)
                        else:
                            return_tem = SendToClientPackageFriendsList(package.fromname,
                                                                        db_friend.sex,
                                                                        db_friend.mail,
                                                                        '',
                                                                        package.agree)
                        return_obj.append(return_tem)
                        retPackage.obj = return_tem

                        user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
                        #检查是否在线,在线发送上线通知
                        online_friend = self.serverList.getUserExistByUsername(package.fromname)
                        if online_friend:
                            #当前在线
                            retPackagetofriendstatus = SendToClientPackage('addfriendstatus')
                            online_obj = []
                            online_status = SendToClientAddFriendStatus(package.fromname,
                                                                        package.toname,
                                                                        user.DBUser.sex,
                                                                        user.DBUser.mail,
                                                                        user.connection._address[0],
                                                                        package.msg,
                                                                        package.agree,
                                                                        user.online)
                            online_obj.append(online_status)
                            retPackagetofriendstatus.status = 1
                            retPackagetofriendstatus.obj = online_status
                            #发送有人添加好友申请
                            online_friend.connection.send_message(json.dumps(retPackagetofriendstatus, cls=ComplexEncoder))

                            #添加到我的好友列表
                            user.addFriend(online_friend)
                            online_friend.addFriend(user)
                        else:
                            new_friend = UserObject(None,self.dbEngine.getUserInfoWithUserName(package.fromname))
                            user.addfriend(new_friend)
                            #此处应该添加系统回复消息至数据库
                            #用户上线时,将此消息发送

                    else:
                        retPackage.errcode = PACKAGE_ERRCODE_NOTHISUSER

                        #返回添加好友状态
                        user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

                else:
                    #已经是好友提示
                    retPackage.errcode = PACKAGE_ERRCODE_FRIENDSHIPEXIST

                    user.connection.send_message(json.dumps(retPackage, cls= ComplexEncoder))

            else:
                #返回状态
                retPackage.status = 1
                #返回添加好友状态
                user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

                #TODO:拒绝不提示
                pass

        else:
            #用户ID异常
            retPackage.errcode = PACKAGE_ERRCODE_USERFRIENDID
            user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----7.删除好友通知----#
    def handleDeleteFriend(self, connection, package):

        user = self.serverList.getUserByConnection(connection)
        retPackage = SendToClientPackage('delfriend')

        # 自己的id
        if user.DBUser.username == package.username and user.DBUser.username != package.friendname:
            retPackage.status = 1

            # 从数据库中删除
            self.dbEngine.deleteFriendshipByUserAndFriendName(package.username, package.friendname)

            user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

            # 给在线好友发送通知,删除
            online_friend = self.serverList.getUserExistByUsername(package.friendname)
            if online_friend:
                sendObj = SendToClientPackageUser(user.DBUser.username,
                                                  user.DBUser.sex,
                                                  user.DBUser.mail)
                retPackage.obj = sendObj
                online_friend.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
                online_friend.deleteFriend(user)
                # 从维护的好友列表中删除
                user.deleteFriend(online_friend)

        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
            user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----8.好友列表返回----#
    def handleGetFriends(self, connection, package):

        user = self.serverList.getUserByConnection(connection)
        retPackage = SendToClientPackage('getfriends')

        #自己的name
        if user.DBUser.username == package.username:

            retFriend = self.getUserFriendsWithUserAndPage(user, int(package.page))

            if len(retFriend) > 0:
                retPackage.obj = retFriend

            retPackage.status = 1

        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
        print('getfriends')
        user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----9.获得好友信息----#
    def handleGetFriendDetail(self, connection, package):

        user = self.serverList.getUserByConnection(connection)
        retPackage = SendToClientPackage('getfrienddetail')

        #自己的id
        if user.DBUser.uid == int(package.uid) and user.DBUser.uid != int(package.fid):
            retPackage.status = 1

            #获取用户详细资料返回

        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
            user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----10.加入群组----#
    def handleJoinGroup(self, package):

        user = self.serverList.getUserByUsername(package.username)
        group = self.serverList.getGroupByGroupname(package.groupname)
        retPackage = SendToClientPackage('memberjoinexitgroup')
        if group:#群组已存在
            # step 1. 检查未入群
            if not user.DBUser.username in self.serverList.group[package.groupname].members:
                retPackage.status = 1
                #维护在线列表
                group.addMember(user)
                #保存关系到数据库
                self.dbEngine.add_user_into_group(package.groupname,package.username)
                my_group = self.dbEngine.findGroupidWithGroupname(package.groupname)
                return_obj = SendToClientPackageGroupsList(my_group.groupname,my_group.groupnumber)
                retPackage.obj = return_obj
                user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
                #广播进退群消息(进群)
                self.broadcastJoinExitStatusToAllMember(package.username, package.groupname, True)

            #已经在群里
            else:
                retPackage.errcode = PACKAGE_ERRCODE_INGROUP
                user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
        else:
            retPackage.status = 1
            self.dbEngine.register_new_group(package.groupname)
            self.dbEngine.add_user_into_group(package.groupname,package.username)
            db_gp = self.dbEngine.findGroupidWithGroupname(package.groupname)
            GO_gp = GroupObject(db_gp)
            self.serverList.addNewGroup(GO_gp)
            db_user = self.dbEngine.findIdWithName(package.username)
            GO_user = UserObject(None,db_user)
            GO_gp.addMember(GO_user)
            return_obj = SendToClientPackageGroupsList(package.groupname,1)
            retPackage.obj = return_obj
            user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----11.获取群列表----#
    def handleGetGroupList(self, connection, package):
        user = self.serverList.getUserByConnection(connection)
        retPackage = SendToClientPackage('getgrouplist')

        #自己的name
        if user.DBUser.username == package.username:
            return_obj = self.getGroupListWithUser(user)
            if len(return_obj) > 0:
                retPackage.obj =return_obj
            retPackage.status = 1
        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
        print ('getgrouplist')
        user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----12.获取群成员----#
    def handleGetGroupMember(self, connection, package):
        user = self.serverList.getUserByConnection(connection)
        group = self.serverList.getGroupByGroupname(package.groupname)
        retPackage = SendToClientPackage('getgroupmember')

        #自己的name
        if user.DBUser.username == package.username:
            #群组是否存在
            if group:
                #用户是群组成员
                if user.DBUser.username in group.members:
                    retPackage.status = 1
                    return_obj = self.getGroupMember(group)
                    if len(return_obj) > 0:
                        retPackage.obj = return_obj
                else:
                    retPackage.errcode = PACKAGE_ERRCODE_NOTINGROUP
            else:
                retPackage.errcode = PACKAGE_ERRCODE_GROUPNOTEXIST
        else:
            retPackage.errcode = PACKAGE_ERRCODE_USERID
        user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #----13.退出群组----#
    def handleExitGroup(self, package):

        user = self.serverList.getUserByUsername(package.username)
        group = self.serverList.getGroupByGroupname(package.groupname)
        retPackage = SendToClientPackage('memberjoinexitgroup')
        
        #1群存在
        if group:
            #在群里
            if user.DBUser.username in self.serverList.group[package.groupname].members:
                retPackage.status = 1
                #更新群组成员列表
                group.deleteMember(user)
                #从数据库中删除
                print (package.groupname,package.username)
                self.dbEngine.del_user_from_group(package.groupname,package.username)
                #维护该群的群成员列表
                db_user = self.dbEngine.findIdWithName(package.username)
                GO_user = UserObject(None,db_user)
                group.deleteMember(GO_user)
                #返回退群成功包
                user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
                #获得当前此时群人数
                length = self.dbEngine.get_group_number(package.groupname)
                #群能否继续存在
                if length == 0:
                    #删除该群
                    self.dbEngine.del_the_group(package.groupname)
                    #维护服务器群列表缓存
                    self.serverList.deleteGroupByGroup(group)
                else:
                    #广播进退群消息
                    self.broadcastJoinExitStatusToAllMember(package.username, package.groupname, False)

            #不在群里
            else:
                retPackage.errcode = PACKAGE_ERRCODE_NOTINGROUP
                user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
        else:
            retPackage.errcode = PACKAGE_ERRCODE_NOTINGROUP
            user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))


    #----14.发送聊天消息----#
    def handleSendChatMessage(self, connection, package):

        user = self.serverList.getUserByConnection(connection)
        retPackage = SendToClientPackage('sendchatmsg')

        #不是群组消息
        if package.groupname == '':
            print ("private message")
            #自己的name
            if user.DBUser.username == package.fromname and user.DBUser.username != package.toname:

                #寻找好友
                for friend in user.getAllFriends():

                    if friend.DBUser.username == package.toname:
                        #发送消息给好友
                        retPackage.status = 1

                        user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
                        chat_obj = []
                        chat = SendToClientPackageChatMessage(package.fromname,
                                                              package.toname,
                                                              '',
                                                              package.chatmsg,
                                                              datetime.datetime.now())
                        chat_obj.append(chat)
                        retPackage.obj = chat_obj

                        #在线
                        if friend.connection:
                            friend.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
                        #不在线,数据库插入离线消息
                        else:
                            self.dbEngine.addOfflineChatMessageWithUserName(package.fromname,
                                                                            package.toname,
                                                                            '',
                                                                            package.chatmsg,
                                                                            datetime.datetime.now())
                            print ("insert offlinechatmessage")
                print ('not find friend')
            else:
                retPackage.errcode = PACKAGE_ERRCODE_USERID
                user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

        #是群组消息
        else:
            #判断自己在群内
            if user.DBUser.username in self.serverList.group[package.groupname].members:
                #发送群组消息返回包
                retPackage.status = 1
                user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
                #寻找群内成员
                for member in self.serverList.group[package.groupname].members:
                    #跳过自己
                    if user.DBUser.username == member:
                        continue
                    #构造群组消息
                    chat_obj = []
                    chat = SendToClientPackageChatMessage(package.fromname,
                                                          '',
                                                          package.groupname,
                                                          package.chatmsg,
                                                          datetime.datetime.now())
                    chat_obj.append(chat)
                    retPackage.obj = chat_obj
                    #在线
                    onlineuser = self.serverList.getUserExistByUsername(member)
                    if onlineuser:
                        onlineuser.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))
                    #不在线,数据库插入离线消息
                    else:
                        print ('insert datebase')
                        self.dbEngine.addOfflineChatMessageWithUserName(package.fromname,
                                                                        member,
                                                                        package.groupname,
                                                                        package.chatmsg,
                                                                        datetime.datetime.now())
            else:
                retPackage.errcode = PACKAGE_ERRCODE_NOTINGROUP
                user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))


    ####################################################################################
    # 三.逻辑中的部分细节处理
    ####################################################################################

    #----1.生成认证码----#
    #----from: 0.handleUserRegister----#
    def getauthcode(self):

        authcode = ''
        for i in range(4):
            authcode += random.choice('abcdefghijklmnopqrstuvwxyz')
        return authcode

    #----2.发送邮箱认证码----#
    #----from: 0.handleUserRegister----#
    def sendmailauth(self, mail, authcode):

        smtp_server = 'smtp.sina.com'
        username = '******'
        password = '******'
        from_addr = '*****@*****.**'
        to_addr = mail
        message = 'authcode:' + authcode
        msg = MIMEText(message, 'plain', 'utf-8')
        server = smtplib.SMTP(smtp_server, 25)
        #server.set_debuglevel(1)
        server.login(username, password)
        server.sendmail(from_addr, [to_addr], msg.as_string())
        server.quit()

    #----3.生成证书----#
    #----from: 2.handleUserLoginr----#
    def createDGPairs(self,username):

        private_path = 'private/'
        public_path = 'public/'
        private_path += username
        public_path += username
        P = PKey()
        P.generate_key(TYPE_RSA, 1024)
        #写入
        with open(public_path,'w') as f:
            f.write(dump_publickey(FILETYPE_PEM, P).decode('utf-8'))
        with open(private_path,'w') as f:
            f.write(dump_privatekey(FILETYPE_PEM, P).decode('utf-8'))

    #----4.获取私钥----#
    def getDGPrivateKey(self, username):

        path = 'private/'
        path += username
        with open(path,'r',encoding='utf-8') as f:
            PrivateKey = f.read()
        return PrivateKey

    #----5.获取公钥----#
    def getDGPublicKey(self, username):

        path = 'public/'
        path += username
        with open(path,'r',encoding='utf-8') as f:
            PublicKey = f.read()
        return PublicKey

    #----6.获取用户的所有好友信息----#
    #----from: 2.handleUserLogin----#
    def getUserFriendsWithDBAndOnLineUsers(self, user):

        #step 1.从数据库加载
        (user1Friends, user2Friends) = self.dbEngine.getUserFriendshipWithUserName(user.DBUser.username)
        for friend in user1Friends:
            db_user = self.dbEngine.getUserInfoWithUserId(friend.user2id)
            friend = UserObject(None, db_user)
            user.addFriend(friend)
            online_friend = self.serverList.getUserExistByUsername(db_user.username)
            if online_friend:
                friend.connection = online_friend.connection
                friend.online = True

        for friend in user2Friends:
            db_user = self.dbEngine.getUserInfoWithUserId(friend.user1id)
            friend = UserObject(None, db_user)
            user.addFriend(friend)
            online_friend = self.serverList.getUserExistByUsername(db_user.username)
            if online_friend:
                friend.connection = online_friend.connection
                friend.online = True

    #---5.获取群组的所有成员信息---#
    #---from: groupInit---#
    def getGroupMemberWithDB(self, group):

        members = self.dbEngine.get_group_member(group.DBGroup.groupname)

        for member in members:
            db_user = self.dbEngine.findNameWithId(member.memberid)
            member = UserObject(None,db_user)
            group.addMember(member)

    #---6.从数据库获取所有离线申请添加好友的用户并发送给用户--#
    #---from: 2.handleUserLogin---#
    def getAllAddFriendRequestFromDBAndSendToClient(self, user):

        add_requests = []
        offline_add_friend_requests = self.dbEngine.getOfflineAddFriendRequests(user.DBUser.username)
        for off_add_req in offline_add_friend_requests:

            fuser = self.dbEngine.getUserInfoWithUserId(off_add_req.fromid)
            send_request = SendToClientPackageRecvAddFriendRequest(fuser.username,
                                                                   user.DBUser.username,
                                                                   user.DBUser.sex,
                                                                   off_add_req.msg,
                                                                   off_add_req.lastdate)
            add_requests.append(send_request)

        if len(add_requests) > 0:
            #发送
            retRequest = SendToClientPackage('addfriend')
            retRequest.status = 1
            retRequest.obj = add_requests

            user.connection.send_message(json.dumps(retRequest, cls=ComplexEncoder))

            #删除离线好友请求
            self.dbEngine.deleteOfflineAddFriendRequestWithUserName(user.DBUser.username)


    #---7.获取所有离线消息并发送---#
    #---from: 2.handleUserLogin---#
    def getOfflineChatMessageAndSendWithUser(self, user):

        db_offline_chat_messages = self.dbEngine.getAllOfflineChatMessageWithUserName(user.DBUser.username)

        ret_off_chat_messages = []
        if db_offline_chat_messages:
            for off_chat_msg in db_offline_chat_messages:
                fuser = self.dbEngine.getUserInfoWithUserId(off_chat_msg.fromuserid)
                fgroup = self.dbEngine.getGroupInfoWithGroupId(off_chat_msg.groupid)
                if fgroup.groupname == '':
                    off_msg = SendToClientPackageChatMessage(fuser.username,
                                                            user.DBUser.username,
                                                            fgroup.groupname,
                                                            off_chat_msg.msg,
                                                            off_chat_msg.last_date)
                else:
                    off_msg = SendToClientPackageChatMessage(fuser.username,
                                                            '',
                                                            fgroup.groupname,
                                                            off_chat_msg.msg,
                                                            off_chat_msg.last_date)
                ret_off_chat_messages.append(off_msg)

        if ret_off_chat_messages:
            #发送离线消息
            retPackage = SendToClientPackage('sendchatmsg')
            retPackage.status = 1
            retPackage.obj = ret_off_chat_messages

            user.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

            #从数据库中删除
            self.dbEngine.deleteAllOfflineChatMessageWithUserName(user.DBUser.username)


    # ---8.将在线用户列表里面的所有状态修改为在线---#
    # ---from: 2.handleUserLogin---#
    def setUserOnlineInOnlineUsersFriends(self, user):

        for friend in user.getAllFriends():
            online_friend = self.serverList.getUserExistByUsername(friend.DBUser.username)
            if online_friend:
                myself = online_friend.getFriendWithUsername(user.DBUser.username)
                myself.connection = user.connection


    #---9.广播用户的上线下线消息---#
    #---from: 2.handleUserLogin & closeConnection---#
    def broadcastOnlineStatusToAllFriend(self, user, online):

        retPackage = SendToClientPackage('useronoffline')

        for friend in user.getAllFriends():
            #通知所有好友上下线
            retPackage.status = 1
            if online:
                obj = SendToClientUserOnOffStatus(user.DBUser.username,
                                                  user.connection._address[0],
                                                  online)
            else:
                obj = SendToClientUserOnOffStatus(user.DBUser.username,
                                                  '',
                                                  online)
            retPackage.obj = obj
            if friend.connection:
                friend.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

            if not online:  #离线
                # 清空连接
                online_friend = self.serverList.getUserExistByUsername(friend.DBUser.username)
                if online_friend:
                    # 从好友列表里面将自己的connection 清0
                    myself = online_friend.getFriendWithUsername(user.DBUser.username)
                    myself.connection = None


    #---10.广播群组成员加退群信息---#
    #---from: 8.handlejoingroup & 9.handleexitgroup---#
    def broadcastJoinExitStatusToAllMember(self, username, groupname, status):

        retPackage = SendToClientPackage('memberjoinexitgroup')
        group = self.serverList.getGroupByGroupname(groupname)
        retPackage.status = 1

        for member in group.members.values():
            #检查是否在线,在线发送上线通知
            online_member = self.serverList.getUserExistByUsername(member.DBUser.username)

            #在线
            if online_member:
                join_exit_status = SendToClientGroupMemberJoinExitStatus(username,
                                                                         groupname,
                                                                         status)
                retPackage.obj = join_exit_status

                #发送入退群通知
                online_member.connection.send_message(json.dumps(retPackage, cls=ComplexEncoder))

    #---11.获取群组列表---#
    def getGroupListWithUser(self, user):
        retList = []
        groups = self.dbEngine.get_list_group(user.DBUser.username)
        if groups:
            for group in groups:
                #根据groupid获取name
                print ("group.groupid",group.groupid)
                my_group = self.dbEngine.getGroupInfoWithGroupId(group.groupid)
                retGroup = SendToClientPackageGroupsList(my_group.groupname,
                                                         my_group.groupnumber)
                retList.append(retGroup)
        return retList
    #---12.获取群组成员
    def getGroupMember(self, group):
        retList = []
        members = group.getAllMember()
        membernum = len(members)
        print ('membernum',membernum)
        if members and membernum > 0:
            for member in members:
                print('username:'******'',
                                                                 False)

                    retFriends.append(retUser)
        return retFriends
Пример #15
0
def delete_comment(comment_id):
    DBEngine().delete_comment(comment_id)
    return '', 200
Пример #16
0
def create_user():
    username = request.form['username']
    email = request.form['email']
    return jsonify({'user': DBEngine().create_user(username, email)}), 201
Пример #17
0
    def __init__(self):
        super(QMainWindow, self).__init__()

        self.setupUi(self)
        self.connButtonBox.button(QDialogButtonBox.Ok).setText("Connect")
        self.runButtonBox.button(QDialogButtonBox.Ok).setText("Run")
        self.tunnelButton.clicked[bool].connect(self.toggle_tunnel)
        self.tunnelWidget.hide()
        self.keyFileButton.clicked.connect(self.choose_keyfile)
        self.clearButton.clicked.connect(self.clear_tunnel)
        self.keyComboBox.activated[str].connect(self.set_key_type)

        self.db_engine = DBEngine()
        self.db_engine.result_signal.connect(self.show_results)
        self.db_engine.progress_signal.connect(self.set_progress)
        self.db_engine.error_signal.connect(self.show_error)
        self.db_engine.msg_signal.connect(self.show_msg)
        self.stmt_signal.connect(self.db_engine.receive_stmt)

        self.db_lite = DBLite()
        self.tunnel = Tunnel()
        self.tunnel_keyfile = ""
        self.data_schema = []
        self.settings = QSettings()
        self.restore_settings()

        history = self.db_lite.history()
        self.historyMenuBar = QMenuBar(self.sqlWidget)
        self.historyMenuBar.setNativeMenuBar(False)
        self.historyMenu = self.historyMenuBar.addMenu('     &History   ⇲    ')
        actions = [
            QAction(sql.replace('\n', ' '), self.historyMenu)
            for sql in history
        ]
        for i in range(len(actions)):
            actions[i].triggered.connect(partial(self.use_history, history[i]))
        self.historyMenu.addActions(actions)

        self.history_cache = pylru.lrucache(history_limit, self.remove_action)
        for i in reversed(range(len(history))):
            self.history_cache[history[i]] = {
                KEY_ACTION: actions[i],
                KEY_RESULTS: [],
                KEY_COLUMNS: []
            }

        self.historyMenu.setStyleSheet("""
        QMenu {
            max-width: 1000px;
            font-size: 12px;
        }
        """)
        self.historyMenuBar.setStyleSheet("""
        QMenuBar {
            border: None;
        }
        QMenuBar::item {
            background: #404040;
            color: #ffffff;
            border-radius: 4px;
        }
        QMenuBar::item:selected {
            background: rgba(1, 1, 1, 0.2);;
            color: #404040;
            border-radius: 4px;
        }
        """)
        self.sqlWidgetLayout.insertWidget(0, self.historyMenuBar)

        self.connButtonBox.accepted.connect(self.connect)
        self.connButtonBox.rejected.connect(self.disconnect)
        self.runButtonBox.accepted.connect(self.run)
        self.runButtonBox.rejected.connect(self.cancel)
        self.tablesWidget.itemDoubleClicked.connect(self.get_meta)
        self.tablesWidget.itemExpanded.connect(self.get_meta)

        self.progressBar = QProgressBar()
        self.statusbar.addPermanentWidget(self.progressBar)
        self.progressBar.setValue(100)
        QApplication.processEvents()

        self.highlight = syntax.PrestoHighlighter(self.sqlEdit)

        self.dataWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.dataWidget.customContextMenuRequested.connect(
            self.show_table_context_menu)
        self.dataWidget.horizontalHeader().setStretchLastSection(False)
        self.dataWidget.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)

        self.schemaView.header().setStretchLastSection(False)
        self.schemaView.header().setSectionResizeMode(
            QHeaderView.ResizeToContents)

        self.runButtonBox.button(
            QDialogButtonBox.Ok).setShortcut("Ctrl+Return")

        self.completer = SQLCompleter(self)
        self.sqlEdit.setCompleter(self.completer)

        self.set_key_type(self.keyComboBox.currentText())
        self.sqlEdit.setFocus()
Пример #18
0
def get_post(post_id):
    return jsonify({'post': DBEngine().get_post(post_id)}), 200
Пример #19
0
class BlockChainServer(db_pb2_grpc.BlockChainMinerServicer):
    def __init__(self, serverId, addr, peers, dataDir):
        super()

        if not os.path.exists(dataDir):
            os.makedirs(dataDir)

        self.serverId = serverId
        self.addr = addr
        self.database = DBEngine(dataDir)
        self.miner = MinerThreading()
        self.daemonTimer = RepeatedTimer(0.5, self.daemon)

        self.peers = peers
        self.stubs = []
        for peer in self.peers:
            logging.info('added peer {}'.format(peer))
            channel = grpc.insecure_channel(peer)
            self.stubs.append(db_pb2_grpc.BlockChainMinerStub(channel))
            self.stubs[-1].addr = peer

        self.miner.daemon = True
        self.miner.start()
        self.daemonTimer.start()

    def daemon(self):
        if self.miner.block is not None and self.miner.success:
            self.database.addBlock(self.miner.block)

        if len(self.database.curChain) != 0:
            for stub in self.stubs:
                try:
                    stub.PushBlock(
                        db_pb2.JsonBlockString(
                            Json=self.database.curChain[-1].toJson()))
                except grpc.RpcError:
                    pass

        block = self.database.packToBlock('Server{:02}'.format(self.serverId))
        if block is not None:
            self.miner.setBlock(block)

    def Get(self, request, context):
        logging.info("query balance of {}".format(request.UserID))
        value = self.database.get(request.UserID)
        return db_pb2.GetResponse(Value=value)

    def Transfer(self, request, context):
        if not self.database.pushTransaction(Transaction(request)):
            return db_pb2.BooleanResponse(Success=False)
        logging.info("transfer {} from {} to {}".format(
            request.Value, request.FromID, request.ToID))
        success = False
        for stub in self.stubs:
            try:
                stub.PushTransaction(request, timeout=10)
                success = True
            except grpc.RpcError:
                continue
        return db_pb2.BooleanResponse(Success=success)

    def Verify(self, request, context):
        trans = Transaction(request)
        logging.info("verify transfer ({} from {} to {})".format(
            request.Value, request.FromID, request.ToID))
        res = self.database.verify(Transaction(request))
        if res == 'SUCCEEDED':
            return db_pb2.VerifyResponse(
                Result=db_pb2.VerifyResponse.SUCCEEDED,
                BlockHash=self.database.blockByTrans(trans).hash)
        elif res == 'PENDING':
            return db_pb2.VerifyResponse(
                Result=db_pb2.VerifyResponse.PENDING,
                BlockHash=self.database.blockByTrans(trans).hash)
        else:
            return db_pb2.VerifyResponse(Result=db_pb2.VerifyResponse.FAILED,
                                         BlockHash="")

    def PushTransaction(self, request, context):
        self.database.pushTransaction(Transaction(request))
        return db_pb2.Null()

    def PushBlock(self, request, context):
        blockJsonString = request.Json
        try:
            block = Block(blockJsonString)
        except (json.JSONDecodeError, AttributeError):
            return db_pb2.Null()
        if len(block.MinerID) != 8 or \
            block.MinerID[:6] != 'Server' or \
            not block.MinerID[6:8].isdigit() or \
            not checkHash(block.hash):
            return db_pb2.Null()

        self.database.addBlock(block)

        last = block

        while True:
            if last.PrevHash == BlockChain.NullHash or last.PrevHash in self.database.blocks:
                break
            found = False
            for stub in self.stubs:
                try:
                    logging.info("acquire block from {} with hash {}".format(
                        stub.addr, last.PrevHash[:12]))
                    J = stub.GetBlock(
                        db_pb2.GetBlockRequest(BlockHash=last.PrevHash),
                        timeout=10).Json
                    if J == "":
                        continue
                    reqBlock = Block(J)
                except (grpc.RpcError, json.JSONDecodeError, AttributeError):
                    continue
                self.database.addBlock(reqBlock)
                last = reqBlock
                found = True
                break
            if not found:
                break

        self.database.updateLongestBlockChain()

        return db_pb2.Null()

    def GetHeight(self, request, context):
        self.database.updateLongestBlockChain()
        length = len(self.database.curChain)
        if length == 0:
            hash = ""
        else:
            hash = self.database.curChain[-1].hash
        time.sleep(2)
        return db_pb2.GetHeightResponse(Height=length, LeafHash=hash)

    def GetBlock(self, request, context):
        return db_pb2.GetBlockRequest(
            BlockHash=self.database.getBlockByHash(request.BlockHash))
Пример #20
0
def get_comment(comment_id):
    return jsonify({'comment': DBEngine().get_comment(comment_id)}), 200
Пример #21
0
def get_user(user_id):
    return jsonify({'user': DBEngine().get_user(user_id)}), 200
Пример #22
0
    def __init__(self):

        self.onlineUsers = UserModel()
        self.dbEngine = DBEngine()
Пример #23
0
import sys
import os
from db import DBEngine

if __name__ == "__main__":
    argv = sys.argv

    if len(argv) != 2:
        print("Usage: %s <path_to_db>" % argv[0])
        sys.exit(1)

    path_to_db = os.path.abspath(argv[1])
    engine = DBEngine(path_to_db)
    engine.create_db()