from flask import Blueprint, request, jsonify, send_from_directory from app.api.services import ( LoginService, RegisterService, AccountService, ProductsService, AuthorizationService, MyProductsService, ContactService, OfficeAuthService, OfficeDashboardService, WebContentsService, SubscriptionsService, CommonDataService, OfficeCustomerService, AutomationCalls, GenerativesService, OfficeUsersService, OfficeTemplatesService, OfficeCountryService, WebsiteService, FileUploadService, ReportService ) from app.api.services.comments import CommentsService from app.models import Country from app.utils.logger import logger from app.api.middlewares import enforce_json, require_auth import os from flask_jwt_extended import ( JWTManager, jwt_required, create_access_token, get_jwt_identity, create_refresh_token, ) from werkzeug.utils import secure_filename import requests api = Blueprint("api", __name__) # @api.before_request # def cors_middleware(): # """Middleware applied globally to all API routes in this blueprint""" # return enforce_json() # Swagger JSON file @api.route("/swagger.json", methods=["GET"]) def swagger_json(): swagger_dir = os.path.join("swagger") return send_from_directory(swagger_dir, "merms_swagger.json") @api.route("/swagger/") def serve_paths(filename): swagger_dir = os.path.join("swagger") return send_from_directory(swagger_dir, filename) @api.route("/panel/auth/reset", methods=["POST"]) # @jwt_required() def merms_reset(): data = request.get_json() response = LoginService.process_reset(data) return response @api.route("/panel/auth/resetverify", methods=["POST"]) # @jwt_required() def merms_resetverify(): data = request.get_json() response = LoginService.verify_reset(data) return response @api.route("/panel/auth/resetcomplete", methods=["POST"]) # @jwt_required() def merms_resetcomplete(): data = request.get_json() response = LoginService.complete_reset(data) return response @api.route("/panel/Login", methods=["POST"]) @jwt_required() def merms_login(): data = request.get_json() response = LoginService.process_request(data) return response @api.route("/panel/Register", methods=["POST"]) @jwt_required() def merms_register(): data = request.get_json() response = RegisterService.start_account_register(data) return response # /panel/Register/verify @api.route("/panel/Register/verify", methods=["POST"]) @jwt_required() def merms_register_verify(): data = request.get_json() response = RegisterService.process_verify(data) return response @api.route("/panel/Register/complete", methods=["POST"]) @jwt_required() def merms_register_complete(): data = request.get_json() response = RegisterService.process_complete(data) return response UPLOAD_FOLDER = '/app/uploads' # '/uploads' ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'} def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @api.route('/upload/profile-picture', methods=['GET', 'POST']) def upload_profile_picture_file(): response = [] if request.method == 'POST': logger.info('POST CALLED 0') logger.info(f'POST CALLED 1 {request}') logger.info(f'POST CALLED 2 {request.data}') logger.info(f'POST CALLED 3 {request.files}') member_uid = request.form.get('member_uid' '') token = request.form.get('token', '') # Use .get() to avoid errors if key is missing logger.info(f'POST CALLED 22 {member_uid}') logger.info(f'POST CALLED 33 {token}') # check if the post request has the file part if 'file' not in request.files: logger.info('No file part') file = request.files['file'] # If the user does not select a file, the browser submits an # empty file without a filename. logger.info(f'POST CALLED 4 {file}') if file.filename == '': logger.info('No selected file') if file and allowed_file(file.filename): logger.info(f'POST CALLED 5 {file.filename}') response = FileUploadService.process_profile_file_upload("PROFILE_MEDIA", file, member_uid) if request.method == 'GET': logger.info('GET CALLED') return response @api.route('/upload/webfiles', methods=['GET', 'POST']) def upload_file(): response = [] if request.method == 'POST': logger.info('POST CALLED 0') logger.info(f'POST CALLED 1 {request}') logger.info(f'POST CALLED 2 {request.data}') logger.info(f'POST CALLED 3 {request.files}') member_uid = request.form.get('member_uid' '') token = request.form.get('token', '') # Use .get() to avoid errors if key is missing logger.info(f'POST CALLED 22 {member_uid}') logger.info(f'POST CALLED 33 {token}') # check if the post request has the file part if 'file' not in request.files: logger.info('No file part') file = request.files['file'] # If the user does not select a file, the browser submits an # empty file without a filename. logger.info(f'POST CALLED 4 {file}') if file.filename == '': logger.info('No selected file') if file and allowed_file(file.filename): logger.info(f'POST CALLED 5 {file.filename}') response = FileUploadService.process_file_upload("WEB_MEDIA", file, member_uid) # save_path=UPLOAD_FOLDER + "/" + "F000000000001" # filename = secure_filename(file.filename) # final_save_path = os.path.join(save_path, filename) # logger.info(f'POST CALLED 6 {final_save_path}') # # try: # if not os.path.isdir(save_path): # os.makedirs(save_path) # # file.save(final_save_path) # except Exception as e: # # Catches any other exception and stores the message in 'e' # print(f"An unexpected error occurred: {e}") if request.method == 'GET': logger.info('GET CALLED') return response @api.route("/panel/account", methods=["POST"]) @jwt_required() def merms_account(): data = request.get_json() response = AccountService.process_request(data) return response @api.route("/panel/account/profile", methods=["POST"]) @jwt_required() def merms_account_profile(): data = request.get_json() response = AccountService.process_profile_data(data) return response @api.route("/panel/account/profile-update", methods=["POST"]) @jwt_required() def merms_account_profile_update(): data = request.get_json() response = AccountService.update_profile_data(data) return response @api.route("/panel/account/profilelinks-update", methods=["POST"]) @jwt_required() def merms_account_profile_links_update(): data = request.get_json() response = AccountService.update_profile_link_data(data) return response @api.route("/panel/account-bar", methods=["POST"]) @jwt_required() def merms_account_bar(): data = request.get_json() response = AccountService.process_bar_data(data) return response @api.route("/panel/account/bar", methods=["POST"]) @jwt_required() def merms_account_bar2(): data = request.get_json() response = AccountService.process_bar_data(data) return response @api.route("/panel/account/actions", methods=["POST"]) @jwt_required() def merms_account_actions(): data = request.get_json() response = AccountService.process_action_request(data) return response @api.route("/panel/account/productsurl", methods=["POST"]) @jwt_required() def merms_account_product_url(): data = request.get_json() response = ProductsService.product_url_request(data) return response @api.route("/panel/account/payments", methods=["POST"]) @jwt_required() def merms_account_payments(): data = request.get_json() response = AccountService.process_payments_data(data) return response @api.route("/panel/account/media-files", methods=["POST"]) def get_websitefiles(): data = request.get_json() # logger.info(f"Route FileUploadService URL Data ==>>>> {data}") response = FileUploadService.member_webfiles(data) return response @api.route("/panel/account/products/url", methods=["POST"]) def myproduct_url(): data = request.get_json() # logger.info(f"Route Product URL Data ==>>>> {data}") response = ProductsService.product_url_request(data) return response @api.route("/panel/account/products/refresh", methods=["POST"]) def myproduct_refresh(): data = request.get_json() # logger.info(f"Route Product URL Data ==>>>> {data}") response = ProductsService.myproduct_refresh_request(data) return response @api.route("/panel/account/products/templates", methods=["POST"]) # @token_required def get_myproduct_templates(): # Call the Template service data = request.get_json() # logger.info(f"Route Product Template Data ==>>>> {data}") response = MyProductsService.mpproduct_template_data(data) return response @api.route("/panel/report/topics", methods=["POST"]) @jwt_required() def merms_report_topics(): data = request.get_json() response = ReportService.process_report_topic_request(data) return response @api.route("/panel/report/item/payment", methods=["POST"]) @jwt_required() def merms_report_topics_payment(): data = request.get_json() response = ReportService.process_report_topic_item("PAYMENT", data) return response @api.route("/panel/report/item/system", methods=["POST"]) @jwt_required() def merms_report_topics_system(): data = request.get_json() response = ReportService.process_report_topic_item("SYSTEM",data) return response @api.route("/panel/report/item/product", methods=["POST"]) @jwt_required() def merms_report_topics_product(): data = request.get_json() response = ReportService.process_report_topic_item("PRODUCT",data) return response # @api.route("/panel/report/topics", methods=["POST"]) # @jwt_required() # def merms_report_topics(): # data = request.get_json() # response = ReportService.process_report_topic_request(data) # return response @api.route("/panel/account/products/color-styles", methods=["POST"]) # @token_required def get_myproduct_colorstyles(): # Call the ColorStyles service data = request.get_json() # logger.info(f"Route Product ColorStyles Data ==>>>> {data}") response = MyProductsService.mpproduct_colostyles_data(data) return response @api.route("/panel/account/template/activate", methods=["POST"]) # @token_required def get_myproduct_templates_activate(): data = request.get_json() # logger.info(f"Route Product Template Data ==>>>> {data}") response = MyProductsService.process_set_template(data) # try to refresh now if response: try: refresh_data = { "token": data["token"], "uid": data["uid"], "product_id": data["product_id"], "subscription_uid": response["subscription_uid"] } logger.info(f"Starting Template Refresh with Data ==>>>> {refresh_data}") refresh_response = ProductsService.myproduct_refresh_request(refresh_data) except: print("An exception occurred in setting refresh") return response @api.route("/panel/account/colorstyle/activate", methods=["POST"]) # @token_required def get_myproduct_colorstyle_activate(): data = request.get_json() # logger.info(f"Route Product Template Data ==>>>> {data}") response = MyProductsService.process_set_colorstyle(data) return response @api.route("/panel/contacts", methods=["POST"]) def merms_contacts(): data = request.get_json() # logger.info(f"Route ContactService URL Data ==>>>> {data}") response = ContactService.process_request(data) return response @api.route("/panel/comments", methods=["POST"]) def merms_site_comments(): data = request.get_json() # logger.info(f"Route CommentsService URL Data ==>>>> {data}") response = CommentsService.process_comments_request(data) return response @api.route("/panel/account/products", methods=["POST"]) @jwt_required() def merms_products(): data = request.get_json() response = ProductsService.process_request(data) return response @api.route("/panel/myproduct/dash", methods=["POST"]) def myproduct_dash(): data = request.get_json() # logger.info(f"Route MyProduct Data ==>>>> {data}") response = MyProductsService.process_request(data) return response @api.route("/panel/myproduct/external-url", methods=["POST"]) def set_external_url(): data = request.get_json() # logger.info(f"Route MyProduct Data ==>>>> {data}") response = MyProductsService.set_external_url(data) return response @api.route("/panel/myproduct/settings", methods=["POST"]) def myproduct_settings(): data = request.get_json() # logger.info(f"Route Save MyProduct Settings Data ==>>>> {data}") response = MyProductsService.process_settings(data) return response @api.route("/panel/myproduct/configuration", methods=["POST"]) def myproduct_configuration(): data = request.get_json() # logger.info(f"Route Save MyProduct Settings Data ==>>>> {data}") response = MyProductsService.product_configuration(data) return response @api.route("/panel/myproduct/template-config", methods=["POST"]) def myproduct_template_config(): data = request.get_json() logger.info(f"Route Save MyProduct_Template_Config ==>>>> {data}") response = MyProductsService.template_configuration(data) return response @api.route("/panel/myproduct/template-media-set", methods=["POST"]) def myproduct_template_set_media(): data = request.get_json() logger.info(f"Route Save MyProduct_Template_Config ==>>>> {data}") response = MyProductsService.template_set_media(data) return response @api.route("/panel/myproduct/settings/values", methods=["POST"]) def myproduct_settings_values(): data = request.get_json() # logger.info(f"Route Get MyProduct Settings Data ==>>>> {data}") response = MyProductsService.process_settings_values(data) return response @api.route("/panel/subscription/products", methods=["POST"]) def subscription_products(): data = request.get_json() # logger.info(f"Route Subscription Product Data ==>>>> {data}") response = SubscriptionsService.subscription_available_products(data) return response # @api.route("/panel/subscription/start", methods=["POST"]) def subscription_sessuib_start(): data = request.get_json() # logger.info(f"Route Subscription Session Start ==>>>> {data}") response = SubscriptionsService.subscription_session_start(data) return response # /panel/myproduct/subscription @api.route("/panel/myproduct/subscription", methods=["POST"]) def myproduct_subscription(): data = request.get_json() # logger.info(f"Route MyProduct Data ==>>>> {data}") response = MyProductsService.process_subscription(data) # GenerativesService.process_generatives_list(response) #INITIATE GENERATIVES return response # /panel/myproduct/provision @api.route("/panel/myproduct/provision", methods=["POST"]) def myproduct_provision(): data = request.get_json() # logger.info(f"Route MyProduct Data ==>>>> {data}") response = MyProductsService.process_provision(data) return response @api.route("/panel/myproduct/provision-actions", methods=["POST"]) def myproduct_provision_actions(): data = request.get_json() # logger.info(f"Route MyProduct Provision Actions ==>>>> {data}") response = MyProductsService.process_provision_actions(data) return response @api.route("/stripe/payments", methods=["POST"]) def stripe_payments_webhook_post(): try: logger.info(f"Route Stripe Webhook POST ENTRY==>>>>") data = request.get_json() logger.info(f"Route Stripe Webhook POST ==>>>> {data}") SubscriptionsService.subscription_webhook_start(data) return [] except Exception as e: # A general exception handler for any other type of exception logger.error(f"An unexpected error occurred: {e}") else: # Code to execute if no exception occurs in the try block logger.info("Operation successful!") finally: # Code that will always execute, regardless of whether an exception occurred or not logger.info("This block always runs.") # /panel/account/calendar @api.route("/panel/account/calendar", methods=["POST"]) def mycalendar_dash(): data = request.get_json() # logger.info(f"Route Calendar Data ==>>>> {data}") response = AccountService.process_calendar(data) return response # /panel/account/calendar @api.route("/panel/account/startprofile", methods=["POST"]) def account_startprofile(): data = request.get_json() logger.info(f"Route StartProfile Data ==>>>> {data}") response = AccountService.process_startprofile(data) return response # Health Check Endpoint @api.route("/test", methods=["GET"]) def test_check(): data = {"uid": "ok", "token": "jjjfjfjfjfjjf"} logger.info(f"Member Actions Error: {data}") response = AccountService.process_action_request(data) # response = ProductsService.process_request(data) return {"status": "ok"}, 200 # ====================================================== @api.route('/website/contact', methods=['POST']) def website_contact(): data = request.get_json() # Save Website Contact Data result = WebsiteService.save_web_contact_data(data) # # Check if result is a tuple (error response) # if isinstance(result, tuple): # return jsonify(result[0]), result[1] return jsonify(result) # ====================================================== @api.route('/office/login', methods=['POST']) def login(): data = request.get_json() # Check if username and password are provided if not data or 'username' not in data or 'password' not in data: return jsonify({ 'error': 'Missing credentials', 'message': 'Username and password are required' }), 400 username = data.get('username', '') password = data.get('password', '') # Call the login method from AuthService result = OfficeAuthService.login(username, password) # Check if result is a tuple (error response) if isinstance(result, tuple): return jsonify(result[0]), result[1] return jsonify(result) @api.route('/office/dashboard', methods=['GET']) # @token_required def get_dashboard(): # Call the dashboard service result = OfficeDashboardService.get_dashboard_data() return jsonify(result) @api.route('/office/country', methods=['GET']) # @token_required def get_office_country(): # Call the dashboard service result = OfficeCountryService.get_office_country_list() return jsonify(result) @api.route('/office/set-country', methods=['POST']) # @token_required def set_office_country(): # Call the dashboard service data = request.get_json() result = OfficeCountryService.set_office_country_list(data) return jsonify(result) @api.route('/office/customers', methods=['GET']) # @token_required def get_customer_office(): # Call the dashboard service filters = { 'username': request.args.get('username'), 'email': request.args.get('email'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } response = OfficeCustomerService.get_customer_data(filters) return response @api.route('/office/subcriptions', methods=['GET']) # @token_required def get_subscriptions_list_office(): # Call the dashboard service filters = { 'product_id': request.args.get('product_id'), 'member_id': request.args.get('member_id'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } response = SubscriptionsService.get_subscription_data(filters) return response @api.route('/office/subscription-view', methods=['GET']) # @token_required def get_subcriptions_view_office(): # Call the dashboard service filters = { 'subscription_uid': request.args.get('subscription_uid') } response = OfficeDashboardService.get_subscription_view_data(filters) return response @api.route('/office/template/set-custom', methods=['POST']) # @token_required def get_set_custom_template_office(): data = request.get_json() response = OfficeTemplatesService.set_office_custom_template(data) return response @api.route('/office/template/set-template', methods=['POST']) # @token_required def get_set_template_office(): data = request.get_json() response = OfficeTemplatesService.set_office_user_template(data) return response @api.route('/office/template/custom-add', methods=['POST']) # @token_required def get_create_custom_template_office(): data = request.get_json() response = OfficeTemplatesService.create_custom_template(data) return response @api.route('/office/billings', methods=['GET']) # @token_required def get_subscription_billings_office(): # Call the dashboard service filters = { 'product_id': request.args.get('product_id'), 'member_id': request.args.get('member_id'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } result = OfficeDashboardService.get_payments_data(filters) return jsonify(result) @api.route('/office/file-uploads', methods=['GET']) # @token_required def get_file_uploads_office(): # Call the dashboard service filters = { 'product_id': request.args.get('product_id'), 'member_id': request.args.get('member_id'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } result = OfficeDashboardService.get_file_upload_data(filters) return jsonify(result) @api.route('/office/transaction', methods=['GET']) def get_subscription_transaction_office(): # Call the dashboard service filters = { 'product_id': request.args.get('product_id'), 'member_id': request.args.get('member_id'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } result = OfficeDashboardService.get_payments_data(filters) return jsonify(result) @api.route('/office/recent-signup', methods=['GET']) def get_recent_signup_office(): # Call the dashboard service filters = {} result = OfficeDashboardService.get_recent_signup_data(filters) return jsonify(result) @api.route('/office/recent-account', methods=['GET']) def get_recent_account_office(): # Call the dashboard service filters = {} result = OfficeDashboardService.get_recent_account_data(filters) return jsonify(result) @api.route('/office/right-sidebar', methods=['GET']) def get_office_sidebar(): # Call the dashboard service filters = {} result = OfficeDashboardService.get_office_sidebar(filters) return jsonify(result) @api.route('/office/users', methods=['GET']) def get_office_users(): logger.info('API::get office users') filters = {} result = OfficeUsersService.get_office_users(filters) return jsonify(result) @api.route('/office/products', methods=['GET']) def get_product_office(): # Call the dashboard service filters = {} result = OfficeDashboardService.get_office_products(filters) return jsonify(result) @api.route('/office/product-view', methods=['GET']) def get_product_view_office(): # Call the dashboard service filters = { 'product_id': request.args.get('product_id') } result = OfficeDashboardService.get_office_product_detail(filters) return jsonify(result) @api.route('/office/product-update', methods=['POST']) def get_product_update_office(): # Call the dashboard service data = request.get_json() result = OfficeDashboardService.get_office_product_update(data) return jsonify(result) @api.route('/office/rebuild-template', methods=['POST']) def product_rebuild_office(): # Call the dashboard service data = request.get_json() result = OfficeTemplatesService.office_template_rebuild(data) return jsonify(result) @api.route('/office/update-profile', methods=['POST']) def member_office_update(): # Call the dashboard service data = request.get_json() result = OfficeCustomerService.update_customer_data(data) return jsonify(result) @api.route('/office/products-templates', methods=['GET']) def get_product_templates(): # Call the dashboard service filters = { 'product_id': request.args.get('product_id'), 'provision_name': request.args.get('provision_name'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } result = OfficeDashboardService.get_office_product_templates(filters) return jsonify(result) @api.route('/office/account-view', methods=['GET']) def get_office_accoint_view(): # Call the office account viiew logger.info('API::get office account view') filters = { 'member_uid': request.args.get('member_uid') } response = OfficeDashboardService.get_office_account_view(filters) # return response return jsonify(response) @api.route('/office/custom-templates', methods=['GET']) def get_custom_templates(): # Call the dashboard service filters = { 'custom_id': request.args.get('custom_id'), 'provision_name': request.args.get('provision_name'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } logger.info("CALLING :: Getting office custom templates") result = OfficeDashboardService.get_office_custom_templates(filters) return jsonify(result) # ===================================================== @api.route('/web/contents', methods=['GET']) # @token_required def get_web_contents(): # Call the dashboard service provision_uid = request.args.get('provision_uid') result = WebContentsService.get_web_contents_data(provision_uid) return jsonify(result) # ===================================================== @api.route('/web/contacts', methods=['POST']) # @token_required def get_web_receive_contacts(): # Call the dashboard service logger.info("CONTACT FORM FROM ****** ") data = request.get_json() result = ContactService.process_save_contacts(data) return jsonify(result) # ===================================================== @api.route('/web/generatives', methods=['GET']) def get_refresh_generatives(): logger.info("START TO ENTER GENERATIVE") # Call the dashboard service data = [] result = GenerativesService.process_generatives_list(data) return jsonify(result) # ===================================================== @api.route('/web/traffic', methods=['POST']) # @token_required def get_web_traffic(): # Call the dashboard service data = request.get_json() result = WebContentsService.get_web_trafic_data(data) return jsonify(data) # =================================================== # Common Data # ===================================================== @api.route('/panel/common/practice', methods=['POST']) # @token_required def common_practice(): # Call the dashboard service data = request.get_json() logger.info(f"Route common Practice Data ==>>>> {data}") response = CommonDataService.available_practices(data) return response # return jsonify(result) # =================================================== # Health Check Endpoint @api.route("/testemail", methods=["GET"]) def email_check(): data = {} AccountService.process_test_email(data) return {"status": "ok"}, 200 # =================================================== # Health Check Endpoint @api.route("/cron/refresh-payhx", methods=["GET"]) def refresh_payhx(): data = {} AutomationCalls.process_stripe_payment_refresh(data) return {"status": "ok"}, 200 # Automatic Reporting @api.route("/auto/dailyReport", methods=["GET"]) def refresh_daily_report(): data = {} # AutomationCalls.process_stripe_payment_refresh(data) return {"status": "ok"}, 200 # Generative Actions @api.route("/auto/generativeAction", methods=["GET"]) def refresh_generative_action(): data = {} logger.info(f"Generative Actions ==>>>>") GenerativesService.process_generatives_list(data) #INITIATE GENERATIVES return {"status": "ok"}, 200 # Health Check Endpoint @api.route("/health", methods=["GET"]) def health_check(): return {"status": "ok"}, 200 # Authorize endpoint @api.route("/Authorize", methods=["POST"]) def authorize(): data = request.get_json() # logger.info(f"Authorize request received: {data}") response = AuthorizationService.process_request(data) return response # Authorize refresh endpoint @api.route("/AuthorizeRefresh", methods=["POST"]) @jwt_required(refresh=True) def refresh(): data = request.get_json() # logger.info(f"Authorize refresh request received: {data}") response = AuthorizationService.process_refresh_request() return response @api.route("/cron/report-subscription", methods=["GET"]) def report_subs(): data = {} AccountService.process_test_email(data) return {"status": "ok"}, 200