Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.my-work-resources/.config
25 changes: 25 additions & 0 deletions .my-work-resources/collect_lines_modified.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# credits to OG: Piotr Karkut <karkucik@gmail.com>

import subprocess
import sys
from collections import Counter

data = Counter()
directory, date, gituser = sys.argv[1], sys.argv[2], sys.argv[3]

log = subprocess.check_output(f'git -C ./{directory} log --all --after="{date}-01 00:00" --before="{date}-31 23:59" --author={gituser} --pretty=format:"%h"', shell=True)

for commit in log.splitlines():
commit = commit.decode()
try:
stats = subprocess.check_output(f'git -C ./{directory} diff %s^ %s --numstat' % (commit, commit), shell=True, stderr=open('/dev/null'))
except Exception:
stats = subprocess.check_output(f'git -C ./{directory} diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 %s --numstat' % commit, shell=True)
for stat in stats.splitlines():
ins, dels, f = stat.split(None, 2)
try:
data[f.decode()] += (int(ins) + int(dels))
except Exception:
pass

print("('{0}', {1})".format(directory, list(data.items()) or []))
42 changes: 42 additions & 0 deletions .my-work-resources/generate_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import sys
from pathlib import Path
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's so much better ! 👍


from weasyprint import HTML, CSS
from ast import literal_eval
from jinja2 import Environment, FileSystemLoader


current_directory = Path(__file__).parent

env = Environment(loader=FileSystemLoader(current_directory))


def render_template(_name_and_surname, _report_date, _report_data):
return env.get_template("report-template.j2").render(
name_and_surname=_name_and_surname,
report_date=_report_date,
report_data=_report_data,
)


name_and_surname, report_date, report_data_file = sys.argv[1], sys.argv[2], sys.argv[3]
with open(report_data_file, "r") as f:
report_data_raw = f.read()

# HACK: from bash array to Python list :facepalm:
report_data = literal_eval("[" + report_data_raw.replace(")(", "), (") + "]")
report_data = [entry for entry in report_data if entry[1]]

html_text = render_template(
_name_and_surname=name_and_surname,
_report_date=report_date,
_report_data=report_data,
)

html = HTML(string=html_text)
css = CSS(str(current_directory / "report-template.css"))

html.write_pdf(
str(current_directory.parent / "my-work-reports" / f"{report_date}.pdf"),
stylesheets=[css],
)
6 changes: 6 additions & 0 deletions .my-work-resources/report-template.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@page {
margin-bottom: 2.5cm;
@bottom-center{
content: "Strona " counter(page) " z " counter(pages);
}
}
30 changes: 30 additions & 0 deletions .my-work-resources/report-template.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<html>
<head lang="en">
<meta charset="UTF-8">
<title>raport-pracy-tworczej-{{ report_date }}</title>
</head>
<body>
<h4>[{{ name_and_surname }}] Zestawienie efektów pracy twórczej stanowiących utwór za okres {{ report_date }}</h4>
<p>
{% for project in report_data %}
<p>{{ project[0] }}</p>
<ul>
{% for changes_data in project[1] %}
<li>{{ changes_data[0] }} modified lines: {{ changes_data[1] }}</li>
{% endfor %}
</ul>
<hr />
{% endfor %}
</p>
<div>
<div style="width:75%; float: left;">
Podpis pracownika:<br><br>
........................................
</div>
<div style="width:25%; float: left;">
Podpis pracodawcy:<br><br>
........................................
</div>
</div>
</body>
</html>
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# internal-tools
### Lokalny setup

