Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/tenant #92

Merged
merged 4 commits into from
Aug 31, 2023
Merged
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
4 changes: 3 additions & 1 deletion backend/app/controllers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .step_api import bp as step_api_bp
from .step_requirement import bp as step_requirement_bp
from .setting import bp as setting_bp
from .tenant_pro import bp as tenant_bp

def register_controllers(app):
app.register_blueprint(user_bp)
Expand All @@ -19,4 +20,5 @@ def register_controllers(app):
app.register_blueprint(step_subtask_bp)
app.register_blueprint(step_code_bp)
app.register_blueprint(step_devops_bp)
app.register_blueprint(setting_bp)
app.register_blueprint(setting_bp)
app.register_blueprint(tenant_bp)
15 changes: 10 additions & 5 deletions backend/app/controllers/requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from app.pkgs.tools.i18b import getI18n
from app.models.requirement import Requirement
from app.models.requirement_memory_pro import RequirementMemory
from app.models.tenant_pro import Tenant
from config import REQUIREMENT_STATUS_NotStarted, GRADE

bp = Blueprint('requirement', __name__, url_prefix='/requirement')
Expand All @@ -17,11 +18,12 @@ def clear_up():
print("clear_up failed:"+str(e))

session[session["username"]] = getEmptyTaskInfo()
# todo 1
session['tenant_id'] = 0
session.update()
tenant_name = "DevOpsGPT"
if GRADE != "base":
tenant = Tenant.get_tenant_baseinfo_by_id(session["tenant_id"])
tenant_name = tenant["name"]

return {"username": session["username"], "info": session[session["username"]]}
return {"username": session["username"], "tenant_name": tenant_name, "tenant_id": session["tenant_id"], "info": session[session["username"]]}


@bp.route('/setup_app', methods=['POST'])
Expand All @@ -35,7 +37,10 @@ def setup_app():
username = session['username']
tenantID = session['tenant_id']

requirement = Requirement.create_requirement(tenantID, "", "New", appID, 1, sourceBranch, featureBranch, REQUIREMENT_STATUS_NotStarted, 0, 0)
if GRADE != "base" and not Tenant.check_quota(tenantID):
raise Exception(_("You have exceeded your quota limit, please check your business bill."))

requirement = Requirement.create_requirement(tenantID, "New requirement", "New", appID, 1, sourceBranch, featureBranch, REQUIREMENT_STATUS_NotStarted, 0, 0)

