<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2017 <NAME>. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Time sheet evaluator that uses the Google Calendar API."""

from datetime import datetime, date, timedelta
import humanfriendly
import json
import os.path
import re
import sqlite3
import sys
import tempfile
import webbrowser
from lxml import etree

from oauth2client import client
from helpers import init

__author__ = "<NAME> <<EMAIL>>"

date_time_re = re.compile(
    '(?P<Y>\\d\\d\\d\\d)-'
    '(?P<m>1[0-2]|0[1-9]|[1-9])-'
    '(?P<d>3[0-1]|[1-2]\\d|0[1-9])T'
    '(?P<H>2[0-3]|[0-1]\\d|\\d):'
    '(?P<M>[0-5]\\d|\\d):'
    '(?P<S>6[0-1]|[0-5]\\d|\\d)'
    '(?P<z>[+-]\\d\\d:[0-5]\\d)')

entry_re = re.compile('\[(?P<p>[a-z0-9 _-]*)\](?P<d>.*)',
                      re.IGNORECASE)

DATE_FORMAT = "%d.%m.%Y"
TIME_FORMAT = "%d.%m.%Y %H:%M:%S"


def _print_msg(e, msg):
    print(msg, end='\n')


def _open_browser(e, msg):
    _print_msg(e, msg)
    webbrowser.open(e["htmlLink"], new=2)


class CalendarEntry:
    def __init__(self, entry_id, start, end, summary, description, location,
                 link):
        def to_datetime(s):
            global date_time_re
            inp = s["dateTime"]
            found = date_time_re.fullmatch(inp)
            if not found:
                raise ValueError("time data %r does not match expected format"
                                 % inp)

            d = found.groupdict()
            return datetime(int(d["Y"]), int(d["m"]), int(d["d"]),
                            int(d["H"]), int(d["M"]))

        self.id = entry_id
        self.start = to_datetime(start)
        self.end = to_datetime(end)
        self.summary = summary
        self.description = description
        self.location = location
        self.link = link


class Project:
    def __init__(self, pid, key, title):
        self.pid = pid
        self.key = key
        self.title = title
        self.kvp = dict()


class UsedProject:
    def __init__(self, project):
        self.project = project
        self.entries = []


class CalendarDb:
    def __init__(self, name):
        self.conn = sqlite3.connect(name)

    def get_projects(self):
        c = self.conn.cursor()
        p = None
        # noinspection SqlResolve
        projects = c.execute("SELECT p.Id, p.ProjectKey, p.ProjectTitle, "
                             "kvp.Key, kvp.value "
                             "FROM Projects p "
                             "LEFT JOIN ProjectKeyValuePairs kvp "
                             "ON p.Id = kvp.ProjectID "
                             "ORDER BY p.ProjectKey")
        for pid, project_key, title, kvk, kvv in projects:
            if p is None or p.pid != pid:
                if p is not None:
                    yield p
                p = Project(pid, project_key, title)
            if kvk is not None:
                p.kvp[kvk] = kvv
        if p is not None:
            yield p


class TimeSheet:
    def __init__(self, argv):
        # Authenticate and construct service.
        self.service, self.arguments = init(
            argv, 'calendar', 'v3', __doc__, __file__,
            parents=[self._create_argument_parser()],
            scope='https://www.googleapis.com/auth/calendar.readonly')

        # user info
        self.user = None
        self.title = None
        with open("user.json", 'r', encoding='utf-8') as fp:
            user_data = json.load(fp)
            self.user = user_data["user"]
            self.title = user_data["title"]

        # projects database
        self.db = CalendarDb(self.arguments.database)
        self.projects = dict()
        for p in self.db.get_projects():
            self.projects[p.key] = p

        # start and end date
        if self.arguments.start_date is None and \
                self.arguments.end_date is None and \
                self.arguments.period is None:
            self.arguments.period = "last-month"

        self.start_date = date.today().replace(day=1)
        self.end_date = date.today() + timedelta(days=1)

        if self.arguments.period is not None:
            if self.arguments.period == "last-month":
                self.end_date = self.start_date
                self.start_date = (self.end_date - timedelta(days=1)).replace(
                    day=1)
            else:
                raise ValueError("Unknown period: %s" % self.arguments.period)
            if self.arguments.start_date is not None or \
                    self.arguments.end_date is not None:
                raise ValueError(
                    "You cannot combine --period and explicit date")
        else:
            if self.arguments.start_date is not None:
                y, m, d, *r = humanfriendly.parse_date(<commit_msg>Support period "current-month"<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2017 <NAME>. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Time sheet evaluator that uses the Google Calendar API."""

