itlsoft / lb

0 stars 0 forks source link

Bugs #7

Open itlsoft opened 8 months ago

itlsoft commented 3 months ago
import logging
import requests
import threading
from queue import Queue
from time import sleep
from requests.auth import HTTPBasicAuth

class HttpLogger(logging.Logger):
    def __init__(self, name, level=logging.NOTSET, endpoint='http://localhost:5000/log', batch_interval=300, username=None, password=None):
        super().__init__(name, level)
        self.endpoint = endpoint
        self.batch_interval = batch_interval  # Czas w sekundach między wysyłkami zbiorczymi
        self.info_queue = Queue()
        self.username = username
        self.password = password
        self._start_batching_thread()

    def _start_batching_thread(self):
        threading.Thread(target=self._batch_sender, daemon=True).start()

    def _batch_sender(self):
        while True:
            sleep(self.batch_interval)
            if not self.info_queue.empty():
                logs_to_send = []
                while not self.info_queue.empty():
                    logs_to_send.append(self.info_queue.get())

                # Wysłanie zbiorczego requestu
                try:
                    response = requests.post(
                        self.endpoint,
                        json={"logs": logs_to_send},
                        auth=HTTPBasicAuth(self.username, self.password)
                    )
                    if response.status_code != 200:
                        self.error(f"Failed to send batch logs: {response.status_code} - {response.text}")
                except requests.RequestException as e:
                    self.error(f"Failed to send batch logs: {e}")

    def error(self, msg, category_id=None, app_name=None, *args, **kwargs):
        super().error(msg, *args, **kwargs)
        # Wykonanie HTTP requestu przy logowaniu błędu
        if category_id and app_name:
            try:
                response = requests.post(
                    self.endpoint,
                    json={
                        "error": msg,
                        "category_id": category_id,
                        "app_name": app_name
                    },
                    auth=HTTPBasicAuth(self.username, self.password)
                )
                if response.status_code != 200:
                    super().error(f"Failed to send error log: {response.status_code} - {response.text}")
            except requests.RequestException as e:
                super().error(f"Failed to send error log: {e}")

    def info(self, msg, category_id=None, app_name=None, *args, **kwargs):
        super().info(msg, *args, **kwargs)
        # Zbieranie logów do zbiorczego wysłania
        if category_id and app_name:
            self.info_queue.put({
                "info": msg,
                "category_id": category_id,
                "app_name": app_name
            })

# Funkcja do konfiguracji loggera
def setup_logger(name, endpoint='http://localhost:5000/log', batch_interval=300, username='admin', password='password'):
    logger = HttpLogger(name, endpoint=endpoint, batch_interval=batch_interval, username=username, password=password)
    handler = logging.StreamHandler()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    return logger

if __name__ == "__main__":
    logger = setup_logger('my_app_logger', endpoint='http://localhost:5000/log', username='admin', password='password')

    # Przykład użycia
    logger.error('This is an error', 2, 'APP ABC')
    logger.info('This is an info message', 4, 'APP DEF')
itlsoft commented 3 months ago
if __name__ == "__main__":
    logger = setup_logger('my_app_logger', endpoint='http://your-endpoint.com/log', batch_interval=300)

    # Przykład użycia
    logger.error('This is an error', 2, 'APP ABC')
    logger.info('This is an info message', 4, 'APP DEF')
itlsoft commented 3 months ago
from flask import Flask, request, jsonify, Response
from functools import wraps
import json
import os

app = Flask(__name__)

# Zdefiniowane dane do autoryzacji
USERNAME = 'admin'
PASSWORD = 'password'

# Funkcja autoryzacji Basic Auth
def authenticate():
    return Response(
        'Authentication required', 401,
        {'WWW-Authenticate': 'Basic realm="Login Required"'})

