Esempio n. 1
0
    def file_message(self, data):
        content = {'command': 'file_message'}
        try:
            username = self.scope['user']
            room_id = self.scope['room_id']
            text = data['text']

            chat_room = ChatRoom.objects.get(id=room_id)
            message = Message.objects.create(author=username,
                                             type='file',
                                             chat_room=chat_room,
                                             content=text)
            content['message'] = self.message_to_json(message)

            cache.set("room_nm:" + room_id, (username, message.id))
            self.send_chat_message(content, room_id)
            group_notification(room_id, chat_room.notification_key, username,
                               text)

        except ChatUser.DoesNotExist:
            content['result'] = 'Fail file messages.(chat user)'
            self.send_message(content)
        except ChatRoom.DoesNotExist:
            content['result'] = 'Fail file messages. (chat room)'
            self.send_message(content)
        except User.DoesNotExist:
            content['result'] = 'Fail file messages. (user)'
            self.send_message(content)
        except KeyError:
            content['result'] = 'Fail file messages. (key error)'
            self.send_message(content)
Esempio n. 2
0
    def intent_message(self, data):
        content = {'command': 'intent_message'}
        try:
            username = self.scope['user']
            room_id = self.scope['room_id']
            text = data['text']
            intent = data['intent']
            lan = data['lan']

            chat_room = ChatRoom.objects.get(id=room_id)
            message = Message.objects.create(author=username,
                                             chat_room=chat_room,
                                             content=text)
            content['message'] = self.message_to_json(message)

            content['message']['intent'] = intent

            #text = "%s 모드로 변경 되었습니다." % category

            if intent == '1':
                content['message'][
                    'intentdata'] = "https://www.google.com/maps/search/?api=1&query=%s" % text
            elif intent == '2':
                content['message'][
                    'intentdata'] = "https://www.youtube.com/results?search_query=%s" % text
            elif intent == '3':
                content['message']['intentdata'] = "https://mail.google.com"
            elif intent == '4':
                content['message'][
                    'intentdata'] = "https://www.google.com/calendar"
            elif intent == '5':
                content['message'][
                    'intentdata'] = "https://contacts.google.com/search/%s" % text
            elif intent == '6':
                content['message'][
                    'intentdata'] = "https://en.wikipedia.org/wiki/%s" % text
            elif intent == '7':
                content['message'][
                    'intentdata'] = "https://search.naver.com/search.naver?sm=top_hty&fbm=0&ie=utf8&query=%s" % text
            elif intent == '8':
                content['message'][
                    'intentdata'] = "https://www.hotelscombined.co.kr/Place/%s" % text
            elif intent == '9':
                content['message'][
                    'intentdata'] = "https://www.skyscanner.co.kr"
            elif intent == '10':
                content['message'][
                    'intentdata'] = "https://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords=%s" % text
            elif intent == '11':
                content['message'][
                    'intentdata'] = "https://search.naver.com/search.naver?sm=top_hty&fbm=0&ie=utf8&query=%s" % text
            elif intent == '12':
                content['message'][
                    'intentdata'] = "https://kin.naver.com/search/list.nhn?query=%s" % text
            elif intent == '13':
                content['message'][
                    'intentdata'] = "https://www.textures.com/category/doors/148"
            elif intent == '14':
                content['message'][
                    'intentdata'] = "https://search.naver.com/search.naver?query=%s&where=news" % text
            elif intent == '15':
                content['message'][
                    'intentdata'] = "https://movie.naver.com/movie/search/result.nhn?query=%s" % text
            elif intent == '16':
                content['message'][
                    'intentdata'] = "https://m.stock.naver.com/searchItem.nhn?keyword_input=&keyword=%s" % text
            elif intent == '17':
                content['message'][
                    'intentdata'] = "https://chat.neoali.com:8074/"
            elif intent == '18':
                content['message'][
                    'intentdata'] = "https://search.naver.com/search.naver?query=%s" % text
            elif intent == '19':
                content['message'][
                    'intentdata'] = "https://sports.news.naver.com/"
            elif intent == '20':
                content['message'][
                    'intentdata'] = "https://book.naver.com/search/search.nhn?sm=sta_hty.book&sug=&where=nexearch&query=%s" % text
            else:
                content['message']['intentdata'] = '...'

            cache.set("room_im:" + room_id, (username, message.id))
            self.send_chat_message(content, room_id)
            group_notification(room_id, chat_room.notification_key, username,
                               text)

        except ChatUser.DoesNotExist:
            content['result'] = 'Fail ceslea message.(chat user)'
            self.send_message(content)
        except ChatRoom.DoesNotExist:
            content['result'] = 'Fail ceslea message. (chat room)'
            self.send_message(content)
        except User.DoesNotExist:
            content['result'] = 'Fail ceslea message. (user)'
            self.send_message(content)
        except KeyError:
            content['result'] = 'Fail ceslea message. (key error)'
            self.send_message(content)
