From b305173b9daab2b17bf702334a1df13255530c3b Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 9 Nov 2025 12:26:46 -0300 Subject: [PATCH] initial commit --- .gitignore | 0 .idea/.gitignore | 8 ++ .idea/RicoToGhostfolio.iml | 10 ++ .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 6 + .idea/modules.xml | 8 ++ Dockerfile | 12 ++ converter.py | 112 ++++++++++++++++++ docker-compose.yml | 6 + ghostfolio_service.py | 40 +++++++ main.py | 30 +++++ mappings.py | 16 +++ .../XPINC_NOTA_NEGOCIACAO_B3_1_10_2024.pdf | Bin 0 -> 44404 bytes ntfy_service.py | 6 + playwright_t.py | 36 ++++++ requirements.txt | Bin 0 -> 2470 bytes test_main.http | 11 ++ 17 files changed, 307 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/RicoToGhostfolio.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 Dockerfile create mode 100644 converter.py create mode 100644 docker-compose.yml create mode 100644 ghostfolio_service.py create mode 100644 main.py create mode 100644 mappings.py create mode 100644 notas-teste/XPINC_NOTA_NEGOCIACAO_B3_1_10_2024.pdf create mode 100644 ntfy_service.py create mode 100644 playwright_t.py create mode 100644 requirements.txt create mode 100644 test_main.http diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/RicoToGhostfolio.iml b/.idea/RicoToGhostfolio.iml new file mode 100644 index 0000000..6f7c1f5 --- /dev/null +++ b/.idea/RicoToGhostfolio.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..e899fe4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0de4795 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ea862cc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +# Use the official Python image +FROM python:3.12-slim + +WORKDIR /code + +COPY ./requirements.txt /code/requirements.txt + +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt + +COPY . /code/app + +CMD ["fastapi", "run", "app/main.py", "--port", "8000"] \ No newline at end of file diff --git a/converter.py b/converter.py new file mode 100644 index 0000000..6d8feb1 --- /dev/null +++ b/converter.py @@ -0,0 +1,112 @@ +import io +import logging +import simplejson as json +import pandas as pd +import mappings +import ghostfolio_service +import datetime +from correpy.domain.enums import TransactionType +from correpy.parsers.brokerage_notes.parser_factory import ParserFactory +from fastapi import UploadFile + +account_id = '1590f1bb-b3ee-4dc8-ac46-bd1f15a83e87' + +logger = logging.getLogger(__name__) + + +def read_brokerage_pdf(file: UploadFile): + content = io.BytesIO(file.file.read()) + content.seek(0) + + logger.info(f'Processing {file.filename} ') + + try: + brokerage_notes = ParserFactory(brokerage_note=content, password='052').parse() + return convert_to_ghostfolio(brokerage_notes, file.filename) + except Exception as e: + print(f'Failed to parse {file.filename}: {e}') + logger.error(f'Failed to parse {file.filename}: {e}') + return 500 + + +def convert_to_ghostfolio(brokerage_list: list, filename: str): + activities = {} + + for brokerage_note in brokerage_list: + reference_date = brokerage_note.reference_date.isoformat() + 'T00:00:00.000Z' + fees = (brokerage_note.settlement_fee + brokerage_note.emoluments + brokerage_note.others) / len( + brokerage_note.transactions) + + # activities['meta'] = {'date': datetime.datetime.now().isoformat(), 'version': 'v0'} + activities['activities'] = [] + # activities['updateCashBalance'] = 'false' + + for transaction in brokerage_note.transactions: + + # activity['fee'] = (brokerage_note.settlement_fee + brokerage_note.emoluments) + + transaction_type: str = '' + + if transaction.transaction_type == TransactionType.BUY: + transaction_type = 'BUY' + elif transaction.transaction_type == TransactionType.SELL: + transaction_type = 'SELL' + + activity = {'accountId': account_id, 'comment': filename, 'date': reference_date, + 'type': transaction_type, + 'fee': fees, 'unitPrice': transaction.unit_price, 'quantity': transaction.amount, + 'symbol': mappings.name_to_tickers[transaction.security.name.strip()].strip(), + 'currency': 'BRL', + 'dataSource': 'YAHOO'} + activities['activities'].append(activity) + + if len(activity['symbol']) < 1: + logger.info(f'No symbol for {transaction.security.name}') + + result = ghostfolio_service.import_activities(activities, filename) + + return result + + +def read_dividends_xlsx(file: UploadFile): + dividends_xlsx = file.file + df = pd.read_excel(dividends_xlsx, engine='openpyxl') + path = f'./{file.filename}' + df.to_csv(path, encoding='utf-8') + df = pd.read_csv(path, encoding='utf-8') + df = df[df['Produto'].notnull()] + df = df[df['Tipo de Evento'] != 'PAGAMENTO DE JUROS'] + + return dividends_df_to_ghostfolio(df, file.filename) + + +def dividends_df_to_ghostfolio(dividends_df: pd.DataFrame, filename: str): + activities = {"activities": []} + + for index, row in dividends_df.iterrows(): + payment_date = datetime.datetime.strptime(row['Pagamento'], "%d/%m/%Y").isoformat() + name = row['Produto'].split('-')[0].strip() + '.SA' + + if name in mappings.ticker_changes: + symbol = mappings.ticker_changes[name] + else: + symbol = name + + activity = { + "accountId": account_id, + "date": payment_date, + "comment": filename, + "currency": "BRL", + "dataSource": "YAHOO", + "quantity": row['Quantidade'], + "type": "DIVIDEND", + "symbol": symbol, + "unitPrice": row['Preço unitário'], + "fee": 0 + } + + activities["activities"].append(activity) + + print(activities) + + return ghostfolio_service.import_activities(activities, filename) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5b14fa4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,6 @@ +services: + rico-to-ghostfolio: + ports: + - "8001:8000" + build: + dockerfile: Dockerfile \ No newline at end of file diff --git a/ghostfolio_service.py b/ghostfolio_service.py new file mode 100644 index 0000000..fb6ecf1 --- /dev/null +++ b/ghostfolio_service.py @@ -0,0 +1,40 @@ +import logging + +import requests +import simplejson as json +import ntfy_service + +logger = logging.getLogger(__name__) + + +def get_bearer_token(): + response = requests.post('http://192.168.1.202:3333/api/v1/auth/anonymous', data={ + "accessToken": "cab07a6b0a87711013ee5457411a26c7c7dd2787830b64b914d5678d4dc54af911752975380467fd73c3798b043855520ab148a372d8fd859860703833e96cba"} + ) + + token = response.json()['authToken'] + + return token + + +def import_activities(activities_json, filename: str): + bearer_token = get_bearer_token() + + data = json.dumps(activities_json) + + response = requests.post('http://192.168.1.202:3333/api/v1/import', data=data, + headers={"Authorization": "Bearer " + bearer_token, "Content-Type": "application/json"}) + + print(response.json()) + + if len(response.json()['activities']) < 1: + logger.info(f'No activity imported for {filename}') + print(f'No activity imported for {filename}') + ntfy_service.send_notification(f'No activity imported for {filename}') + else: + ntfy_service.send_notification(f'Imported {len(response.json()['activities'])} activities from {filename}') + print(f'Imported {len(response.json()['activities'])} activities from {filename}') + + # print(json.dumps(response.json(), indent=4)) + + return response.status_code diff --git a/main.py b/main.py new file mode 100644 index 0000000..3e3a90c --- /dev/null +++ b/main.py @@ -0,0 +1,30 @@ +import logging +from starlette.requests import Request +from starlette.responses import Response +import uvicorn +from fastapi import FastAPI, Form, UploadFile, File +import ntfy_service + +from converter import read_brokerage_pdf, read_dividends_xlsx +import io +app = FastAPI() + +logger = logging.getLogger(__name__) +logging.basicConfig(filename='rico-to-ghostfolio.log', level=logging.INFO) + +@app.post("/brokerage") +async def convert_pdf(file: UploadFile = File(...)): + return read_brokerage_pdf(file) + +@app.post("/b3dividends") +async def convert_pdf(file: UploadFile = File(...)): + return read_dividends_xlsx(file) + +@app.post("/notification") +async def notification(request: Request): + message = await request.body() + return ntfy_service.send_notification(message.decode('utf8')) + + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=8000) \ No newline at end of file diff --git a/mappings.py b/mappings.py new file mode 100644 index 0000000..6388413 --- /dev/null +++ b/mappings.py @@ -0,0 +1,16 @@ +name_to_tickers = { + "BRASIL ON NM" : 'BBAS3.SA', + "BRASIL ON EJ NM": 'BBAS3.SA', + "METAL LEVE ON NM": 'LEVE3.SA', + "METAL LEVE ON ED NM": 'LEVE3.SA', + "TRAN PAULIST PN N1": 'ISAE4.SA', + "ISA ENERGIA PN N1": 'ISAE4.SA', + "TAESA PN N2": 'TAEE4.SA', + "VALE ON NM": 'VALE3.SA', + "OI ON N1": 'OIBR3.SA' +} + + +ticker_changes = { + "TRPL4.SA": 'ISAE4.SA', +} \ No newline at end of file diff --git a/notas-teste/XPINC_NOTA_NEGOCIACAO_B3_1_10_2024.pdf b/notas-teste/XPINC_NOTA_NEGOCIACAO_B3_1_10_2024.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ea48675ac15f9437afbbf4a4bdeb7a772d5aafa5 GIT binary patch literal 44404 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 b^qU_pL=#8nAIk;|5)cIAv9QRiE8zVD59*(w literal 0 HcmV?d00001 diff --git a/ntfy_service.py b/ntfy_service.py new file mode 100644 index 0000000..b0f441b --- /dev/null +++ b/ntfy_service.py @@ -0,0 +1,6 @@ +import requests + + +def send_notification(message: str): + response = requests.post('https://ntfy.ccalifice.com/ghostfolio', data=message, headers={"Authorization": "Bearer tk_dl5jaui6j3pc2dx9rx8qj9sdwh23k"}) + return response.status_code \ No newline at end of file diff --git a/playwright_t.py b/playwright_t.py new file mode 100644 index 0000000..b98e35e --- /dev/null +++ b/playwright_t.py @@ -0,0 +1,36 @@ +from playwright.sync_api import sync_playwright +import time + +with sync_playwright() as p: + # Launch a browser + browser = p.chromium.launch(headless=False) # Set headless=True if you don't want to see the browser + page = browser.new_page() + + # Go to the login page + page.goto("https://www.investidor.b3.com.br/login") + + # Fill in the username and password + page.fill('input[name="investidor"]', '01783945052') + page.click('button[type="submit"]') + + time.sleep(2) + + page.fill('input[type="password"]', 'malvado6696') + + time.sleep(200) + page.click('input[type="checkbox"]') + page.click('button[type="submit"]') + + + # Wait for navigation or any element that confirms login success + page.wait_for_load_state('networkidle') + + # Go to the protected page + page.goto("https://example.com/secret-page") + + # Get the page content + content = page.content() + print(content) + + # Close the browser + #browser.close() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..55d560062fd4bb2971f54c098885f68004b47a27 GIT binary patch literal 2470 zcmZXW%WfJ`5Jc}fQa%Ob0o$<`SwxDmh+@f-S6NvY#s-^L2Jq|Slho;&W<&(UYvd$EN?NskC4{Te- zHf`LXoXIlWTgS@S$UZCgdWaqyzDGR-uE9ZM4 zkQr3CWfazNc?#5vc;7D#-sevDk!dTc*mi z44;AQooaRDo(bu;JhyBo`rZbzwdhNW%t>{(7Uk=20)Q~7VjVjT6DE4?H8Ww1yO zDn{{cwovl)$mey>ZlEqD`b@LARIT8{t7=u4=`GzwdFJLJJj^01chMsI^jPh+-ZK-PkhS*}duM|D0|s_D9XFFyhSCf-8s09kINBDy&T9-L)ofB~Blm0`$)(jiCN z>OIhl+VQ1hoc^rHJF~B9j=M$XE|#s#EIjXd!X*24=(`ZYJTTl1Gh^y_*t4nKR$J06 za`(DZRQoVYuo}*G{)*~BOYwBNvQIyU#`VxD$kX7DKl{=z49D&%I|bad