from datetime import datetime, date, timedelta
import humanfriendly
import json
import os.path
import re
import sqlite3
import sys
import tempfile
import webbrowser
from lxml import etree

from oauth2client import client
from helpers import init

__author__ = "<NAME> <<EMAIL>>"

date_time_re = re.compile(
    '(?P<Y>\\d\\d\\d\\d)-'
    '(?P<m>1[0-2]|0[1-9]|[1-9])-'
    '(?P<d>3[0-1]|[1-2]\\d|0[1-9])T'
    '(?P<H>2[0-3]|[0-1]\\d|\\d):'
    '(?P<M>[0-5]\\d|\\d):'
    '(?P<S>6[0-1]|[0-5]\\d|\\d)'
    '(?P<z>[+-]\\d\\d:[0-5]\\d)')

entry_re = re.compile('\[(?P<p>[a-z0-9 _-]*)\](?P<d>.*)',
                      re.IGNORECASE)

DATE_FORMAT = "%d.%m.%Y"
TIME_FORMAT = "%d.%m.%Y %H:%M:%S"


def _print_msg(e, msg):
    print(msg, end='\n')


def _open_browser(e, msg):
    _print_msg(e, msg)
    webbrowser.open(e["htmlLink"], new=2)


class CalendarEntry:
    def __init__(self, entry_id, start, end, summary, description, location,
                 link):
        def to_datetime(s):
            global date_time_re
            inp = s["dateTime"]
            found = date_time_re.fullmatch(inp)
            if not found:
                raise ValueError("time data %r does not match expected format"
                                 % inp)

            d = found.groupdict()
            return datetime(int(d["Y"]), int(d["m"]), int(d["d"]),
                            int(d["H"]), int(d["M"]))

        self.id = entry_id
        self.start = to_datetime(start)
        self.end = to_datetime(end)
        self.summary = summary
        self.description = description
        self.location = location
        self.link = link


class Project:
    def __init__(self, pid, key, title):
        self.pid = pid
        self.key = key
        self.title = title
        self.kvp = dict()


class UsedProject:
    def __init__(self, project):
        self.project = project
        self.entries = []


class CalendarDb:
    def __init__(self, name):
        self.conn = sqlite3.connect(name)

    def get_projects(self):
        c = self.conn.cursor()
        p = None
        # noinspection SqlResolve
        projects = c.execute("SELECT p.Id, p.ProjectKey, p.ProjectTitle, "
                             "kvp.Key, kvp.value "
                             "FROM Projects p "
                             "LEFT JOIN ProjectKeyValuePairs kvp "
                             "ON p.Id = kvp.ProjectID "
                             "ORDER BY p.ProjectKey")
        for pid, project_key, title, kvk, kvv in projects:
            if p is None or p.pid != pid:
                if p is not None:
                    yield p
                p = Project(pid, project_key, title)
            if kvk is not None:
                p.kvp[kvk] = kvv
        if p is not None:
            yield p


class TimeSheet:
    def __init__(self, argv):
        # Authenticate and construct service.
        self.service, self.arguments = init(
            argv, 'calendar', 'v3', __doc__, __file__,
            parents=[self._create_argument_parser()],
            scope='https://www.googleapis.com/auth/calendar.readonly')

        # user info
        self.user = None
        self.title = None
        with open("user.json", 'r', encoding='utf-8') as fp:
            user_data = json.load(fp)
            self.user = user_data["user"]
            self.title = user_data["title"]

        # projects database
        self.db = CalendarDb(self.arguments.database)
        self.projects = dict()
        for p in self.db.get_projects():
            self.projects[p.key] = p

        # start and end date
        if self.arguments.start_date is None and \
                self.arguments.end_date is None and \
                self.arguments.period is None:
            self.arguments.period = "last-month"

        self.start_date = date.today().replace(day=1)
        self.end_date = date.today() + timedelta(days=1)

        if self.arguments.period is not None:
            if self.arguments.period == "last-month":
                self.end_date = self.start_date
                self.start_date = (self.end_date - timedelta(days=1)).replace(
                    day=1)
            elif self.arguments.period == "current-month":
                pass
            else:
                raise ValueError("Unknown period: %s" % self.arguments.period)
            if self.arguments.start_date is not None or \
                    self.arguments.end_date is not None:
                raise ValueError(
                    "You cannot combine --period and explicit date")
        else:
            if self.arguments.start_date is not None:
                y, m, d, *r = humanfriendly.parse_date(
{'fraction_non_alphanumeric': 0.12519809825673534, 'fraction_numerical': 0.009508716323296355, 'mean_word_length': 1.8838709677419354, 'pattern_counts': {'":': 3, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1490093', 'n_tokens_mistral': 3355, 'n_tokens_neox': 3208, 'n_words': 883}