Esempio n. 3
0
def room_invite(request):
    json_data = json.loads(request.body.decode('UTF8'))
    response = {'result': 'True'}
    try:
        my = json_data['my']
        participants = json_data['participants']
        room_id = json_data['room_id']

        if room_id == '' or not room_id:
            response['result'] = 'False'
            return JsonResponse(response, safe=False)

        chat_room = ChatRoom.objects.get(id=room_id)
        notification_key = chat_room.notification_key

        registration_ids = list()
        invite_user = str()
        for participant in participants:
            user = User.objects.get(username=participant)
            chat_user, created = ChatUser.objects.get_or_create(user=user, chat_room=chat_room)

            if created:
                registration_ids.append(user.firebase_id)
                invite_user += '%s, ' % participant
            else:
                if chat_user.room_exit:
                    chat_user.room_exit = False
                    chat_user.room_join()
                    # chat_user.save()

                    registration_ids.append(user.firebase_id)
                    invite_user += '%s, ' % participant

        if len(registration_ids) > 0:
            for registration_id in set(registration_ids):
                chat_user = chat_room.chat_user.filter(user__firebase_id=registration_id)
                if chat_user.count() == 1:
                    notification_key = add_notification_group(room_id, notification_key, [registration_id])

                    if notification_key != '':
                        chat_room.notification_key = notification_key

            # 초대 및 방 개설 됨을 알려준다.
            group_notification(room_id, notification_key, 'system', '', participants)

            chat_room.is_single = False
            chat_room.save()

            str_len = len(invite_user)
            if str_len > 0:
                invite_user = invite_user[:str_len-2]
            text = '%s님이 %s님을 초대하였습니다.' %(my, invite_user)
            # eng_text = '%s invited %s.' %(my, invite_user)

            send_group_message(room_id, 'system', 'invite', chat_room, text)

            cache.set("room_nu:" + room_id, participants)

        chat_user_list = chat_room.chat_user.exclude(Q(user__username=my) | Q(room_exit=True))
        friend_list = list()
        for chat_user in chat_user_list:
            if str(chat_user.user) == "ceslea":
                continue

            user = chat_user.user
            friend_list.append(user.username)

        friend_list.sort()
        response['participants'] = friend_list

    except User.DoesNotExist:
        response['result'] = 'False'
    except ChatRoom.DoesNotExist:
        response['result'] = 'False'
    except KeyError:
        response['result'] = 'False'

    return JsonResponse(response, safe=False)
