Example #1
0
    def handle(self, *args, **options):
        task_name = self.get_task_name(options)

        try:
            start_time = time.time()
            self.run_task(options)

            runtime = round(time.time() - start_time, 2)

            # Monitor duration of the task
            logger.info("Task " + task_name + " executed in " + str(runtime) +
                        "s",
                        extra={
                            'task': task_name,
                            'success': True,
                            'runtime': runtime
                        })

        except Exception as error:
            if not settings.DEBUG:
                # Say if PROD or PRE-PROD and report to sentry a problem has been detected
                client.user_context({'prod_status': settings.PROD_STATUS})
                client.captureException()

                # Log the error
                logger.error("Task " + task_name + " failed",
                             extra={
                                 'task': task_name,
                                 'success': False
                             })
            else:
                raise error
Example #2
0
    def send_fb_message(self, url, message):
        if self.client_send:
            try:
                response = requests.post(url, headers={"Content-Type": "application/json"}, data=message)

                if response.status_code != 200:
                    logger.warning("Facebook message sending error", extra={
                        'url': url,
                        'content': str(response.content),
                        'response_code': response.status_code
                    })
                else:
                    logger.info("Facebook message sending success", extra={
                        'url': url,
                        'content': str(response.content),
                        'response_code': response.status_code
                    })

            except Timeout:
                logger.error("Facebook message sending timed out", extra={
                    'url': url,
                    'data': message
                })
            except:
                logger.error("Facebook message sending failed", extra={
                    'url': url,
                    'data': message
                })

        else:
            self.messages.append(message)
def add_image_for_highlight(highlight):
    img_link = highlight.img_link

    # No need to upload in debug mode
    if settings.DEBUG:
        return

    # No need to upload default images
    if _is_default_highlight_img(img_link):
        return

    # No need to upload if image already exists
    if HighlightImage.objects.filter(match_id=highlight.id, img_link=img_link):
        return

    # Upload the image to the cloud
    try:
        img_uploaded_link = uploader.upload_image(img_link)

        logger.info("Image added for img_link: " + img_link, extra={
            'img_link': img_link,
            'img_uploaded_link': img_uploaded_link
        })

    except:
        logger.error("Image failed uploading: " + img_link)
        return

    HighlightImage.objects.update_or_create(match_id=highlight.id,
                                            img_link=img_link,
                                            img_uploaded_link=img_uploaded_link,
                                            source=highlight.source)
Example #4
0
def fetch_highlights(site):
    highlights = fetcher.fetch(site)

    # Add new highlights
    for highlight in highlights:

        if latest_highlight_manager.has_highlight(highlight):
            # Skip if highlight already in database
            continue

        # Determine if highlight with teams inverted exists (Barcelona - Arsenal instead of Arsenal - Barcelona)
        inverted_highlights = latest_highlight_manager.get_inverted_teams_highlights(
            highlight)

        if len(inverted_highlights) > 1 or any(
            [h.sent for h in inverted_highlights]):
            highlight.swap_home_side()

        # Mark as sent if a similar highlight (same match, different provider) is in database and has already been sent
        sent = False

        if latest_highlight_manager.get_same_highlights_sent(highlight):
            sent = True

        new_highlight = latest_highlight_manager.add_highlight(highlight,
                                                               sent=sent)

        # No highlight has been created
        if not new_highlight:
            continue

        logger.info("Highlight added: " + new_highlight.link,
                    extra={
                        'link': new_highlight.link,
                        'img_link': new_highlight.img_link,
                        'category': new_highlight.category.name,
                        'time_since_added': new_highlight.time_since_added,
                        'team1': new_highlight.team1.name,
                        'score1': new_highlight.score1,
                        'team2': new_highlight.team2.name,
                        'score2': new_highlight.score2,
                        'source': new_highlight.source,
                        'goal_data': new_highlight.goal_data,
                    })

        # Add the image for this new inserted highlight
        highlight_image_manager.add_image_for_highlight(new_highlight)

        # Set to all highlights the best image
        same_highlights = latest_highlight_manager.get_same_highlights(
            new_highlight)
        best_image_link = highlight_image_manager.fetch_best_image_for_highlight(
            new_highlight)

        for h in same_highlights:
            latest_highlight_manager.set_img_link(h, best_image_link)