def requires_auth(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        auth = request.authorization
        if not auth or not (auth.username == USERNAME and auth.password == PASSWORD):
            return authenticate()
        return f(*args, **kwargs)
    return decorated

# Endpoint do odbierania logów
@app.route('/log', methods=['POST'])
@requires_auth
def receive_log():
    data = request.json

    # Ścieżka do pliku JSON
    file_path = r'C:\app\data.json'

    # Sprawdzanie, czy plik istnieje. Jeśli nie, to tworzymy pustą listę.
    if not os.path.exists(file_path):
        with open(file_path, 'w') as f:
            json.dump([], f)

    # Wczytywanie istniejących danych
    with open(file_path, 'r') as f:
        logs = json.load(f)

    # Dodawanie nowych danych
    logs.append(data)

    # Zapis zaktualizowanych danych do pliku
    with open(file_path, 'w') as f:
        json.dump(logs, f, indent=4)

    return jsonify({"message": "Log received successfully"}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
itlsoft commented 3 months ago
DECLARE @procName NVARCHAR(255)
DECLARE @sqlCmd NVARCHAR(MAX)

DECLARE cur CURSOR FOR
SELECT name
FROM sys.procedures
WHERE name LIKE 'sp_Q%'

OPEN cur
FETCH NEXT FROM cur INTO @procName

WHILE @@FETCH_STATUS = 0
BEGIN
    -- Sprawdzenie czy użytkownik Dsecr ma już uprawnienia EXECUTE do danej procedury
    IF EXISTS (
        SELECT 1
        FROM sys.database_permissions p
        JOIN sys.objects o ON p.major_id = o.object_id
        JOIN sys.schemas s ON o.schema_id = s.schema_id
        WHERE p.grantee_principal_id = USER_ID('Dsecr')
        AND o.name = @procName
        AND p.permission_name = 'EXECUTE'
        AND p.state_desc = 'GRANT'
    )
    BEGIN
        PRINT 'User Dsecr already has access to ' + @procName
    END
    ELSE
    BEGIN
        -- Dodanie uprawnień EXECUTE dla użytkownika Dsecr
        SET @sqlCmd = 'GRANT EXECUTE ON ' + QUOTENAME(@procName) + ' TO Dsecr'
        EXEC sp_executesql @sqlCmd
        PRINT 'New access has been added for ' + @procName
    END

    FETCH NEXT FROM cur INTO @procName
END

CLOSE cur
DEALLOCATE cur
itlsoft commented 3 months ago

20240822_201054

itlsoft commented 3 months ago
import requests
import smtplib
from sqlalchemy.exc import SQLAlchemyError

def request_a():
    try:
        response = requests.get("http://example.com/api")
        response.raise_for_status()  # Zgłaszaj wyjątek, jeśli status != 200
        return response.json()
    except requests.exceptions.RequestException as e:
        # Logowanie błędu lub inne działania
        raise Exception(f"RequestA failed: {str(e)}")  # Rzuć wyjątek do obsługi w trigger()

def request_b():
    try:
        response = requests.post("http://example.com/api", json={})
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        raise Exception(f"RequestB failed: {str(e)}")

def sql_update_a(session):
    try:
        # Przykład aktualizacji SQLAlchemy
        session.query(MyModel).filter_by(id=1).update({"field": "value"})
        session.commit()
    except SQLAlchemyError as e:
        session.rollback()  # Cofnij transakcję w razie błędu
        raise Exception(f"SqlUpdateA failed: {str(e)}")

def sql_update_b(session):
    try:
        session.query(AnotherModel).filter_by(id=2).update({"field": "value"})
        session.commit()
    except SQLAlchemyError as e:
        session.rollback()
        raise Exception(f"SqlUpdateB failed: {str(e)}")

def send_email_a():
    try:
        # Przykład wysyłania e-maila (może być inne API SMTP)
        smtp_server = smtplib.SMTP('smtp.example.com', 587)
        smtp_server.sendmail("from@example.com", "to@example.com", "Email body")
        smtp_server.quit()
    except smtplib.SMTPException as e:
        raise Exception(f"SendEmailA failed: {str(e)}")

def send_email_b():
    try:
        smtp_server = smtplib.SMTP('smtp.example.com', 587)
        smtp_server.sendmail("from@example.com", "to@example.com", "Email body")
        smtp_server.quit()
    except smtplib.SMTPException as e:
        raise Exception(f"SendEmailB failed: {str(e)}")
itlsoft commented 3 months ago
$(document).ready(function() {
    // Funkcja do aktualizacji wartości pól i tekstu HTML
    $('input[name="rdelegate"]').change(function() {
        // Znajdź wybraną opcję radio i przypisane do niej pola hidden
        var selectedOption = $('input[name="rdelegate"]:checked').closest('label');
        var semailValue = selectedOption.find('input[id^="semail"]').val();
        var sNameValue = selectedOption.find('input[id^="sName"]').val();

        // Ustaw wartość w polu hidden o id="semail"
        $('#semail').val(semailValue);

        // Ustaw tę samą wartość w polu hidden o id="demail"
        $('#demail').val($('#semail').val());

        // Ustaw wartość jako tekst HTML w elemencie z klasą "delegatedperson"
        $('.delegatedperson').html(sNameValue);
    });
});
itlsoft commented 2 months ago
$(document).ready(function() {
    // Inicjalizacja DataTables
    var table = $('#example').DataTable({
        "ajax": {
            "url": "/get_data",  // Twoja ścieżka Flask
            "type": "GET"
        },
        "columns": [
            { "data": "incident_id" },
            { "data": "name" },
            { "data": "status" }
            // Inne kolumny
        ]
    });

    // Funkcja do pobierania parametru z URL
    function getParameterByName(name) {
        name = name.replace(/[\[\]]/g, '\\$&');
        var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
            results = regex.exec(window.location.href);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, ' '));
    }

    // Pobierz parametr "incidentid" z URL
    var incidentID = getParameterByName('incidentid');

    if (incidentID) {
        // Ustaw wartość w polu input
        $('#IncID').val(incidentID);

        // Filtruj tabelę na podstawie wartości incidentID
        table.column(0).search(incidentID).draw();
    }

    // Opcjonalnie: Zdarzenie na zmianę wartości w polu input (ręczna filtracja)
    $('#IncID').on('keyup change', function() {
        table.column(0).search(this.value).draw();
    });
});
itlsoft commented 2 months ago
$(document).ready(function() {
    $('#exportBtn').click(function() {
        let csv = [];
        let rows = document.querySelectorAll(".exportTable tr");

        // Iterowanie po wierszach tabeli
        for (let i = 0; i < rows.length; i++) {
            let row = [];
            let cols = rows[i].querySelectorAll("td, th");

            // Iterowanie po komórkach wiersza
            for (let j = 0; j < cols.length; j++) {
                row.push(cols[j].innerText);
            }

            // Dodaj wiersz do CSV, rozdzielony przecinkami
            csv.push(row.join(","));
        }

        // Utworzenie pliku CSV
        let csvFile = new Blob([csv.join("\n")], { type: "text/csv" });
        let downloadLink = document.createElement("a");
        downloadLink.href = URL.createObjectURL(csvFile);
        downloadLink.download = "tabela.csv";

        // Automatyczne kliknięcie, aby pobrać plik
        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
    });
});
itlsoft commented 2 months ago