Esempio n. 4
0
    def new_message(self, data):
        content = {'command': 'new_message'}
        try:
            username = self.scope['user']
            room_id = self.scope['room_id']

            text = data['text']
            lan = data['lan']

            chat_room = ChatRoom.objects.get(id=room_id)
            message = Message.objects.create(author=username,
                                             chat_room=chat_room,
                                             content=text)
            content['message'] = self.message_to_json(message)

            if chat_room.bot_state == 'MAX' or chat_room.bot_state == 'SEMI':

                # intent
                if lan == 'ko-KR':
                    client = create_client("155.230.24.108", 50069)
                    client.send({
                        'roomState': 0,
                        'roomId': 999,
                        'sentence': 'null'
                    })
                    result = client.send({
                        'roomState': 2,
                        'roomId': 999,
                        'sentence': text
                    })

                    if result is None or str(result) == '':
                        content['message']['intent'] = '0'
                    else:
                        textStr = str(result)
                        textStr = textStr.replace("{", "")
                        textStr = textStr.replace("}", "")
                        textStr = textStr.replace("\'", "")
                        textStr = textStr.replace("\"", "")
                        textArr = textStr.split(':')
                        if len(textArr) > 1:
                            textStr = textArr[1].replace(" ", "")
                        else:
                            textStr = '0'

                        content['message']['intent'] = str(textStr)

                        if str(textStr) == '1':
                            content['message'][
                                'intentdata'] = '제가 그 지도 정보를 보여드릴까요? 어느 지역을 보여드릴까요? 지역을 입력해주세요.'
                        elif str(textStr) == '2':
                            content['message'][
                                'intentdata'] = '제가 입력하신 동영상을 보여드릴까요? 유튜브에서 어떤 동영상을 보여드릴까요? 키워드를 말씀해주세요.'
                        elif str(textStr) == '3':
                            content['message'][
                                'intentdata'] = '제가 그 이메일 정보를 보여드릴까요? 이메일을 누구에게 보내시겠어요? 보내실 이메일 주소를 입력해주세요.'
                        elif str(textStr) == '4':
                            content['message'][
                                'intentdata'] = '제가 캘린더를 보여드릴까요? 누구의 캘린더를 보여드릴까요?'
                        elif str(textStr) == '5':
                            content['message'][
                                'intentdata'] = '제가 주소록 정보를 드릴까요? 누구의 연락처를 보여드릴까요? 이름을 입력해주세요.'
                        elif str(textStr) == '6':
                            content['message'][
                                'intentdata'] = '제가 위키피디아를 보여드릴까요? 위키피디아에서 어떤 것을 검색해드릴까요? 키워드를 입력해주세요.'
                        elif str(textStr) == '7':
                            content['message'][
                                'intentdata'] = '제가 그 지역의 날씨정보를 보여드릴까요? 어디 지역의 날씨를 보여드릴까요?'
                        elif str(textStr) == '8':
                            content['message'][
                                'intentdata'] = '제가 그 호텔에 대한 정보를 보여드릴까요? 어디 지역의 호텔을 찾아드릴까요? 위치를 말씀해주세요.'
                        elif str(textStr) == '9':
                            content['message'][
                                'intentdata'] = '제가 항공 정보 사이트를 띄워드릴까요? 어디로 떠나고 싶으세요? 여행하고 싶으신 지역의 공항 위치를 말씀해주세요.'
                        elif str(textStr) == '10':
                            content['message'][
                                'intentdata'] = '제가 아마존 쇼핑 정보를 보여드릴까요? 아마존에서 무엇을 구매하고 싶으신가요? 구매하고 싶으신 키워드를 입력해주세요.'
                        elif str(textStr) == '11':
                            content['message'][
                                'intentdata'] = '제가 입력하신 식당에 대한 정보를 보여드릴까요? 어떤 음식을 먹고 싶으신가요? 키워드를 입력해주세요.'
                        elif str(textStr) == '12':
                            content['message'][
                                'intentdata'] = '제가 그 질의응답을 만들어봐도 될까요? 어떤 질문을 하고 싶으신가요? 키워드를 입력해주시면 답변해드리겠습니다.'
                        elif str(textStr) == '13':
                            content['message'][
                                'intentdata'] = '제가 문(door)을 보여드릴까요? 어떤 종류의 문을 원하시나요? 키워드를 입력해주세요.'
                        elif str(textStr) == '14':
                            content['message'][
                                'intentdata'] = '제가 그 신문 기사를 보여드릴까요? 신문 주제로 어떤것을 찾으시나요? 주제를 입력해주세요.'
                        elif str(textStr) == '15':
                            content['message'][
                                'intentdata'] = '제가 그 영화 정보를 보여드릴까요? 어떤 영화를 보고 싶으세요? 영화 제목을 입력해주세요.'
                        elif str(textStr) == '16':
                            content['message'][
                                'intentdata'] = '제가 그 주식에 대한 정보를 보여드릴까요? 어떤 회사의 주식을 찾고 계신가요? 주식 종목을 입력해주세요.'
                        elif str(textStr) == '17':
                            content['message'][
                                'intentdata'] = '제가 입력하신 문장에 대한 요약을 해드릴까요? 대화 요약 서비스로 안내해드릴까요?'
                        elif str(textStr) == '18':
                            content['message'][
                                'intentdata'] = '제가 격려해드려도 될까요? 격려에 도움이 되는 웹페이지를 보여드릴까요?'
                        elif str(textStr) == '19':
                            content['message'][
                                'intentdata'] = '제가 원하시는 스포츠를 보여드릴까요? 어떤 주제의 스포츠가 보고 싶으신가요? 키워드를 입력해주세요.'
                        elif str(textStr) == '20':
                            content['message'][
                                'intentdata'] = '제가 그 책 정보를 보여드릴까요? 어떤 주제의 책을 보여드릴까요? 주제를 입력해주세요.'
                        else:
                            content['message']['intentdata'] = ''

                elif lan == 'en-US':
                    client = create_client("155.230.24.108", 50059)
                    client.send({
                        'roomState': 0,
                        'roomId': 999,
                        'sentence': 'null'
                    })
                    result = client.send({
                        'roomState': 2,
                        'roomId': 999,
                        'sentence': text
                    })

                    if result is None or str(result) == '':
                        content['message']['intent'] = '0'
                    else:
                        textStr = str(result)
                        textStr = textStr.replace("{", "")
                        textStr = textStr.replace("}", "")
                        textStr = textStr.replace("\'", "")
                        textStr = textStr.replace("\"", "")
                        textArr = textStr.split(':')
                        if len(textArr) > 1:
                            textStr = textArr[1].replace(" ", "")
                        else:
                            textStr = '0'

                        content['message']['intent'] = str(textStr)

                        if str(textStr) == '1':
                            content['message'][
                                'intentdata'] = 'Can I show you the map information? Which area would you like to show you? Please enter a region.'
                        elif str(textStr) == '2':
                            content['message'][
                                'intentdata'] = 'Shall I show you the video you entered? What videos do you want to show on YouTube? Please tell me your keywords.'
                        elif str(textStr) == '3':
                            content['message'][
                                'intentdata'] = 'Can I show you the email information? Who would you like to send the email to? Please enter the email address to send.'
                        elif str(textStr) == '4':
                            content['message'][
                                'intentdata'] = 'Shall I show you the calendar? Whose calendar can I show you?'
                        elif str(textStr) == '5':
                            content['message'][
                                'intentdata'] = 'Can I give you the contact information? Whose contact can I show you? Input your name, please.'
                        elif str(textStr) == '6':
                            content['message'][
                                'intentdata'] = 'Shall I show you Wikipedia? What would you like to search for on Wikipedia? Please enter a keyword.'
                        elif str(textStr) == '7':
                            content['message'][
                                'intentdata'] = 'Can I show you the weather information for that area? Where can I show you the local weather?'
                        elif str(textStr) == '8':
                            content['message'][
                                'intentdata'] = 'Can I show you some information about the hotel? Where can I find a hotel in the area? Please tell me the location.'
                        elif str(textStr) == '9':
                            content['message'][
                                'intentdata'] = 'Shall I launch an airline information site? Where do you want to go? Please tell me the location of the airport in the area you want to travel to.'
                        elif str(textStr) == '10':
                            content['message'][
                                'intentdata'] = 'Can I show you Amazon shopping information? What would you like to buy on Amazon? Please enter the keyword you want to purchase.'
                        elif str(textStr) == '11':
                            content['message'][
                                'intentdata'] = 'Would you like to show you the information about the restaurant you entered? What kind of food would you like to eat? Please enter a keyword.'
                        elif str(textStr) == '12':
                            content['message'][
                                'intentdata'] = 'Can I make the question and answer? What question do you want to ask? Please enter your keywords and I will answer you.'
                        elif str(textStr) == '13':
                            content['message'][
                                'intentdata'] = 'Shall I show you the door? What kind of door do you want? Please enter a keyword.'
                        elif str(textStr) == '14':
                            content['message'][
                                'intentdata'] = 'Shall I show you the newspaper article? What are you looking for on a newspaper topic? Please enter a subject.'
                        elif str(textStr) == '15':
                            content['message'][
                                'intentdata'] = 'Can I show you the movie information? Which movie would you like to see? Please enter the movie title.'
                        elif str(textStr) == '16':
                            content['message'][
                                'intentdata'] = 'Can I show you some information about the stock? What company are you looking for? Please enter the stock item.'
                        elif str(textStr) == '17':
                            content['message'][
                                'intentdata'] = 'May I give you a summary of the sentence you entered? Can I guide you to the conversation summary service?'
                        elif str(textStr) == '18':
                            content['message'][
                                'intentdata'] = 'Can I encourage you? Would you like to show you a web page to help you encourage?'
                        elif str(textStr) == '19':
                            content['message'][
                                'intentdata'] = 'Shall I show you the sport you want? What kind of sports would you like to see? Please enter a keyword.'
                        elif str(textStr) == '20':
                            content['message'][
                                'intentdata'] = 'Can I show you the information for that book? What topics would you like to show you? Please enter a subject.'
                        else:
                            content['message']['intentdata'] = ''

                if lan == 'ko-KR':
                    client = create_client("155.230.24.108", 50068)
                    client.send({
                        'roomState': 0,
                        'roomId': 999,
                        'sentence': 'null'
                    })
                    result = client.send({
                        'roomState': 2,
                        'roomId': 999,
                        'sentence': text
                    })
                elif lan == 'en-US':
                    client = create_client("155.230.24.108", 50058)
                    client.send({
                        'roomState': 0,
                        'roomId': 999,
                        'sentence': 'null'
                    })
                    result = client.send({
                        'roomState': 2,
                        'roomId': 999,
                        'sentence': text
                    })
                else:
                    result = ''

                if result is None or str(result) == '':
                    content['message']['emotion'] = ''
                else:
                    ret = str(result)
                    ret = ret.replace("\'", "\"")
                    json_data = json.loads(ret)
                    ret = json_data['output']
                    content['message']['emotion'] = str(ret)
            else:
                content['message']['emotion'] = ''
                content['message']['intent'] = '0'

            cache.set("room_nm:" + room_id, (username, message.id))
            self.send_chat_message(content, room_id)
            group_notification(room_id, chat_room.notification_key, username,
                               text)

        except ChatUser.DoesNotExist:
            content['result'] = 'Fail new messages.(chat user)'
            self.send_message(content)
        except ChatRoom.DoesNotExist:
            content['result'] = 'Fail new messages. (chat room)'
            self.send_message(content)
        except User.DoesNotExist:
            content['result'] = 'Fail new messages. (user)'
            self.send_message(content)
        except KeyError:
            content['result'] = 'Fail new messages. (key error)'
            self.send_message(content)