def get_video_info(link):

    # Make sure video is from matchat.online or videostreamlet.net
    if not providers.MATCHAT_ONLINE in link \
            and not providers.CONTENT_VENTURES in link \
            and not providers.VIDEO_STREAMLET in link \
            and not providers.VEUCLIPS in link:
        return None

    # Disable temporarily matchat.online as not working anymore
    if providers.MATCHAT_ONLINE in link or providers.CONTENT_VENTURES in link:
        return None

    try:
        page = requests.get(link)

        regex = "settings.bitrates = {hls:\"(.*?)\""
        streaming_link_search_result = re.compile(regex, 0).search(page.text)

        streaming_link = 'https://' + streaming_link_search_result.groups(
        )[0].replace('//', '').replace('0.m3u8', '360p.m3u8')

        text = requests.get(streaming_link).text

        regex = "#EXTINF:(.*?),"
        durations_search_result = re.findall(regex, text)

        duration = int(sum([float(d) for d in durations_search_result]))

        info = {'duration': duration, 'video_url': None}

        scrapping_status_manager.update_scrapping_status('m3u8', True)
        logger.info('matchat.online SUCCESS | url: ' + link + ' | duration: ' +
                    str(duration))

        return info

    except:
        client.captureException()
        logger.error("Failed to fetch info for link {}".format(link))

        try:
            if ressource_checker.check(link):
                scrapping_status_manager.update_scrapping_status('m3u8', False)
                logger.error('matchat.online FAILURE | url: ' + link)

                return {
                    'duration':
                    0,  # Allow for retries if link is valid but scrapping not working
                    'video_url': None
                }

            else:
                return None

        except:
            client.captureException()
            logger.error(
                "Failed to fetch info for link {} and resource check failed".
                format(link))

            return {
                'duration':
                0,  # Allow for retries if link is valid but scrapping not working
                'video_url': None
            }
Example #6
0
def send_most_recent_highlights():
    # Set incomplete infos
    for h in latest_highlight_manager.get_recent_highlights_with_incomplete_infos(
    ):
        reference_highlight = latest_highlight_manager.get_same_highlight_from_sources(
            h, sources.get_sources_with_complete_data_in_order_of_priority())

        if not reference_highlight:
            continue

        latest_highlight_manager.set_goal_data(h,
                                               reference_highlight.goal_data)
        latest_highlight_manager.set_score(h, reference_highlight.score1,
                                           reference_highlight.score2)

    # Send highlights not already sent
    not_sent_highlights = latest_highlight_manager.get_valid_not_sent_highlights(
        AVAILABLE_SOURCES)

    time_now = datetime.now()

    for highlight in not_sent_highlights:

        if _should_send_highlight(time_now, highlight):

            # prevent sending 2 times same highlight with inverted home and away teams
            inverted_highlights = latest_highlight_manager.get_inverted_teams_highlights(
                highlight)

            if any([h.sent for h in inverted_highlights]):
                new_id = inverted_highlights[0].id
                latest_highlight_manager.swap_home_side(highlight, new_id)

            # prevent from sending a highlight if find the same already sent
            if latest_highlight_manager.get_same_highlights_sent(highlight):
                latest_highlight_manager.set_sent(highlight)
                continue

            # Set highlights for same match to sent
            similar_highlights = latest_highlight_manager.get_similar_highlights(
                highlight, not_sent_highlights)

            for h in similar_highlights:
                latest_highlight_manager.set_sent(h)

            logger.info("Highlight preparing to be sent: " +
                        highlight.get_match_name(),
                        extra={
                            'match': highlight.get_match_name(),
                        })

            # Send highlight to users
            _send_highlight_to_users(highlight)

            logger.info("Highlight sent: " + highlight.get_match_name(),
                        extra={
                            'match': highlight.get_match_name(),
                        })

    # Delete old highlights
    # FIXME: try to find a way to keep old highlights
    all_highlights = latest_highlight_manager.get_all_highlights()

    for highlight in all_highlights:
        time_since_added = highlight.get_parsed_time_since_added()

        # Old highlight, delete
        if (time_now - time_since_added) > timedelta(days=60):
            latest_highlight_manager.delete_highlight(highlight)