_ddb96ef5-583a-4235-9f4c-3747df622580 _07d3ff64-d2f4-4896-8f6c-c6ff17c92e44

itlsoft commented 2 months ago

SmartSelect_20240911_103431_LinkedIn

itlsoft commented 2 months ago
DECLARE @dbname NVARCHAR(128)
SET @dbname = 'YourDatabaseName';  -- Podaj nazwę swojej bazy danych

WITH ForeignKeys AS (
    SELECT 
        fk.name AS ForeignKeyName,
        tp.name AS ParentTableName,
        cp.name AS ParentColumnName,
        tr.name AS ReferencedTableName,
        cr.name AS ReferencedColumnName
    FROM 
        sys.foreign_keys fk
        INNER JOIN sys.tables tp ON fk.parent_object_id = tp.object_id
        INNER JOIN sys.tables tr ON fk.referenced_object_id = tr.object_id
        INNER JOIN sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id
        INNER JOIN sys.columns cp ON fkc.parent_object_id = cp.object_id AND fkc.parent_column_id = cp.column_id
        INNER JOIN sys.columns cr ON fkc.referenced_object_id = cr.object_id AND fkc.referenced_column_id = cr.column_id
)
SELECT
    'erDiagram' AS MermaidSyntax,
    STRING_AGG(
        CONCAT(
            '[', ParentTableName, '] ||--o{ [', ReferencedTableName, ']: "', ForeignKeyName, '"'
        ), CHAR(10)
    ) AS MermaidDiagramCode
FROM ForeignKeys
WHERE DB_NAME() = @dbname;
itlsoft commented 2 months ago
from flask import Flask, render_template, request, send_file
import mermaid  # Import python-mermaid
import os

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    mermaid_code = ''
    svg_content = ''
    if request.method == 'POST':
        mermaid_code = request.form.get('mermaid_code', '')

        # Generowanie SVG z kodu Mermaid.js
        if mermaid_code:
            svg_content = mermaid.render_mermaid(mermaid_code, format='svg')

    return render_template('index.html', mermaid_code=mermaid_code, svg_content=svg_content)

@app.route('/generate_svg', methods=['POST'])
def generate_svg():
    mermaid_code = request.form.get('mermaid_code', '')
    if mermaid_code:
        # Generowanie pliku SVG i zapisanie do pliku
        svg_content = mermaid.render_mermaid(mermaid_code, format='svg')
        with open('diagram.svg', 'w', encoding='utf-8') as svg_file:
            svg_file.write(svg_content)

        return send_file('diagram.svg', as_attachment=True, mimetype='image/svg+xml', download_name='diagram.svg')

    return "No Mermaid code provided", 400

if __name__ == '__main__':
    app.run(debug=True)
itlsoft commented 2 months ago
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mermaid.js ER Diagram Generator</title>
</head>
<body>

    <h1>Generate ER Diagram with Mermaid.js</h1>

    <form method="POST">
        <textarea name="mermaid_code" rows="10" cols="50" placeholder="Insert Mermaid.js code here...">{{ mermaid_code }}</textarea>
        <br><br>
        <button type="submit">Generate Diagram</button>
    </form>

    {% if svg_content %}
        <h2>ER Diagram Preview:</h2>
        <div>
            {{ svg_content | safe }}
        </div>
    {% endif %}

    <br>
    <form action="/generate_svg" method="POST">
        <textarea name="mermaid_code" hidden>{{ mermaid_code }}</textarea>
        <button type="submit">Download as SVG</button>
    </form>

</body>
</html>
itlsoft commented 2 months ago
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pływający Przycisk</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        body {
            margin: 0;
            padding: 0;
            height: 2000px; /* Aby móc przewijać stronę */
        }
        #floatingButton {
            position: fixed;
            width: 50px;
            height: 50px;
            background-color: red;
            color: white;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: grab;
            z-index: 9999;
            right: 10px;
            bottom: 50px;
        }
        #floatingButton.grabbing {
            cursor: grabbing;
            border: 2px dashed #FFF; /* Dodanie białego border po 1 sekundzie */
        }
        .modal-content {
            background-color: #fff;
        }
    </style>
</head>
<body>

    <!-- Przycisk -->
    <div id="floatingButton">
        <i class="fas fa-question"></i>
    </div>

    <!-- Modal -->
    <div class="modal fade" id="Modal3" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalLabel">Tytuł Modala</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    Treść modala
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Zamknij</button>
                </div>
            </div>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
    <script src="https://kit.fontawesome.com/a076d05399.js"></script>
    <script>
        $(document).ready(function() {
            // Pobierz pozycję z localStorage
            let x = localStorage.getItem('buttonX') || null;
            let y = localStorage.getItem('buttonY') || null;

            // Ustaw domyślną pozycję, jeśli pozycja nie jest jeszcze zapisana
            if (x !== null && y !== null) {
                $('#floatingButton').css({
                    left: x + 'px',
                    top: y + 'px',
                    right: 'auto',
                    bottom: 'auto'
                });
            }

            let isDragging = false;
            let offsetX, offsetY;
            let mouseDownTime, longPressTimeout;

            // Zmienne do kontrolowania długiego naciśnięcia
            const LONG_PRESS_TIME = 1000; // 1 sekunda

            // Przeciąganie przycisku
            $('#floatingButton').on('mousedown', function(e) {
                // Zapisz czas naciśnięcia przycisku
                mouseDownTime = new Date().getTime();
                isDragging = false; // Na początku nie przeciągamy

                // Opóźnienie, aby wykryć długie naciśnięcie
                longPressTimeout = setTimeout(function() {
                    // Zmieniamy wygląd przycisku po długim naciśnięciu
                    $('#floatingButton').addClass('grabbing');
                    offsetX = e.clientX - $('#floatingButton').offset().left;
                    offsetY = e.clientY - $('#floatingButton').offset().top;
                    isDragging = true; // Dopiero po długim naciśnięciu zaczyna się przeciąganie
                }, LONG_PRESS_TIME);
            });

            $(document).on('mousemove', function(e) {
                if (isDragging) {
                    $('#floatingButton').css({
                        left: e.clientX - offsetX + 'px',
                        top: e.clientY - offsetY + 'px',
                        right: 'auto',
                        bottom: 'auto'
                    });
                }
            });

            $(document).on('mouseup', function() {
                clearTimeout(longPressTimeout); // Usuń timeout, aby uniknąć późnego uruchomienia

                let mouseUpTime = new Date().getTime();
                let clickDuration = mouseUpTime - mouseDownTime;

                // Jeśli kliknięcie trwało mniej niż 1 sekundę, otwórz modal
                if (clickDuration < LONG_PRESS_TIME) {
                    $('#Modal3').modal('show');
                }

                if (isDragging) {
                    isDragging = false;
                    $('#floatingButton').removeClass('grabbing'); // Usuń efekt grabbing

                    // Pobierz aktualną szerokość i wysokość okna
                    let windowWidth = $(window).width();
                    let windowHeight = $(window).height();

                    // Pobierz aktualną pozycję przycisku
                    let buttonX = $('#floatingButton').offset().left;
                    let buttonY = $('#floatingButton').offset().top;

                    // Sprawdź, czy pozycja przekracza okno przeglądarki
                    if (buttonX + $('#floatingButton').width() > windowWidth || buttonY + $('#floatingButton').height() > windowHeight) {
                        // Usuń wartości z localStorage, jeśli przycisk jest poza widocznym obszarem
                        localStorage.removeItem('buttonX');
                        localStorage.removeItem('buttonY');
                        alert("Przycisk został przeniesiony poza obszar okna. Zresetowano pozycję.");
                    } else {
                        // Zapisz pozycję do localStorage, jeśli przycisk jest w widocznym obszarze
                        localStorage.setItem('buttonX', buttonX);
                        localStorage.setItem('buttonY', buttonY);
                    }
                }
            });
        });
    </script>