Esempio n. 5
0
def room_join(request):
    response = dict()
    # 룸생성과 동시에 해당 룸에는 세실리아가 만들어진다.
    try:
        json_data = json.loads(request.body.decode('UTF8'))

        my_username = json_data['my']
        participants = json_data['participants']
        room_id = json_data['room_id']

        if room_id  == 'me':
            len_participants = len(participants)
            # 1:1 대화 확인용
                
            chat_room = ChatRoom.objects.create(is_single=False)

            # 1:1 채팅 및 단체톡 생성
            room_id = str(chat_room.id)

            ceslea, _ = User.objects.get_or_create(username='******')
            ChatUser.objects.create(user=ceslea, chat_room=chat_room)

            registration_ids = list()
            user = User.objects.get(username=my_username)
            registration_ids.append(user.firebase_id)
            ChatUser.objects.create(user=user, chat_room=chat_room)

            notification_key = create_notification_group(room_id, registration_ids)
            chat_room.notification_key = notification_key
            chat_room.save()

            # 초대 및 방 개설 됨을 알려준다.
            response['room_id'] = room_id
            
            participants_info = list()
            user_dict = dict()
            user_dict['id'] = my_username
            user = User.objects.get(username=my_username)
            user_thumbnail_url = str(user.user_thumbnail)
            if user_thumbnail_url:
                user_dict['profile_image'] = settings.SERVER_MEDIA_URL + user_thumbnail_url
            else:
                user_dict['profile_image'] = settings.DEFULT_USER_THUMBNAIL_URL

            participants_info.append(user_dict)

            response['room_name'] = my_username
            # response['room_name'] = user.is_name

            def extract_time(user_dict):
                return user_dict['id']

            participants_info.sort(key=extract_time)
            response['participants'] = participants_info
            response['mode'] = chat_room.bot_state

            cache.set("room_cm:" + room_id, chat_room.bot_state.lower())

        else :
            len_participants = len(participants)
            if not room_id:
                # 1:1 대화 확인용
                if len_participants == 1:
                    try:
                        # 만약 방을 만들 때, 1:1 방이 존재 한다면
                        # 더이상 진행하지 않고, 해당 방에 정보를 보내준다.
                        my_chat_list = ChatUser.objects.filter(user__username=my_username)
                        for my_chat in my_chat_list.iterator():
                            my_chat_room = my_chat.chat_room
                            is_single = my_chat_room.is_single

                            if is_single:
                                is_user = my_chat_room.chat_user.filter(user__username=participants[0]).count()
                                if 1 == is_user:
                                    room_id = str(my_chat_room.id)
                                    response['room_name'] = participants[0]
                                    response['room_id'] = room_id

                                    response['participants'] = [{'id': participants[0]}]
                                    user = User.objects.get(username=participants[0])
                                    user_thumbnail_url = str(user.user_thumbnail)
                                    if user_thumbnail_url:
                                        response['participants'][0]['profile_image'] = settings.SERVER_MEDIA_URL + user_thumbnail_url
                                    else:
                                        response['participants'][0]['profile_image'] = settings.DEFULT_USER_THUMBNAIL_URL

                                    if my_chat.room_exit:
                                        my_chat.room_exit = False
                                        my_chat.room_join()

                                        registration_id = my_chat.user.firebase_id
                                        notification_key = add_notification_group(room_id, my_chat_room.notification_key, [registration_id])

                                        if notification_key != '':
                                            my_chat_room.notification_key = notification_key
                                            my_chat_room.save()

                                    cache.set("room_cm:" + room_id, my_chat_room.bot_state.lower())

                                    return JsonResponse(response, safe=False)
                                
                    except ChatUser.DoesNotExist:
                        response['room_id'] = None
                        return JsonResponse(response, safe=False)

                    chat_room = ChatRoom.objects.create(is_single=True)
                else:
                    chat_room = ChatRoom.objects.create(is_single=False)

                # 1:1 채팅 및 단체톡 생성
                room_id = str(chat_room.id)

                ceslea, _ = User.objects.get_or_create(username='******')
                ChatUser.objects.create(user=ceslea, chat_room=chat_room)

                registration_ids = list()
                for i, participant in enumerate(participants + [my_username]):
                    user = User.objects.get(username=participant)
                    registration_ids.append(user.firebase_id)
                    ChatUser.objects.create(user=user, chat_room=chat_room)

                notification_key = create_notification_group(room_id, registration_ids)
                chat_room.notification_key = notification_key
                chat_room.save()

                # 초대 및 방 개설 됨을 알려준다.
                group_notification(room_id, notification_key, 'system', '', participants)
                response['room_id'] = room_id
            else:
                chat_room = ChatRoom.objects.get(id=room_id)
                response['room_id'] = room_id

            str_participant = str()
            len_participant = len(participants)
            participants_info = list()
            for i, participant in enumerate(participants):
                user_dict = dict()
                user_dict['id'] = participant

                user = User.objects.get(username=participant)
                user_thumbnail_url = str(user.user_thumbnail)
                if user_thumbnail_url:
                    user_dict['profile_image'] = settings.SERVER_MEDIA_URL + user_thumbnail_url
                else:
                    user_dict['profile_image'] = settings.DEFULT_USER_THUMBNAIL_URL

                participants_info.append(user_dict)

                len_str_participant = len(str_participant)
                if len_str_participant + len(participant) >= 50:
                    if i == 0:
                        str_participant = participant
                    else:
                        continue
                elif i == len_participant - 1:
                    str_participant += participant
                else:
                    str_participant += participant + ', '

            if len_participants == 1:
                response['room_name'] = participants[0]
            else:
                if chat_room.is_single:
                    room_user = chat_room.chat_user.exclude(Q(user__username=my_username) |
                                                            Q(user__username='******')).first()
                    response['room_name'] = str(room_user.user)
                else:
                    response['room_name'] = str_participant

            def extract_time(user_dict):
                return user_dict['id']

            participants_info.sort(key=extract_time)
            response['participants'] = participants_info
            response['mode'] = chat_room.bot_state

            cache.set("room_cm:" + room_id, chat_room.bot_state.lower())

    except IntegrityError:
        response['room_id'] = None
    except User.DoesNotExist:
        response['room_id'] = None
    except KeyError:
        response['room_id'] = None

    return JsonResponse(response, safe=False)