Example #7
0
    def post(self, request, *args, **kwargs):

        # Converts the text payload into a python dictionary
        incoming_message = json.loads(request.body.decode('utf-8'))

        logger.info("Message received", extra={
            'incoming_message': incoming_message
        })

        response_msg = []

        for entry in incoming_message['entry']:

            for message in entry['messaging']:

                sender_id = message['sender'].get('id')
                HighlightsBotView.LATEST_SENDER_ID = sender_id

                user = user_manager.get_user(sender_id)
                user_manager.increment_user_message_count(sender_id)

                logger.log_for_user("Message received", sender_id, extra={
                    'full_msg': message
                })

                # Events
                if 'message' in message:

                    text = message['message'].get('text') if message['message'].get('text') else ''
                    message = language.remove_accents(text.lower())

                    logger.log_for_user("Text message received", sender_id, extra={
                        'full_msg': message,
                        'msg_type': 'message'
                    })

                    # Do not respond in those cases
                    if 'no' == message or 'nothing' == message or 'ok' == message or 'shut up' in message or message == '':
                        logger.log_for_user('No response', sender_id)
                        continue

                    # Send typing event - so user is aware received message
                    sender.send_typing(sender_id)

                    # Special replies
                    # TODO: remove at some point
                    if message == EMOJI_TROPHY + ' add nations league':
                        logger.log_for_user("ADD NATIONS LEAGUE", sender_id)

                        context_manager.update_context(sender_id, ContextType.SUBSCRIPTIONS_SETTING)

                        registration_competition_manager.add_competition(sender_id, 'nations league')

                        response_msg.append(
                            manager_response.send_registration_added_message(sender_id, 'Nations League')
                        )

                        response_msg.append(
                            view_message_helper.send_subscriptions_settings(sender_id)
                        )

                    # Special replies
                    # TODO: remove at some point
                    elif message == EMOJI_CROSS + ' no thanks':
                        logger.log_for_user("NO THANKS NATIONS LEAGUE", sender_id)

                        response_msg.append(
                            manager_response.send_facebook_message(
                                sender_id, manager_response.create_message("Another time! " + EMOJI_SMILE))
                        )

                    # Cancel quick reply
                    elif 'cancel' in message:
                        logger.log_for_user("CANCEL", sender_id)

                        context_manager.set_default_context(sender_id)
                        response_msg.append(
                            manager_response.send_cancel_message(sender_id)
                        )

                    # Done quick reply
                    elif 'done' in message:
                        logger.log_for_user("DONE", sender_id)

                        context_manager.set_default_context(sender_id)
                        response_msg.append(
                            manager_response.send_done_message(sender_id)
                        )

                    # HELP
                    elif 'help' in message:
                        logger.log_for_user("HELP", sender_id)

                        context_manager.set_default_context(sender_id)
                        response_msg.append(
                            manager_response.send_help_message(sender_id)
                        )

                    elif accepted_messages(message, ['thank you', 'thanks', 'cheers', 'merci', 'cimer',
                                                     'good job', 'good bot']):
                        logger.log_for_user("THANK YOU MESSAGE", sender_id)

                        context_manager.set_default_context(sender_id)
                        response_msg.append(
                            manager_response.send_thank_you_message(sender_id)
                        )

                    # TUTORIAL CONTEXT
                    elif context_manager.is_tutorial_context(sender_id):
                        logger.log_for_user("TUTORIAL ADD REGISTRATION", sender_id, extra={
                            'action': 'tutorial'
                        })

                        message = message

                        # Check if team exists, make a recommendation if no teams
                        if football_team_manager.has_football_team(message):
                            # Does team exist check

                            registration_team_manager.add_team(sender_id, message)

                            response_msg.append(
                                manager_highlights.send_tutorial_message(sender_id, text)
                            )

                            response_msg.append(
                                manager_highlights.send_highlights_for_team_or_competition(sender_id,
                                                                                           message,
                                                                                           highlight_count=1,
                                                                                           default_teams=['psg', 'barcelona', 'real madrid', 'spain', 'france'])
                            )

                            response_msg.append(
                                view_message_helper.send_subscriptions_settings(sender_id)
                            )

                        elif football_competition_manager.has_football_competition(message):
                            # Does competition exist check

                            registration_competition_manager.add_competition(sender_id, message)

                            response_msg.append(
                                manager_highlights.send_tutorial_message(sender_id, text)
                            )

                            response_msg.append(
                                manager_highlights.send_highlights_for_team_or_competition(sender_id,
                                                                                           message,
                                                                                           highlight_count=1,
                                                                                           default_teams=['psg', 'barcelona', 'real madrid', 'spain', 'france'])
                            )

                            response_msg.append(
                                view_message_helper.send_subscriptions_settings(sender_id)
                            )

                        elif football_team_manager.similar_football_team_names(message) \
                            + football_competition_manager.similar_football_competition_names(message):
                            # Registration recommendation

                            # Register wrong search
                            new_football_registration_manager.add_football_registration(message, 'user', user)

                            recommendations = football_team_manager.similar_football_team_names(message) \
                                              + football_competition_manager.similar_football_competition_names(message)

                            # Format recommendation names
                            recommendations = [recommendation.title() for recommendation in recommendations]

                            response_msg.append(
                                manager_highlights.send_recommended_team_or_competition_tutorial_message(sender_id, recommendations)
                            )

                        else:
                            # No team or recommendation found

                            # Register wrong search
                            new_football_registration_manager.add_football_registration(message, 'user', user)

                            response_msg.append(
                                manager_highlights.send_team_not_found_tutorial_message(sender_id)
                            )

                    # SEE RESULT CHANGE SETTING
                    elif context_manager.is_see_result_setting_context(sender_id):
                        logger.log_for_user("SEE RESULT CHANGE SETTING", sender_id)

                        if text in [SHOW_BUTTON, HIDE_BUTTON]:
                            user_manager.set_see_result_setting(sender_id, text == SHOW_BUTTON)

                            response_msg.append(
                                manager_response.send_setting_changed(sender_id)
                            )

                            context_manager.set_default_context(sender_id)

                        else:
                            response_msg.append(
                                manager_response.send_setting_invalid(sender_id)
                            )

                            response_msg.append(
                                manager_response.send_see_result_setting(sender_id)
                            )

                    # ADD REGISTRATION SETTING
                    elif accepted_messages(message, ['add']) and context_manager.is_notifications_setting_context(sender_id):
                        logger.log_for_user("ADD REGISTRATION SETTING", sender_id)

                        context_manager.update_context(sender_id, ContextType.ADDING_REGISTRATION)

                        response_msg.append(
                            manager_response.send_add_registration_message(sender_id)
                        )

                    # REMOVE REGISTRATION SETTING
                    elif accepted_messages(message, ['remove']) and context_manager.is_notifications_setting_context(sender_id):
                        logger.log_for_user("REMOVE REGISTRATION SETTING", sender_id)

                        context_manager.update_context(sender_id, ContextType.REMOVE_REGISTRATION)

                        registrations = view_message_helper.get_registrations_formatted(sender_id)

                        response_msg.append(
                            manager_response.send_delete_registration_message(sender_id, registrations)
                        )

                    # ADDING REGISTRATION
                    elif context_manager.is_adding_registration_context(sender_id) \
                            or context_manager.is_notifications_setting_context(sender_id):
                        logger.log_for_user("ADDING REGISTRATION", sender_id)

                        message = message

                        # Check if registration exists, make a recommendation if no registration
                        if message == OTHER_BUTTON.lower() or message == TRY_AGAIN_BUTTON.lower():
                            context_manager.update_context(sender_id, ContextType.ADDING_REGISTRATION)

                            response_msg.append(
                                manager_response.send_add_registration_message(sender_id)
                            )

                        elif accepted_messages(message, [I_M_GOOD_BUTTON.lower(), 'stop', 'done', 'good']):
                            response_msg.append(
                                view_message_helper.send_subscriptions_settings(sender_id)
                            )

                        elif football_team_manager.has_football_team(message):
                            # Does team exist check
                            registration_team_manager.add_team(sender_id, message)

                            response_msg.append(
                                manager_response.send_registration_added_message(sender_id, text)
                            )

                            response_msg.append(
                                manager_response.send_add_registration_message(sender_id)
                            )

                        elif football_competition_manager.has_football_competition(message):
                            # Does competition exist check
                            registration_competition_manager.add_competition(sender_id, message)

                            response_msg.append(
                                manager_response.send_registration_added_message(sender_id, text)
                            )

                            response_msg.append(
                                manager_response.send_add_registration_message(sender_id)
                            )

                        elif football_team_manager.similar_football_team_names(message) or \
                                football_competition_manager.similar_football_competition_names(message):
                            # Registration recommendation
                            context_manager.update_context(sender_id, ContextType.ADDING_REGISTRATION)

                            # Register wrong search
                            new_football_registration_manager.add_football_registration(message, 'user', user)

                            recommendations = football_team_manager.similar_football_team_names(message)\
                                              + football_competition_manager.similar_football_competition_names(message)

                            # Format recommendation names
                            recommendations = [recommendation.title() for recommendation in recommendations]

                            response_msg.append(
                                manager_response.send_recommended_registration_message(sender_id, recommendations)
                            )

                        else:
                            # No registration recommendation found
                            context_manager.update_context(sender_id, ContextType.ADDING_REGISTRATION)

                            # Register wrong search
                            new_football_registration_manager.add_football_registration(message, 'user', user)

                            response_msg.append(
                                manager_response.send_registration_not_found_message(sender_id)
                            )

                    # REMOVING REGISTRATION
                    elif context_manager.is_deleting_team_context(sender_id):
                        logger.log_for_user("REMOVING REGISTRATION", sender_id)
                        registration_to_delete = message.lower()

                        if football_team_manager.has_football_team(registration_to_delete):
                            # Delete team
                            registration_team_manager.delete_team(sender_id, registration_to_delete)

                            response_msg.append(
                                manager_response.send_registration_deleted_message(sender_id, registration_to_delete.title())
                            )

                            response_msg.append(
                                view_message_helper.send_subscriptions_settings(sender_id)
                            )

                        elif football_competition_manager.has_football_competition(registration_to_delete):
                            # Delete competition
                            registration_competition_manager.delete_competition(sender_id, registration_to_delete)

                            response_msg.append(
                                manager_response.send_registration_deleted_message(sender_id, registration_to_delete.title())
                            )

                            response_msg.append(
                                view_message_helper.send_subscriptions_settings(sender_id)
                            )

                        else:
                            # Registration to delete not found
                            context_manager.update_context(sender_id, ContextType.REMOVE_REGISTRATION)

                            registrations = view_message_helper.get_registrations_formatted(sender_id)

                            response_msg.append(
                                manager_response.send_registration_to_delete_not_found_message(sender_id, registrations)
                            )

                    # SUBSCRIPTION SETTING
                    elif accepted_messages(message, ['subscription', 'teams', 'subscribe', 'notification', 'add', 'remove']):
                        logger.log_for_user("SUBSCRIPTION SETTING", sender_id, extra={
                            'action': 'subscriptions'
                        })

                        response_msg.append(
                            view_message_helper.send_subscriptions_settings(sender_id)
                        )

                    # SEE RESULT SETTING
                    elif accepted_messages(message, ['settings', 'see result setting', 'spoiler', 'show result', 'hide result',
                                                     'show score', 'hide score', 'no score']):
                        logger.log_for_user("SEE RESULT SETTING", sender_id, extra={
                            'action': 'settings'
                        })

                        response_msg.append(
                            view_message_helper.send_send_see_result_settings(sender_id)
                        )

                    # SHARE
                    elif accepted_messages(message, ['share', 'send to a friend']):
                        logger.log_for_user("SHARE", sender_id, extra={
                            'action': 'share'
                        })

                        response_msg.append(
                            manager_share.send_share_introduction_message(sender_id)
                        )
                        response_msg.append(
                            manager_share.send_share_message(sender_id)
                        )

                    # SEARCH HIGHLIGHT OPTION
                    elif accepted_messages(message, ['search', 'search again']):
                        logger.log_for_user("SEARCH HIGHLIGHTS", sender_id, extra={
                            'action': 'search'
                        })

                        response_msg.append(
                            view_message_helper.search_highlights(sender_id)
                        )

                    # SEARCHING HIGHLIGHTS
                    elif context_manager.is_searching_highlights_context(sender_id):
                        logger.log_for_user("SEARCHING HIGHLIGHTS", sender_id, extra={
                            'action': 'searching'
                        })

                        team_or_competition = message

                        if football_team_manager.has_football_team(team_or_competition) \
                                or football_competition_manager.has_football_competition(team_or_competition):
                            # Team or competition found

                            response_msg.append(
                                manager_highlights.send_highlights_for_team_or_competition(sender_id, team_or_competition)
                            )

                        elif football_team_manager.similar_football_team_names(team_or_competition) \
                                + football_competition_manager.similar_football_competition_names(team_or_competition):
                            # Recommendation found

                            # Register wrong search
                            new_football_registration_manager.add_football_registration(team_or_competition, 'user', user)

                            recommendations = football_team_manager.similar_football_team_names(team_or_competition) \
                                              + football_competition_manager.similar_football_competition_names(team_or_competition)

                            if len(recommendations) == 1:
                                response_msg.append(
                                    manager_highlights.send_highlights_for_team_or_competition(sender_id, recommendations[0])
                                )

                            else:
                                # Format recommendation names
                                recommendations = [recommendation.title() for recommendation in recommendations]

                                response_msg.append(
                                    manager_highlights.send_recommended_team_or_competition_message(sender_id, recommendations)
                                )

                        else:
                            # No team or recommendation found

                            # Register wrong search
                            new_football_registration_manager.add_football_registration(team_or_competition, 'user', user)

                            response_msg.append(
                                manager_highlights.send_team_not_found_tutorial_message(sender_id)
                            )

                if 'postback' in message:
                    postback = message['postback']['payload']

                    logger.log_for_user("Postback message received", sender_id, extra={
                        'full_msg': message,
                        'msg_type': 'postback'
                    })

                    if postback == 'get_started':
                        logger.log_for_user("GET STARTED POSTBACK", sender_id, extra={
                            'action': 'start'
                        })

                        response_msg.append(
                            manager_response.send_getting_started_message(sender_id, user.first_name)
                        )
                        response_msg.append(
                            manager_response.send_getting_started_message_2(sender_id)
                        )

                        # Set the user in tutorial context
                        context_manager.update_context(sender_id, ContextType.TUTORIAL_ADD_TEAM)

                    # SEARCH HIGHLIGHT SETTING POSTBACK
                    elif postback == 'search_highlights':
                        logger.log_for_user("SEARCH HIGHLIGHTS POSTBACK", sender_id, extra={
                            'action': 'search'
                        })

                        response_msg.append(
                            view_message_helper.search_highlights(sender_id)
                        )

                    # SUBSCRIPTION SETTING POSTBACK
                    elif postback == 'my_subscriptions':
                        logger.log_for_user("SUBSCRIPTION SETTING POSTBACK", sender_id, extra={
                            'action': 'subscriptions'
                        })

                        response_msg.append(
                            view_message_helper.send_subscriptions_settings(sender_id)
                        )

                    # SHARE POSTBACK
                    elif postback == 'share':
                        logger.log_for_user("SHARE POSTBACK", sender_id, extra={
                            'action': 'share'
                        })

                        response_msg.append(
                            manager_share.send_share_introduction_message(sender_id)
                        )
                        response_msg.append(
                            manager_share.send_share_message(sender_id)
                        )

                    # SEE RESULT SETTING POSTBACK
                    elif postback == 'see_result_setting':
                        logger.log_for_user("SEE RESULT SETTING POSTBACK", sender_id, extra={
                            'action': 'settings'
                        })

                        response_msg.append(
                            view_message_helper.send_send_see_result_settings(sender_id)
                        )

                # Log the responses
                for msg in response_msg:
                    logger.log_for_user("Message sent", sender_id, extra={
                        'full_msg': msg,
                        'msg_type': 'response'
                    })
                HighlightsBotView.LATEST_SENDER_ID = 0

        if not settings.DEBUG:
            return HttpResponse()

        else:
            # DEBUG MODE ONLY
            formatted_response = "[" + ", ".join(response_msg) + "]"
            return JsonResponse(formatted_response, safe=False)