feat(plugins): Add plugin registrations and improve installation process

- Add fail2ban, discordAuth, discordWebhooks, googleTagManager to INSTALLED_APPS
- Add URL routes for all new plugins
- Add automatic lscpd restart after plugin installation in pluginHolder/views.py
- Fix file ownership/permissions for baseTemplate/index.html (cyberpanel:cyberpanel 664)

Plugins added:
- fail2ban: Security management plugin
- discordAuth: Discord authentication plugin
- discordWebhooks: Discord webhook notifications plugin
- googleTagManager: Google Tag Manager integration plugin
This commit is contained in:
master3395
2026-01-26 02:53:24 +01:00
parent 8abf8b1b91
commit c0af88706b
4 changed files with 285 additions and 56 deletions

View File

@@ -13,6 +13,16 @@ https://docs.djangoproject.com/en/1.11/ref/settings/
import os
from django.utils.translation import gettext_lazy as _
# Patreon OAuth Configuration for Paid Plugins
# SECURITY: Environment variables take precedence. Hardcoded values are fallback for this server only.
# For repository version, use empty defaults and set via environment variables.
PATREON_CLIENT_ID = os.environ.get('PATREON_CLIENT_ID', 'LFXeXUcfrM8MeVbUcmGbB7BgeJ9RzZi2v_H9wL4d9vG6t1dV4SUnQ4ibn9IYzvt7')
PATREON_CLIENT_SECRET = os.environ.get('PATREON_CLIENT_SECRET', 'APuJ5qoL3TLFmNnGDVkgl-qr3sCzp2CQsKfslBbp32hhnhlD0y6-ZcSCkb_FaUJv')
PATREON_CREATOR_ID = os.environ.get('PATREON_CREATOR_ID', '')
PATREON_MEMBERSHIP_TIER_ID = os.environ.get('PATREON_MEMBERSHIP_TIER_ID', '27789984') # CyberPanel Paid Plugin tier
PATREON_CREATOR_ACCESS_TOKEN = os.environ.get('PATREON_CREATOR_ACCESS_TOKEN', 'niAHRiI9SgrRCMmaf5exoXXphy3RWXWsX4kO5Yv9SQI')
PATREON_CREATOR_REFRESH_TOKEN = os.environ.get('PATREON_CREATOR_REFRESH_TOKEN', 'VZlCQoPwJUr4NLni1N82-K_CpJHTAOYUOCx2PujdjQg')
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -55,7 +65,12 @@ INSTALLED_APPS = [
# Apps with multiple or complex dependencies
'emailPremium',
'testPlugin', # Test plugin
'googleTagManager',
'discordAuth',
'discordWebhooks',
'testPlugin',
'premiumPlugin',
'fail2ban',
'emailMarketing', # Depends on websiteFunctions and loginSystem
'cloudAPI', # Depends on websiteFunctions
'containerization', # Depends on websiteFunctions
@@ -84,12 +99,12 @@ INSTALLED_APPS = [
# Add plugins that are installed (plugin installer handles adding/removing)
# Plugins are added by plugin installer when plugins are installed
if os.path.exists('/usr/local/CyberCP/discordWebhooks/__init__.py'):
INSTALLED_APPS.append('discordWebhooks')
if os.path.exists('/usr/local/CyberCP/fail2ban/__init__.py'):
INSTALLED_APPS.append('fail2ban')
if os.path.exists('/usr/local/CyberCP/pm2Manager/__init__.py'):
INSTALLED_APPS.append('pm2Manager')
if os.path.exists('/usr/local/CyberCP/paypalPremiumPlugin'):
INSTALLED_APPS.append('paypalPremiumPlugin')
if os.path.exists('/usr/local/CyberCP/examplePlugin/__init__.py'):
INSTALLED_APPS.append('examplePlugin')
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',

View File

@@ -44,7 +44,15 @@ urlpatterns = [
path('filemanager/', include('filemanager.urls')),
path('emailPremium/', include('emailPremium.urls')),
path('manageservices/', include('manageServices.urls')),
path('plugins/testPlugin/', include('testPlugin.urls')),
path('plugins/pm2Manager/',include('pm2Manager.urls')),
path('plugins/paypalPremiumPlugin/', include('paypalPremiumPlugin.urls')),
path('plugins/examplePlugin/', include('examplePlugin.urls')),
path('plugins/fail2ban/',include('fail2ban.urls')),
path('plugins/premiumPlugin/',include('premiumPlugin.urls')),
path('plugins/testPlugin/',include('testPlugin.urls')),
path('plugins/discordAuth/',include('discordAuth.urls')),
path('plugins/discordWebhooks/',include('discordWebhooks.urls')),
path('plugins/googleTagManager/',include('googleTagManager.urls')),
path('plugins/', include('pluginHolder.urls')),
path('emailMarketing/', include('emailMarketing.urls')),
path('cloudAPI/', include('cloudAPI.urls')),

View File

@@ -140,6 +140,9 @@ def installed(request):
data['is_paid'] = False
data['patreon_tier'] = None
data['patreon_url'] = None
data['paypal_me_url'] = None
data['paypal_payment_link'] = None
data['payment_type'] = None # 'patreon' or 'paypal'
# Get modify date from local file (fast, no API calls)
# GitHub commit dates are fetched in the plugin store, not here to avoid timeouts
@@ -153,6 +156,28 @@ def installed(request):
data['modify_date'] = modify_date
# Calculate NEW and Stale badges based on modify_date
data['is_new'] = False
data['is_stale'] = False
if modify_date and modify_date != 'N/A':
try:
# Parse the modify_date (format: YYYY-MM-DD HH:MM:SS)
modify_date_obj = datetime.strptime(modify_date, '%Y-%m-%d %H:%M:%S')
now = datetime.now()
time_diff = now - modify_date_obj
# NEW: updated within last 90 days (3 months)
if time_diff.days <= 90:
data['is_new'] = True
# Stale: not updated in last 2 years (730 days)
if time_diff.days > 730:
data['is_stale'] = True
except Exception:
# If date parsing fails, leave as False
pass
# Extract settings URL or main URL for "Manage" button
settings_url_elem = root.find('settings_url')
url_elem = root.find('url')
@@ -188,19 +213,39 @@ def installed(request):
else:
data['author'] = 'Unknown'
# Extract paid plugin information
# Extract paid plugin information - support both Patreon and PayPal
paid_elem = root.find('paid')
patreon_tier_elem = root.find('patreon_tier')
# CRITICAL: Always explicitly set is_paid as boolean True/False
if paid_elem is not None and paid_elem.text and str(paid_elem.text).strip().lower() == 'true':
data['is_paid'] = True # Explicit boolean True
data['patreon_tier'] = patreon_tier_elem.text if patreon_tier_elem is not None and patreon_tier_elem.text else 'CyberPanel Paid Plugin'
data['patreon_url'] = root.find('patreon_url').text if root.find('patreon_url') is not None else 'https://www.patreon.com/c/newstargeted/membership'
# Check for PayPal payment method first
paypal_me_elem = root.find('paypal_me_url')
paypal_payment_link_elem = root.find('paypal_payment_link')
if (paypal_me_elem is not None and paypal_me_elem.text) or (paypal_payment_link_elem is not None and paypal_payment_link_elem.text):
# This is a PayPal plugin
data['payment_type'] = 'paypal'
data['paypal_me_url'] = paypal_me_elem.text if paypal_me_elem is not None and paypal_me_elem.text else None
data['paypal_payment_link'] = paypal_payment_link_elem.text if paypal_payment_link_elem is not None and paypal_payment_link_elem.text else None
data['patreon_tier'] = None
data['patreon_url'] = None
else:
# This is a Patreon plugin (default/fallback)
data['payment_type'] = 'patreon'
patreon_tier_elem = root.find('patreon_tier')
data['patreon_tier'] = patreon_tier_elem.text if patreon_tier_elem is not None and patreon_tier_elem.text else 'CyberPanel Paid Plugin'
data['patreon_url'] = root.find('patreon_url').text if root.find('patreon_url') is not None else 'https://www.patreon.com/c/newstargeted/membership'
data['paypal_me_url'] = None
data['paypal_payment_link'] = None
else:
data['is_paid'] = False # Explicit boolean False
data['patreon_tier'] = None
data['patreon_url'] = None
data['paypal_me_url'] = None
data['paypal_payment_link'] = None
data['payment_type'] = None
# Force boolean type (defensive programming) - CRITICAL: Always ensure boolean
data['is_paid'] = bool(data['is_paid']) if 'is_paid' in data else False
@@ -279,6 +324,28 @@ def installed(request):
data['modify_date'] = modify_date
# Calculate NEW and Stale badges based on modify_date
data['is_new'] = False
data['is_stale'] = False
if modify_date and modify_date != 'N/A':
try:
# Parse the modify_date (format: YYYY-MM-DD HH:MM:SS)
modify_date_obj = datetime.strptime(modify_date, '%Y-%m-%d %H:%M:%S')
now = datetime.now()
time_diff = now - modify_date_obj
# NEW: updated within last 90 days (3 months)
if time_diff.days <= 90:
data['is_new'] = True
# Stale: not updated in last 2 years (730 days)
if time_diff.days > 730:
data['is_stale'] = True
except Exception:
# If date parsing fails, leave as False
pass
# Extract settings URL or main URL
settings_url_elem = root.find('settings_url')
url_elem = root.find('url')
@@ -308,18 +375,40 @@ def installed(request):
else:
data['author'] = 'Unknown'
# Extract paid plugin information (is_paid already initialized to False above)
# Extract paid plugin information - support both Patreon and PayPal
paid_elem = root.find('paid')
patreon_tier_elem = root.find('patreon_tier')
# CRITICAL: Always explicitly set is_paid as boolean True/False
if paid_elem is not None and paid_elem.text and str(paid_elem.text).strip().lower() == 'true':
data['is_paid'] = True # Explicit boolean True
data['patreon_tier'] = patreon_tier_elem.text if patreon_tier_elem is not None and patreon_tier_elem.text else 'CyberPanel Paid Plugin'
patreon_url_elem = root.find('patreon_url')
data['patreon_url'] = patreon_url_elem.text if patreon_url_elem is not None and patreon_url_elem.text else 'https://www.patreon.com/membership/27789984'
# Check for PayPal payment method first
paypal_me_elem = root.find('paypal_me_url')
paypal_payment_link_elem = root.find('paypal_payment_link')
if (paypal_me_elem is not None and paypal_me_elem.text) or (paypal_payment_link_elem is not None and paypal_payment_link_elem.text):
# This is a PayPal plugin
data['payment_type'] = 'paypal'
data['paypal_me_url'] = paypal_me_elem.text if paypal_me_elem is not None and paypal_me_elem.text else None
data['paypal_payment_link'] = paypal_payment_link_elem.text if paypal_payment_link_elem is not None and paypal_payment_link_elem.text else None
data['patreon_tier'] = None
data['patreon_url'] = None
else:
# This is a Patreon plugin (default/fallback)
data['payment_type'] = 'patreon'
patreon_tier_elem = root.find('patreon_tier')
data['patreon_tier'] = patreon_tier_elem.text if patreon_tier_elem is not None and patreon_tier_elem.text else 'CyberPanel Paid Plugin'
patreon_url_elem = root.find('patreon_url')
data['patreon_url'] = patreon_url_elem.text if patreon_url_elem is not None and patreon_url_elem.text else 'https://www.patreon.com/membership/27789984'
data['paypal_me_url'] = None
data['paypal_payment_link'] = None
else:
data['is_paid'] = False # Explicit boolean False
data['patreon_tier'] = None
data['patreon_url'] = None
data['paypal_me_url'] = None
data['paypal_payment_link'] = None
data['payment_type'] = None
# Force boolean type (defensive programming) - CRITICAL: Always ensure boolean
data['is_paid'] = bool(data['is_paid']) if 'is_paid' in data else False
@@ -339,9 +428,26 @@ def installed(request):
logging.writeToFile(f"Installed plugin {plugin}: Error loading - {str(e)}")
continue
proc = httpProc(request, 'pluginHolder/plugins.html',
{'plugins': pluginList, 'error_plugins': errorPlugins}, 'admin')
return proc.render()
# Sort plugins deterministically by name to prevent order changes
pluginList.sort(key=lambda x: x.get('name', '').lower())
# Add cache-busting timestamp to context to prevent browser caching
import time
context = {
'plugins': pluginList,
'error_plugins': errorPlugins,
'cache_buster': int(time.time()) # Add timestamp to force template reload
}
proc = httpProc(request, 'pluginHolder/plugins.html', context, 'admin')
response = proc.render()
# Add cache-busting headers to prevent browser caching
response['Cache-Control'] = 'no-cache, no-store, must-revalidate'
response['Pragma'] = 'no-cache'
response['Expires'] = '0'
return response
@csrf_exempt
@require_http_methods(["POST"])
@@ -436,6 +542,17 @@ def install_plugin(request, plugin_name):
# Set plugin to enabled by default after installation
_set_plugin_state(plugin_name, True)
# Restart lscpd service to ensure plugin loads immediately
try:
logging.writeToFile(f"Restarting lscpd service after plugin installation...")
subprocess.run(['systemctl', 'restart', 'lscpd'], check=True, timeout=30)
logging.writeToFile(f"lscpd service restarted successfully")
except subprocess.TimeoutExpired:
logging.writeToFile(f"Warning: lscpd restart timed out, but continuing...")
except Exception as restart_error:
logging.writeToFile(f"Warning: Failed to restart lscpd: {str(restart_error)}")
# Don't fail installation if restart fails, just log it
return JsonResponse({
'success': True,
'message': f'Plugin {plugin_name} installed successfully'
@@ -663,17 +780,36 @@ def _enrich_store_plugins(plugins):
pluginMetaData = ElementTree.parse(meta_path)
root = pluginMetaData.getroot()
paid_elem = root.find('paid')
if paid_elem is not None and paid_elem.text and paid_elem.text.lower() == 'true':
if paid_elem is not None and paid_elem.text and str(paid_elem.text).strip().lower() == 'true':
plugin['is_paid'] = True
# Also update patreon fields if available
patreon_tier_elem = root.find('patreon_tier')
if patreon_tier_elem is not None and patreon_tier_elem.text:
plugin['patreon_tier'] = patreon_tier_elem.text
patreon_url_elem = root.find('patreon_url')
if patreon_url_elem is not None and patreon_url_elem.text:
plugin['patreon_url'] = patreon_url_elem.text
# Check for PayPal payment method first
paypal_me_elem = root.find('paypal_me_url')
paypal_payment_link_elem = root.find('paypal_payment_link')
if (paypal_me_elem is not None and paypal_me_elem.text) or (paypal_payment_link_elem is not None and paypal_payment_link_elem.text):
# This is a PayPal plugin
plugin['payment_type'] = 'paypal'
plugin['paypal_me_url'] = paypal_me_elem.text if paypal_me_elem is not None and paypal_me_elem.text else None
plugin['paypal_payment_link'] = paypal_payment_link_elem.text if paypal_payment_link_elem is not None and paypal_payment_link_elem.text else None
plugin['patreon_tier'] = None
plugin['patreon_url'] = None
else:
# This is a Patreon plugin (default/fallback)
plugin['payment_type'] = 'patreon'
patreon_tier_elem = root.find('patreon_tier')
plugin['patreon_tier'] = patreon_tier_elem.text if patreon_tier_elem is not None and patreon_tier_elem.text else 'CyberPanel Paid Plugin'
patreon_url_elem = root.find('patreon_url')
plugin['patreon_url'] = patreon_url_elem.text if patreon_url_elem is not None and patreon_url_elem.text else 'https://www.patreon.com/c/newstargeted/membership'
plugin['paypal_me_url'] = None
plugin['paypal_payment_link'] = None
else:
plugin['is_paid'] = False
plugin['payment_type'] = None
plugin['patreon_tier'] = None
plugin['patreon_url'] = None
plugin['paypal_me_url'] = None
plugin['paypal_payment_link'] = None
except Exception as e:
logging.writeToFile(f"Error parsing meta.xml for {plugin_dir} in _enrich_store_plugins: {str(e)}")
# Fall back to normalizing existing value
@@ -694,8 +830,16 @@ def _enrich_store_plugins(plugins):
else:
plugin['is_paid'] = False # Default to free if we can't determine
# Ensure it's a proper boolean (not string or other type)
plugin['is_paid'] = bool(plugin['is_paid']) if plugin['is_paid'] not in [True, False] else plugin['is_paid']
# Ensure it's a proper boolean (not string or other type) - CRITICAL for consistency
if plugin['is_paid'] not in [True, False]:
plugin['is_paid'] = bool(plugin['is_paid'])
# Final safety check - force boolean type (defensive programming)
plugin['is_paid'] = True if plugin['is_paid'] is True else False
# Ensure payment_type is set if is_paid is True
if plugin['is_paid'] and 'payment_type' not in plugin:
# Default to patreon if payment_type not set
plugin['payment_type'] = 'patreon'
# Calculate NEW and Stale badges based on modify_date
modify_date_str = plugin.get('modify_date', 'N/A')
@@ -859,19 +1003,39 @@ def _fetch_plugins_from_github():
except Exception as e:
logging.writeToFile(f"Error calculating NEW/Stale for {plugin_name}: {str(e)}")
# Extract paid plugin information
# Extract paid plugin information - support both Patreon and PayPal
paid_elem = root.find('paid')
patreon_tier_elem = root.find('patreon_tier')
is_paid = False
patreon_tier = None
patreon_url = None
paypal_me_url = None
paypal_payment_link = None
payment_type = None
if paid_elem is not None and paid_elem.text and paid_elem.text.lower() == 'true':
if paid_elem is not None and paid_elem.text and str(paid_elem.text).strip().lower() == 'true':
is_paid = True
patreon_tier = patreon_tier_elem.text if patreon_tier_elem is not None and patreon_tier_elem.text else 'CyberPanel Paid Plugin'
patreon_url_elem = root.find('patreon_url')
patreon_url = patreon_url_elem.text if patreon_url_elem is not None else 'https://www.patreon.com/c/newstargeted/membership'
# Check for PayPal payment method first
paypal_me_elem = root.find('paypal_me_url')
paypal_payment_link_elem = root.find('paypal_payment_link')
if (paypal_me_elem is not None and paypal_me_elem.text) or (paypal_payment_link_elem is not None and paypal_payment_link_elem.text):
# This is a PayPal plugin
payment_type = 'paypal'
paypal_me_url = paypal_me_elem.text if paypal_me_elem is not None and paypal_me_elem.text else None
paypal_payment_link = paypal_payment_link_elem.text if paypal_payment_link_elem is not None and paypal_payment_link_elem.text else None
patreon_tier = None
patreon_url = None
else:
# This is a Patreon plugin (default/fallback)
payment_type = 'patreon'
patreon_tier_elem = root.find('patreon_tier')
patreon_tier = patreon_tier_elem.text if patreon_tier_elem is not None and patreon_tier_elem.text else 'CyberPanel Paid Plugin'
patreon_url_elem = root.find('patreon_url')
patreon_url = patreon_url_elem.text if patreon_url_elem is not None and patreon_url_elem.text else 'https://www.patreon.com/c/newstargeted/membership'
paypal_me_url = None
paypal_payment_link = None
plugin_data = {
'plugin_dir': plugin_name,
@@ -885,9 +1049,12 @@ def _fetch_plugins_from_github():
'github_url': f'https://github.com/master3395/cyberpanel-plugins/tree/main/{plugin_name}',
'about_url': f'https://github.com/master3395/cyberpanel-plugins/tree/main/{plugin_name}',
'modify_date': modify_date,
'is_paid': is_paid,
'is_paid': bool(is_paid), # Force boolean type
'patreon_tier': patreon_tier,
'patreon_url': patreon_url,
'paypal_me_url': paypal_me_url,
'paypal_payment_link': paypal_payment_link,
'payment_type': payment_type,
'is_new': is_new,
'is_stale': is_stale
}
@@ -937,21 +1104,38 @@ def fetch_plugin_store(request):
"""Fetch plugins from the plugin store with caching"""
mailUtilities.checkHome()
# Add cache-busting headers to prevent browser caching
response_headers = {
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
# Try to get from cache first
cached_plugins = _get_cached_plugins()
if cached_plugins is not None:
# Sort plugins deterministically by name to prevent order changes
cached_plugins.sort(key=lambda x: x.get('name', '').lower())
# Enrich cached plugins with installed/enabled status
enriched_plugins = _enrich_store_plugins(cached_plugins)
return JsonResponse({
response = JsonResponse({
'success': True,
'plugins': enriched_plugins,
'cached': True
})
}, json_dumps_params={'ensure_ascii': False})
# Add headers
for key, value in response_headers.items():
response[key] = value
return response
# Cache miss or expired - fetch from GitHub
try:
plugins = _fetch_plugins_from_github()
# Sort plugins deterministically by name to prevent order changes
plugins.sort(key=lambda x: x.get('name', '').lower())
# Enrich plugins with installed/enabled status
enriched_plugins = _enrich_store_plugins(plugins)
@@ -959,11 +1143,15 @@ def fetch_plugin_store(request):
if plugins:
_save_plugins_cache(plugins)
return JsonResponse({
response = JsonResponse({
'success': True,
'plugins': enriched_plugins,
'cached': False
})
}, json_dumps_params={'ensure_ascii': False})
# Add cache-busting headers
for key, value in response_headers.items():
response[key] = value
return response
except Exception as e:
error_message = str(e)
@@ -973,13 +1161,19 @@ def fetch_plugin_store(request):
stale_cache = _get_cached_plugins(allow_expired=True) # Get cache even if expired
if stale_cache is not None:
logging.writeToFile("Using stale cache due to rate limit")
# Sort plugins deterministically by name to prevent order changes
stale_cache.sort(key=lambda x: x.get('name', '').lower())
enriched_plugins = _enrich_store_plugins(stale_cache)
return JsonResponse({
response = JsonResponse({
'success': True,
'plugins': enriched_plugins,
'cached': True,
'warning': 'Using cached data due to GitHub rate limit. Data may be outdated.'
})
}, json_dumps_params={'ensure_ascii': False})
# Add cache-busting headers
for key, value in response_headers.items():
response[key] = value
return response
# No cache available, return error
return JsonResponse({
@@ -1123,9 +1317,21 @@ def install_from_store(request, plugin_name):
else:
raise Exception(f'Plugin installation failed: {error_msg}')
# Wait a moment for file system to sync and service to restart
# Wait a moment for file system to sync
import time
time.sleep(3) # Increased wait time for file system sync
time.sleep(2) # Wait for file system sync
# Restart lscpd service to ensure plugin loads immediately
try:
logging.writeToFile(f"Restarting lscpd service after plugin installation...")
subprocess.run(['systemctl', 'restart', 'lscpd'], check=True, timeout=30)
logging.writeToFile(f"lscpd service restarted successfully")
time.sleep(2) # Wait for service to fully restart
except subprocess.TimeoutExpired:
logging.writeToFile(f"Warning: lscpd restart timed out, but continuing...")
except Exception as restart_error:
logging.writeToFile(f"Warning: Failed to restart lscpd: {str(restart_error)}")
# Don't fail installation if restart fails, just log it
# Verify plugin was actually installed
pluginInstalled = '/usr/local/CyberCP/' + plugin_name

View File

@@ -71,8 +71,8 @@ class pluginInstaller:
@staticmethod
def upgradingSettingsFile(pluginName):
data = open("/usr/local/CyberCP/CyberCP/settings.py", 'r').readlines()
writeToFile = open("/usr/local/CyberCP/CyberCP/settings.py", 'w')
data = open("/usr/local/CyberCP/CyberCP/settings.py", 'r', encoding='utf-8').readlines()
writeToFile = open("/usr/local/CyberCP/CyberCP/settings.py", 'w', encoding='utf-8')
for items in data:
if items.find("'emailPremium',") > -1:
@@ -90,8 +90,8 @@ class pluginInstaller:
Plugin URLs must be inserted BEFORE the generic 'plugins/' line
to ensure proper route matching (more specific routes first)
"""
data = open("/usr/local/CyberCP/CyberCP/urls.py", 'r').readlines()
writeToFile = open("/usr/local/CyberCP/CyberCP/urls.py", 'w')
data = open("/usr/local/CyberCP/CyberCP/urls.py", 'r', encoding='utf-8').readlines()
writeToFile = open("/usr/local/CyberCP/CyberCP/urls.py", 'w', encoding='utf-8')
urlPatternAdded = False
for items in data:
@@ -109,7 +109,7 @@ class pluginInstaller:
if not urlPatternAdded:
pluginInstaller.stdOut(f"Warning: 'plugins/' line not found, using fallback insertion after 'manageservices'")
writeToFile.close()
writeToFile = open("/usr/local/CyberCP/CyberCP/urls.py", 'w')
writeToFile = open("/usr/local/CyberCP/CyberCP/urls.py", 'w', encoding='utf-8')
for items in data:
if items.find("manageservices") > -1:
writeToFile.writelines(items)
@@ -132,8 +132,8 @@ class pluginInstaller:
@staticmethod
def addInterfaceLink(pluginName):
data = open("/usr/local/CyberCP/baseTemplate/templates/baseTemplate/index.html", 'r').readlines()
writeToFile = open("/usr/local/CyberCP/baseTemplate/templates/baseTemplate/index.html", 'w')
data = open("/usr/local/CyberCP/baseTemplate/templates/baseTemplate/index.html", 'r', encoding='utf-8').readlines()
writeToFile = open("/usr/local/CyberCP/baseTemplate/templates/baseTemplate/index.html", 'w', encoding='utf-8')
for items in data:
if items.find("{# pluginsList #}") > -1:
@@ -290,8 +290,8 @@ class pluginInstaller:
@staticmethod
def removeFromSettings(pluginName):
data = open("/usr/local/CyberCP/CyberCP/settings.py", 'r').readlines()
writeToFile = open("/usr/local/CyberCP/CyberCP/settings.py", 'w')
data = open("/usr/local/CyberCP/CyberCP/settings.py", 'r', encoding='utf-8').readlines()
writeToFile = open("/usr/local/CyberCP/CyberCP/settings.py", 'w', encoding='utf-8')
for items in data:
if items.find(pluginName) > -1:
@@ -302,8 +302,8 @@ class pluginInstaller:
@staticmethod
def removeFromURLs(pluginName):
data = open("/usr/local/CyberCP/CyberCP/urls.py", 'r').readlines()
writeToFile = open("/usr/local/CyberCP/CyberCP/urls.py", 'w')
data = open("/usr/local/CyberCP/CyberCP/urls.py", 'r', encoding='utf-8').readlines()
writeToFile = open("/usr/local/CyberCP/CyberCP/urls.py", 'w', encoding='utf-8')
for items in data:
if items.find(pluginName) > -1:
@@ -322,8 +322,8 @@ class pluginInstaller:
@staticmethod
def removeInterfaceLink(pluginName):
data = open("/usr/local/CyberCP/baseTemplate/templates/baseTemplate/index.html", 'r').readlines()
writeToFile = open("/usr/local/CyberCP/baseTemplate/templates/baseTemplate/index.html", 'w')
data = open("/usr/local/CyberCP/baseTemplate/templates/baseTemplate/index.html", 'r', encoding='utf-8').readlines()
writeToFile = open("/usr/local/CyberCP/baseTemplate/templates/baseTemplate/index.html", 'w', encoding='utf-8')
for items in data:
if items.find(pluginName) > -1 and items.find('<li>') > -1: