Beispiel #1
0
def sidebar(config: Config):
    config.KPI_IMPROVEMENT_RATE = st.sidebar.number_input(
        "KPI improvement rate",
        min_value=1.0,
        max_value=10.0,
        value=config.KPI_IMPROVEMENT_RATE)

    config.KPI_HISTORICAL_WINDOW = st.sidebar.slider(
        "KPI historical window",
        min_value=1,
        max_value=10,
        value=config.KPI_HISTORICAL_WINDOW)

    config.BALANCE_LIFE_DISTRIBUTION = json.loads(
        st.sidebar.text_input(
            "Balanced life distribution: [life, personal, career, hobby, society, health]",
            config.BALANCE_LIFE_DISTRIBUTION))
Beispiel #2
0
 def __init__(self, data: WeeklyStats, raw_data: PomodorosProcessed):
     self.data = data
     self.raw_data = raw_data
     current = get_current_week(data)
     recent = get_recent_weeks(data)
     value = int(current.df.done.iloc[0])
     target = round(recent.df.done.median() * Config().KPI_IMPROVEMENT_RATE) if len(recent.df) > 0 else 0
     self.pomodoros_left_7_days = None
     self.pomodoros_left_6_days = None
     self.pomodoros_left_5_days = None
     zone = self._compute_zone(value=value, target=target)
     super().__init__(value=value, target=target, zone=zone)
Beispiel #3
0
    def test_config_should_be_dict_like(self):
        config = Config(file_path='tests/static/test_settings.yml')
        self.assertIn('default', config)
        self.assertTrue(hasattr(config, 'get'))

        config['default']['pipename'] = 'test-pipeline'
        config['default']['users_file'] = 'test_admins.yml'
        config['default']['secret_key'] = 'thisisverysecret'
        self.assertDictEqual(
            config['default'], {
                'pipename': 'test-pipeline',
                'users_file': 'test_admins.yml',
                'secret_key': 'thisisverysecret'
            })
Beispiel #4
0
    def compute_value(week: BalanceCoefData,
                      desired_dist: Optional[pd.Series] = None) -> float:
        if desired_dist is not None:
            assert np.all(desired_dist.index == BalanceCoefData.LIFE_DOMAINS)
        else:
            desired_dist = BalanceCoefKPI.desired_distr(config=Config())

        df = week.df
        all_pomodoros = df.Pomodoros.sum()
        actual_dist = [
            df.loc[df[col], 'Pomodoros'].sum() / all_pomodoros
            for col in BalanceCoefData.LIFE_DOMAINS
        ]

        return mse(desired_dist, actual_dist)
Beispiel #5
0
def rotten_projects_table(raw_data: PomodorosProcessed):
    data = build_rotten_projects_table(raw_data)
    config = Config()
    green_threshold = config.ROTTEN_PROJECT_GREEN_THRESHOLD
    yellow_threshold = config.ROTTEN_PROJECT_YELLOW_THRESHOLD

    def colorize(row):
        days = row['Inactive Days']
        if days < 0:
            color = 'white'
        elif days <= green_threshold:
            color = 'rgb(210, 229, 158)'
        elif days <= yellow_threshold:
            color = 'rgb(252, 231, 128)'
        else:
            color = 'rgb(255, 143, 102)'
        return [f"background-color: {color}"] * len(row)

    st.subheader("Current Active Project Rotten Table:")
    df = data.df.sort_values(
        by='Inactive Days',
        ascending=False).reset_index(drop=True).style.apply(colorize, axis=1)
    st.dataframe(df)
Beispiel #6
0
def get_recent_weeks(weekly_stats: WeeklyStats) -> WeeklyStats:
    current = weekly_stats.df.Week.max()
    df = weekly_stats.df
    return WeeklyStats(
        df.loc[(current - df.Week <= Config().KPI_HISTORICAL_WINDOW) &
               (current - df.Week > 0), :])
Beispiel #7
0
    pomodoros = load(
        credentials=credentials,
        pomodoros_spreadsheet_id=config.POMODOROS_SPREADSHEET_ID,
        pomodoros_range=config.POMODOROS_RANGE,
        activities_spreadsheet_id=config.ACTIVITIES_SPREADSHEET_ID,
        activities_range=config.ACTIVITIES_RANGE)
    monthly_goals = MonthlyGoalsData.load(
        credentials=credentials,
        spreadsheet_id=config.MONTHLY_GOALS_SPREADSHEET_ID,
        range_name=config.MONTHLY_GOALS_RANGE,
    )
    return pomodoros, monthly_goals


args = parse_arguments()
config = Config.load(args.config)