Projekt pozwala na proste generowanie raportów potrzebnych do rozliczania godzin pracy twórczej.
Aby narzędzie działało poprawnie należy spełnić podstawowe zależności:
- Python 3
- poprawnie uporządkowane katalogi projektowe (przykład w zakładce #WSF (Wymagana Struktura Folderów))

### WSF (Wymagana Struktura Folderów)
Do poprawnego działania skyptu wymagana jest następująca folderów:

```
/folder-glowny (tutaj powinny znjdować się wszystkie projekty które chcemy uwzględnić w raporcie)
/projekt1
/projekt2
...
```

W `/folder-glowny` nie powinien znajdować się plik `.git` - taka sytuacja mogłaby wskazywać na złe umiejscowienie pliku skryptu.

### I w końcu - jak tego użyć :national_park:

Skopiuj zawartość repozytorium do katalogu głównego:

*Upewnij się, że jesteś w folderze głównym, a repozytorium `internal-tools` również zostało umieszczone pod nim.

```bash
$ pwd
/.../folder-glowny
$ cp -r internal-tools/. .
$ ls
projekt1 projekt2 my-work.sh ...
```

Opcjonalnie można też usunąć plik README.md:

```bash
$ pwd
/.../folder-glowny
$ rm -f README.md
```

### Uruchomienie skryptu

```bash
$ ./my-work.sh
```

### Gdzie znajdę raport :thinking:

Raporty będę dostępne w katalogu `my-work-reports` znajdującego się w katalogu `/folder-glowny`
114 changes: 77 additions & 37 deletions my-work.sh
Original file line number Diff line number Diff line change
@@ -1,54 +1,94 @@
#!/bin/sh
BASE_RESOURCE_PATH=./.my-work-resources/
PROJECT_PYTHON_ENV_NAME=my-work-venv
LINES_MODIFIED_PATH=${BASE_RESOURCE_PATH}collect_lines_modified.py
REPORT_GENERATE_PATH=${BASE_RESOURCE_PATH}generate_report.py
CONFIG_FILE_PATH=${BASE_RESOURCE_PATH}.config
REPORT_MULTI_LINE_PROJECT_ARRAY=()

is_git_repo() {
[[ -d .git ]] || git -C ${1} rev-parse --git-dir > /dev/null 2>&1
}

check_if_python_virtual_env_exits() {
[[ -f "${BASE_RESOURCE_PATH}${PROJECT_PYTHON_ENV_NAME}" ]]
}

create_python_virtual_env() {
python3 -m venv ${BASE_RESOURCE_PATH}${PROJECT_PYTHON_ENV_NAME}
}

check_if_weasyprint_installed() {
pip list --disable-pip-version-check | grep -c WeasyPrint
}

check_if_jinja2_installed() {
pip list --disable-pip-version-check | grep -c Jinja2
}


if ! [[ -f "$CONFIG_FILE_PATH" ]]; then
read -p "Imię i nazwisko: " name surname
name_and_surname="${name} ${surname}"
if ! [[ -z "$name_and_surname" ]]; then
touch "${CONFIG_FILE_PATH}"
echo "name_and_surname='${name_and_surname}'" > "${CONFIG_FILE_PATH}"
fi; else
. ${CONFIG_FILE_PATH}
fi

if [[ -z "$name_and_surname" ]]; then
echo "Konieczne poprawne wprowadzenie: Imię i nazwisko"
fi

defdate=`date "+%Y-%m"`

read -p "Data logu rrrr-mm [${defdate}]: " date </dev/tty

if [ -z "$date" ]; then
if [[ -z "$date" ]]; then
date=${defdate}
fi

if [[ -z "$gituser" ]]; then
defgituser=`git config user.email`
read -p "Email użytkownika git: [${defgituser}]: " gituser </dev/tty

defgituser=`git config user.email`
read -p "Email użytkownika git: [${defgituser}]: " gituser </dev/tty
if [[ -z "$gituser" ]]; then
gituser=${defgituser}
fi

if [ -z "$gituser" ]; then
gituser=${defgituser}
echo "gituser='${gituser}'" >> "${CONFIG_FILE_PATH}"
fi
echo
echo

echo "========================================================================="
echo "ZAŁĄCZNIK A do Raportu wykonania zlecenia"
echo "Changes in ${PWD##*/} for date: ${date}, created by: ${gituser}"
echo


python > /dev/tty <<-EOF
import subprocess
from collections import Counter
mkdir -p my-work-reports

data = Counter()
if is_git_repo .; then
echo "'my-work.sh' should run in top directory"
exit 1
fi

log = subprocess.check_output('git log --all --after="${date}-01 00:00" --before="${date}-31 23:59" --author=${gituser} --pretty=format:"%h"', shell=True)
if ! check_if_python_virtual_env_exits; then
create_python_virtual_env
fi

for commit in log.splitlines():
commit = commit.decode()
try:
stats = subprocess.check_output('git diff %s^ %s --numstat' % (commit, commit), shell=True, stderr=open('/dev/null'))
except Exception:
stats = subprocess.check_output('git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 %s --numstat' % commit, shell=True)
for stat in stats.splitlines():
# print(stat.decode())
ins, dels, f = stat.split(None, 2)
try:
data[f.decode()] += (int(ins) + int(dels))
except Exception:
pass
if [ -f ${BASE_RESOURCE_PATH}${PROJECT_PYTHON_ENV_NAME}/bin/activate ]; then
source ${BASE_RESOURCE_PATH}${PROJECT_PYTHON_ENV_NAME}/bin/activate
else
source ${BASE_RESOURCE_PATH}${PROJECT_PYTHON_ENV_NAME}/Scripts/activate
fi

for f, ch in data.items():
print("File %s, modified lines: %s" % (f, ch))
EOF
if [[ "$(check_if_weasyprint_installed)" -lt 1 || "$(check_if_jinja2_installed)" -lt 1 ]]; then
pip install weasyprint
pip install Jinja2
fi

echo "............. .............."
echo "Zleceniodawca Zleceniobiorca"
echo "========================================================================="
for f in *; do
if [[ -d "$f" ]]; then
if is_git_repo "./$f"; then
REPORT_MULTI_LINE_PROJECT_ARRAY+="$(python ${LINES_MODIFIED_PATH} "$f" "$date" "$gituser")"
fi
fi
done
echo ${REPORT_MULTI_LINE_PROJECT_ARRAY[0]} > ${BASE_RESOURCE_PATH}/tmp
python ${REPORT_GENERATE_PATH} "${name_and_surname}" "${date}" "${BASE_RESOURCE_PATH}/tmp"
rm ${BASE_RESOURCE_PATH}/tmp