Compare commits

...

4 Commits

5 changed files with 227 additions and 13 deletions

Binary file not shown.

View File

@@ -25,15 +25,8 @@
\begin{center} \begin{center}
\begin{minipage}{0.9\textwidth} \begin{minipage}{0.9\textwidth}
\section*{Ruder ID Format} \section*{Ruder ID Format}
% \begin{table}[]
% \centering \vspace{15mm}
% \setlength{\tabcolsep}{40pt} % Adjust column spacing
% \LARGE
% \begin{tabular}{ccccccc}
% \textbf{S1} & \textbf{S2} & \textbf{S3} & \textbf{S4} & \textbf{S5} & \textbf{S6} & \textbf{S7} \\
% \textbf{Typ} & \textbf{Marke} & \textbf{Blatttyp} & \textbf{Anschaffungsjahr} & \textbf{Nummer} & \textbf{Seite} & \textbf{Rest}
% \end{tabular}
% \end{table}
\begin{table}[] \begin{table}[]
\centering \centering
@@ -43,15 +36,17 @@
\textbf{S1} & \textbf{S2} & \textbf{S3} & \textbf{S4} & \textbf{S5} & \textbf{S6} & \textbf{S7} \\ \textbf{S1} & \textbf{S2} & \textbf{S3} & \textbf{S4} & \textbf{S5} & \textbf{S6} & \textbf{S7} \\
\textbf{Typ} & \textbf{Marke} & \textbf{Blatttyp} & \textbf{Anschaffungsjahr} & \textbf{Nummer} & \textbf{Seite} & \textbf{Rest} \textbf{Typ} & \textbf{Marke} & \textbf{Blatttyp} & \textbf{Anschaffungsjahr} & \textbf{Nummer} & \textbf{Seite} & \textbf{Rest}
\end{tabular} \end{tabular}
\end{table} \end{table}
\vspace{15mm}
\section*{Erklärung der Segmente} \section*{Erklärung der Segmente}
\begin{table}[h!] \begin{table}[h!]
\centering \centering
\setlength{\tabcolsep}{40pt} % Adjust column spacing \setlength{\tabcolsep}{60pt} % Adjust column spacing
\LARGE \LARGE
\begin{tabular}{ccccc} % Remove extra space on the sides \begin{tabular}{|ccccc|} % Remove extra space on the sides
\toprule \toprule
\textbf{Segmentnummer} & \textbf{Segmentname} & \textbf{Anzahl Stellen} & \textbf{Wert} & \textbf{Langtext} \\ \textbf{Segmentnummer} & \textbf{Segmentname} & \textbf{Anzahl Stellen} & \textbf{Wert} & \textbf{Langtext} \\
\midrule \midrule
@@ -103,8 +98,10 @@
\end{tabular} \end{tabular}
\end{table} \end{table}
\vspace{15mm}
\section*{Beispiele} \section*{Beispiele}
\vspace{5mm}
\begin{center} \begin{center}
\Huge \Huge
\textbf{S-C2-H-201X-99-B-sk} \textbf{S-C2-H-201X-99-B-sk}

View File

@@ -226,7 +226,7 @@
" f\"TEL;TYPE=CELL:{phone}\"]\n", " f\"TEL;TYPE=CELL:{phone}\"]\n",
" \n", " \n",
" if rower is True:\n", " if rower is True:\n",
" lines.append(f'NOTE:JG {year}')\n", " lines.append(f'NOTE:JG {int(year)}')\n",
"\n", "\n",
" if photo_b64:\n", " if photo_b64:\n",
" lines.append(f\"PHOTO;ENCODING=b;TYPE=JPEG:{photo_b64}\")\n", " lines.append(f\"PHOTO;ENCODING=b;TYPE=JPEG:{photo_b64}\")\n",

View File