session[username]['memory']['task_info'] = {
"app_id": appID,
Expand Down
3 changes: 3 additions & 0 deletions backend/app/controllers/step_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ def gen_interface_doc():
userPrompt = request.json.get('user_prompt')
username = session["username"]
requirementID = request.json.get('task_id')
tenant_id = session['tenant_id']

# todo Use llm to determine which interface documents to adjust
req = Requirement.get_requirement_by_id(requirementID)
apiDoc, success = getServiceSwagger(req["app_id"], 0)

Requirement.update_requirement(requirement_id=requirementID, original_requirement=userPrompt)

msg, success = clarifyAPI(requirementID, userPrompt, apiDoc)

session[username]['memory']['originalPrompt'] = userPrompt
Expand Down
13 changes: 11 additions & 2 deletions backend/app/controllers/step_requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
from app.pkgs.prompt.prompt import clarifyRequirement
from app.pkgs.knowledge.app_info import getAppArchitecture
from app.models.requirement import Requirement
from app.models.tenant_pro import Tenant
from app.models.tenant_bill_pro import TenantBill
from config import GRADE
from config import REQUIREMENT_STATUS_InProgress

bp = Blueprint('step_requirement', __name__, url_prefix='/step_requirement')
Expand All @@ -17,14 +20,20 @@ def clarify():
globalContext = request.json.get('global_context')
userName = session["username"]
requirementID = request.json.get('task_id')
tenantID = session['tenant_id']

req = Requirement.get_requirement_by_id(requirementID)

if not req["app_id"] or req["app_id"] < 1 :
if not req or req["app_id"] < 1 :
raise Exception(_("Please select the application you want to develop."))

if len(globalContext) < 4 :
Requirement.update_requirement(requirement_id=requirementID, original_requirement=userPrompt, status=REQUIREMENT_STATUS_InProgress)
Requirement.update_requirement(requirement_id=requirementID, requirement_name=userPrompt, status=REQUIREMENT_STATUS_InProgress)

if GRADE != "base" and not Tenant.check_quota(tenantID):
raise Exception(_("You have exceeded your quota limit, please check your business bill."))
if GRADE != "base":
TenantBill.record_requirement(tenantID, userName, requirementID, userPrompt)

appArchitecture, _ = getAppArchitecture(req["app_id"])
msg, success = clarifyRequirement(requirementID, userPrompt, globalContext, appArchitecture)
Expand Down
20 changes: 20 additions & 0 deletions backend/app/controllers/tenant_pro.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from flask import Blueprint
from app.controllers.common import json_response
from app.pkgs.tools.i18b import getI18n

bp = Blueprint('tenant', __name__, url_prefix='/tenant')

def test():
pass

@bp.route('/get_all', methods=['GET'])
@json_response
def get_all():
_ = getI18n("controllers")
raise Exception(_("The current version does not support this feature."))

@bp.route('/create', methods=['POST'])
@json_response
def create():
_ = getI18n("controllers")
raise Exception(_("The current version does not support this feature."))
10 changes: 8 additions & 2 deletions backend/app/controllers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from app.pkgs.tools.i18b import getFrontendText
from app.models.user import User
from app.models.user_pro import UserPro
from app.models.tenant_user_pro import TenantUser
from config import GRADE
from config import LANGUAGE

Expand All @@ -25,10 +26,16 @@ def register():
if GRADE == "base":
raise Exception("The current version does not support this feature")
else:
# todo 0
current_tenant = 0
tus = TenantUser.get_tenant_user_by_invite_email(email)
for tu in tus:
current_tenant = tu["tenant_id"]

user = UserPro.create_user(username, password, phone_number, email, zone_language, current_tenant)

for tu in tus:
TenantUser.active_tenant_user(tu["tenant_user_id"], user.user_id)

return user.username

@bp.route('/login', methods=['POST'])
Expand All @@ -50,7 +57,6 @@ def login():
session['tenant_id'] = userinfo["current_tenant"]

if ok:
session['logged_in'] = True
session['username'] = username
return {'message': _('Login successful.')}
else:
Expand Down
34 changes: 18 additions & 16 deletions backend/app/models/requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,24 @@ def get_all_requirements(tenantID=None):
@staticmethod
def get_requirement_by_id(requirement_id):
req = Requirement.query.get(requirement_id)
req_dict = {
'requirement_id': req.requirement_id,
'requirement_name': req.requirement_name,
'original_requirement': req.original_requirement,
'app_id': req.app_id,
'user_id': req.user_id,
'default_source_branch': req.default_source_branch,
'default_target_branch': req.default_target_branch,
'status': req.status,
'satisfaction_rating': req.satisfaction_rating,
'completion_rating': req.completion_rating,
'created_at': req.created_at,
'updated_at': req.updated_at,
'app': Application.get_application_by_id(req.app_id)
}
return req_dict
if req:
req_dict = {
'requirement_id': req.requirement_id,
'requirement_name': req.requirement_name,
'original_requirement': req.original_requirement,
'app_id': req.app_id,
'user_id': req.user_id,
'default_source_branch': req.default_source_branch,
'default_target_branch': req.default_target_branch,
'status': req.status,
'satisfaction_rating': req.satisfaction_rating,
'completion_rating': req.completion_rating,
'created_at': req.created_at,
'updated_at': req.updated_at,
'app': Application.get_application_by_id(req.app_id)
}
return req_dict
return None

@staticmethod
def update_requirement(requirement_id, requirement_name=None, original_requirement=None, app_id=None, user_id=None, status=None, satisfaction_rating=None, completion_rating=None):
Expand Down
3 changes: 3 additions & 0 deletions backend/app/models/tenant_bill_pro.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class TenantBill():
def test():
pass
3 changes: 3 additions & 0 deletions backend/app/models/tenant_pro.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Tenant():
def test():
pass
3 changes: 3 additions & 0 deletions backend/app/models/tenant_user_pro.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class TenantUser():
def test():
pass
29 changes: 28 additions & 1 deletion backend/app/pkgs/tools/i18b.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ def getFrontendText():
"app_list": _("APP List"),
"setting": _("Setting"),
"create_new": _("Create new"),
"back_to_list": _("Back to list page"),
"app_name": _("APP name"),
"app_intro": _("APP introduction"),
"app_base_branch": _("Base branch"),
Expand Down Expand Up @@ -122,5 +123,31 @@ def getFrontendText():
"password": _("Password"),
"register": _("Register"),
"email": _("Email"),
"phone": _("Phone"),
"tenant_name": _("Company Name"),
"tenant_status": _("Company Status"),
"tenant_description": _("Company Description"),
"tenant_billing_type": _("Billing type"),
"tenant_billing_quota": _("Billing quota"),
"tenant_created_at": _("Created"),
"tenant_billing_end": _("Plus expiry"),
"employee_count": _("Employee count"),
"industry_type": _("Industry type"),
"change_tenant": _("Switch Tenant"),
"tenant_member_count": _("Member Count"),
"create_tenant_notice": _("Please ensure that the information is accurate and we will review it within 24 hours to activate your account."),
"create_user_notice": _("In order to protect your rights, please ensure that the information is accurate."),
"enter": _("Enter"),
"show_tenant": _("Details"),
"members": _("Members"),
"country": _("Country"),
"role": _("Role"),
"phone": _("Phone Number"),
"add_member": _("Add member"),
"invite": _("Invite"),
"billing": _("Billing"),
"bill_type": _("Bill type"),
"bill_user": _("Operating user"),
"bill_date": _("Billing date"),
"remarks": _("Remarks"),
"operate": _("Operate"),
}
100 changes: 100 additions & 0 deletions backend/app/pkgs/tools/utils_tool.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import json
import re
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
import ssl