</body>
</html>
itlsoft commented 2 months ago
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Formularz</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        $(document).ready(function() {
            // Funkcja sprawdzająca zawartość pola textarea
            function checkTextarea() {
                var textLength = $('#justification').val().length;

                if (textLength > 0) {
                    // Jeśli tekst jest obecny, usuń klasę disabled i aktywuj przycisk
                    $('#submit').removeClass('disabled').prop('disabled', false);
                } else {
                    // Jeśli pole jest puste, dodaj klasę disabled i wyłącz przycisk
                    $('#submit').addClass('disabled').prop('disabled', true);
                }
            }

            // Wywołanie funkcji podczas załadowania strony (sprawdzenie początkowego stanu)
            checkTextarea();

            // Podpinamy metodę keyup pod textarea, aby sprawdzać w czasie rzeczywistym
            $('#justification').on('keyup', function() {
                checkTextarea();
            });
        });
    </script>
    <style>
        .disabled {
            background-color: grey;
            pointer-events: none;
            cursor: not-allowed;
        }
    </style>
</head>
<body>

    <form>
        <textarea id="justification" placeholder="Wpisz uzasadnienie..."></textarea><br>
        <button id="submit" class="disabled" disabled>Wyślij</button>
    </form>

</body>
</html>
itlsoft commented 2 months ago
$(document).ready(function(){
    // Funkcja ograniczająca tekst do 50 znaków z trzema kropkami
    function truncateText(text, maxLength) {
        if (text.length > maxLength) {
            return text.substring(0, maxLength) + '...';
        } else {
            return text;
        }
    }

    // Iterujemy po wszystkich opcjach w select i skracamy ich tekst do 50 znaków, jednocześnie zapisując pełny tekst w atrybucie data-full-text
    $('#just option').each(function() {
        var fullText = $(this).text(); // Pobieramy pełny tekst opcji
        $(this).attr('data-full-text', fullText); // Zapisujemy pełny tekst w atrybucie
        var truncatedText = truncateText(fullText, 50); // Skracamy tekst do 50 znaków
        $(this).text(truncatedText); // Ustawiamy skrócony tekst w opcji
    });

    // Obsługa przenoszenia pełnego tekstu wybranej opcji do textarea
    $('#just').change(function(){
        var fullText = $('#just option:selected').attr('data-full-text'); // Pobieramy pełny tekst z atrybutu data-full-text
        $('#justarea').val(fullText); // Przenosimy pełny tekst do textarea
    });
});
itlsoft commented 2 months ago
$(document).ready(function() {
    // Funkcja do uruchamiania animacji alertu
    function animateAlert(alert) {
        var progressLine = alert.find('.progress-line'); // Znajdujemy linię postępu

        // Pobieramy bieżącą szerokość elementu alert
        var alertWidth = alert.width(); 

        // Ustawiamy początkową szerokość paska na bieżącą szerokość alertu
        progressLine.css('width', alertWidth + 'px');

        // Teraz uruchamiamy animację zmniejszania szerokości
        progressLine.animate({ width: '0%' }, 20000, function() {
            // Po zakończeniu animacji ustaw linię na przezroczystą
            progressLine.css('background-color', 'transparent');
        });

        // Animacja znikania alertu po 20 sekundach
        alert.delay(20000).slideUp(1000, function() {
            alert.remove(); // Usuwa alert z DOM po zakończeniu
        });
    }

    // Uruchom animację dla każdego alertu
    $('.alert').each(function() {
        var alert = $(this);
        animateAlert(alert);
    });
});
itlsoft commented 2 months ago
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Toggle Container</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        .container-wrapper {
            display: flex;
            align-items: center;
        }

        .button-container {
            display: flex;
            overflow: hidden;
            white-space: nowrap;
            transition: width 0.5s ease;
        }

        .con-item {
            margin-right: 10px;
        }

        .toggle-button {
            cursor: pointer;
            margin-left: 10px;
        }
    </style>
</head>
<body>

<div class="container-wrapper">
    <div class="button-container">
        <button class="btn btn-primary con-item">Button 1</button>
        <select class="form-control con-item">
            <option>Option 1</option>
            <option>Option 2</option>
        </select>
        <textarea class="form-control con-item" rows="1" cols="10">Textarea</textarea>
        <a href="#" class="con-item">Link</a>
        <div class="con-item">Div content</div>
    </div>
    <button class="btn btn-secondary toggle-button">More ></button>