sidebar(config=config)

creds = authenticate()
if creds:
    raw_data, monthly_data = load_data(creds, config=config)
    monthly_kpi = MonthlyPercentageKPI.compute(monthly_data)
    weekly_stats = compute_weekly_stats(raw_data)
    overall_stats = compute_overall_stats(raw_data)
    weekly_done_kpi = WeeklyDoneKPI(weekly_stats, raw_data)
    projects = compute_activity_pomodoros(raw_data)

    print_current_pomodoros_kpi(weekly_done_kpi)
    print_pomodoros_suggested_action(weekly_done_kpi)
    print_current_monthly_kpi(monthly_kpi)
Beispiel #8
0
        from flask import Flask
        ...
        app = Flask(__name__)
        ...
        dashboard.bind(app)

    The dashboard with the results that are collected can be found at:
        localhost:5000/dashboard
"""

import os
from flask import Blueprint
from dashboard.config import Config
from unittest import TestLoader

config = Config()
user_app = None


# get current location of the project
def loc():
    return os.path.abspath(os.path.dirname(__file__)) + '/'


# define the blueprint
blueprint = Blueprint('dashboard',
                      __name__,
                      template_folder=loc() + 'templates')


def bind(app, blue_print=None):
Beispiel #9
0
 def is_admin(self):
     user_roles = Config(config['default']['users_file'])
     return self.email in user_roles['admins']
Beispiel #10
0
def monthly_goals_tree(goals: MonthlyGoalsData):

    cmap = plt.get_cmap('viridis')

    def float2int(c):
        f2 = max(0.0, min(1.0, c))
        return floor(255 if f2 == 1.0 else f2 * 256.0)

    def colorize(node):
        r, g, b, a = cmap(float(node['done']))
        return {
            **node,
            **{
                'itemStyle': {
                    'color':
                    '#%02x%02x%02x' % (float2int(r), float2int(g), float2int(b))
                }
            }
        }

    data = goals.as_tree(node_formatter=colorize)
    options = {
        'tooltip': {
            'trigger': 'item',
            'triggerOn': 'mousemove'
        },
        'series': [{
            'type': 'tree',
            'id': 0,
            'name': 'tree1',
            'data': [data],
            # 'top': '10%',
            'left': '5%',
            # 'bottom': '1%',
            # 'right': '20%',
            'symbolSize': 7,
            'edgeShape': 'polyline',
            'edgeForkPosition': '50%',
            'initialTreeDepth': 3,
            'lineStyle': {
                'width': 2
            },
            'label': {
                'backgroundColor': '#fff',
                'position': 'left',
                'verticalAlign': 'middle',
                'align': 'right'
            },
            'leaves': {
                'label': {
                    'position': 'right',
                    'verticalAlign': 'middle',
                    'align': 'left'
                }
            },
            'emphasis': {
                'focus': 'descendant'
            },
            'expandAndCollapse': True
        }]
    }

    st_echarts(options=options,
               height=Config().MONTHLY_GOALS_TREE_CHART_HEIGHT)
 def test_config_object_can_be_created(self):
     Config(file_path='tests/static/test_settings.yml')
 def test_config_raises_when_try_to_set_new_section(self):
     config = Config(file_path='tests/static/test_settings.yml')
     with self.assertRaises(TypeError):
         config['new_section'] = {'test': 'foo'}
 def test_config_raises_when_file_path_is_unexpected_type(self):
     with self.assertRaises(TypeError):
         Config(file_path=124234)
 def test_config_can_be_created_with_file_path_expect_types(self):
     Config(file_path='tests/static/test_settings.yml')
     Config(file_path=os.path.normpath('tests/static/test_settings.yml'))
     Config(file_path=b'tests/static/test_settings.yml')
 def test_config_raises_when_file_path_does_not_exist(self):
     with self.assertRaises(FileNotFoundError):
         Config(file_path='/fake/path/settings.yml')
Beispiel #16
0
sys.path.append("../liveq-common")
# ----------

import logging
import time
import signal
import sys

from dashboard.config import Config
from dashboard.component import DashboardComponent

from liveq import handleSIGINT, exit
from liveq.events import GlobalEvents
from liveq.exceptions import ConfigException

# Prepare runtime configuration
runtimeConfig = { }

# Load configuration
try:
	Config.fromFile( "config/jobmanager.conf.local", runtimeConfig )
except ConfigException as e:
	print("ERROR   Configuration exception: %s" % e)
	exit(1)

# Hook sigint -> Shutdown
handleSIGINT()

# Start job manager
JobManagerComponent.runThreaded()