@@ -0,0 +1,217 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 83,
"id": "152c4ce0",
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"import pandas as pd\n",
"import datetime as dt\n",
"import openpyxl.styles"
]
},
{
"cell_type": "code",
"execution_count": 84,
"id": "041b0ab6",
"metadata": {},
"outputs": [],
"source": [
"# --- Configuration ---\n",
"NEXTCLOUD_URL = \"https://nextcloud.karnelegger.eu\"\n",
"USERNAME = \"Georg Brantegger\"\n",
"with open('app_pw.txt','r') as f:\n",
" APP_PASSWORD = f.readline()\n"
]
},
{
"cell_type": "code",
"execution_count": 85,
"id": "b4c04efb",
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"import vobject\n",
"\n",
"\n",
"# This is the \"URL slug\" of your address book. \n",
"# Usually, if you name it \"Athletes\", the slug is \"athletes\" (lowercase).\n",
"# You can find the exact name by going to Contacts -> Settings (bottom left) -> \n",
"# Click the 3 dots next to your address book -> \"Copy link\". \n",
"# The link will end with /addressbooks/users/username/THIS_PART/\n",
"ADDRESSBOOK_NAME = \"rv-villach-athletinnen\" \n",
"\n",
"\n",
"# The ?export parameter tells Nextcloud to dump the whole address book at once\n",
"CARDDAV_URL = f\"{NEXTCLOUD_URL}/remote.php/dav/addressbooks/users/{USERNAME}/{ADDRESSBOOK_NAME}/?export\"\n",
"\n",
"def get_athlete_data():\n",
" print(f\"Fetching contacts from the '{ADDRESSBOOK_NAME}' address book...\")\n",
" response = requests.get(CARDDAV_URL, auth=(USERNAME, APP_PASSWORD))\n",
" \n",
" if response.status_code != 200:\n",
" print(f\"❌ Error {response.status_code}: Could not fetch address book.\")\n",
" print(\"Check your URL, credentials, and make sure the ADDRESSBOOK_NAME is exactly right.\")\n",
" return []\n",
"\n",
" vcf_data = response.text\n",
" first_names = []\n",
" last_names = []\n",
" genders = []\n",
" years_of_birth = []\n",
"\n",
" # Parse the multi-contact VCF data\n",
" for vcard in vobject.readComponents(vcf_data):\n",
" # The 'n' property in a vCard holds the structured Name (First, Last, etc.)\n",
" if hasattr(vcard, 'n'):\n",
" first_name = vcard.n.value.given\n",
" last_name = vcard.n.value.family\n",
" \n",
" first_names.append(first_name)\n",
" last_names.append(last_name)\n",
" else: print(vcard.fn.value)\n",
" \n",
" if hasattr(vcard, 'note'):\n",
" [_,year_of_birth,gender] = vcard.note.value.split(' ')\n",
" \n",
" genders.append(gender)\n",
" years_of_birth.append(int(year_of_birth))\n",
" \n",
" return last_names,first_names,genders,years_of_birth"
]
},
{
"cell_type": "code",
"execution_count": 86,
"id": "3efe3bb1",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Fetching contacts from the 'rv-villach-athletinnen' address book...\n"
]
}
],
"source": [
"a,b,c,d = get_athlete_data()\n",
"data_dict = {'Nachname':a,'Vorname':b,'Gender':c,'Jahrgang':d}\n",
"\n",
"df = pd.DataFrame(data_dict)"
]
},
{
"cell_type": "code",
"execution_count": 87,
"id": "a65d7693",
"metadata": {},
"outputs": [],
"source": [
"def evaluate_class(row):\n",
" gender = row['Gender']\n",
" yob = row['Jahrgang']\n",
" age = dt.datetime.now().year - yob\n",
" \n",
" if age <= 12:\n",
" c1 = 'Sch'\n",
" c2 = 'B'\n",
" elif 12 < age <= 14:\n",
" c1 = 'Sch'\n",
" c2 = 'A'\n",
" elif 14 < age <= 16:\n",
" c1 = 'Jun'\n",
" c2 = 'B'\n",
" elif 16 < age <= 18:\n",
" c1 = 'Jun'\n",
" c2 = 'A'\n",
" elif 18 < age <= 23:\n",
" c1 = 'Sen'\n",
" c2 = 'B'\n",
" elif 23 < age <= 30:\n",
" c1 = 'Sen'\n",
" c2 = 'A'\n",
" \n",
" return f'{c1}-{gender}-{c2}'\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "529f37c2",
"metadata": {},
"outputs": [],
"source": [
"df['Klasse'] = df.apply(evaluate_class,axis=1)\n",
"df[f'Ruderpass {dt.datetime.now().year}'] = 0"
]
},
{
"cell_type": "code",
"execution_count": 90,
"id": "7ff6f41c",
"metadata": {},
"outputs": [],
"source": [
"file_name = 'temp.xlsx'\n",
"\n",
"with pd.ExcelWriter(file_name, engine='openpyxl') as writer:\n",
" \n",
" df_styled = df.style.set_properties(**{'text-align': 'center'})\n",
" # 2 Write to xlsx\n",
" df_styled.to_excel(writer, sheet_name=\"Athlet_innen\",index=False)\n",
"\n",
" # 3 after writing, change other formats\n",
" # --- Access the openpyxl worksheet object ---\n",
" worksheet = writer.sheets[\"Athlet_innen\"]\n",
"\n",
" # 3.2 format the header\n",
" # Define a bold, larger font\n",
" header_font = openpyxl.styles.Font(name='Arial', size=12, bold=True, color=\"000000\")\n",
"\n",
" worksheet.column_dimensions['A'].width = 18*1.63\n",
" worksheet.column_dimensions['B'].width = 18*0.86\n",
" worksheet.column_dimensions['C'].width = 18*0.72\n",
" worksheet.column_dimensions['D'].width = 18*0.91\n",
" worksheet.column_dimensions['E'].width = 18*0.72\n",
" worksheet.column_dimensions['F'].width = 18*1.45\n",
"\n",
" \n",
" # Iterate through the first row (Header)\n",
" # worksheet[1] returns all cells in the first row\n",
" for cell in worksheet[1]:\n",
" cell.font = header_font\n",
" cell.alignment = openpyxl.styles.Alignment(horizontal='center', vertical='center')\n",
" cell.border = openpyxl.styles.Border(bottom=openpyxl.styles.Side(border_style='medium', color='000000'))\n",
"\n",
" # 3.3 freeze the first row\n",
" worksheet.freeze_panes = 'A2' "
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}