osci/notify/generate_email/generate_email.py (78 lines of code) (raw):

"""Copyright since 2019, EPAM Systems This file is part of OSCI. OSCI is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OSCI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OSCI. If not, see <http://www.gnu.org/licenses/>.""" import datetime import logging import pandas as pd from typing import Iterable from osci.notify.generate_email.consts import OSCI_REPORTS_URLS from osci.config import Config from osci.datalake import DataLake from osci.notify.generate_email.email import EmailBodyTemplate from osci.postprocess.osci_change_report.process import get_previous_date from osci.datalake.reports.general import OSCIChangeRanking from osci.datalake.reports.excel import OSCIChangeRankingExcel log = logging.getLogger(__name__) def __add_suffix(column, suffix): return f"{column} {suffix}" def __cast_columns_to_int(df: pd.DataFrame, columns: Iterable[str]) -> pd.DataFrame: return df.astype({col: 'Int64' for col in columns}) def __get_shift_up(change_ranking: pd.DataFrame, change_position_field: str) -> pd.DataFrame: return change_ranking[change_ranking[change_position_field] < 0].sort_values(change_position_field).head(5) def __get_shift_down(change_ranking: pd.DataFrame, change_position_field: str) -> pd.DataFrame: return change_ranking[change_ranking[change_position_field] > 0].sort_values(change_position_field, ascending=False).head(5) def __add_arrows_prefix(df: pd.DataFrame, column: str): def get_arrow(v): if v == 0: return '—' arrow_down = '▼' arrow_up = '▲' arrow = arrow_down if v > 0 else arrow_up return f'{arrow} {abs(v)}' if df.empty: return df ndf = df.copy() ndf[column] = [get_arrow(v) for v in ndf[column]] return ndf def __get_company_neighbors(df, company, company_field, rank_field, neighbors=1): company_rows = df[df[company_field] == company] if not company_rows.empty: position = company_rows[rank_field].array[0] left_border = position - neighbors right_border = position + neighbors return df[(df[rank_field] >= left_border) & (df[rank_field] <= right_border)] return pd.DataFrame() def generate_email_body(date: datetime, company=Config().default_company): report = OSCIChangeRanking(date=date) company_contributors_ranking_schema = DataLake().public.schemas.company_contributors_ranking change_ranking = report.read().reset_index() change_ranking = change_ranking.rename(columns={'index': company_contributors_ranking_schema.position}) change_ranking[company_contributors_ranking_schema.position] += 1 change_ranking = __cast_columns_to_int(df=change_ranking, columns=[ report.schema.total, report.schema.active, company_contributors_ranking_schema.position, report.schema.total_change, report.schema.active_change, report.schema.position_change, ]) shift_up = __add_arrows_prefix(df=__get_shift_up(change_ranking=change_ranking, change_position_field=report.schema.position_change), column=report.schema.position_change) shift_down = __add_arrows_prefix(df=__get_shift_down(change_ranking=change_ranking, change_position_field=report.schema.position_change), column=report.schema.position_change) company_position = __add_arrows_prefix(df=__get_company_neighbors(df=change_ranking, company=company, company_field=report.schema.company, rank_field=company_contributors_ranking_schema.position), column=report.schema.position_change) DataLake().public.save_email(email_body=EmailBodyTemplate().render( date=date, compared_date=get_previous_date(date), shift_up=shift_up, shift_down=shift_down, company=company, company_position=company_position, solutionshub_osci_change_ranking=OSCIChangeRankingExcel(to_date=date).url, osci_reports_urls={name: report_cls(date=date).url for name, report_cls in OSCI_REPORTS_URLS.items()} ), date=date)