</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
    var isExpanded = false;

    // Początkowa szerokość kontenera przycisków (możemy zacząć od pierwszego elementu)
    var initialWidth = $('.button-container .con-item:first').outerWidth(true); // Szerokość pierwszego elementu

    // Ustaw początkową szerokość na szerokość jednego elementu
    $('.button-container').css('width', initialWidth);

    // Funkcja obsługująca kliknięcie przycisku
    $('.toggle-button').on('click', function() {
        if (!isExpanded) {
            // Zwiększamy szerokość kontenera na szerokość wszystkich elementów .con-item
            var fullWidth = 0;
            $('.button-container .con-item').each(function() {
                fullWidth += $(this).outerWidth(true); // Szerokość każdego elementu z marginesami
            });
            $('.button-container').css('width', fullWidth); // Rozwiń kontener
            $(this).text('Less <'); // Zmieniamy tekst przycisku
        } else {
            // Zwijamy kontener do szerokości jednego elementu
            $('.button-container').css('width', initialWidth); // Zwiń kontener
            $(this).text('More >'); // Zmieniamy tekst przycisku
        }
        isExpanded = !isExpanded; // Przełącz stan
    });
});
</script>

</body>
</html>
itlsoft commented 1 month ago
/* Wrapper for the alert and blur effect */
.alert-container {
    position: relative;
    display: inline-block;
}

/* Blurred background */
.blur-background {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: url('your-image-or-color-here') no-repeat center center;
    background-size: cover;
    filter: blur(8px);
    z-index: 1;
    border-radius: 5px;
}

/* Alert box with semi-transparent background */
.alert-message {
    position: relative;
    background-color: rgba(255, 255, 255, 0.9);
    z-index: 2;
    border-radius: 5px;
    padding: 15px;
}
itlsoft commented 1 month ago
$(document).ready(function() {
    // Dodajemy pionową linię do body
    $('body').append('<div id="line"></div>');

    // Aktualizujemy pozycję linii przy ruchu myszy
    $(document).mousemove(function(e) {
        $('#line').css({
            left: e.pageX + 'px'
        });
    });
});
itlsoft commented 1 month ago
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Scroll Control</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <style>
        /* Styl do testowania */
        body {
            height: 2000px; /* Aby mieć co scrollować */
        }
        .delegatedarea {
            width: 200px;
            height: 100px;
            background-color: lightblue;
            position: fixed;
            bottom: 20px; /* Startowe położenie */
            right: 20px;
        }
    </style>
</head>
<body>

<div class="delegatedarea">
    Ten element ma być widoczny
</div>

<script>
$(document).ready(function() {
    // Funkcja sprawdzająca, czy element jest w obrębie widocznej części okna przeglądarki (viewportu)
    function isInViewport(element) {
        var elementTop = element.offset().top;
        var elementBottom = elementTop + element.outerHeight();

        var viewportTop = $(window).scrollTop();
        var viewportBottom = viewportTop + $(window).height();

        // Sprawdzamy czy choć część elementu jest widoczna
        return elementBottom > viewportTop && elementTop < viewportBottom;
    }

    // Funkcja do animowanego przesunięcia elementu, aby był widoczny
    function scrollElementIntoView(element) {
        var viewportTop = $(window).scrollTop();
        var viewportBottom = viewportTop + $(window).height();
        var elementTop = element.offset().top;
        var elementBottom = elementTop + element.outerHeight();

        if (elementBottom > viewportBottom) {
            // Jeśli dolna część elementu wychodzi poza widok, przesuwamy go do góry
            $('html, body').animate({
                scrollTop: elementBottom - $(window).height()
            }, 500);
        } else if (elementTop < viewportTop) {
            // Jeśli górna część elementu wychodzi poza widok, przesuwamy go w dół
            $('html, body').animate({
                scrollTop: elementTop
            }, 500);
        }
    }

    // Sprawdzamy, czy element z klasą "delegatedarea" jest widoczny
    if ($('.delegatedarea').is(':visible')) {
        // Nasłuchujemy scrollowania
        $(window).on('scroll', function() {
            if (!isInViewport($('.delegatedarea'))) {
                scrollElementIntoView($('.delegatedarea'));
            }
        });
    }
});
</script>

</body>
</html>
itlsoft commented 1 month ago
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Scroll Control</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <style>
        body {
            height: 2000px; /* Aby mieć co scrollować */
        }
        .delegatedarea {
            width: 200px;
            height: 100px;
            background-color: lightblue;
            position: fixed;
            bottom: 20px; /* Startowa pozycja */
            right: 20px;
            transition: bottom 0.5s ease; /* Dodajemy płynność animacji */
        }
    </style>
</head>
<body>

<div class="delegatedarea">
    Ten element ma być zawsze widoczny
</div>