from app.pkgs.tools.llm import chatCompletion
from config import EMAIL_PASSWORD, EMAIL_PORT, EMAIL_SENDER, EMAIL_SERVER, EMAIL_SSL


def detect_programming_language(file_path):
Expand Down Expand Up @@ -97,3 +103,97 @@ def get_code_from_str(input_string):
output_string = match

return output_string

def send_email(receiver_email, subject, html_content):
# 邮件服务器的信息
smtp_server = EMAIL_SERVER
smtp_port = EMAIL_PORT

# 发件人和收件人信息
sender_email = EMAIL_SENDER
password = EMAIL_PASSWORD

msg = MIMEMultipart()
msg['From'] = sender_email
msg['To'] = receiver_email
msg['Subject'] = subject

html = """
<!DOCTYPE html>
<html>
<head>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
}

.container {
max-width: 600px;
margin: 0 auto;
background-color: #ffffff;
padding: 20px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
border-radius: 5px;
}

.header {
text-align: center;
padding: 20px 0;
}

.header h1 {
color: #333;
margin: 0;
}

.content {
padding: 20px 0;
}

.footer {
text-align: center;
padding: 20px 0;
color: #888;
font-size: 12px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>"""+subject+"""</h1>
</div>
<div class="content">
"""+html_content+"""
</div>
<div class="footer">
<p>本邮件为系统邮件,请勿回复。This email is a system email, please do not reply.</p>
<p>如有疑问,请添加我们的公众号:KuafuAI</p>
</div>
</div>
</body>
</html>

"""

html_part = MIMEText(html, 'html')
msg.attach(html_part)

# 建立与邮件服务器的连接并发送邮件
try:
if EMAIL_SSL:
context = ssl.create_default_context()
server = smtplib.SMTP_SSL(smtp_server, smtp_port, context=context)
else:
server = smtplib.SMTP(smtp_server, smtp_port)
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, msg.as_string())
server.quit()
print("邮件发送成功")
return True
except Exception as e:
print(f"邮件发送失败: {e}")
return False
5 changes: 5 additions & 0 deletions backend/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ def read_config(key):
CD_TOOLS = read_config("CD_TOOLS")
CD_ACCESS_KEY = read_config("CD_ACCESS_KEY")
CD_SECRET_KEY = read_config("CD_SECRET_KEY")
EMAIL_SERVER = read_config("EMAIL_SERVER")
EMAIL_PORT = read_config("EMAIL_PORT")
EMAIL_SSL = read_config("EMAIL_SSL")
EMAIL_SENDER = read_config("EMAIL_SENDER")
EMAIL_PASSWORD = read_config("EMAIL_PASSWORD")
except Exception as e:
print(f"\033[91mError: Failed to read the configuration, please copy a new env.yaml from env.yaml.tpl and reconfigure it according to the documentation. Error in env.yaml: {str(e)}. 读取配置错误,请重新从 env.yaml.tpl 复制一个 env.yaml 进行配置后重启程序。 \033[0m")
input("Press Enter to exit...")
Expand Down
Loading