From 112a99ffcb2991413c4410e73e73071b8de26a01 Mon Sep 17 00:00:00 2001 From: Kobe Date: Mon, 9 Jun 2025 09:54:37 +0200 Subject: [PATCH] adding instances --- __pycache__/app.cpython-313.pyc | Bin 8214 -> 10288 bytes __pycache__/models.cpython-313.pyc | Bin 35519 -> 37092 bytes migrations/versions/add_instances_table.py | 39 +++ models.py | 20 +- routes/__pycache__/main.cpython-313.pyc | Bin 78535 -> 83471 bytes routes/main.py | 94 +++++- templates/components/header.html | 33 +- templates/main/instances.html | 342 ++++++++++++++++++++- templates/settings/settings.html | 9 + 9 files changed, 523 insertions(+), 14 deletions(-) create mode 100644 migrations/versions/add_instances_table.py diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc index 4236a75183d4d9a540649f040ed80cf092434032..0244db845e75700f226a8997045d0d237bc528af 100644 GIT binary patch delta 4230 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 diff --git a/__pycache__/models.cpython-313.pyc b/__pycache__/models.cpython-313.pyc index 4d2cb8b11ead17eca43d0055c5ed3012ca36bdc6..961c0702dd59404b0a4514bc3c3d02b30eb00575 100644 GIT binary patch delta 688 zcmX|7O-vI}5Z*1V>=ygCT?$>mLZh)8451i|71W4?*s2L}qe(ToY-)pR=(fHshLTVk z;}3G7bYfcI&~hN+tppEEOw_X{_F%H<1rj}(5TnA~w+Ozxe3|*?&3yB{Pj5`$S55Xm zHk*~e=UaZ{QU30ty_I~hak}4PZ6*AKFvt*A zS#?5IX@{Kz+dv64{0jO0#~Vr?RHqwB2WV;#wu7`;I3_egcG?Hql4tR!wGpQw6LKBY zcPZK=*b2|P;9Z9szVa;=8rM7!^t2r^9)s<+hZ<0e;NS?Dy*n!Nr}bf z-y}iQY589YV=4Be2|GhR14LXyek1C{P^V-?ilybJaa4m{;i}a-cr*oOUv%}ljTpFlITaLgM6@cu_0Q8_JLlS}UjD9GkB~g{9 zHnJM2ks5bl%iN+nnIc`FOa5|TDX@M;bN1xIy1Tg;Duhb6%F*R$1+Cn#-qzd$xf{B} zwUC+5l$f%2*;_fga-w=lbDYmz(`}B0=zKJfikU*D!obY>V~b`B*0T6+@CW$j)_GzhDMmLiKO1%{fin9$_bgd!0^_pF;~%uc!7293C|P E1+iG-ng9R* delta 100 zcmaE|kZJ!^Cce+Syj%=G(7D7ZBRqT}p9G`HMs-tGmUIqHo6TLUd`(Q6+M64Cg&371 ufvSp3L4*;IxW!?Uo1apelWJGApOJw9h!~26Ht*^aVB-49z{h9^RtW$(6d0`l diff --git a/migrations/versions/add_instances_table.py b/migrations/versions/add_instances_table.py new file mode 100644 index 0000000..74928fb --- /dev/null +++ b/migrations/versions/add_instances_table.py @@ -0,0 +1,39 @@ +"""add instances table + +Revision ID: add_instances_table +Revises: +Create Date: 2024-03-19 10:00:00.000000 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'add_instances_table' +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_table('instances', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=100), nullable=False), + sa.Column('company', sa.String(length=100), nullable=False), + sa.Column('rooms_count', sa.Integer(), nullable=False, server_default='0'), + sa.Column('conversations_count', sa.Integer(), nullable=False, server_default='0'), + sa.Column('data_size', sa.Float(), nullable=False, server_default='0.0'), + sa.Column('payment_plan', sa.String(length=20), nullable=False, server_default='Basic'), + sa.Column('main_url', sa.String(length=255), nullable=False), + sa.Column('status', sa.String(length=20), nullable=False, server_default='inactive'), + sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP')), + sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP')), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('name'), + sa.UniqueConstraint('main_url') + ) + + +def downgrade(): + op.drop_table('instances') \ No newline at end of file diff --git a/models.py b/models.py index 895e7b2..2ded884 100644 --- a/models.py +++ b/models.py @@ -493,4 +493,22 @@ class ManagementAPIKey(db.Model): creator = db.relationship('User', backref=db.backref('created_api_keys', cascade='all, delete-orphan')) def __repr__(self): - return f'' \ No newline at end of file + return f'' + +class Instance(db.Model): + __tablename__ = 'instances' + + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(100), nullable=False) + company = db.Column(db.String(100), nullable=False) + rooms_count = db.Column(db.Integer, default=0) + conversations_count = db.Column(db.Integer, default=0) + data_size = db.Column(db.Float, default=0) # in GB + payment_plan = db.Column(db.String(50), nullable=False) + main_url = db.Column(db.String(255), nullable=False) + status = db.Column(db.String(20), default='inactive') # active or inactive + created_at = db.Column(db.DateTime, default=datetime.utcnow) + updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) + + def __repr__(self): + return f'' \ No newline at end of file diff --git a/routes/__pycache__/main.cpython-313.pyc b/routes/__pycache__/main.cpython-313.pyc index 321d4b778cc2f842c16ae5df2a5a4e7e3317b5da..4f74aa36d2d7019964413f69e87c99603b017c53 100644 GIT binary patch delta 11793 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 Jn3+DM{SS1f07n1- delta 8779 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', methods=['PUT']) + @login_required + @require_password_change + def update_instance(instance_id): + if not os.environ.get('MASTER', 'false').lower() == 'true': + return jsonify({'error': 'Unauthorized'}), 403 + + instance = Instance.query.get_or_404(instance_id) + data = request.get_json() + + try: + instance.name = data.get('name', instance.name) + instance.company = data.get('company', instance.company) + instance.payment_plan = data.get('payment_plan', instance.payment_plan) + instance.main_url = data.get('main_url', instance.main_url) + instance.status = data.get('status', instance.status) + + db.session.commit() + return jsonify({ + 'message': 'Instance updated successfully', + 'instance': { + 'id': instance.id, + 'name': instance.name, + 'company': instance.company, + 'rooms_count': instance.rooms_count, + 'conversations_count': instance.conversations_count, + 'data_size': instance.data_size, + 'payment_plan': instance.payment_plan, + 'main_url': instance.main_url, + 'status': instance.status + } + }) + except Exception as e: + db.session.rollback() + return jsonify({'error': str(e)}), 400 + + @main_bp.route('/instances/', methods=['DELETE']) + @login_required + @require_password_change + def delete_instance(instance_id): + if not os.environ.get('MASTER', 'false').lower() == 'true': + return jsonify({'error': 'Unauthorized'}), 403 + + instance = Instance.query.get_or_404(instance_id) + try: + db.session.delete(instance) + db.session.commit() + return jsonify({'message': 'Instance deleted successfully'}) + except Exception as e: + db.session.rollback() + return jsonify({'error': str(e)}), 400 UPLOAD_FOLDER = '/app/uploads/profile_pics' if not os.path.exists(UPLOAD_FOLDER): diff --git a/templates/components/header.html b/templates/components/header.html index 83c5717..6b9293a 100644 --- a/templates/components/header.html +++ b/templates/components/header.html @@ -1,4 +1,4 @@ -{% macro header(title, description="", button_text="", button_url="", icon="fa-folder", button_class="", button_icon="fa-plus", button_style="") %} +{% macro header(title, description="", button_text="", button_url="", icon="fa-folder", button_class="", button_icon="fa-plus", button_style="", buttons=None) %}
@@ -11,8 +11,31 @@

{{ description }}

{% endif %}
- {% if button_text and button_url %} -
+
+ {% if buttons %} + {% for button in buttons %} + {% if button.url == "#" %} + + {% else %} + + {% endif %} + {% endfor %} + {% elif button_text and button_url %} {% if button_url == "#" %}
- {% endif %} + {% endif %} +
diff --git a/templates/main/instances.html b/templates/main/instances.html index f10ab10..ba34f97 100644 --- a/templates/main/instances.html +++ b/templates/main/instances.html @@ -7,14 +7,344 @@ {{ header( title="Instances", description="Manage your DocuPulse instances", - button_text="", - button_url="", - icon="fa-server" + icon="fa-server", + buttons=[ + { + 'text': 'Launch New Instance', + 'url': '#', + 'icon': 'fa-rocket', + 'class': 'btn-primary', + 'onclick': 'showAddInstanceModal()' + }, + { + 'text': 'Add Existing Instance', + 'url': '#', + 'icon': 'fa-link', + 'class': 'btn-primary', + 'onclick': 'showAddExistingInstanceModal()' + } + ] ) }} -
-
-

Instance management will be available soon.

+
+
+
+
+
+
+ + + + + + + + + + + + + + + + {% for instance in instances %} + + + + + + + + + + + + {% endfor %} + +
NameCompanyRoomsConversationsDataPayment PlanMain URLStatusActions
{{ instance.name }}{{ instance.company }}{{ instance.rooms_count }}{{ instance.conversations_count }}{{ "%.1f"|format(instance.data_size) }} GB{{ instance.payment_plan }}{{ instance.main_url }} + + {{ instance.status|title }} + + +
+ + +
+
+
+
+
+
+ + + + + + + + + + +{% endblock %} + +{% block extra_js %} + {% endblock %} \ No newline at end of file diff --git a/templates/settings/settings.html b/templates/settings/settings.html index d0931d5..754ebc7 100644 --- a/templates/settings/settings.html +++ b/templates/settings/settings.html @@ -35,6 +35,7 @@ Theme Colors + {% if not is_master %} + {% endif %} + {% if not is_master %} + + {% endif %}
+ {% if not is_master %}
{{ company_info_tab(site_settings, form, csrf_token) }} @@ -88,12 +94,14 @@
{{ email_templates_tab(email_templates, csrf_token) }}
+ {% endif %}
{{ mails_tab(mails, csrf_token, users, total_pages, current_page) }}
+ {% if not is_master %}
{{ security_tab() }} @@ -103,6 +111,7 @@
{{ events_tab(events, csrf_token, users, total_pages, current_page) }}
+ {% endif %}