<script>
$(document).ready(function() {
    // Funkcja sprawdzająca, czy element jest w obrębie widocznej części okna przeglądarki (viewportu)
    function isInViewport(element) {
        var elementTop = element.offset().top;
        var elementBottom = elementTop + element.outerHeight();

        var viewportTop = $(window).scrollTop();
        var viewportBottom = viewportTop + $(window).height();

        // Sprawdzamy czy choć część elementu jest widoczna
        return elementBottom > viewportTop && elementTop < viewportBottom;
    }

    // Nasłuchujemy scrollowania strony
    $(window).on('scroll', function() {
        var $element = $('.delegatedarea');
        var scrollPosition = $(window).scrollTop();
        var windowHeight = $(window).height();
        var elementHeight = $element.outerHeight();

        // Sprawdzamy, czy element jest widoczny
        if (!isInViewport($element)) {
            // Jeśli element jest poza widokiem, ustawiamy nową pozycję, by wrócił na ekran
            // Przesuwamy element w dół lub w górę zależnie od scrolla
            var newBottom = windowHeight - (scrollPosition + windowHeight - $element.offset().top);

            if (newBottom < 0) newBottom = 0; // Upewniamy się, że nie wyjdzie poza górę ekranu
            if (newBottom > windowHeight - elementHeight) newBottom = windowHeight - elementHeight; // Upewniamy się, że nie wyjdzie poza dół ekranu

            $element.css('bottom', newBottom + 'px'); // Ustawiamy nową wartość 'bottom'
        }
    });
});
</script>

</body>
</html>
itlsoft commented 1 month ago
.image-container {
    position: relative;
    width: 1000px;
    height: 800px;
    overflow: hidden;
    background-image: url('img/header.jpg');
    background-size: cover;
    background-position: center;
}

.image-layer {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-image: url('img/header.jpg');
    background-size: cover;
    background-position: center;
    filter: blur(0px);
    opacity: 0.5; /* Opcjonalnie, delikatnie mniejsze nasycenie */
    transition: filter 5s ease-in-out;
}

.image-layer.blur {
    filter: blur(8px);
}

$(document).ready(function() {
    var $imageLayer = $('.image-layer');
    var intervalTime = 10000; // Czas interwału animacji w milisekundach
    var movementRange = 20; // Zakres ruchu w pikselach

    function randomMovement() {
        var randomX = (Math.random() * movementRange) - (movementRange / 2); // Losowy ruch w lewo/prawo
        var randomY = (Math.random() * movementRange) - (movementRange / 2); // Losowy ruch w górę/dół

        // Przesuwanie obrazu
        $imageLayer.css({
            transform: `translate(${randomX}px, ${randomY}px)`
        });
    }

    function animateBlur() {
        $imageLayer.toggleClass('blur'); // Zmiana rozmycia
    }

    // Wywołujemy funkcje w stałych interwałach
    setInterval(function() {
        randomMovement();
        animateBlur();
    }, intervalTime);
});
itlsoft commented 1 month ago
document.addEventListener('DOMContentLoaded', () => {
  // Inicjalizacja edytora
  const editor = grapesjs.init({
    container: '#editor',
    height: '100%',
    width: 'auto',
    plugins: ['grapesjs-mjml'],
    pluginsOpts: {
      'grapesjs-mjml': {}
    },
    storageManager: false,  // Wyłączamy automatyczne zapisywanie do localStorage
    blockManager: {
      appendTo: '#blocks',  // Panel boczny
      blocks: [
        {
          id: 'mj-section',  // Musimy zacząć od dodania sekcji
          label: 'Section',
          content: '<mj-section><mj-column><mj-text>New Section</mj-text></mj-column></mj-section>',
          category: 'Layout',
          draggable: true,  // Element może być przeciągany
          selectable: true,
        },
        {
          id: 'mj-column',  // Następnie dodajemy kolumny
          label: 'Column',
          content: '<mj-column><mj-text>New Column</mj-text></mj-column>',
          category: 'Layout',
          draggable: true,
          selectable: true,
        },
        {
          id: 'mj-text',
          label: 'Text',
          content: '<mj-text>This is a text block</mj-text>',
          category: 'Basic',
          // Dodajemy ograniczenia: tylko wewnątrz `mj-column`
          draggable: '[data-gjs-type=mj-column]',
          selectable: true,
        },
        {
          id: 'mj-button',
          label: 'Button',
          content: '<mj-button>Click me</mj-button>',
          category: 'Basic',
          draggable: '[data-gjs-type=mj-column]',  // Tylko wewnątrz kolumny
          selectable: true,
        },
        {
          id: 'mj-image',
          label: 'Image',
          content: '<mj-image src="https://via.placeholder.com/150" />',
          category: 'Basic',
          draggable: '[data-gjs-type=mj-column]',  // Tylko wewnątrz kolumny
          selectable: true,
        },
        {
          id: 'mj-divider',
          label: 'Divider',
          content: '<mj-divider />',
          category: 'Basic',
          draggable: '[data-gjs-type=mj-column]',  // Tylko wewnątrz kolumny
          selectable: true,
        }
      ],
    }
  });

  // Zapisz szablon na serwerze
  document.getElementById('save-template').addEventListener('click', () => {
    const content = editor.getHtml();  // Pobiera zawartość w formacie MJML
    const filename = document.getElementById('template-filename').value || 'template.mjml';

    fetch('/save_template', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        content: content,
        filename: filename
      }),
    })
    .then(response => response.json())
    .then(data => {
      alert(data.message);
    })
    .catch(error => {
      console.error('Error:', error);
    });
  });
});

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Email Template Builder</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/grapesjs/0.20.3/css/grapes.min.css">
    <style>
        body, html {
            margin: 0;
            padding: 0;
            height: 100%;
            font-family: Arial, sans-serif;
            box-sizing: border-box;
        }

        #app {
            display: flex;
            height: 100vh;
        }

        #blocks {
            width: 300px;
            background-color: #f7f7f7;
            padding: 10px;
            box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1);
            overflow-y: auto;
        }

        #editor {
            flex-grow: 1;
            display: flex;
            justify-content: center;
            align-items: center;
            background-color: #ffffff;
            padding: 20px;
        }

        #editor-container {
            width: 700px; /* Sekcja na środku o szerokości 700px */
            background-color: #f0f0f0;
            padding: 20px;
            box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1);
            border-radius: 10px;
        }

        .mjml-button {
            display: inline-block;
            padding: 10px 20px;
            background-color: #ff4c4c; /* Wewnętrzny kolor czerwony */
            color: white;
            text-align: center;
            text-decoration: none;
            border-radius: 5px;
        }

        .mjml-section {
            margin-bottom: 20px;
        }

        .mjml-header {
            font-size: 24px;
            font-weight: bold;
            margin-bottom: 10px;
            text-align: center;
        }

        .mjml-text {
            font-size: 16px;
            line-height: 1.5;
            margin-bottom: 20px;
            text-align: center;
        }

    </style>
</head>
<body>
    <div id="app">
        <!-- Panel boczny z blokami -->
        <div id="blocks">
            <h3>Blocks</h3>
        </div>

        <!-- Główny edytor -->
        <div id="editor">
            <div id="editor-container">
                <!-- Przykładowa sekcja MJML -->
                <section class="mjml-section">
                    <div class="mjml-header">Example Email Header</div>
                    <div class="mjml-text">
                        This is an example email body. You can add text, images, and buttons.
                    </div>
                    <div class="mjml-button">
                        Click Me!
                    </div>
                </section>
                <section class="mjml-section">
                    <div class="mjml-button">
                        Another Button
                    </div>
                </section>
            </div>
        </div>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/grapesjs/0.20.3/grapes.min.js"></script>
    <script src="https://unpkg.com/grapesjs-mjml"></script>
    <script src="/static/app.js"></script>
</body>
</html>
itlsoft commented 1 month ago
# database.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "mssql+pyodbc://username:password@server/database?driver=ODBC+Driver+17+for+SQL+Server"

# Tworzenie połączenia
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# Funkcja do pobierania sesji z bazy danych
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# models.py

from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    user_id = Column(Integer, primary_key=True, index=True)
    name = Column(String)
    email = Column(String)
    created_at = Column(DateTime)

# main.py

from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from database import get_db
import json

app = FastAPI()

# Pobieranie danych GET
@app.get("/users/{user_id}")
async def get_user_data(user_id: int, db: Session = Depends(get_db)):
    # Wywołanie procedury składowanej
    result = db.execute(f"EXEC dbo.GetUserData @user_id={user_id}")
    user = result.fetchone()

    if user:
        return {
            "user_id": user.user_id,
            "name": user.name,
            "email": user.email,
            "created_at": user.created_at
        }
    else:
        raise HTTPException(status_code=404, detail="User not found")

# Zapisywanie danych POST
@app.post("/users/")
async def insert_user_data(user_id: int, user_id2: int, date_from: str, date_to: str, reason_text: str, reason_id: int, db: Session = Depends(get_db)):
    # Wywołanie procedury składowanej
    db.execute(f"""
        EXEC dbo.InsertUserData 
        @user_id={user_id}, 
        @user_id2={user_id2}, 
        @date_from='{date_from}', 
        @date_to='{date_to}', 
        @reason_text='{reason_text}', 
        @reason_id={reason_id}
    """)
    db.commit()

    return {"status": "Data inserted successfully"}
itlsoft commented 1 week ago

PSX_20241118_124522

itlsoft commented 1 week ago

PSX_20241118_130035

itlsoft commented 5 days ago

image_86c2d499-baf8-4de8-807f-7aee00fc232e20241121_134136